[llvm] [LICM] Invalidate cached SCEV results after reassociation (PR #92655)
via llvm-commits
llvm-commits at lists.llvm.org
Sat May 18 08:09:27 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Antonio Frighetto (antoniofrighetto)
<details>
<summary>Changes</summary>
After reassociating expressions, LICM is required to invalidate SCEV results, as otherwise it could lead subsequent passes in the pipeline (e.g., IndVars) to miscompile.
Fixes: https://github.com/llvm/llvm-project/issues/91957.
---
Full diff: https://github.com/llvm/llvm-project/pull/92655.diff
2 Files Affected:
- (modified) llvm/lib/Transforms/Scalar/LICM.cpp (+7-5)
- (added) llvm/test/Transforms/LICM/update-scev-after-hoist.ll (+24)
``````````diff
diff --git a/llvm/lib/Transforms/Scalar/LICM.cpp b/llvm/lib/Transforms/Scalar/LICM.cpp
index 6aa4188d1cc4d..d5716c5cda59d 100644
--- a/llvm/lib/Transforms/Scalar/LICM.cpp
+++ b/llvm/lib/Transforms/Scalar/LICM.cpp
@@ -194,7 +194,7 @@ static bool pointerInvalidatedByBlock(BasicBlock &BB, MemorySSA &MSSA,
static bool hoistArithmetics(Instruction &I, Loop &L,
ICFLoopSafetyInfo &SafetyInfo,
MemorySSAUpdater &MSSAU, AssumptionCache *AC,
- DominatorTree *DT);
+ DominatorTree *DT, ScalarEvolution *SE);
static Instruction *cloneInstructionInExitBlock(
Instruction &I, BasicBlock &ExitBlock, PHINode &PN, const LoopInfo *LI,
const LoopSafetyInfo *SafetyInfo, MemorySSAUpdater &MSSAU);
@@ -987,7 +987,7 @@ bool llvm::hoistRegion(DomTreeNode *N, AAResults *AA, LoopInfo *LI,
// Try to reassociate instructions so that part of computations can be
// done out of loop.
- if (hoistArithmetics(I, *CurLoop, *SafetyInfo, MSSAU, AC, DT)) {
+ if (hoistArithmetics(I, *CurLoop, *SafetyInfo, MSSAU, AC, DT, SE)) {
Changed = true;
continue;
}
@@ -2690,7 +2690,7 @@ static bool isReassociableOp(Instruction *I, unsigned IntOpcode,
static bool hoistMulAddAssociation(Instruction &I, Loop &L,
ICFLoopSafetyInfo &SafetyInfo,
MemorySSAUpdater &MSSAU, AssumptionCache *AC,
- DominatorTree *DT) {
+ DominatorTree *DT, ScalarEvolution *SE) {
if (!isReassociableOp(&I, Instruction::Mul, Instruction::FMul))
return false;
Value *VariantOp = I.getOperand(0);
@@ -2761,6 +2761,8 @@ static bool hoistMulAddAssociation(Instruction &I, Loop &L,
Mul = Builder.CreateFMulFMF(U->get(), Factor, Ins, "factor.op.fmul");
U->set(Mul);
}
+ if (SE)
+ SE->forgetValue(&I);
I.replaceAllUsesWith(VariantOp);
eraseInstruction(I, SafetyInfo, MSSAU);
return true;
@@ -2769,7 +2771,7 @@ static bool hoistMulAddAssociation(Instruction &I, Loop &L,
static bool hoistArithmetics(Instruction &I, Loop &L,
ICFLoopSafetyInfo &SafetyInfo,
MemorySSAUpdater &MSSAU, AssumptionCache *AC,
- DominatorTree *DT) {
+ DominatorTree *DT, ScalarEvolution *SE) {
// Optimize complex patterns, such as (x < INV1 && x < INV2), turning them
// into (x < min(INV1, INV2)), and hoisting the invariant part of this
// expression out of the loop.
@@ -2794,7 +2796,7 @@ static bool hoistArithmetics(Instruction &I, Loop &L,
}
bool IsInt = I.getType()->isIntOrIntVectorTy();
- if (hoistMulAddAssociation(I, L, SafetyInfo, MSSAU, AC, DT)) {
+ if (hoistMulAddAssociation(I, L, SafetyInfo, MSSAU, AC, DT, SE)) {
++NumHoisted;
if (IsInt)
++NumIntAssociationsHoisted;
diff --git a/llvm/test/Transforms/LICM/update-scev-after-hoist.ll b/llvm/test/Transforms/LICM/update-scev-after-hoist.ll
new file mode 100644
index 0000000000000..f0876c3fa00e6
--- /dev/null
+++ b/llvm/test/Transforms/LICM/update-scev-after-hoist.ll
@@ -0,0 +1,24 @@
+; RUN: opt -S -passes='loop-unroll,loop-mssa(licm),print<scalar-evolution>' -unroll-count=4 -disable-output < %s 2>&1 | FileCheck %s --check-prefix=SCEV-EXPR
+
+define i16 @main() {
+; SCEV-EXPR: Classifying expressions for: @main
+; SCEV-EXPR-NEXT: %mul = phi i16 [ 1, %entry ], [ %mul.n.3, %loop ]
+; SCEV-EXPR-NEXT: --> %mul U: [0,-15) S: [-32768,32753) Exits: 4096 LoopDispositions: { %loop: Variant }
+; SCEV-EXPR-NEXT: %div = phi i16 [ 32767, %entry ], [ %div.n.3, %loop ]
+; SCEV-EXPR-NEXT: --> %div U: [-2048,-32768) S: [-2048,-32768) Exits: 7 LoopDispositions: { %loop: Variant }
+; SCEV-EXPR-NEXT: %mul.n = mul i16 %mul, 8
+; SCEV-EXPR-NEXT: --> (8 * %mul) U: [0,-7) S: [-32768,32761) Exits: -32768 LoopDispositions: { %loop: Variant }
+entry:
+ br label %loop
+
+loop:
+ %mul = phi i16 [ 1, %entry ], [ %mul.n, %loop ]
+ %div = phi i16 [ 32767, %entry ], [ %div.n, %loop ]
+ %mul.n = mul i16 %mul, 2
+ %div.n = sdiv i16 %div, 2
+ %cmp = icmp sgt i16 %div, 0
+ br i1 %cmp, label %loop, label %end
+
+end:
+ ret i16 %mul
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/92655
More information about the llvm-commits
mailing list