Skip to content

Commit aa784fd

Browse files
dtcxzywllvmbot
authored andcommitted
[SCEV] Use ashr to adjust constant multipliers (#135534)
SCEV converts "-2 *nsw (i32 V)" into "2148473647 *nsw (i32 V)". But we cannot preserve the nsw flag when the constant multiplier is negative. This patch changes lshr to ashr so that we can preserve both nsw and nuw flags. Alive2 proof: https://alive2.llvm.org/ce/z/LZVSEa Closes #135531. (cherry picked from commit bb9580a)
1 parent e0db588 commit aa784fd

File tree

2 files changed

+20
-1
lines changed

2 files changed

+20
-1
lines changed

llvm/lib/Analysis/ScalarEvolution.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -7854,7 +7854,7 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) {
78547854
unsigned GCD = std::min(MulZeros, TZ);
78557855
APInt DivAmt = APInt::getOneBitSet(BitWidth, TZ - GCD);
78567856
SmallVector<const SCEV*, 4> MulOps;
7857-
MulOps.push_back(getConstant(OpC->getAPInt().lshr(GCD)));
7857+
MulOps.push_back(getConstant(OpC->getAPInt().ashr(GCD)));
78587858
append_range(MulOps, LHSMul->operands().drop_front());
78597859
auto *NewMul = getMulExpr(MulOps, LHSMul->getNoWrapFlags());
78607860
ShiftedLHS = getUDivExpr(NewMul, getConstant(DivAmt));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt -disable-output -passes='print<scalar-evolution>' < %s 2>&1 | FileCheck %s
3+
4+
define i32 @pr135511(i32 %x) {
5+
; CHECK-LABEL: 'pr135511'
6+
; CHECK-NEXT: Classifying expressions for: @pr135511
7+
; CHECK-NEXT: %and = and i32 %x, 16382
8+
; CHECK-NEXT: --> (2 * (zext i13 (trunc i32 (%x /u 2) to i13) to i32))<nuw><nsw> U: [0,16383) S: [0,16383)
9+
; CHECK-NEXT: %neg = sub nsw i32 0, %and
10+
; CHECK-NEXT: --> (-2 * (zext i13 (trunc i32 (%x /u 2) to i13) to i32))<nsw> U: [0,-1) S: [-16382,1)
11+
; CHECK-NEXT: %res = and i32 %neg, 268431360
12+
; CHECK-NEXT: --> (4096 * (zext i16 (trunc i32 ((-1 * (zext i13 (trunc i32 (%x /u 2) to i13) to i32))<nsw> /u 2048) to i16) to i32))<nuw><nsw> U: [0,268431361) S: [0,268431361)
13+
; CHECK-NEXT: Determining loop execution counts for: @pr135511
14+
;
15+
%and = and i32 %x, 16382
16+
%neg = sub nsw i32 0, %and
17+
%res = and i32 %neg, 268431360
18+
ret i32 %res
19+
}

0 commit comments

Comments
 (0)