summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/Transforms/Scalar/LICM.cpp6
-rw-r--r--llvm/test/Transforms/LICM/sinking.ll33
2 files changed, 37 insertions, 2 deletions
diff --git a/llvm/lib/Transforms/Scalar/LICM.cpp b/llvm/lib/Transforms/Scalar/LICM.cpp
index c706248267f..99725b5f738 100644
--- a/llvm/lib/Transforms/Scalar/LICM.cpp
+++ b/llvm/lib/Transforms/Scalar/LICM.cpp
@@ -847,8 +847,10 @@ void LICM::PromoteAliasSet(AliasSet &AS,
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)
+ // make sure we catch that. An additional load may be generated in the
+ // preheader for SSA updater, so also avoid sinking when no preheader
+ // is available.
+ if (!HasDedicatedExits || !Preheader)
return;
// Note that we only check GuaranteedToExecute inside the store case
diff --git a/llvm/test/Transforms/LICM/sinking.ll b/llvm/test/Transforms/LICM/sinking.ll
index f01367b01aa..d7a8fcdafca 100644
--- a/llvm/test/Transforms/LICM/sinking.ll
+++ b/llvm/test/Transforms/LICM/sinking.ll
@@ -359,6 +359,39 @@ lab22:
indirectbr i8* undef, [label %lab5, label %lab6, label %lab7]
}
+; Test that we don't crash when trying to sink stores and there's no preheader
+; available (which is used for creating loads that may be used by the SSA
+; updater)
+define void @test13() {
+; CHECK-LABEL: @test13
+ br label %lab59
+
+lab19:
+ br i1 undef, label %lab20, label %lab38
+
+lab20:
+ br label %lab60
+
+lab21:
+ br i1 undef, label %lab22, label %lab38
+
+lab22:
+ br label %lab38
+
+lab38:
+ ret void
+
+lab59:
+ indirectbr i8* undef, [label %lab60, label %lab38]
+
+lab60:
+; CHECK: lab60:
+; CHECK: store
+; CHECK-NEXT: indirectbr
+ store i32 2145244101, i32* undef, align 4
+ indirectbr i8* undef, [label %lab21, label %lab19]
+}
+
declare void @f(i32*)
declare void @g()
OpenPOWER on IntegriCloud