[LICM] Store sink and indirectbr instructions

Loop simplify skips exit-block insertion when exits contain indirectbr
instructions. This leads to an assertion in LICM when trying to sink
stores out of non-dedicated loop exits containing indirectbr
instructions. This patch fix this issue by re-checking for dedicated
exits in LICM prior to store sink attempts.

Differential Revision: http://reviews.llvm.org/D6414

rdar://problem/18943047

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@222927 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Bruno Cardoso Lopes 2014-11-28 19:47:46 +00:00
parent 04122090c2
commit 69ed1ff9b3
2 changed files with 51 additions and 0 deletions

View File

@ -810,6 +810,7 @@ void LICM::PromoteAliasSet(AliasSet &AS,
// us to prove better alignment.
unsigned Alignment = 1;
AAMDNodes AATags;
bool HasDedicatedExits = CurLoop->hasDedicatedExits();
// Check that all of the pointers in the alias set have the same type. We
// cannot (yet) promote a memory location that is loaded and stored in
@ -844,6 +845,11 @@ void LICM::PromoteAliasSet(AliasSet &AS,
assert(!store->isVolatile() && "AST broken");
if (!store->isSimple())
return;
// Don't sink stores from loops without dedicated block exits. Exits
// containing indirect branches are not transformed by loop simplify,
// make sure we catch that.
if (!HasDedicatedExits)
return;
// Note that we only check GuaranteedToExecute inside the store case
// so that we do not introduce stores where they did not exist before

View File

@ -314,6 +314,51 @@ exit:
ret i32 %lcssa
}
; Can't sink stores out of exit blocks containing indirectbr instructions
; because loop simplify does not create dedicated exits for such blocks. Test
; that by sinking the store from lab21 to lab22, but not further.
define void @test12() {
; CHECK-LABEL: @test12
br label %lab4
lab4:
br label %lab20
lab5:
br label %lab20
lab6:
br label %lab4
lab7:
br i1 undef, label %lab8, label %lab13
lab8:
br i1 undef, label %lab13, label %lab10
lab10:
br label %lab7
lab13:
ret void
lab20:
br label %lab21
lab21:
; CHECK: lab21:
; CHECK-NOT: store
; CHECK: br i1 false, label %lab21, label %lab22
store i32 36127957, i32* undef, align 4
br i1 undef, label %lab21, label %lab22
lab22:
; CHECK: lab22:
; CHECK: store
; CHECK-NEXT: indirectbr i8* undef
indirectbr i8* undef, [label %lab5, label %lab6, label %lab7]
}
declare void @f(i32*)
declare void @g()