aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2013-02-16 23:41:36 +0000
committerBill Wendling <isanbard@gmail.com>2013-02-16 23:41:36 +0000
commitcc54889cd58322b8766525f43cc1f7cb52e4692e (patch)
tree5ba9b3526a38ff6196352d2f5b19a65ccc8de4cc
parent5be5fa468acc4948b8f4d7f5e945d77a53e40bb8 (diff)
downloadexternal_llvm-cc54889cd58322b8766525f43cc1f7cb52e4692e.zip
external_llvm-cc54889cd58322b8766525f43cc1f7cb52e4692e.tar.gz
external_llvm-cc54889cd58322b8766525f43cc1f7cb52e4692e.tar.bz2
The transform is:
(or (bool?A:B),(bool?C:D)) --> (bool?(or A,C):(or B,D)) By the time the OR is visited, both the SELECTs have been visited and not optimized and the OR itself hasn't been transformed so we do this transform in the hopes that the new ORs will be optimized. The transform is explicitly disabled for vector-selects until "codegen matures to handle them better". Patch by Muhammad Tauqir! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175380 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Transforms/InstCombine/InstCombineAndOrXor.cpp14
-rw-r--r--test/Transforms/InstCombine/logical-select.ll30
-rw-r--r--test/Transforms/InstCombine/or.ll5
3 files changed, 26 insertions, 23 deletions
diff --git a/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index bf065fe..4332467 100644
--- a/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -2071,6 +2071,20 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {
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;
}
diff --git a/test/Transforms/InstCombine/logical-select.ll b/test/Transforms/InstCombine/logical-select.ll
index 07a326b..f8c0676 100644
--- a/test/Transforms/InstCombine/logical-select.ll
+++ b/test/Transforms/InstCombine/logical-select.ll
@@ -10,10 +10,8 @@ define i32 @foo(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
%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 @@ define i32 @bar(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
%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 @@ entry:
%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 @@ entry:
%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 @@ entry:
%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]]
}
diff --git a/test/Transforms/InstCombine/or.ll b/test/Transforms/InstCombine/or.ll
index c0bb28d..bde2a54 100644
--- a/test/Transforms/InstCombine/or.ll
+++ b/test/Transforms/InstCombine/or.ll
@@ -344,10 +344,9 @@ define <4 x i32> @test32(<4 x i1> %and.i1352, <4 x i32> %vecinit6.i176, <4 x i32
%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) {