Skip to content

Commit 70091dc

Browse files
[LICM] Invalidate cached SCEV results in hoistMulAddAssociation
While reassociating expressions, LICM is required to invalidate SCEV results, as otherwise subsequent passes in the pipeline that leverage LICM foldings (e.g. IndVars), may reason on invalid expressions; thus miscompiling. This is achieved by rewriting the reassociable instruction from scratch. Fixes: #91957.
1 parent c2a9a97 commit 70091dc

File tree

2 files changed

+17
-5
lines changed

2 files changed

+17
-5
lines changed

llvm/lib/Transforms/Scalar/LICM.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2751,16 +2751,28 @@ static bool hoistMulAddAssociation(Instruction &I, Loop &L,
27512751
IRBuilder<> Builder(Preheader->getTerminator());
27522752
for (auto *U : Changes) {
27532753
assert(L.isLoopInvariant(U->get()));
2754-
Instruction *Ins = cast<Instruction>(U->getUser());
2754+
auto *Ins = cast<BinaryOperator>(U->getUser());
27552755
Value *Mul;
27562756
if (I.getType()->isIntOrIntVectorTy()) {
27572757
Mul = Builder.CreateMul(U->get(), Factor, "factor.op.mul");
27582758
// Drop the poison flags on the original multiply.
27592759
Ins->dropPoisonGeneratingFlags();
27602760
} else
27612761
Mul = Builder.CreateFMulFMF(U->get(), Factor, Ins, "factor.op.fmul");
2762-
U->set(Mul);
2762+
2763+
// Rewrite the reassociable instruction.
2764+
unsigned OpIdx = U->getOperandNo();
2765+
auto *LHS = OpIdx == 0 ? Mul : Ins->getOperand(0);
2766+
auto *RHS = OpIdx == 1 ? Mul : Ins->getOperand(1);
2767+
auto *NewBO = BinaryOperator::Create(Ins->getOpcode(), LHS, RHS,
2768+
Ins->getName() + ".reass", Ins);
2769+
NewBO->copyIRFlags(Ins);
2770+
if (VariantOp == Ins)
2771+
VariantOp = NewBO;
2772+
Ins->replaceAllUsesWith(NewBO);
2773+
eraseInstruction(*Ins, SafetyInfo, MSSAU);
27632774
}
2775+
27642776
I.replaceAllUsesWith(VariantOp);
27652777
eraseInstruction(I, SafetyInfo, MSSAU);
27662778
return true;

llvm/test/Transforms/LICM/update-scev-after-hoist.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
define i16 @main() {
44
; SCEV-EXPR: Classifying expressions for: @main
55
; SCEV-EXPR-NEXT: %mul = phi i16 [ 1, %entry ], [ %mul.n.3, %loop ]
6-
; SCEV-EXPR-NEXT: --> %mul U: full-set S: [-32768,32753) Exits: 4096 LoopDispositions: { %loop: Variant }
6+
; SCEV-EXPR-NEXT: --> %mul U: [0,-15) S: [-32768,32753) Exits: 4096 LoopDispositions: { %loop: Variant }
77
; SCEV-EXPR-NEXT: %div = phi i16 [ 32767, %entry ], [ %div.n.3, %loop ]
88
; SCEV-EXPR-NEXT: --> %div U: [-2048,-32768) S: [-2048,-32768) Exits: 7 LoopDispositions: { %loop: Variant }
9-
; SCEV-EXPR-NEXT: %mul.n = mul i16 %mul, 8
10-
; SCEV-EXPR-NEXT: --> (2 * %mul) U: [0,-1) S: [-32768,32767) Exits: 8192 LoopDispositions: { %loop: Variant }
9+
; SCEV-EXPR-NEXT: %mul.n.reass.reass = mul i16 %mul, 8
10+
; SCEV-EXPR-NEXT: --> (8 * %mul) U: [0,-7) S: [-32768,32761) Exits: -32768 LoopDispositions: { %loop: Variant }
1111
entry:
1212
br label %loop
1313

0 commit comments

Comments
 (0)