[PATCH] D33172: [InstCombine] Simpify inverted predicates in 'or'
Brian Gesiak via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Sun May 14 15:43:08 PDT 2017
modocache updated this revision to Diff 98935.
modocache added a comment.
Use PatternMatch.h. Also, actually perform checks for zero operands (whoops!).
https://reviews.llvm.org/D33172
Files:
lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
test/Transforms/InstCombine/logical-select.ll
Index: test/Transforms/InstCombine/logical-select.ll
===================================================================
--- test/Transforms/InstCombine/logical-select.ll
+++ test/Transforms/InstCombine/logical-select.ll
@@ -62,6 +62,22 @@
ret i32 %t3
}
+; PR32791 - https://bugs.llvm.org//show_bug.cgi?id=32791
+; Fold two selects with inverted predicates and zero operands.
+define i32 @pal(i32 %a, i32 %b, i32 %c, i32 %d) {
+; CHECK-LABEL: @pal(
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 %a, %b
+; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 %c, i32 %d
+; CHECK-NEXT: ret i32 [[SEL]]
+;
+ %cmp1 = icmp slt i32 %a, %b
+ %sel1 = select i1 %cmp1, i32 %c, i32 0
+ %cmp2 = icmp sge i32 %a, %b
+ %sel2 = select i1 %cmp2, i32 %d, i32 0
+ %or = or i32 %sel1, %sel2
+ ret i32 %or
+}
+
define i32 @par(i32 %a, i32 %b, i32 %c, i32 %d) {
; CHECK-LABEL: @par(
; CHECK-NEXT: [[T0:%.*]] = icmp slt i32 %a, %b
Index: lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
===================================================================
--- lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -2266,6 +2266,33 @@
}
}
+ // Change (or (X ? A : B), (!X ? C : D)) --> (X ? A : C), iff (B|D) == 0
+ // That is, if the comparison is based on the results of two select
+ // instructions, check whether those conditions are inverse icmp instructions
+ // with zero operands. If so, simplify to a single select on one of the
+ // conditions.
+ {
+ Value *X = nullptr, *Y = nullptr;
+ // Match both:
+ // (or (X ? 0 : A), (!X ? 0 : C))
+ // (or (X ? A : 0), (!X ? C : 0))
+ if ((match(Op0, m_Select(m_Value(X), m_Value(A), m_Zero())) &&
+ match(Op1, m_Select(m_Value(Y), m_Value(C), m_Zero()))) ||
+ (match(Op0, m_Select(m_Value(X), m_Zero(), m_Value(A))) &&
+ match(Op1, m_Select(m_Value(Y), m_Zero(), m_Value(C))))) {
+ // Only transform into a select if X and Y have inverted predicates
+ // with identical operands.
+ auto XCmp = dyn_cast<CmpInst>(X);
+ auto YCmp = dyn_cast<CmpInst>(Y);
+ if (XCmp && YCmp &&
+ XCmp->getPredicate() == YCmp->getInversePredicate() &&
+ XCmp->getOperand(0) == YCmp->getOperand(0) &&
+ XCmp->getOperand(1) == YCmp->getOperand(1)) {
+ return SelectInst::Create(XCmp, A, C);
+ }
+ }
+ }
+
return Changed ? &I : nullptr;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D33172.98935.patch
Type: text/x-patch
Size: 2452 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170514/84e2e1ae/attachment.bin>
More information about the llvm-commits
mailing list