[llvm] 13441eb - [InstCombine] Add folds for `(icmp spred (ssub.sat X, Y), 0)` -> `X spred Y`

Noah Goldstein via llvm-commits llvm-commits at lists.llvm.org
Wed May 3 09:12:15 PDT 2023


Author: Noah Goldstein
Date: 2023-05-03T11:11:49-05:00
New Revision: 13441eb0f88f1dc7d95fa9eb2f77889ec9ad90e8

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

LOG: [InstCombine] Add folds for `(icmp spred (ssub.sat X, Y), 0)` -> `X spred Y`

Alive2 links:
    eq: https://alive2.llvm.org/ce/z/Fv3mvc
    ne: https://alive2.llvm.org/ce/z/AEuEXU
    sle: https://alive2.llvm.org/ce/z/mfKGUS
    sge: https://alive2.llvm.org/ce/z/tX3_M4
    sgt: https://alive2.llvm.org/ce/z/x7VgnZ
    slt: https://alive2.llvm.org/ce/z/rQN4TM

Reviewed By: nikic

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

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
    llvm/test/Transforms/InstCombine/cmp-intrinsic.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index d7c4927e4546f..1815fc858c679 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -3395,6 +3395,11 @@ Instruction *InstCombinerImpl::foldICmpEqIntrinsicWithConstant(
     break;
   }
 
+  case Intrinsic::ssub_sat:
+    // ssub.sat(a, b) == 0 -> a == b
+    if (C.isZero())
+      return new ICmpInst(Pred, II->getArgOperand(0), II->getArgOperand(1));
+    break;
   case Intrinsic::usub_sat: {
     // usub.sat(a, b) == 0  ->  a <= b
     if (C.isZero()) {
@@ -3593,6 +3598,21 @@ Instruction *InstCombinerImpl::foldICmpIntrinsicWithConstant(ICmpInst &Cmp,
     }
     break;
   }
+  case Intrinsic::ssub_sat:
+    // ssub.sat(a, b) spred 0 -> a spred b
+    if (ICmpInst::isSigned(Pred)) {
+      if (C.isZero())
+        return new ICmpInst(Pred, II->getArgOperand(0), II->getArgOperand(1));
+      // X s<= 0 is cannonicalized to X s< 1
+      if (Pred == ICmpInst::ICMP_SLT && C.isOne())
+        return new ICmpInst(ICmpInst::ICMP_SLE, II->getArgOperand(0),
+                            II->getArgOperand(1));
+      // X s>= 0 is cannonicalized to X s> -1
+      if (Pred == ICmpInst::ICMP_SGT && C.isAllOnes())
+        return new ICmpInst(ICmpInst::ICMP_SGE, II->getArgOperand(0),
+                            II->getArgOperand(1));
+    }
+    break;
   default:
     break;
   }

diff  --git a/llvm/test/Transforms/InstCombine/cmp-intrinsic.ll b/llvm/test/Transforms/InstCombine/cmp-intrinsic.ll
index 625cf9a0211be..5955650167c21 100644
--- a/llvm/test/Transforms/InstCombine/cmp-intrinsic.ll
+++ b/llvm/test/Transforms/InstCombine/cmp-intrinsic.ll
@@ -885,8 +885,7 @@ define i1 @uadd_sat_ne_zero_fail_multiuse(i8 %x, i8 %y) {
 
 define i1 @ssub_sat_ne_zero(i8 %x, i8 %y) {
 ; CHECK-LABEL: @ssub_sat_ne_zero(
-; CHECK-NEXT:    [[M:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT:    [[R:%.*]] = icmp ne i8 [[M]], 0
+; CHECK-NEXT:    [[R:%.*]] = icmp ne i8 [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret i1 [[R]]
 ;
   %m = call i8 @llvm.ssub.sat.i8(i8 %x, i8 %y)
@@ -907,8 +906,7 @@ define i1 @ssub_sat_ne_fail_nonzero(i8 %x, i8 %y) {
 
 define i1 @ssub_sat_eq_zero(i8 %x, i8 %y) {
 ; CHECK-LABEL: @ssub_sat_eq_zero(
-; CHECK-NEXT:    [[M:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[M]], 0
+; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret i1 [[R]]
 ;
   %m = call i8 @llvm.ssub.sat.i8(i8 %x, i8 %y)
@@ -918,8 +916,7 @@ define i1 @ssub_sat_eq_zero(i8 %x, i8 %y) {
 
 define i1 @ssub_sat_sle_zero(i8 %x, i8 %y) {
 ; CHECK-LABEL: @ssub_sat_sle_zero(
-; CHECK-NEXT:    [[M:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT:    [[R:%.*]] = icmp slt i8 [[M]], 1
+; CHECK-NEXT:    [[R:%.*]] = icmp sle i8 [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret i1 [[R]]
 ;
   %m = call i8 @llvm.ssub.sat.i8(i8 %x, i8 %y)
@@ -929,8 +926,7 @@ define i1 @ssub_sat_sle_zero(i8 %x, i8 %y) {
 
 define i1 @ssub_sat_sge_zero(i8 %x, i8 %y) {
 ; CHECK-LABEL: @ssub_sat_sge_zero(
-; CHECK-NEXT:    [[M:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT:    [[R:%.*]] = icmp sgt i8 [[M]], -1
+; CHECK-NEXT:    [[R:%.*]] = icmp sge i8 [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret i1 [[R]]
 ;
   %m = call i8 @llvm.ssub.sat.i8(i8 %x, i8 %y)
@@ -940,8 +936,7 @@ define i1 @ssub_sat_sge_zero(i8 %x, i8 %y) {
 
 define i1 @ssub_sat_slt_zero(i8 %x, i8 %y) {
 ; CHECK-LABEL: @ssub_sat_slt_zero(
-; CHECK-NEXT:    [[M:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT:    [[R:%.*]] = icmp slt i8 [[M]], 0
+; CHECK-NEXT:    [[R:%.*]] = icmp slt i8 [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret i1 [[R]]
 ;
   %m = call i8 @llvm.ssub.sat.i8(i8 %x, i8 %y)
@@ -962,8 +957,7 @@ define i1 @ssub_sat_slt_neg1_fail(i8 %x, i8 %y) {
 
 define i1 @ssub_sat_sgt_zero(i8 %x, i8 %y) {
 ; CHECK-LABEL: @ssub_sat_sgt_zero(
-; CHECK-NEXT:    [[M:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT:    [[R:%.*]] = icmp sgt i8 [[M]], 0
+; CHECK-NEXT:    [[R:%.*]] = icmp sgt i8 [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret i1 [[R]]
 ;
   %m = call i8 @llvm.ssub.sat.i8(i8 %x, i8 %y)


        


More information about the llvm-commits mailing list