[llvm] [LICM] Invalidate cached SCEV results after reassociation (PR #92655)
Antonio Frighetto via llvm-commits
llvm-commits at lists.llvm.org
Sat May 18 08:08:53 PDT 2024
https://github.com/antoniofrighetto created https://github.com/llvm/llvm-project/pull/92655
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.
>From a00695a7c29b09bae29b09a6532353d9c0de6fdb Mon Sep 17 00:00:00 2001
From: Antonio Frighetto <me at antoniofrighetto.com>
Date: Sat, 18 May 2024 16:46:03 +0200
Subject: [PATCH 1/2] [LICM] Introduce test for PR92654
---
.../LICM/update-scev-after-hoist.ll | 24 +++++++++++++++++++
1 file changed, 24 insertions(+)
create mode 100644 llvm/test/Transforms/LICM/update-scev-after-hoist.ll
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..f834a74b6f247
--- /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: full-set 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: --> (2 * %mul) U: [0,-1) S: [-32768,32767) Exits: 8192 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
+}
>From b9ae0cf9f7ec8c84cb879fd0d9ce9a731f072661 Mon Sep 17 00:00:00 2001
From: Antonio Frighetto <me at antoniofrighetto.com>
Date: Sat, 18 May 2024 16:52:17 +0200
Subject: [PATCH 2/2] [LICM] Invalidate cached SCEV results after reassociation
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.
---
llvm/lib/Transforms/Scalar/LICM.cpp | 12 +++++++-----
llvm/test/Transforms/LICM/update-scev-after-hoist.ll | 4 ++--
2 files changed, 9 insertions(+), 7 deletions(-)
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
index f834a74b6f247..f0876c3fa00e6 100644
--- a/llvm/test/Transforms/LICM/update-scev-after-hoist.ll
+++ b/llvm/test/Transforms/LICM/update-scev-after-hoist.ll
@@ -3,11 +3,11 @@
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: full-set S: [-32768,32753) Exits: 4096 LoopDispositions: { %loop: Variant }
+; 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: --> (2 * %mul) U: [0,-1) S: [-32768,32767) Exits: 8192 LoopDispositions: { %loop: Variant }
+; SCEV-EXPR-NEXT: --> (8 * %mul) U: [0,-7) S: [-32768,32761) Exits: -32768 LoopDispositions: { %loop: Variant }
entry:
br label %loop
More information about the llvm-commits
mailing list