Skip to content

Commit bb9580a

Browse files
authored
[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.
1 parent 77fcdb9 commit bb9580a

File tree

2 files changed

+20
-1
lines changed

2 files changed

+20
-1
lines changed

llvm/lib/Analysis/ScalarEvolution.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7841,7 +7841,7 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) {
78417841
unsigned GCD = std::min(MulZeros, TZ);
78427842
APInt DivAmt = APInt::getOneBitSet(BitWidth, TZ - GCD);
78437843
SmallVector<const SCEV*, 4> MulOps;
7844-
MulOps.push_back(getConstant(OpC->getAPInt().lshr(GCD)));
7844+
MulOps.push_back(getConstant(OpC->getAPInt().ashr(GCD)));
78457845
append_range(MulOps, LHSMul->operands().drop_front());
78467846
auto *NewMul = getMulExpr(MulOps, LHSMul->getNoWrapFlags());
78477847
ShiftedLHS = getUDivExpr(NewMul, getConstant(DivAmt));
Lines changed: 19 additions & 0 deletions
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)