[PATCH] Invariant intrinsic canonicalization

hfinkel at anl.gov hfinkel at anl.gov
Tue Jul 15 09:22:38 PDT 2014


Also canonicalize: invariant(!(a || b)) -> invariant(!a); invariant(!b);

http://reviews.llvm.org/D4491

Files:
  lib/Transforms/InstCombine/InstCombineCalls.cpp
  test/Transforms/InstCombine/invariants.ll

Index: lib/Transforms/InstCombine/InstCombineCalls.cpp
===================================================================
--- lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -997,6 +997,22 @@
       return EraseInstFromFunction(CI);
     break;
   }
+  case Intrinsic::invariant: {
+    // Canonicalize invariant(a && b) -> invariant(a); invariant(b);
+    Value *IIOperand = II->getArgOperand(0), *A, *B;
+    if (match(IIOperand, m_And(m_Value(A), m_Value(B)))) {
+      Builder->CreateCall(II->getCalledValue(), A, II->getName());
+      Builder->CreateCall(II->getCalledValue(), B, II->getName());
+      return EraseInstFromFunction(*II);
+    }
+    // invariant(!(a || b)) -> invariant(!a); invariant(!b);
+    if (match(IIOperand, m_Not(m_Or(m_Value(A), m_Value(B))))) {
+      Builder->CreateCall(II->getCalledValue(), Builder->CreateNot(A), II->getName());
+      Builder->CreateCall(II->getCalledValue(), Builder->CreateNot(B), II->getName());
+      return EraseInstFromFunction(*II);
+    }
+    break;
+  }
   }
 
   return visitCallSite(II);
Index: test/Transforms/InstCombine/invariants.ll
===================================================================
--- test/Transforms/InstCombine/invariants.ll
+++ test/Transforms/InstCombine/invariants.ll
@@ -140,7 +140,39 @@
 ; CHECK-LABEL: @icmp2
 ; CHECK: call void @llvm.invariant
 ; CHECK: ret i32 0
+}
+
+; Function Attrs: nounwind uwtable
+define i32 @can1(i1 %a, i1 %b, i1 %c) {
+entry:
+  %and1 = and i1 %a, %b
+  %and  = and i1 %and1, %c
+  tail call void @llvm.invariant(i1 %and)
+
+; CHECK-LABEL: @can1
+; CHECK: call void @llvm.invariant(i1 %a)
+; CHECK: call void @llvm.invariant(i1 %b)
+; CHECK: call void @llvm.invariant(i1 %c)
+; CHECK: ret i32
+
+  ret i32 5
+}
+
+; Function Attrs: nounwind uwtable
+define i32 @can2(i1 %a, i1 %b, i1 %c) {
+entry:
+  %v = or i1 %a, %b
+  %w = xor i1 %v, 1
+  tail call void @llvm.invariant(i1 %w)
+
+; CHECK-LABEL: @can2
+; CHECK: %[[V1:[^ ]+]] = xor i1 %a, true
+; CHECK: call void @llvm.invariant(i1 %[[V1]])
+; CHECK: %[[V2:[^ ]+]] = xor i1 %b, true
+; CHECK: call void @llvm.invariant(i1 %[[V2]])
+; CHECK: ret i32
 
+  ret i32 5
 }
 
 attributes #0 = { nounwind uwtable }
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D4491.11444.patch
Type: text/x-patch
Size: 2247 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140715/8933fa42/attachment.bin>


More information about the llvm-commits mailing list