[PATCH] Transform OR of SELECTs to SELECT of ORs
Muhammad Tauqir Ahmad
muhammad.t.ahmad at intel.com
Fri Feb 1 12:13:46 PST 2013
Updated the patch to make sure Op0, Op1 have one uses each before doing the transform.
http://llvm-reviews.chandlerc.com/D362
CHANGE SINCE LAST DIFF
http://llvm-reviews.chandlerc.com/D362?vs=859&id=860#toc
Files:
lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
test/Transforms/InstCombine/logical-select.ll
Index: lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
===================================================================
--- lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -2071,6 +2071,23 @@
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;
+ // FIXME: Disable vector-select until codegen matures to handle them better.
+ // See test32 in test/Transforms/InstCombine/or.ll
+ if (!I.getType()->isVectorTy())
+ if (Op0->hasOneUse() && Op1->hasOneUse() &&
+ match(Op0, m_Select(m_Value(X), m_Value(A), m_Value(B))) &&
+ match(Op1, m_Select(m_Value(X), m_Value(C), m_Value(D)))) {
+ 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]]
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D362.2.patch
Type: text/x-patch
Size: 3346 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130201/61bf0d09/attachment.bin>
More information about the llvm-commits
mailing list