[LICM] Store sink and indirectbr instructions
authorBruno Cardoso Lopes <bruno.cardoso@gmail.com>
Fri, 28 Nov 2014 19:47:46 +0000 (19:47 +0000)
committerBruno Cardoso Lopes <bruno.cardoso@gmail.com>
Fri, 28 Nov 2014 19:47:46 +0000 (19:47 +0000)
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

lib/Transforms/Scalar/LICM.cpp
test/Transforms/LICM/sinking.ll

index 5f00bb94188f2636644047e41f63e9e2d589f14b..c706248267ffa9d0647ec3aa3b3d9615c30763b2 100644 (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
index ccc9186f7a483237b8aa66c9e80f59ec495ea477..f01367b01aa51ce7d3c106dbf44b0dcbbd931eb6 100644 (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()