[PATCH] D29107: Fix a bug when unswitching on partial LIV for SwitchInst

Xin Tong via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 24 17:07:49 PST 2017


trentxintong created this revision.
Herald added a subscriber: mzolotukhin.

Fix a bug when unswitching on partial LIV for SwitchInst.


https://reviews.llvm.org/D29107

Files:
  lib/Transforms/Scalar/LoopUnswitch.cpp
  test/Transforms/LoopUnswitch/basictest.ll


Index: test/Transforms/LoopUnswitch/basictest.ll
===================================================================
--- test/Transforms/LoopUnswitch/basictest.ll
+++ test/Transforms/LoopUnswitch/basictest.ll
@@ -101,7 +101,49 @@
 ; CHECK: }
 }
 
+; Make sure we do not unswitch this loop, as we do not really know the 
+; right value for %a to unswitch on.
+;
+; CHECK:  define i32 @and_as_switch_input(i32
+; CHECK: entry:
+; This is an indication that the loop has been unswitched.
+; CHECK-NOT: icmp
+; CHECK: br
+define i32 @and_as_switch_input(i32 %a) #0 {
+entry:
+  br label %for.body
+
+for.body:
+  %i = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
+  %and = and i32 %a, %i
+  switch i32 %and, label %sw.default [
+    i32 11, label %sw.bb
+    i32 12, label %sw.bb1
+  ]
+
+sw.bb:
+  %call = call i32 (...) @boo()
+  br label %sw.epilog
+
+sw.bb1:
+  br label %sw.epilog
+
+sw.default:
+  br label %sw.epilog
+
+sw.epilog:
+  br label %for.inc
+
+for.inc:
+  %inc = add nsw i32 %i, 1
+  %cmp = icmp slt i32 %inc, 1024
+  br i1 %cmp, label %for.body, label %for.end
+
+for.end:
+  ret i32 %a
+}
 
+declare i32 @boo(...) 
 declare void @incf() noreturn
 declare void @decf() noreturn
 declare void @conv() convergent
Index: lib/Transforms/Scalar/LoopUnswitch.cpp
===================================================================
--- lib/Transforms/Scalar/LoopUnswitch.cpp
+++ lib/Transforms/Scalar/LoopUnswitch.cpp
@@ -644,8 +644,27 @@
     } else if (SwitchInst *SI = dyn_cast<SwitchInst>(TI)) {
       Value *LoopCond = FindLIVLoopCondition(SI->getCondition(),
                                              currentLoop, Changed);
+      //  %and = and i32 %loop_invariant, %loop_variant
+      //  switch i32 %and,
+      //    label %sw.default [
+      //     i32 11, label %sw.bb
+      //     i32 12, label %sw.bb1
+      //  ]
+      //
+      // Only unswitch on the switchinst input value. It is not meaningful
+      // to compare the %loop_invariant with one of the switch case value.
+      // This will most likely lead to no simplication opportunities in
+      // the original loop and the newly generated loop.
+      //
+      // i.e. the only thing we know is the loop-invariant input to the
+      // and is/isnt the value we choose to unswitch on. This most
+      // likely will not enable us to simplify the switch instruction.
+      //
+      // To make matter worse, we do not record this loop has been unswitched
+      // on this particular value and we keep unswitching it on the same
+      // value until we run out of quota.
       unsigned NumCases = SI->getNumCases();
-      if (LoopCond && NumCases) {
+      if (LoopCond && LoopCond == SI->getCondition() && NumCases) {
         // Find a value to unswitch on:
         // FIXME: this should chose the most expensive case!
         // FIXME: scan for a case with a non-critical edge?


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D29107.85661.patch
Type: text/x-patch
Size: 2878 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170125/8ba996dc/attachment.bin>


More information about the llvm-commits mailing list