[PATCH] D29037: Constant fold switch inst when looking for trivial conditions to unswitch on.

Xin Tong via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 26 15:19:17 PST 2017


trentxintong updated this revision to Diff 85974.
trentxintong added a comment.

Address comments.


https://reviews.llvm.org/D29037

Files:
  lib/Transforms/Scalar/LoopUnswitch.cpp
  test/Transforms/LoopUnswitch/trivial-unswitch.ll


Index: test/Transforms/LoopUnswitch/trivial-unswitch.ll
===================================================================
--- test/Transforms/LoopUnswitch/trivial-unswitch.ll
+++ test/Transforms/LoopUnswitch/trivial-unswitch.ll
@@ -44,4 +44,48 @@
   ret i32 0
 }
 
-declare void @some_func() noreturn
\ No newline at end of file
+
+; We will not be able trivially unswitch on the SwitchInst, as its input
+; is a constant. However, since its a constant we should be able to figure
+; out that the switch can be folded into a unconditional branch to %continue.
+; Then we unswitch on the br inst in %continue.
+;
+; CHECK: define i32 @test2(
+; This is an indication that the loop has been unswitched on %cond1.
+; CHECK:  br i1 %cond1, label %..split_crit_edge, label %.loop_exit.split_crit_edge
+
+; CHECK:  ..split_crit_edge:                                ; preds = %0
+; CHECK:    br label %.split
+
+; CHECK:  .split:                                           ; preds = %..split_crit_edge
+; CHECK:    br label %loop_begin
+
+; CHECK:  loop_begin:                                       ; preds = %do_something, %.split
+; CHECK:    switch i32
+
+; CHECK:  continue:                                         ; preds = %loop_begin
+; CHECK:    %var_val = load i32, i32* %var
+; CHECK:    br i1 true, label %do_something, label %loop_exit
+
+define i32 @test2(i32* %var, i1 %cond1) {
+  br label %loop_begin
+
+loop_begin:  
+  switch i32 1, label %continue [
+    i32 0, label %loop_exit
+    i32 1, label %continue
+  ]
+
+continue:
+  %var_val = load i32, i32* %var
+  br i1 %cond1, label %do_something, label %loop_exit
+
+do_something:
+  call void @some_func() noreturn nounwind
+  br label %loop_begin
+
+loop_exit:
+  ret i32 0
+}
+
+declare void @some_func() noreturn
Index: lib/Transforms/Scalar/LoopUnswitch.cpp
===================================================================
--- lib/Transforms/Scalar/LoopUnswitch.cpp
+++ lib/Transforms/Scalar/LoopUnswitch.cpp
@@ -899,7 +899,6 @@
       if (I.mayHaveSideEffects())
         return false;
 
-    // FIXME: add check for constant foldable switch instructions.
     if (BranchInst *BI = dyn_cast<BranchInst>(CurrentTerm)) {
       if (BI->isUnconditional()) {
         CurrentBB = BI->getSuccessor(0);
@@ -911,7 +910,16 @@
         // Found a trivial condition candidate: non-foldable conditional branch.
         break;
       }
-    } else {
+    } else if (SwitchInst *SI = dyn_cast<SwitchInst>(CurrentTerm)) {
+      // At this point, any constant-foldable instructions should have probably
+      // been folded.
+      ConstantInt *Cond = dyn_cast<ConstantInt>(SI->getCondition());
+      if (!Cond)
+        break;
+      // Find the target block we are definitely going to.
+      CurrentBB = SI->findCaseValue(Cond).getCaseSuccessor();
+    } else { 
+      // We do not understand these terminator instructions.
       break;
     }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D29037.85974.patch
Type: text/x-patch
Size: 2912 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170126/5b8743ff/attachment.bin>


More information about the llvm-commits mailing list