[llvm] r339520 - [InstCombine] Fold Select with binary op - non-commutative opcodes

David Bolvansky via llvm-commits llvm-commits at lists.llvm.org
Sun Aug 12 10:30:07 PDT 2018


Author: xbolva00
Date: Sun Aug 12 10:30:07 2018
New Revision: 339520

URL: http://llvm.org/viewvc/llvm-project?rev=339520&view=rev
Log:
[InstCombine] Fold Select with binary op - non-commutative opcodes

Summary:
Basic version was merged - https://reviews.llvm.org/D49954

This adds support for FP & non-commutative opcodes

Precommited tests: https://reviews.llvm.org/rL338727

Reviewers: spatel, lebedev.ri

Reviewed By: spatel

Subscribers: jfb

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

Modified:
    llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp
    llvm/trunk/test/Transforms/InstCombine/select-binop-icmp.ll

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp?rev=339520&r1=339519&r2=339520&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp Sun Aug 12 10:30:07 2018
@@ -68,15 +68,16 @@ static Instruction *foldSelectBinOpIdent
 
   // A select operand must be a binop, and the compare constant must be the
   // identity constant for that binop.
-  // TODO: Support non-commutative binops.
   bool IsEq = Pred == ICmpInst::ICMP_EQ;
   BinaryOperator *BO;
   if (!match(Sel.getOperand(IsEq ? 1 : 2), m_BinOp(BO)) ||
-      ConstantExpr::getBinOpIdentity(BO->getOpcode(), BO->getType(), false) != C)
+      ConstantExpr::getBinOpIdentity(BO->getOpcode(), BO->getType(), true) != C)
     return nullptr;
 
   // Last, match the compare variable operand with a binop operand.
   Value *Y;
+  if (!BO->isCommutative() && !match(BO, m_BinOp(m_Value(Y), m_Specific(X))))
+    return nullptr;
   if (!match(BO, m_c_BinOp(m_Value(Y), m_Specific(X))))
     return nullptr;
 

Modified: llvm/trunk/test/Transforms/InstCombine/select-binop-icmp.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/select-binop-icmp.ll?rev=339520&r1=339519&r2=339520&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/select-binop-icmp.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/select-binop-icmp.ll Sun Aug 12 10:30:07 2018
@@ -235,8 +235,7 @@ define float @select_fdiv_fcmp(float %x,
 define i32 @select_sub_icmp(i32 %x, i32 %y, i32 %z) {
 ; CHECK-LABEL: @select_sub_icmp(
 ; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 0
-; CHECK-NEXT:    [[B:%.*]] = sub i32 [[Z:%.*]], [[X]]
-; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
+; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]]
 ; CHECK-NEXT:    ret i32 [[C]]
 ;
   %A = icmp eq i32 %x, 0
@@ -249,8 +248,7 @@ define i32 @select_sub_icmp_2(i32 %x, i3
 ; CHECK-LABEL: @select_sub_icmp_2(
 ; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 0
 ; CHECK-NEXT:    call void @use2(i1 [[A]])
-; CHECK-NEXT:    [[B:%.*]] = sub i32 [[Z:%.*]], [[X]]
-; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
+; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]]
 ; CHECK-NEXT:    ret i32 [[C]]
 ;
   %A = icmp eq i32 %x, 0
@@ -264,8 +262,7 @@ define i32 @select_sub_icmp_3(i32 %x, i3
 ; CHECK-LABEL: @select_sub_icmp_3(
 ; CHECK-NEXT:    [[A:%.*]] = icmp ne i32 [[X:%.*]], 0
 ; CHECK-NEXT:    call void @use2(i1 [[A]])
-; CHECK-NEXT:    [[B:%.*]] = sub i32 [[Z:%.*]], [[X]]
-; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[Y:%.*]], i32 [[B]]
+; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[Y:%.*]], i32 [[Z:%.*]]
 ; CHECK-NEXT:    ret i32 [[C]]
 ;
   %A = icmp ne i32 %x, 0
@@ -278,8 +275,7 @@ define i32 @select_sub_icmp_3(i32 %x, i3
 define <2 x i8> @select_sub_icmp_vec(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) {
 ; CHECK-LABEL: @select_sub_icmp_vec(
 ; CHECK-NEXT:    [[A:%.*]] = icmp eq <2 x i8> [[X:%.*]], zeroinitializer
-; CHECK-NEXT:    [[B:%.*]] = sub <2 x i8> [[Z:%.*]], [[X]]
-; CHECK-NEXT:    [[C:%.*]] = select <2 x i1> [[A]], <2 x i8> [[B]], <2 x i8> [[Y:%.*]]
+; CHECK-NEXT:    [[C:%.*]] = select <2 x i1> [[A]], <2 x i8> [[Z:%.*]], <2 x i8> [[Y:%.*]]
 ; CHECK-NEXT:    ret <2 x i8> [[C]]
 ;
   %A = icmp eq <2 x i8>  %x, <i8 0, i8 0>
@@ -292,8 +288,7 @@ define i32 @select_shl_icmp(i32 %x, i32
 ; CHECK-LABEL: @select_shl_icmp(
 ; CHECK-NEXT:    [[A:%.*]] = icmp ne i32 [[X:%.*]], 0
 ; CHECK-NEXT:    call void @use2(i1 [[A]])
-; CHECK-NEXT:    [[B:%.*]] = shl i32 [[Z:%.*]], [[X]]
-; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[Y:%.*]], i32 [[B]]
+; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[Y:%.*]], i32 [[Z:%.*]]
 ; CHECK-NEXT:    ret i32 [[C]]
 ;
   %A = icmp ne i32 %x, 0
@@ -306,8 +301,7 @@ define i32 @select_shl_icmp(i32 %x, i32
 define i32 @select_lshr_icmp(i32 %x, i32 %y, i32 %z) {
 ; CHECK-LABEL: @select_lshr_icmp(
 ; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 0
-; CHECK-NEXT:    [[B:%.*]] = lshr i32 [[Z:%.*]], [[X]]
-; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
+; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]]
 ; CHECK-NEXT:    ret i32 [[C]]
 ;
   %A = icmp eq i32 %x, 0
@@ -320,8 +314,7 @@ define i32 @select_ashr_icmp(i32 %x, i32
 ; CHECK-LABEL: @select_ashr_icmp(
 ; CHECK-NEXT:    [[A:%.*]] = icmp ne i32 [[X:%.*]], 0
 ; CHECK-NEXT:    call void @use2(i1 [[A]])
-; CHECK-NEXT:    [[B:%.*]] = ashr i32 [[Z:%.*]], [[X]]
-; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[Y:%.*]], i32 [[B]]
+; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[Y:%.*]], i32 [[Z:%.*]]
 ; CHECK-NEXT:    ret i32 [[C]]
 ;
   %A = icmp ne i32 %x, 0
@@ -334,8 +327,7 @@ define i32 @select_ashr_icmp(i32 %x, i32
 define i32 @select_udiv_icmp(i32 %x, i32 %y, i32 %z) {
 ; CHECK-LABEL: @select_udiv_icmp(
 ; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 1
-; CHECK-NEXT:    [[B:%.*]] = udiv i32 [[Z:%.*]], [[X]]
-; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[B]], i32 [[Y:%.*]]
+; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[Z:%.*]], i32 [[Y:%.*]]
 ; CHECK-NEXT:    ret i32 [[C]]
 ;
   %A = icmp eq i32 %x, 1
@@ -348,8 +340,7 @@ define i32 @select_sdiv_icmp(i32 %x, i32
 ; CHECK-LABEL: @select_sdiv_icmp(
 ; CHECK-NEXT:    [[A:%.*]] = icmp ne i32 [[X:%.*]], 1
 ; CHECK-NEXT:    call void @use2(i1 [[A]])
-; CHECK-NEXT:    [[B:%.*]] = sdiv i32 [[Z:%.*]], [[X]]
-; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[Y:%.*]], i32 [[B]]
+; CHECK-NEXT:    [[C:%.*]] = select i1 [[A]], i32 [[Y:%.*]], i32 [[Z:%.*]]
 ; CHECK-NEXT:    ret i32 [[C]]
 ;
   %A = icmp ne i32 %x, 1




More information about the llvm-commits mailing list