diff --git a/lib/Transforms/Scalar/LICM.cpp b/lib/Transforms/Scalar/LICM.cpp index c706248267f..99725b5f738 100644 --- a/lib/Transforms/Scalar/LICM.cpp +++ b/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/test/Transforms/LICM/sinking.ll b/test/Transforms/LICM/sinking.ll index f01367b01aa..d7a8fcdafca 100644 --- a/test/Transforms/LICM/sinking.ll +++ b/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()