[PATCH] D33172: [InstCombine] Simpify inverted predicates in 'or'

Brian Gesiak via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sun May 14 18:24:32 PDT 2017


modocache updated this revision to Diff 98939.
modocache added a comment.

Use a match() in the nested condition, update comment for clarity. To come: additional tests.


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,31 @@
     }
   }
 
+  // Change (or (select (cmp Pred1, A, B), C, 0), (select (cmp Pred2, A, B), D, 0)) --> (select (cmp Pred1, A, B), C, D)
+  // when Pred1 is the inverse of Pred2. That is, if the or is based on the
+  // results of two select instructions, check whether the conditions of those
+  // select instructions 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(C), m_Zero())) &&
+         match(Op1, m_Select(m_Value(Y), m_Value(D), m_Zero()))) ||
+        (match(Op0, m_Select(m_Value(X), m_Zero(), m_Value(C))) &&
+         match(Op1, m_Select(m_Value(Y), m_Zero(), m_Value(D))))) {
+      // Only transform into a select if X and Y have inverted predicates
+      // with identical operands.
+      CmpInst::Predicate Pred1, Pred2;
+      if (match(X, m_Cmp(Pred1, m_Value(A), m_Value(B))) &&
+          match(Y, m_Cmp(Pred2, m_Specific(A), m_Specific(B))) &&
+          CmpInst::getInversePredicate(Pred1) == Pred2) {
+        return SelectInst::Create(X, C, D);
+      }
+    }
+  }
+
   return Changed ? &I : nullptr;
 }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D33172.98939.patch
Type: text/x-patch
Size: 2488 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170515/dc71ad37/attachment.bin>


More information about the llvm-commits mailing list