[llvm] r293250 - Constant fold switch inst when looking for trivial conditions to unswitch on.

Xin Tong via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 26 17:42:20 PST 2017


Author: trentxintong
Date: Thu Jan 26 19:42:20 2017
New Revision: 293250

URL: http://llvm.org/viewvc/llvm-project?rev=293250&view=rev
Log:
Constant fold switch inst when looking for trivial conditions to unswitch on.

Summary: Constant fold switch inst when looking for trivial conditions to unswitch on.

Reviewers: sanjoy, chenli, hfinkel, efriedma

Subscribers: llvm-commits, mzolotukhin

Differential Revision: https://reviews.llvm.org/D29037

Modified:
    llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp
    llvm/trunk/test/Transforms/LoopUnswitch/trivial-unswitch.ll

Modified: llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp?rev=293250&r1=293249&r2=293250&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp Thu Jan 26 19:42:20 2017
@@ -899,7 +899,6 @@ bool LoopUnswitch::TryTrivialLoopUnswitc
       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 @@ bool LoopUnswitch::TryTrivialLoopUnswitc
         // 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;
     }
 

Modified: llvm/trunk/test/Transforms/LoopUnswitch/trivial-unswitch.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopUnswitch/trivial-unswitch.ll?rev=293250&r1=293249&r2=293250&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/LoopUnswitch/trivial-unswitch.ll (original)
+++ llvm/trunk/test/Transforms/LoopUnswitch/trivial-unswitch.ll Thu Jan 26 19:42:20 2017
@@ -44,4 +44,48 @@ loop_exit:
   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




More information about the llvm-commits mailing list