diff options
| -rw-r--r-- | llvm/lib/Transforms/Scalar/LICM.cpp | 6 | ||||
| -rw-r--r-- | llvm/test/Transforms/LICM/sinking.ll | 45 |
2 files changed, 51 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Scalar/LICM.cpp b/llvm/lib/Transforms/Scalar/LICM.cpp index 5f00bb94188..c706248267f 100644 --- a/llvm/lib/Transforms/Scalar/LICM.cpp +++ b/llvm/lib/Transforms/Scalar/LICM.cpp @@ -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 diff --git a/llvm/test/Transforms/LICM/sinking.ll b/llvm/test/Transforms/LICM/sinking.ll index ccc9186f7a4..f01367b01aa 100644 --- a/llvm/test/Transforms/LICM/sinking.ll +++ b/llvm/test/Transforms/LICM/sinking.ll @@ -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() |

