Skip to content

Commit d99f3ba

Browse files
author
Max Kazantsev
committedMay 23, 2018
[LoopUnswitch] Fix SCEV invalidation in unswitching
Loop unswitching makes substantial changes to a loop that can also affect cached SCEV info in its outer loops as well, but it only cares to invalidate SCEV cache for the innermost loop in case of full unswitching and does not invalidate anything at all in case of trivial unswitching. As result, we may end up with incorrect data in cache. Differential Revision: https://reviews.llvm.org/D46045 Reviewed By: mzolotukhin llvm-svn: 333072
1 parent c0099f9 commit d99f3ba

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed
 

‎llvm/lib/Transforms/Scalar/LoopUnswitch.cpp

+7-1
Original file line numberDiff line numberDiff line change
@@ -975,6 +975,10 @@ void LoopUnswitch::UnswitchTrivialCondition(Loop *L, Value *Cond, Constant *Val,
975975
<< " blocks] in Function "
976976
<< L->getHeader()->getParent()->getName()
977977
<< " on cond: " << *Val << " == " << *Cond << "\n");
978+
// We are going to make essential changes to CFG. This may invalidate cached
979+
// information for L or one of its parent loops in SCEV.
980+
if (auto *SEWP = getAnalysisIfAvailable<ScalarEvolutionWrapperPass>())
981+
SEWP->getSE().forgetTopmostLoop(L);
978982

979983
// First step, split the preheader, so that we know that there is a safe place
980984
// to insert the conditional branch. We will change loopPreheader to have a
@@ -1201,8 +1205,10 @@ void LoopUnswitch::UnswitchNontrivialCondition(Value *LIC, Constant *Val,
12011205
<< " blocks] in Function " << F->getName() << " when '"
12021206
<< *Val << "' == " << *LIC << "\n");
12031207

1208+
// We are going to make essential changes to CFG. This may invalidate cached
1209+
// information for L or one of its parent loops in SCEV.
12041210
if (auto *SEWP = getAnalysisIfAvailable<ScalarEvolutionWrapperPass>())
1205-
SEWP->getSE().forgetLoop(L);
1211+
SEWP->getSE().forgetTopmostLoop(L);
12061212

12071213
LoopBlocks.clear();
12081214
NewBlocks.clear();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
; RUN: opt -S -indvars -loop-unswitch < %s | FileCheck %s
2+
3+
target triple = "x86_64-unknown-linux-gnu"
4+
5+
define void @test_01() {
6+
7+
; Make sure we don't fail by SCEV's assertion due to incorrect invalidation.
8+
; CHECK-LABEL: @test_01
9+
10+
entry:
11+
br label %loop
12+
13+
loop: ; preds = %backedge, %entry
14+
%p_50.addr.0 = phi i16 [ undef, %entry ], [ %add2699, %backedge ]
15+
%idxprom2690 = sext i16 %p_50.addr.0 to i32
16+
%arrayidx2691 = getelementptr inbounds [5 x i32], [5 x i32]* undef, i32 0, i32 %idxprom2690
17+
%0 = load i32, i32* %arrayidx2691, align 1
18+
%tobool2692 = icmp ne i32 %0, 0
19+
br label %inner_loop
20+
21+
inner_loop: ; preds = %inner_backedge, %loop
22+
br i1 %tobool2692, label %backedge, label %inner_backedge
23+
24+
inner_backedge: ; preds = %inner_loop
25+
br label %inner_loop
26+
27+
backedge: ; preds = %inner_loop
28+
%add2699 = add nsw i16 %p_50.addr.0, 1
29+
br i1 false, label %loop, label %exit
30+
31+
exit: ; preds = %backedge
32+
unreachable
33+
}

0 commit comments

Comments
 (0)
Please sign in to comment.