[PATCH] D46203: [InstCombine] Widen guards with conditions between

Philip Reames via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 27 12:04:59 PDT 2018


reames created this revision.
reames added reviewers: anna, mkazantsev.
Herald added subscribers: bollu, mcrosier.

The previous handling for guard widening in InstCombine was extremely restrictive.  In particular, it didn't handle the common case where we had two guards separated by a single icmp.  Handle this by scanning through a small fixed window of instructions to find the next guard if needed.


Repository:
  rL LLVM

https://reviews.llvm.org/D46203

Files:
  lib/Transforms/InstCombine/InstCombineCalls.cpp
  test/Transforms/InstCombine/call-guard.ll


Index: test/Transforms/InstCombine/call-guard.ll
===================================================================
--- test/Transforms/InstCombine/call-guard.ll
+++ test/Transforms/InstCombine/call-guard.ll
@@ -30,3 +30,25 @@
   call void(i1, ...) @llvm.experimental.guard( i1 %C, i32 789 )[ "deopt"() ]
   ret void
 }
+
+; This version tests for the common form where the conditions are
+; between the guards
+define void @test_guard_adjacent_diff_cond2(i32 %V1, i32 %V2) {
+; CHECK-LABEL: @test_guard_adjacent_diff_cond2(
+; CHECK-NEXT:    %1 = and i32 %V1, %V2
+; CHECK-NEXT:    %2 = icmp slt i32 %1, 0
+; CHECK-NEXT:    %and = and i32 %V1, 255
+; CHECK-NEXT:    %C = icmp ult i32 %and, 129
+; CHECK-NEXT:    %3 = and i1 %2, %C
+; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 %3, i32 123) [ "deopt"() ]
+; CHECK-NEXT:    ret void
+  %A = icmp slt i32 %V1, 0
+  call void(i1, ...) @llvm.experimental.guard( i1 %A, i32 123 )[ "deopt"() ]
+  %B = icmp slt i32 %V2, 0
+  call void(i1, ...) @llvm.experimental.guard( i1 %B, i32 456 )[ "deopt"() ]
+  %and = and i32 %V1, 255
+  %C = icmp sle i32 %and, 128
+  call void(i1, ...) @llvm.experimental.guard( i1 %C, i32 789 )[ "deopt"() ]
+  ret void
+}
+
Index: lib/Transforms/InstCombine/InstCombineCalls.cpp
===================================================================
--- lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -3624,8 +3624,16 @@
   }
 
   case Intrinsic::experimental_guard: {
-    // Is this guard followed by another guard?
+    // Is this guard followed by another guard?  We scan forward over a small
+    // fixed window of instructions to handle common cases with conditions
+    // computed between guards.
     Instruction *NextInst = II->getNextNode();
+    for (int i = 0; i < 3; i++) {
+      // Note: Using context-free form to avoid compile time blow up
+      if (!isSafeToSpeculativelyExecute(NextInst))
+        break;
+      NextInst = NextInst->getNextNode();
+    }
     Value *NextCond = nullptr;
     if (match(NextInst,
               m_Intrinsic<Intrinsic::experimental_guard>(m_Value(NextCond)))) {
@@ -3636,6 +3644,12 @@
         return eraseInstFromFunction(*NextInst);
 
       // Otherwise canonicalize guard(a); guard(b) -> guard(a & b).
+      Instruction* MoveI = II->getNextNode();
+      while (MoveI != NextInst) {
+        auto *Temp = MoveI;
+        MoveI = MoveI->getNextNode();
+        Temp->moveBefore(II);
+      }
       II->setArgOperand(0, Builder.CreateAnd(CurrCond, NextCond));
       return eraseInstFromFunction(*NextInst);
     }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D46203.144378.patch
Type: text/x-patch
Size: 2619 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180427/5fbf0d9a/attachment.bin>


More information about the llvm-commits mailing list