[llvm] 817d0cb - [InstCombine] Simplify commutative compares of symmetric pairs (#80134)

via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 31 05:21:31 PST 2024


Author: Yingwei Zheng
Date: 2024-01-31T21:21:27+08:00
New Revision: 817d0cb4856236e16c7065fc37fbdd97a3ca67e0

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

LOG: [InstCombine] Simplify commutative compares of symmetric pairs (#80134)

Fixes #78038.

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
    llvm/test/Transforms/InstCombine/fcmp-select.ll
    llvm/test/Transforms/InstCombine/icmp-select.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index eab2c8bd8efde..d295853798b80 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -7055,6 +7055,14 @@ Instruction *InstCombinerImpl::visitICmpInst(ICmpInst &I) {
           foldICmpCommutative(I.getSwappedPredicate(), Op1, Op0, I))
     return Res;
 
+  if (I.isCommutative()) {
+    if (auto Pair = matchSymmetricPair(I.getOperand(0), I.getOperand(1))) {
+      replaceOperand(I, 0, Pair->first);
+      replaceOperand(I, 1, Pair->second);
+      return &I;
+    }
+  }
+
   // In case of a comparison with two select instructions having the same
   // condition, check whether one of the resulting branches can be simplified.
   // If so, just compare the other branch and select the appropriate result.
@@ -7668,6 +7676,14 @@ Instruction *InstCombinerImpl::visitFCmpInst(FCmpInst &I) {
     }
   }
 
+  if (I.isCommutative()) {
+    if (auto Pair = matchSymmetricPair(I.getOperand(0), I.getOperand(1))) {
+      replaceOperand(I, 0, Pair->first);
+      replaceOperand(I, 1, Pair->second);
+      return &I;
+    }
+  }
+
   // If we're just checking for a NaN (ORD/UNO) and have a non-NaN operand,
   // then canonicalize the operand to 0.0.
   if (Pred == CmpInst::FCMP_ORD || Pred == CmpInst::FCMP_UNO) {

diff  --git a/llvm/test/Transforms/InstCombine/fcmp-select.ll b/llvm/test/Transforms/InstCombine/fcmp-select.ll
index b4ab8ef725d71..f37c586845b12 100644
--- a/llvm/test/Transforms/InstCombine/fcmp-select.ll
+++ b/llvm/test/Transforms/InstCombine/fcmp-select.ll
@@ -114,3 +114,37 @@ define double @one_swapped(double %x) {
   ret double %cond
 }
 
+define i1 @fcmp_oeq_select(i1 %cond, float %a, float %b) {
+; CHECK-LABEL: @fcmp_oeq_select(
+; CHECK-NEXT:    [[RES:%.*]] = fcmp oeq float [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[RES]]
+;
+  %lhs = select i1 %cond, float %a, float %b
+  %rhs = select i1 %cond, float %b, float %a
+  %res = fcmp oeq float %lhs, %rhs
+  ret i1 %res
+}
+
+define i1 @fcmp_uno_select(i1 %cond, float %a, float %b) {
+; CHECK-LABEL: @fcmp_uno_select(
+; CHECK-NEXT:    [[RES:%.*]] = fcmp uno float [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[RES]]
+;
+  %lhs = select i1 %cond, float %a, float %b
+  %rhs = select i1 %cond, float %b, float %a
+  %res = fcmp uno float %lhs, %rhs
+  ret i1 %res
+}
+
+define i1 @fcmp_ogt_select(i1 %cond, float %a, float %b) {
+; CHECK-LABEL: @fcmp_ogt_select(
+; CHECK-NEXT:    [[LHS:%.*]] = select i1 [[COND:%.*]], float [[A:%.*]], float [[B:%.*]]
+; CHECK-NEXT:    [[RHS:%.*]] = select i1 [[COND]], float [[B]], float [[A]]
+; CHECK-NEXT:    [[RES:%.*]] = fcmp ogt float [[LHS]], [[RHS]]
+; CHECK-NEXT:    ret i1 [[RES]]
+;
+  %lhs = select i1 %cond, float %a, float %b
+  %rhs = select i1 %cond, float %b, float %a
+  %res = fcmp ogt float %lhs, %rhs
+  ret i1 %res
+}

diff  --git a/llvm/test/Transforms/InstCombine/icmp-select.ll b/llvm/test/Transforms/InstCombine/icmp-select.ll
index 0d723c9df32e2..59d2a1b165c0f 100644
--- a/llvm/test/Transforms/InstCombine/icmp-select.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-select.ll
@@ -604,3 +604,27 @@ define i1 @select_constants_and_icmp_ne_fval(i1 %x, i1 %y) {
   %cmp = icmp ne i8 %and, 3
   ret i1 %cmp
 }
+
+define i1 @icmp_eq_select(i1 %cond, i32 %a, i32 %b) {
+; CHECK-LABEL: @icmp_eq_select(
+; CHECK-NEXT:    [[RES:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[RES]]
+;
+  %lhs = select i1 %cond, i32 %a, i32 %b
+  %rhs = select i1 %cond, i32 %b, i32 %a
+  %res = icmp eq i32 %lhs, %rhs
+  ret i1 %res
+}
+
+define i1 @icmp_slt_select(i1 %cond, i32 %a, i32 %b) {
+; CHECK-LABEL: @icmp_slt_select(
+; CHECK-NEXT:    [[LHS:%.*]] = select i1 [[COND:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]
+; CHECK-NEXT:    [[RHS:%.*]] = select i1 [[COND]], i32 [[B]], i32 [[A]]
+; CHECK-NEXT:    [[RES:%.*]] = icmp slt i32 [[LHS]], [[RHS]]
+; CHECK-NEXT:    ret i1 [[RES]]
+;
+  %lhs = select i1 %cond, i32 %a, i32 %b
+  %rhs = select i1 %cond, i32 %b, i32 %a
+  %res = icmp slt i32 %lhs, %rhs
+  ret i1 %res
+}


        


More information about the llvm-commits mailing list