[PATCH] Transform OR of SELECTs to SELECT of ORs

Muhammad Tauqir Ahmad muhammad.t.ahmad at intel.com
Mon Feb 4 11:54:53 PST 2013


  Update the patch to enable this transform for vector-selects. Update test32 in test/Transforms/InstCombine/or.ll

  codgen produces the same code for the vector select as without vector select for test32.

http://llvm-reviews.chandlerc.com/D362

CHANGE SINCE LAST DIFF
  http://llvm-reviews.chandlerc.com/D362?vs=876&id=877#toc

Files:
  lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
  test/Transforms/InstCombine/logical-select.ll
  test/Transforms/InstCombine/or.ll

Index: lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
===================================================================
--- lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -2071,6 +2071,20 @@
     return BinaryOperator::CreateOr(Inner, C1);
   }
 
+  // Change (or (bool?A:B),(bool?C:D)) --> (bool?(or A,C):(or B,D))
+  // Since this OR statement hasn't been optimized further yet, we hope
+  // that this transformation will allow the new ORs to be optimized.
+  {
+    Value *X = 0, *Y = 0;
+    if (Op0->hasOneUse() && Op1->hasOneUse() &&
+        match(Op0, m_Select(m_Value(X), m_Value(A), m_Value(B))) &&
+        match(Op1, m_Select(m_Value(Y), m_Value(C), m_Value(D))) && X == Y) {
+      Value *orTrue = Builder->CreateOr(A, C);
+      Value *orFalse = Builder->CreateOr(B, D);
+      return SelectInst::Create(X, orTrue, orFalse);
+    }
+  }
+
   return Changed ? &I : 0;
 }
 
Index: test/Transforms/InstCombine/logical-select.ll
===================================================================
--- test/Transforms/InstCombine/logical-select.ll
+++ test/Transforms/InstCombine/logical-select.ll
@@ -10,10 +10,8 @@
   %j = or i32 %g, %i
   ret i32 %j
 ; CHECK: %e = icmp slt i32 %a, %b
-; CHECK-NEXT: %g = select i1 %e, i32 %c, i32 0
-; CHECK-NEXT: %i = select i1 %e, i32 0, i32 %d
-; CHECK-NEXT: %j = or i32 %g, %i
-; CHECK-NEXT: ret i32 %j
+; CHECK-NEXT: [[result:%.*]] = select i1 %e, i32 %c, i32 %d
+; CHECK-NEXT: ret i32 [[result]]
 }
 define i32 @bar(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
   %e = icmp slt i32 %a, %b
@@ -24,10 +22,8 @@
   %j = or i32 %i, %g
   ret i32 %j
 ; CHECK: %e = icmp slt i32 %a, %b
-; CHECK-NEXT: %g = select i1 %e, i32 %c, i32 0
-; CHECK-NEXT: %i = select i1 %e, i32 0, i32 %d
-; CHECK-NEXT: %j = or i32 %i, %g
-; CHECK-NEXT: ret i32 %j
+; CHECK-NEXT: [[result:%.*]] = select i1 %e, i32 %c, i32 %d
+; CHECK-NEXT: ret i32 [[result]]
 }
 
 define i32 @goo(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
@@ -40,10 +36,8 @@
   %3 = or i32 %1, %2
   ret i32 %3
 ; CHECK: %0 = icmp slt i32 %a, %b
-; CHECK-NEXT: %1 = select i1 %0, i32 %c, i32 0
-; CHECK-NEXT: %2 = select i1 %0, i32 0, i32 %d
-; CHECK-NEXT: %3 = or i32 %1, %2
-; CHECK-NEXT: ret i32 %3
+; CHECK-NEXT: [[result:%.*]] = select i1 %0, i32 %c, i32 %d
+; CHECK-NEXT: ret i32 [[result]]
 }
 define i32 @poo(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
 entry:
@@ -55,10 +49,8 @@
   %3 = or i32 %1, %2
   ret i32 %3
 ; CHECK: %0 = icmp slt i32 %a, %b
-; CHECK-NEXT: %1 = select i1 %0, i32 %c, i32 0
-; CHECK-NEXT: %2 = select i1 %0, i32 0, i32 %d
-; CHECK-NEXT: %3 = or i32 %1, %2
-; CHECK-NEXT: ret i32 %3
+; CHECK-NEXT: [[result:%.*]] = select i1 %0, i32 %c, i32 %d
+; CHECK-NEXT: ret i32 [[result]]
 }
 
 define i32 @par(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
@@ -71,8 +63,6 @@
   %3 = or i32 %1, %2
   ret i32 %3
 ; CHECK: %0 = icmp slt i32 %a, %b
-; CHECK-NEXT: %1 = select i1 %0, i32 %c, i32 0
-; CHECK-NEXT: %2 = select i1 %0, i32 0, i32 %d
-; CHECK-NEXT: %3 = or i32 %1, %2
-; CHECK-NEXT: ret i32 %3
+; CHECK-NEXT: [[result:%.*]] = select i1 %0, i32 %c, i32 %d
+; CHECK-NEXT: ret i32 [[result]]
 }
Index: test/Transforms/InstCombine/or.ll
===================================================================
--- test/Transforms/InstCombine/or.ll
+++ test/Transforms/InstCombine/or.ll
@@ -344,10 +344,9 @@
   %and.i = and <4 x i32> %vecinit6.i191, %neg.i   ; <<4 x i32>> [#uses=1]
   %or.i = or <4 x i32> %and.i, %and.i129          ; <<4 x i32>> [#uses=1]
   ret <4 x i32> %or.i
-; Don't turn this into a vector select until codegen matures to handle them
-; better.
+; codegen is mature enough to handle vector selects.
 ; CHECK: @test32
-; CHECK: or <4 x i32> %and.i, %and.i129
+; CHECK: select <4 x i1> %and.i1352, <4 x i32> %vecinit6.i176, <4 x i32> %vecinit6.i191
 }
 
 define i1 @test33(i1 %X, i1 %Y) {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D362.4.patch
Type: text/x-patch
Size: 3884 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130204/0c98b372/attachment.bin>


More information about the llvm-commits mailing list