[PATCH] D29378: [InstCombine] Allow InstCombine to merge adjacent guards

Max Kazantsev via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 1 00:23:33 PST 2017


mkazantsev updated this revision to Diff 86584.

https://reviews.llvm.org/D29378

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
@@ -2,8 +2,8 @@
 
 declare void @llvm.experimental.guard(i1, ...)
 
-define void @test_guard_adjacent(i1 %A) {
-; CHECK-LABEL: @test_guard_adjacent(
+define void @test_guard_adjacent_same_cond(i1 %A) {
+; CHECK-LABEL: @test_guard_adjacent_same_cond(
 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 %A) [ "deopt"() ]
 ; CHECK-NEXT:    ret void
   call void(i1, ...) @llvm.experimental.guard( i1 %A )[ "deopt"() ]
@@ -19,12 +19,27 @@
   ret void
 }
 
-define void @test_guard_adjacent_neg(i1 %A, i1 %B) {
-; CHECK-LABEL: @test_guard_adjacent_neg(
-; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 %A) [ "deopt"() ]
-; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 %B) [ "deopt"() ]
+define void @test_guard_adjacent_diff_cond(i1 %A, i1 %B, i1 %C) {
+; CHECK-LABEL: @test_guard_adjacent_diff_cond(
+; CHECK-NEXT:    %1 = and i1 %A, %B
+; CHECK-NEXT:    %2 = and i1 %1, %C
+; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 %2, i32 789) [ "deopt"() ]
 ; CHECK-NEXT:    ret void
-  call void(i1, ...) @llvm.experimental.guard( i1 %A )[ "deopt"() ]
-  call void(i1, ...) @llvm.experimental.guard( i1 %B )[ "deopt"() ]
+  call void(i1, ...) @llvm.experimental.guard( i1 %A, i32 123 )[ "deopt"() ]
+  call void(i1, ...) @llvm.experimental.guard( i1 %B, i32 456 )[ "deopt"() ]
+  call void(i1, ...) @llvm.experimental.guard( i1 %C, i32 789 )[ "deopt"() ]
+  ret void
+}
+
+define void @test_guard_adjacent_not_cond(i1 %A, i1 %B) {
+; CHECK-LABEL: @test_guard_adjacent_not_cond(
+; CHECK-NEXT:    %1 = or i1 %A, %B
+; CHECK-NEXT:    %2 = xor i1 %1, true
+; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 %2, i32 456) [ "deopt"() ]
+; CHECK-NEXT:    ret void
+  %C = xor i1 %A, true
+  %D = xor i1 %B, true
+  call void(i1, ...) @llvm.experimental.guard( i1 %C, i32 123 )[ "deopt"() ]
+  call void(i1, ...) @llvm.experimental.guard( i1 %D, i32 456 )[ "deopt"() ]
   ret void
 }
Index: lib/Transforms/InstCombine/InstCombineCalls.cpp
===================================================================
--- lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -3255,12 +3255,30 @@
   }
 
   case Intrinsic::experimental_guard: {
-    Value *IIOperand = II->getArgOperand(0);
+    // Is this guard followed by another guard?
+    Value *NextInst = II->getNextNode();
+    Value *NextCond = nullptr;
+    if (match(NextInst,
+              m_Intrinsic<Intrinsic::experimental_guard>(m_Value(NextCond)))) {
+      Value *CurrCond = II->getArgOperand(0);
+
+      // Remove a guard if it is immediately followed by an identical guard.
+      if (CurrCond == NextCond)
+        return eraseInstFromFunction(*II);
+
+      // Otherwise we try to widen the next guard and remove the current.
+      Value *A, *B, *NewCond;
+      if (match(CurrCond, m_Not(m_Value(A))) &&
+          match(NextCond, m_Not(m_Value(B))))
+        // Canonicalize guard(!a); guard(!b) -> guard(!(a | b)).
+        NewCond = Builder->CreateNot(Builder->CreateOr(A, B));
+      else
+        // Otherwise canonicalize guard(a); guard(b) -> guard(a & b).
+        NewCond = Builder->CreateAnd(CurrCond, NextCond);
 
-    // Remove a guard if it is immediately followed by an identical guard.
-    if (match(II->getNextNode(),
-              m_Intrinsic<Intrinsic::experimental_guard>(m_Specific(IIOperand))))
+      cast<IntrinsicInst>(NextInst)->setArgOperand(0, NewCond);
       return eraseInstFromFunction(*II);
+    }
     break;
   }
   }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D29378.86584.patch
Type: text/x-patch
Size: 3743 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170201/05bba730/attachment.bin>


More information about the llvm-commits mailing list