[PATCH] D101375: [InstCombine] Add a few more patterns for folding select of select

Juneyoung Lee via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sat May 1 20:23:15 PDT 2021


aqjune updated this revision to Diff 342194.
aqjune added a comment.

Address comments


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D101375/new/

https://reviews.llvm.org/D101375

Files:
  llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
  llvm/test/Transforms/InstCombine/select-safe-transforms.ll


Index: llvm/test/Transforms/InstCombine/select-safe-transforms.ll
===================================================================
--- llvm/test/Transforms/InstCombine/select-safe-transforms.ll
+++ llvm/test/Transforms/InstCombine/select-safe-transforms.ll
@@ -132,9 +132,7 @@
 define i1 @and_orn_cmp_1_logical(i32 %a, i32 %b, i1 %y) {
 ; CHECK-LABEL: @and_orn_cmp_1_logical(
 ; CHECK-NEXT:    [[X:%.*]] = icmp sgt i32 [[A:%.*]], [[B:%.*]]
-; CHECK-NEXT:    [[X_INV:%.*]] = icmp sle i32 [[A]], [[B]]
-; CHECK-NEXT:    [[OR:%.*]] = select i1 [[Y:%.*]], i1 true, i1 [[X_INV]]
-; CHECK-NEXT:    [[AND:%.*]] = select i1 [[X]], i1 [[OR]], i1 false
+; CHECK-NEXT:    [[AND:%.*]] = select i1 [[X]], i1 [[Y:%.*]], i1 false
 ; CHECK-NEXT:    ret i1 [[AND]]
 ;
   %x = icmp sgt i32 %a, %b
@@ -146,10 +144,8 @@
 
 define i1 @andn_or_cmp_2_logical(i16 %a, i16 %b, i1 %y) {
 ; CHECK-LABEL: @andn_or_cmp_2_logical(
-; CHECK-NEXT:    [[X:%.*]] = icmp sge i16 [[A:%.*]], [[B:%.*]]
-; CHECK-NEXT:    [[X_INV:%.*]] = icmp slt i16 [[A]], [[B]]
-; CHECK-NEXT:    [[OR:%.*]] = select i1 [[Y:%.*]], i1 true, i1 [[X]]
-; CHECK-NEXT:    [[AND:%.*]] = select i1 [[OR]], i1 [[X_INV]], i1 false
+; CHECK-NEXT:    [[X_INV:%.*]] = icmp slt i16 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    [[AND:%.*]] = select i1 [[Y:%.*]], i1 [[X_INV]], i1 false
 ; CHECK-NEXT:    ret i1 [[AND]]
 ;
   %x = icmp sge i16 %a, %b
@@ -161,10 +157,7 @@
 
 define i1 @bools_logical(i1 %a, i1 %b, i1 %c) {
 ; CHECK-LABEL: @bools_logical(
-; CHECK-NEXT:    [[NOT:%.*]] = xor i1 [[C:%.*]], true
-; CHECK-NEXT:    [[AND1:%.*]] = select i1 [[NOT]], i1 [[A:%.*]], i1 false
-; CHECK-NEXT:    [[AND2:%.*]] = select i1 [[C]], i1 [[B:%.*]], i1 false
-; CHECK-NEXT:    [[OR:%.*]] = select i1 [[AND1]], i1 true, i1 [[AND2]]
+; CHECK-NEXT:    [[OR:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A:%.*]]
 ; CHECK-NEXT:    ret i1 [[OR]]
 ;
   %not = xor i1 %c, -1
@@ -176,10 +169,7 @@
 
 define i1 @bools2_logical(i1 %a, i1 %b, i1 %c) {
 ; CHECK-LABEL: @bools2_logical(
-; CHECK-NEXT:    [[NOT:%.*]] = xor i1 [[C:%.*]], true
-; CHECK-NEXT:    [[AND1:%.*]] = select i1 [[C]], i1 [[A:%.*]], i1 false
-; CHECK-NEXT:    [[AND2:%.*]] = select i1 [[NOT]], i1 [[B:%.*]], i1 false
-; CHECK-NEXT:    [[OR:%.*]] = select i1 [[AND1]], i1 true, i1 [[AND2]]
+; CHECK-NEXT:    [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B:%.*]]
 ; CHECK-NEXT:    ret i1 [[OR]]
 ;
   %not = xor i1 %c, -1
Index: llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -2710,6 +2710,34 @@
         return replaceInstUsesWith(SI, Op1);
       }
     }
+
+    // select (select a, true, b), c, false -> select a, c, false
+    // select c, (select a, true, b), false -> select c, a, false
+    //   if c implies that b is false.
+    if (match(CondVal, m_Select(m_Value(A), m_One(), m_Value(B))) &&
+        match(FalseVal, m_Zero())) {
+      auto Res = isImpliedCondition(TrueVal, B, DL);
+      if (Res && *Res == false)
+        return replaceOperand(SI, 0, A);
+    }
+    if (match(TrueVal, m_Select(m_Value(A), m_One(), m_Value(B))) &&
+        match(FalseVal, m_Zero())) {
+      auto Res = isImpliedCondition(CondVal, B, DL);
+      if (Res && *Res == false)
+        return replaceOperand(SI, 1, A);
+    }
+
+    // sel (sel c, a, false), true, (sel !c, b, false) -> sel c, a, b
+    // sel (sel !c, a, false), true, (sel c, b, false) -> sel c, b, a
+    Value *C1, *C2;
+    if (match(CondVal, m_Select(m_Value(C1), m_Value(A), m_Zero())) &&
+        match(TrueVal, m_One()) &&
+        match(FalseVal, m_Select(m_Value(C2), m_Value(B), m_Zero()))) {
+      if (match(C2, m_Not(m_Specific(C1)))) // first case
+        return SelectInst::Create(C1, A, B);
+      else if (match(C1, m_Not(m_Specific(C2)))) // second case
+        return SelectInst::Create(C2, B, A);
+    }
   }
 
   // Selecting between two integer or vector splat integer constants?


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D101375.342194.patch
Type: text/x-patch
Size: 4056 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210502/946c5700/attachment.bin>


More information about the llvm-commits mailing list