[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