[llvm] [SCEV] Use ashr to adjust constant multipliers (PR #135534)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Apr 13 02:11:31 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-analysis
Author: Yingwei Zheng (dtcxzyw)
<details>
<summary>Changes</summary>
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 https://github.com/llvm/llvm-project/issues/135531.
---
Full diff: https://github.com/llvm/llvm-project/pull/135534.diff
2 Files Affected:
- (modified) llvm/lib/Analysis/ScalarEvolution.cpp (+1-1)
- (added) llvm/test/Analysis/ScalarEvolution/pr135531.ll (+19)
``````````diff
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index c62ea1526981d..d193c9e3210ea 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -7841,7 +7841,7 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) {
unsigned GCD = std::min(MulZeros, TZ);
APInt DivAmt = APInt::getOneBitSet(BitWidth, TZ - GCD);
SmallVector<const SCEV*, 4> MulOps;
- MulOps.push_back(getConstant(OpC->getAPInt().lshr(GCD)));
+ MulOps.push_back(getConstant(OpC->getAPInt().ashr(GCD)));
append_range(MulOps, LHSMul->operands().drop_front());
auto *NewMul = getMulExpr(MulOps, LHSMul->getNoWrapFlags());
ShiftedLHS = getUDivExpr(NewMul, getConstant(DivAmt));
diff --git a/llvm/test/Analysis/ScalarEvolution/pr135531.ll b/llvm/test/Analysis/ScalarEvolution/pr135531.ll
new file mode 100644
index 0000000000000..e172d56d3a515
--- /dev/null
+++ b/llvm/test/Analysis/ScalarEvolution/pr135531.ll
@@ -0,0 +1,19 @@
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -disable-output -passes='print<scalar-evolution>' < %s 2>&1 | FileCheck %s
+
+define i32 @pr135511(i32 %x) {
+; CHECK-LABEL: 'pr135511'
+; CHECK-NEXT: Classifying expressions for: @pr135511
+; CHECK-NEXT: %and = and i32 %x, 16382
+; CHECK-NEXT: --> (2 * (zext i13 (trunc i32 (%x /u 2) to i13) to i32))<nuw><nsw> U: [0,16383) S: [0,16383)
+; CHECK-NEXT: %neg = sub nsw i32 0, %and
+; CHECK-NEXT: --> (-2 * (zext i13 (trunc i32 (%x /u 2) to i13) to i32))<nsw> U: [0,-1) S: [-16382,1)
+; CHECK-NEXT: %res = and i32 %neg, 268431360
+; 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)
+; CHECK-NEXT: Determining loop execution counts for: @pr135511
+;
+ %and = and i32 %x, 16382
+ %neg = sub nsw i32 0, %and
+ %res = and i32 %neg, 268431360
+ ret i32 %res
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/135534
More information about the llvm-commits
mailing list