[llvm] [InstCombine] Simplify commutative compares of symmetric pairs (PR #80134)

via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 31 04:22:18 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-transforms

Author: Yingwei Zheng (dtcxzyw)

<details>
<summary>Changes</summary>

Fixes #<!-- -->78038.

---
Full diff: https://github.com/llvm/llvm-project/pull/80134.diff


3 Files Affected:

- (modified) llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp (+16) 
- (modified) llvm/test/Transforms/InstCombine/fcmp-select.ll (+34) 
- (modified) llvm/test/Transforms/InstCombine/icmp-select.ll (+24) 


``````````diff
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
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/80134


More information about the llvm-commits mailing list