[LCSSA] Forget values we create LCSSA phis for
Summary: Currently we only forget the loop we added LCSSA phis for. But SCEV expressions in other loops could also depend on the instruction we added a PHI for and currently we do not invalidate those expressions. This can happen when we use ScalarEvolution before converting a function to LCSSA form. The SCEV expressions will refer to the non-LCSSA value. If this SCEV expression is then used with the expander, we do not preserve LCSSA form. This patch properly forgets the values we created PHIs for. Those need to be recomputed again. This patch fixes PR43458. Currently SCEV::verify does not catch this mismatch and any test would need to run multiple passes to trigger the error (e.g. -loop-reduce -loop-unroll). I will also look into catching this kind of mismatch in the verifier. Also, we currently forget the whole loop in LCSSA and I'll check if we can be more surgical. Reviewers: efriedma, sanjoy.google, reames Reviewed By: efriedma Subscribers: zzheng, hiraditya, javed.absar, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D68194
This commit is contained in:
parent
2c496bb530
commit
596e4ab97a
|
@ -73,7 +73,8 @@ bool formDedicatedExitBlocks(Loop *L, DominatorTree *DT, LoopInfo *LI,
|
||||||
///
|
///
|
||||||
/// Returns true if any modifications are made.
|
/// Returns true if any modifications are made.
|
||||||
bool formLCSSAForInstructions(SmallVectorImpl<Instruction *> &Worklist,
|
bool formLCSSAForInstructions(SmallVectorImpl<Instruction *> &Worklist,
|
||||||
DominatorTree &DT, LoopInfo &LI);
|
DominatorTree &DT, LoopInfo &LI,
|
||||||
|
ScalarEvolution *SE);
|
||||||
|
|
||||||
/// Put loop into LCSSA form.
|
/// Put loop into LCSSA form.
|
||||||
///
|
///
|
||||||
|
|
|
@ -74,7 +74,8 @@ static bool isExitBlock(BasicBlock *BB,
|
||||||
/// that are outside the current loop. If so, insert LCSSA PHI nodes and
|
/// that are outside the current loop. If so, insert LCSSA PHI nodes and
|
||||||
/// rewrite the uses.
|
/// rewrite the uses.
|
||||||
bool llvm::formLCSSAForInstructions(SmallVectorImpl<Instruction *> &Worklist,
|
bool llvm::formLCSSAForInstructions(SmallVectorImpl<Instruction *> &Worklist,
|
||||||
DominatorTree &DT, LoopInfo &LI) {
|
DominatorTree &DT, LoopInfo &LI,
|
||||||
|
ScalarEvolution *SE) {
|
||||||
SmallVector<Use *, 16> UsesToRewrite;
|
SmallVector<Use *, 16> UsesToRewrite;
|
||||||
SmallSetVector<PHINode *, 16> PHIsToRemove;
|
SmallSetVector<PHINode *, 16> PHIsToRemove;
|
||||||
PredIteratorCache PredCache;
|
PredIteratorCache PredCache;
|
||||||
|
@ -134,6 +135,11 @@ bool llvm::formLCSSAForInstructions(SmallVectorImpl<Instruction *> &Worklist,
|
||||||
SSAUpdater SSAUpdate(&InsertedPHIs);
|
SSAUpdater SSAUpdate(&InsertedPHIs);
|
||||||
SSAUpdate.Initialize(I->getType(), I->getName());
|
SSAUpdate.Initialize(I->getType(), I->getName());
|
||||||
|
|
||||||
|
// Force re-computation of I, as some users now need to use the new PHI
|
||||||
|
// node.
|
||||||
|
if (SE)
|
||||||
|
SE->forgetValue(I);
|
||||||
|
|
||||||
// Insert the LCSSA phi's into all of the exit blocks dominated by the
|
// Insert the LCSSA phi's into all of the exit blocks dominated by the
|
||||||
// value, and add them to the Phi's map.
|
// value, and add them to the Phi's map.
|
||||||
for (BasicBlock *ExitBB : ExitBlocks) {
|
for (BasicBlock *ExitBB : ExitBlocks) {
|
||||||
|
@ -368,7 +374,7 @@ bool llvm::formLCSSA(Loop &L, DominatorTree &DT, LoopInfo *LI,
|
||||||
Worklist.push_back(&I);
|
Worklist.push_back(&I);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Changed = formLCSSAForInstructions(Worklist, DT, *LI);
|
Changed = formLCSSAForInstructions(Worklist, DT, *LI, SE);
|
||||||
|
|
||||||
// If we modified the code, remove any caches about the loop from SCEV to
|
// If we modified the code, remove any caches about the loop from SCEV to
|
||||||
// avoid dangling entries.
|
// avoid dangling entries.
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||||
|
; RUN: opt -loop-reduce -loop-unroll -unroll-runtime -verify-scev -verify-loop-lcssa < %s -S | FileCheck %s
|
||||||
|
|
||||||
|
; Test case for PR43458. We check that we do properly invalidate LCSSA phi
|
||||||
|
; users in SCEV. Run -loop-reduce first, so SCEV is already populated.
|
||||||
|
|
||||||
|
define void @spam() {
|
||||||
|
; CHECK-LABEL: @spam(
|
||||||
|
; CHECK-NEXT: bb:
|
||||||
|
; CHECK-NEXT: br label [[BB3:%.*]]
|
||||||
|
; CHECK: bb3:
|
||||||
|
; CHECK-NEXT: br i1 false, label [[BB9:%.*]], label [[BB5_PREHEADER:%.*]]
|
||||||
|
; CHECK: bb5.preheader:
|
||||||
|
; CHECK-NEXT: br label [[BB5:%.*]]
|
||||||
|
; CHECK: bb5:
|
||||||
|
; CHECK-NEXT: br label [[BB9]]
|
||||||
|
; CHECK: bb9:
|
||||||
|
; CHECK-NEXT: [[TMP10:%.*]] = phi i64 [ 0, [[BB3]] ], [ 5, [[BB5]] ]
|
||||||
|
; CHECK-NEXT: [[TMP11:%.*]] = trunc i64 [[TMP10]] to i32
|
||||||
|
; CHECK-NEXT: [[TMP21:%.*]] = sext i32 [[TMP11]] to i64
|
||||||
|
; CHECK-NEXT: [[TMP22:%.*]] = icmp slt i64 0, [[TMP21]]
|
||||||
|
; CHECK-NEXT: br i1 [[TMP22]], label [[BB24_PREHEADER:%.*]], label [[BB29:%.*]]
|
||||||
|
; CHECK: bb24.preheader:
|
||||||
|
; CHECK-NEXT: br label [[BB24:%.*]]
|
||||||
|
; CHECK: bb24:
|
||||||
|
; CHECK-NEXT: [[TMP25:%.*]] = phi i64 [ [[TMP26:%.*]], [[BB24]] ], [ 0, [[BB24_PREHEADER]] ]
|
||||||
|
; CHECK-NEXT: [[TMP26]] = add nuw nsw i64 [[TMP25]], 1
|
||||||
|
; CHECK-NEXT: [[TMP27:%.*]] = icmp slt i64 [[TMP26]], [[TMP21]]
|
||||||
|
; CHECK-NEXT: br i1 [[TMP27]], label [[BB24]], label [[BB29_LOOPEXIT:%.*]]
|
||||||
|
; CHECK: bb29.loopexit:
|
||||||
|
; CHECK-NEXT: br label [[BB29]]
|
||||||
|
; CHECK: bb29:
|
||||||
|
; CHECK-NEXT: ret void
|
||||||
|
;
|
||||||
|
bb:
|
||||||
|
br label %bb3
|
||||||
|
|
||||||
|
bb3: ; preds = %bb9, %bb
|
||||||
|
%pv1 = phi i64 [ 0, %bb ], [ %iv1, %bb9]
|
||||||
|
%c1 = icmp eq i64 %pv1, 5
|
||||||
|
br i1 %c1, label %bb9, label %bb5
|
||||||
|
|
||||||
|
bb5: ; preds = %bb5, %bb3
|
||||||
|
%pv = phi i64 [ 0, %bb3], [ %tmp6, %bb5]
|
||||||
|
%tmp6 = add nsw i64 %pv, 1
|
||||||
|
%cond = icmp eq i64 %tmp6, 5
|
||||||
|
br i1 %cond, label %bb8, label %bb5
|
||||||
|
|
||||||
|
bb8: ; preds = %bb5
|
||||||
|
br label %bb9
|
||||||
|
|
||||||
|
bb9: ; preds = %bb8, %bb3
|
||||||
|
%tmp10 = phi i64 [ 0, %bb3 ], [ %tmp6, %bb8 ]
|
||||||
|
%tmp11 = trunc i64 %tmp10 to i32
|
||||||
|
%iv1 = add nsw i64 %pv1, 1
|
||||||
|
br i1 false, label %bb3, label %bb20
|
||||||
|
|
||||||
|
bb20: ; preds = %bb9
|
||||||
|
%tmp21 = sext i32 %tmp11 to i64
|
||||||
|
%tmp22 = icmp slt i64 0, %tmp21
|
||||||
|
br i1 %tmp22, label %bb24, label %bb29
|
||||||
|
|
||||||
|
bb24: ; preds = %bb24, %bb20
|
||||||
|
%tmp25 = phi i64 [ %tmp26, %bb24 ], [ 0, %bb20 ]
|
||||||
|
%tmp26 = add nuw nsw i64 %tmp25, 1
|
||||||
|
%tmp27 = icmp slt i64 %tmp26, %tmp21
|
||||||
|
br i1 %tmp27, label %bb24, label %bb29
|
||||||
|
|
||||||
|
bb29: ; preds = %bb24, %bb20
|
||||||
|
ret void
|
||||||
|
}
|
Loading…
Reference in New Issue