[llvm] e719550 - [InstCombine] fold icmp + select pattern by distributive laws

via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 2 15:56:30 PST 2022


Author: chenglin.bi
Date: 2022-12-03T07:56:19+08:00
New Revision: e719550e6f0161da597c9c0a0ceb60b3670ce2c2

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

LOG: [InstCombine] fold icmp + select pattern by distributive laws

`C ? (Y != X) : (Z != X) --> (C ? Y : Z) != X`
`C ? (Y == X) : (Z == X) --> (C ? Y : Z) == X`

https://alive2.llvm.org/ce/z/-frXfs

Reviewed By: spatel

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

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
    llvm/test/Transforms/InstCombine/select-cmp.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index f72656b54386..8d6fad3955d9 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -378,6 +378,20 @@ Instruction *InstCombinerImpl::foldSelectOpOp(SelectInst &SI, Instruction *TI,
         }
       }
     }
+
+    // icmp eq/ne with a common operand also can have the common operand
+    // pulled after the select.
+    ICmpInst::Predicate TPred, FPred;
+    if (match(TI, m_ICmp(TPred, m_Value(), m_Value())) &&
+        match(FI, m_ICmp(FPred, m_Value(), m_Value()))) {
+      if (TPred == FPred && ICmpInst::isEquality(TPred)) {
+        if (Value *MatchOp = getCommonOp(TI, FI, true)) {
+          Value *NewSel = Builder.CreateSelect(Cond, OtherOpT, OtherOpF,
+                                               SI.getName() + ".v", &SI);
+          return new ICmpInst(TPred, NewSel, MatchOp);
+        }
+      }
+    }
   }
 
   // Only handle binary operators (including two-operand getelementptr) with

diff  --git a/llvm/test/Transforms/InstCombine/select-cmp.ll b/llvm/test/Transforms/InstCombine/select-cmp.ll
index 386616ec04d7..4abfd31e512a 100644
--- a/llvm/test/Transforms/InstCombine/select-cmp.ll
+++ b/llvm/test/Transforms/InstCombine/select-cmp.ll
@@ -13,9 +13,8 @@ define i1 @f(i1 %cond, i32 %x, i32 %x2) {
 
 define i1 @icmp_ne_common_op00(i1 %c, i6 %x, i6 %y, i6 %z) {
 ; CHECK-LABEL: @icmp_ne_common_op00(
-; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i6 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMP2:%.*]] = icmp ne i6 [[X]], [[Z:%.*]]
-; CHECK-NEXT:    [[R:%.*]] = select i1 [[C:%.*]], i1 [[CMP1]], i1 [[CMP2]]
+; CHECK-NEXT:    [[R_V:%.*]] = select i1 [[C:%.*]], i6 [[Y:%.*]], i6 [[Z:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = icmp ne i6 [[R_V]], [[X:%.*]]
 ; CHECK-NEXT:    ret i1 [[R]]
 ;
   %cmp1 = icmp ne i6 %x, %y
@@ -26,9 +25,8 @@ define i1 @icmp_ne_common_op00(i1 %c, i6 %x, i6 %y, i6 %z) {
 
 define i1 @icmp_ne_common_op01(i1 %c, i3 %x, i3 %y, i3 %z) {
 ; CHECK-LABEL: @icmp_ne_common_op01(
-; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i3 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMP2:%.*]] = icmp ne i3 [[Z:%.*]], [[X]]
-; CHECK-NEXT:    [[R:%.*]] = select i1 [[C:%.*]], i1 [[CMP1]], i1 [[CMP2]]
+; CHECK-NEXT:    [[R_V:%.*]] = select i1 [[C:%.*]], i3 [[Y:%.*]], i3 [[Z:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = icmp ne i3 [[R_V]], [[X:%.*]]
 ; CHECK-NEXT:    ret i1 [[R]]
 ;
   %cmp1 = icmp ne i3 %x, %y
@@ -39,9 +37,8 @@ define i1 @icmp_ne_common_op01(i1 %c, i3 %x, i3 %y, i3 %z) {
 
 define i1 @icmp_ne_common_op10(i1 %c, i4 %x, i4 %y, i4 %z) {
 ; CHECK-LABEL: @icmp_ne_common_op10(
-; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i4 [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:    [[CMP2:%.*]] = icmp ne i4 [[X]], [[Z:%.*]]
-; CHECK-NEXT:    [[R:%.*]] = select i1 [[C:%.*]], i1 [[CMP1]], i1 [[CMP2]]
+; CHECK-NEXT:    [[R_V:%.*]] = select i1 [[C:%.*]], i4 [[Y:%.*]], i4 [[Z:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = icmp ne i4 [[R_V]], [[X:%.*]]
 ; CHECK-NEXT:    ret i1 [[R]]
 ;
   %cmp1 = icmp ne i4 %y, %x
@@ -52,9 +49,8 @@ define i1 @icmp_ne_common_op10(i1 %c, i4 %x, i4 %y, i4 %z) {
 
 define <3 x i1> @icmp_ne_common_op11(<3 x i1> %c, <3 x i17> %x, <3 x i17> %y, <3 x i17> %z) {
 ; CHECK-LABEL: @icmp_ne_common_op11(
-; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne <3 x i17> [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:    [[CMP2:%.*]] = icmp ne <3 x i17> [[Z:%.*]], [[X]]
-; CHECK-NEXT:    [[R:%.*]] = select <3 x i1> [[C:%.*]], <3 x i1> [[CMP1]], <3 x i1> [[CMP2]]
+; CHECK-NEXT:    [[R_V:%.*]] = select <3 x i1> [[C:%.*]], <3 x i17> [[Y:%.*]], <3 x i17> [[Z:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = icmp ne <3 x i17> [[R_V]], [[X:%.*]]
 ; CHECK-NEXT:    ret <3 x i1> [[R]]
 ;
   %cmp1 = icmp ne <3 x i17> %y, %x
@@ -65,9 +61,8 @@ define <3 x i1> @icmp_ne_common_op11(<3 x i1> %c, <3 x i17> %x, <3 x i17> %y, <3
 
 define i1 @icmp_eq_common_op00(i1 %c, i5 %x, i5 %y, i5 %z) {
 ; CHECK-LABEL: @icmp_eq_common_op00(
-; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i5 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i5 [[X]], [[Z:%.*]]
-; CHECK-NEXT:    [[R:%.*]] = select i1 [[C:%.*]], i1 [[CMP1]], i1 [[CMP2]]
+; CHECK-NEXT:    [[R_V:%.*]] = select i1 [[C:%.*]], i5 [[Y:%.*]], i5 [[Z:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = icmp eq i5 [[R_V]], [[X:%.*]]
 ; CHECK-NEXT:    ret i1 [[R]]
 ;
   %cmp1 = icmp eq i5 %x, %y
@@ -78,9 +73,8 @@ define i1 @icmp_eq_common_op00(i1 %c, i5 %x, i5 %y, i5 %z) {
 
 define <5 x i1> @icmp_eq_common_op01(<5 x i1> %c, <5 x i7> %x, <5 x i7> %y, <5 x i7> %z) {
 ; CHECK-LABEL: @icmp_eq_common_op01(
-; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq <5 x i7> [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq <5 x i7> [[Z:%.*]], [[X]]
-; CHECK-NEXT:    [[R:%.*]] = select <5 x i1> [[C:%.*]], <5 x i1> [[CMP1]], <5 x i1> [[CMP2]]
+; CHECK-NEXT:    [[R_V:%.*]] = select <5 x i1> [[C:%.*]], <5 x i7> [[Y:%.*]], <5 x i7> [[Z:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = icmp eq <5 x i7> [[R_V]], [[X:%.*]]
 ; CHECK-NEXT:    ret <5 x i1> [[R]]
 ;
   %cmp1 = icmp eq <5 x i7> %x, %y
@@ -91,9 +85,8 @@ define <5 x i1> @icmp_eq_common_op01(<5 x i1> %c, <5 x i7> %x, <5 x i7> %y, <5 x
 
 define i1 @icmp_eq_common_op10(i1 %c, i32 %x, i32 %y, i32 %z) {
 ; CHECK-LABEL: @icmp_eq_common_op10(
-; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i32 [[X]], [[Z:%.*]]
-; CHECK-NEXT:    [[R:%.*]] = select i1 [[C:%.*]], i1 [[CMP1]], i1 [[CMP2]]
+; CHECK-NEXT:    [[R_V:%.*]] = select i1 [[C:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[R_V]], [[X:%.*]]
 ; CHECK-NEXT:    ret i1 [[R]]
 ;
   %cmp1 = icmp eq i32 %y, %x
@@ -104,9 +97,8 @@ define i1 @icmp_eq_common_op10(i1 %c, i32 %x, i32 %y, i32 %z) {
 
 define i1 @icmp_eq_common_op11(i1 %c, i64 %x, i64 %y, i64 %z) {
 ; CHECK-LABEL: @icmp_eq_common_op11(
-; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i64 [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i64 [[Z:%.*]], [[X]]
-; CHECK-NEXT:    [[R:%.*]] = select i1 [[C:%.*]], i1 [[CMP1]], i1 [[CMP2]]
+; CHECK-NEXT:    [[R_V:%.*]] = select i1 [[C:%.*]], i64 [[Y:%.*]], i64 [[Z:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = icmp eq i64 [[R_V]], [[X:%.*]]
 ; CHECK-NEXT:    ret i1 [[R]]
 ;
   %cmp1 = icmp eq i64 %y, %x
@@ -119,8 +111,8 @@ define i1 @icmp_common_one_use_1(i1 %c, i8 %x, i8 %y, i8 %z) {
 ; CHECK-LABEL: @icmp_common_one_use_1(
 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[Y:%.*]], [[X:%.*]]
 ; CHECK-NEXT:    call void @use(i1 [[CMP1]])
-; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i8 [[Z:%.*]], [[X]]
-; CHECK-NEXT:    [[R:%.*]] = select i1 [[C:%.*]], i1 [[CMP1]], i1 [[CMP2]]
+; CHECK-NEXT:    [[R_V:%.*]] = select i1 [[C:%.*]], i8 [[Y]], i8 [[Z:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[R_V]], [[X]]
 ; CHECK-NEXT:    ret i1 [[R]]
 ;
   %cmp1 = icmp eq i8 %y, %x


        


More information about the llvm-commits mailing list