[llvm] ee3a260 - [InstCombine] support fold select(X|Y,X|Y,X) to X|Y

Congcong Cai via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 17 13:07:22 PDT 2023


Author: Congcong Cai
Date: 2023-04-17T22:07:01+02:00
New Revision: ee3a260e78474b4499fc98737923ebb7df6eada8

URL: https://github.com/llvm/llvm-project/commit/ee3a260e78474b4499fc98737923ebb7df6eada8
DIFF: https://github.com/llvm/llvm-project/commit/ee3a260e78474b4499fc98737923ebb7df6eada8.diff

LOG: [InstCombine] support fold select(X|Y,X|Y,X) to X|Y

Fixed: https://github.com/llvm/llvm-project/issues/62113
Add addtional check in `visitSelectInst` to:
1. match `select(X|Y==0, X, X|Y)` and replaced with `X|Y`
2. match `select(X&Y==-1, X, X&Y)` and replaced with `X&Y`

alive proof:
https://alive2.llvm.org/ce/z/4qHmv-
https://alive2.llvm.org/ce/z/c2MBGy

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D148275

Added: 
    

Modified: 
    llvm/lib/Analysis/InstructionSimplify.cpp
    llvm/test/Transforms/InstSimplify/select_or_and.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 51f8de43e5c8..fb6a395eea08 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -4582,6 +4582,21 @@ static Value *simplifySelectWithICmpCond(Value *CondVal, Value *TrueVal,
       return FalseVal;
   }
 
+  if (Pred == ICmpInst::Predicate::ICMP_EQ) {
+    Value *X;
+    Value *Y;
+    // select(X | Y == 0, X or Y, X | Y) -> X | Y
+    if (match(CondVal, m_ICmp(Pred, m_Specific(FalseVal), m_Zero())) &&
+        match(FalseVal, m_Or(m_Value(X), m_Value(Y))) &&
+        (TrueVal == X || TrueVal == Y))
+      return FalseVal;
+    // select(X & Y == -1, X or Y, X & Y) -> X & Y
+    if (match(CondVal, m_ICmp(Pred, m_Specific(FalseVal), m_AllOnes())) &&
+        match(FalseVal, m_And(m_Value(X), m_Value(Y))) &&
+        (TrueVal == X || TrueVal == Y))
+      return FalseVal;
+  }
+
   return nullptr;
 }
 

diff  --git a/llvm/test/Transforms/InstSimplify/select_or_and.ll b/llvm/test/Transforms/InstSimplify/select_or_and.ll
index 599b783cfac2..2188d3fcb28d 100644
--- a/llvm/test/Transforms/InstSimplify/select_or_and.ll
+++ b/llvm/test/Transforms/InstSimplify/select_or_and.ll
@@ -5,9 +5,7 @@
 define i32 @select_or_1(i32 %x, i32 %y) {
 ; CHECK-LABEL: @select_or_1(
 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[OR]], 0
-; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[OR]]
-; CHECK-NEXT:    ret i32 [[RET]]
+; CHECK-NEXT:    ret i32 [[OR]]
 ;
   %or = or i32 %y, %x
   %cmp = icmp eq i32 %or, 0
@@ -19,9 +17,7 @@ define i32 @select_or_1(i32 %x, i32 %y) {
 define i32 @select_or_2(i32 %x, i32 %y) {
 ; CHECK-LABEL: @select_or_2(
 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[OR]], 0
-; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[OR]]
-; CHECK-NEXT:    ret i32 [[RET]]
+; CHECK-NEXT:    ret i32 [[OR]]
 ;
   %or = or i32 %y, %x
   %cmp = icmp eq i32 %or, 0
@@ -33,9 +29,7 @@ define i32 @select_or_2(i32 %x, i32 %y) {
 define i32 @select_or_3(i32 %x, i32 %y) {
 ; CHECK-LABEL: @select_or_3(
 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[OR]], 0
-; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP]], i32 [[OR]], i32 [[X]]
-; CHECK-NEXT:    ret i32 [[RET]]
+; CHECK-NEXT:    ret i32 [[OR]]
 ;
   %or = or i32 %y, %x
   %cmp = icmp ne i32 %or, 0
@@ -47,9 +41,7 @@ define i32 @select_or_3(i32 %x, i32 %y) {
 define i32 @select_or_4(i32 %x, i32 %y) {
 ; CHECK-LABEL: @select_or_4(
 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[OR]], 0
-; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP]], i32 [[OR]], i32 [[Y]]
-; CHECK-NEXT:    ret i32 [[RET]]
+; CHECK-NEXT:    ret i32 [[OR]]
 ;
   %or = or i32 %y, %x
   %cmp = icmp ne i32 %or, 0
@@ -61,9 +53,7 @@ define i32 @select_or_4(i32 %x, i32 %y) {
 define <4 x i32> @select_or_vec(<4 x i32> %x, <4 x i32> %y) {
 ; CHECK-LABEL: @select_or_vec(
 ; CHECK-NEXT:    [[OR:%.*]] = or <4 x i32> [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <4 x i32> [[OR]], zeroinitializer
-; CHECK-NEXT:    [[RET:%.*]] = select <4 x i1> [[CMP]], <4 x i32> [[OR]], <4 x i32> [[Y]]
-; CHECK-NEXT:    ret <4 x i32> [[RET]]
+; CHECK-NEXT:    ret <4 x i32> [[OR]]
 ;
   %or = or <4 x i32> %y, %x
   %cmp = icmp ne <4 x i32> %or, zeroinitializer
@@ -115,9 +105,7 @@ define i32 @select_or_not_3(i32 %x, i32 %y) {
 define i32 @select_and_1(i32 %x, i32 %y) {
 ; CHECK-LABEL: @select_and_1(
 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], -1
-; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[AND]]
-; CHECK-NEXT:    ret i32 [[RET]]
+; CHECK-NEXT:    ret i32 [[AND]]
 ;
   %and = and i32 %y, %x
   %cmp = icmp eq i32 %and, -1
@@ -129,9 +117,7 @@ define i32 @select_and_1(i32 %x, i32 %y) {
 define i32 @select_and_2(i32 %x, i32 %y) {
 ; CHECK-LABEL: @select_and_2(
 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], -1
-; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[AND]]
-; CHECK-NEXT:    ret i32 [[RET]]
+; CHECK-NEXT:    ret i32 [[AND]]
 ;
   %and = and i32 %y, %x
   %cmp = icmp eq i32 %and, -1
@@ -144,9 +130,7 @@ define i32 @select_and_2(i32 %x, i32 %y) {
 define i32 @select_and_3(i32 %x, i32 %y) {
 ; CHECK-LABEL: @select_and_3(
 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[AND]], -1
-; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP]], i32 [[AND]], i32 [[X]]
-; CHECK-NEXT:    ret i32 [[RET]]
+; CHECK-NEXT:    ret i32 [[AND]]
 ;
   %and = and i32 %y, %x
   %cmp = icmp ne i32 %and, -1
@@ -158,9 +142,7 @@ define i32 @select_and_3(i32 %x, i32 %y) {
 define i32 @select_and_4(i32 %x, i32 %y) {
 ; CHECK-LABEL: @select_and_4(
 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[AND]], -1
-; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP]], i32 [[AND]], i32 [[Y]]
-; CHECK-NEXT:    ret i32 [[RET]]
+; CHECK-NEXT:    ret i32 [[AND]]
 ;
   %and = and i32 %y, %x
   %cmp = icmp ne i32 %and, -1


        


More information about the llvm-commits mailing list