[PATCH] CodeGenPrepare: Avoid and/or i1 in select conditions.
Phabricator
reviews at reviews.llvm.org
Fri Feb 6 09:51:38 PST 2015
REPOSITORY
rL LLVM
http://reviews.llvm.org/D7399
Files:
llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp
llvm/trunk/test/Transforms/InstCombine/select.ll
Index: llvm/trunk/test/Transforms/InstCombine/select.ll
===================================================================
--- llvm/trunk/test/Transforms/InstCombine/select.ll
+++ llvm/trunk/test/Transforms/InstCombine/select.ll
@@ -1492,3 +1492,31 @@
%v = load i128* %p
ret i128 %v
}
+
+define i32 @test_select_select0(i32 %a, i32 %r0, i32 %r1, i32 %v1, i32 %v2) {
+ ; CHECK-LABEL: @test_select_select0(
+ ; CHECK: %[[C0:.*]] = icmp sge i32 %a, %v1
+ ; CHECK-NEXT: %[[C1:.*]] = icmp slt i32 %a, %v2
+ ; CHECK-NEXT: %[[C:.*]] = and i1 %[[C1]], %[[C0]]
+ ; CHECK-NEXT: %[[SEL:.*]] = select i1 %[[C]], i32 %r0, i32 %r1
+ ; CHECK-NEXT: ret i32 %[[SEL]]
+ %c0 = icmp sge i32 %a, %v1
+ %s0 = select i1 %c0, i32 %r0, i32 %r1
+ %c1 = icmp slt i32 %a, %v2
+ %s1 = select i1 %c1, i32 %s0, i32 %r1
+ ret i32 %s1
+}
+
+define i32 @test_select_select1(i32 %a, i32 %r0, i32 %r1, i32 %v1, i32 %v2) {
+ ; CHECK-LABEL: @test_select_select1(
+ ; CHECK: %[[C0:.*]] = icmp sge i32 %a, %v1
+ ; CHECK-NEXT: %[[C1:.*]] = icmp slt i32 %a, %v2
+ ; CHECK-NEXT: %[[C:.*]] = or i1 %[[C1]], %[[C0]]
+ ; CHECK-NEXT: %[[SEL:.*]] = select i1 %[[C]], i32 %r0, i32 %r1
+ ; CHECK-NEXT: ret i32 %[[SEL]]
+ %c0 = icmp sge i32 %a, %v1
+ %s0 = select i1 %c0, i32 %r0, i32 %r1
+ %c1 = icmp slt i32 %a, %v2
+ %s1 = select i1 %c1, i32 %r0, i32 %s0
+ ret i32 %s1
+}
Index: llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp
===================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -1178,20 +1178,38 @@
return NV;
if (SelectInst *TrueSI = dyn_cast<SelectInst>(TrueVal)) {
+ // select(C, select(C, a, b), c) -> select(C, a, c)
if (TrueSI->getCondition() == CondVal) {
if (SI.getTrueValue() == TrueSI->getTrueValue())
return nullptr;
SI.setOperand(1, TrueSI->getTrueValue());
return &SI;
}
+ // select(C0, select(C1, a, b), b) -> select(C0&C1, a, b)
+ // We choose this as normal form to enable folding on the And and shortening
+ // paths for the values (this helps GetUnderlyingObjects() for example).
+ if (TrueSI->getFalseValue() == FalseVal && TrueSI->hasOneUse()) {
+ Value *And = Builder->CreateAnd(CondVal, TrueSI->getCondition());
+ SI.setOperand(0, And);
+ SI.setOperand(1, TrueSI->getTrueValue());
+ return &SI;
+ }
}
if (SelectInst *FalseSI = dyn_cast<SelectInst>(FalseVal)) {
+ // select(C, a, select(C, b, c)) -> select(C, a, c)
if (FalseSI->getCondition() == CondVal) {
if (SI.getFalseValue() == FalseSI->getFalseValue())
return nullptr;
SI.setOperand(2, FalseSI->getFalseValue());
return &SI;
}
+ // select(C0, a, select(C1, a, b)) -> select(C0|C1, a, b)
+ if (FalseSI->getTrueValue() == TrueVal && FalseSI->hasOneUse()) {
+ Value *Or = Builder->CreateOr(CondVal, FalseSI->getCondition());
+ SI.setOperand(0, Or);
+ SI.setOperand(2, FalseSI->getFalseValue());
+ return &SI;
+ }
}
if (BinaryOperator::isNot(CondVal)) {
EMAIL PREFERENCES
http://reviews.llvm.org/settings/panel/emailpreferences/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D7399.19492.patch
Type: text/x-patch
Size: 3148 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150206/57fc75fa/attachment.bin>
More information about the llvm-commits
mailing list