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

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 31 04:21:51 PST 2024


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

Fixes #78038.

>From f67e74a1f7fab0da78c75bb3ae32e6f970b86bbf Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Wed, 31 Jan 2024 20:06:56 +0800
Subject: [PATCH 1/2] [InstCombine] Add pre-commit tests. NFC.

---
 .../Transforms/InstCombine/fcmp-select.ll     | 38 +++++++++++++++++++
 .../Transforms/InstCombine/icmp-select.ll     | 26 +++++++++++++
 2 files changed, 64 insertions(+)

diff --git a/llvm/test/Transforms/InstCombine/fcmp-select.ll b/llvm/test/Transforms/InstCombine/fcmp-select.ll
index b4ab8ef725d71..46fa52524f64a 100644
--- a/llvm/test/Transforms/InstCombine/fcmp-select.ll
+++ b/llvm/test/Transforms/InstCombine/fcmp-select.ll
@@ -114,3 +114,41 @@ 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:    [[LHS:%.*]] = select i1 [[COND:%.*]], float [[A:%.*]], float [[B:%.*]]
+; CHECK-NEXT:    [[RHS:%.*]] = select i1 [[COND]], float [[B]], float [[A]]
+; CHECK-NEXT:    [[RES:%.*]] = fcmp oeq 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 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:    [[LHS:%.*]] = select i1 [[COND:%.*]], float [[A:%.*]], float [[B:%.*]]
+; CHECK-NEXT:    [[RHS:%.*]] = select i1 [[COND]], float [[B]], float [[A]]
+; CHECK-NEXT:    [[RES:%.*]] = fcmp uno 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 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..dfdd498fd8c7e 100644
--- a/llvm/test/Transforms/InstCombine/icmp-select.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-select.ll
@@ -604,3 +604,29 @@ 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:    [[LHS:%.*]] = select i1 [[COND:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]
+; CHECK-NEXT:    [[RHS:%.*]] = select i1 [[COND]], i32 [[B]], i32 [[A]]
+; CHECK-NEXT:    [[RES:%.*]] = icmp eq 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 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
+}

>From 7d8b66840ed6228aa6b96edecd125483b65e7989 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Wed, 31 Jan 2024 20:08:46 +0800
Subject: [PATCH 2/2] [InstCombine] Simplify commutative compares of symmetric
 pairs

---
 .../InstCombine/InstCombineCompares.cpp          | 16 ++++++++++++++++
 llvm/test/Transforms/InstCombine/fcmp-select.ll  |  8 ++------
 llvm/test/Transforms/InstCombine/icmp-select.ll  |  4 +---
 3 files changed, 19 insertions(+), 9 deletions(-)

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 46fa52524f64a..f37c586845b12 100644
--- a/llvm/test/Transforms/InstCombine/fcmp-select.ll
+++ b/llvm/test/Transforms/InstCombine/fcmp-select.ll
@@ -116,9 +116,7 @@ define double @one_swapped(double %x) {
 
 define i1 @fcmp_oeq_select(i1 %cond, float %a, float %b) {
 ; CHECK-LABEL: @fcmp_oeq_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 oeq float [[LHS]], [[RHS]]
+; CHECK-NEXT:    [[RES:%.*]] = fcmp oeq float [[A:%.*]], [[B:%.*]]
 ; CHECK-NEXT:    ret i1 [[RES]]
 ;
   %lhs = select i1 %cond, float %a, float %b
@@ -129,9 +127,7 @@ define i1 @fcmp_oeq_select(i1 %cond, float %a, float %b) {
 
 define i1 @fcmp_uno_select(i1 %cond, float %a, float %b) {
 ; CHECK-LABEL: @fcmp_uno_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 uno float [[LHS]], [[RHS]]
+; CHECK-NEXT:    [[RES:%.*]] = fcmp uno float [[A:%.*]], [[B:%.*]]
 ; CHECK-NEXT:    ret i1 [[RES]]
 ;
   %lhs = select i1 %cond, float %a, float %b
diff --git a/llvm/test/Transforms/InstCombine/icmp-select.ll b/llvm/test/Transforms/InstCombine/icmp-select.ll
index dfdd498fd8c7e..59d2a1b165c0f 100644
--- a/llvm/test/Transforms/InstCombine/icmp-select.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-select.ll
@@ -607,9 +607,7 @@ define i1 @select_constants_and_icmp_ne_fval(i1 %x, i1 %y) {
 
 define i1 @icmp_eq_select(i1 %cond, i32 %a, i32 %b) {
 ; CHECK-LABEL: @icmp_eq_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 eq i32 [[LHS]], [[RHS]]
+; CHECK-NEXT:    [[RES:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
 ; CHECK-NEXT:    ret i1 [[RES]]
 ;
   %lhs = select i1 %cond, i32 %a, i32 %b



More information about the llvm-commits mailing list