[clang-tools-extra] [InstSimplify] Simplify `icmp X & C1, X & C2` when `(C1 & C2) == C1/C2` (PR #65905)

Yingwei Zheng via cfe-commits cfe-commits at lists.llvm.org
Sun Sep 17 10:18:46 PDT 2023


https://github.com/dtcxzyw updated https://github.com/llvm/llvm-project/pull/65905

>From f178af6d47ce6d982c6568ba6e0db517de124291 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Mon, 11 Sep 2023 02:01:12 +0800
Subject: [PATCH 1/2] [InstSimplify] Simplify `icmp X & C1, X & C2` when `(C1 &
 C2) == C1/C2`

---
 llvm/lib/Analysis/InstructionSimplify.cpp     |  28 ++-
 llvm/test/Transforms/InstSimplify/compare.ll  | 194 ++++++++++++++++++
 .../InstSimplify/maxmin_intrinsics.ll         |  97 +++++++++
 3 files changed, 318 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index d0cc56ebc2be319..734029f1ad0bef5 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -3427,7 +3427,7 @@ static Value *simplifyICmpWithBinOp(CmpInst::Predicate Pred, Value *LHS,
     switch (LBO->getOpcode()) {
     default:
       break;
-    case Instruction::Shl:
+    case Instruction::Shl: {
       bool NUW = Q.IIQ.hasNoUnsignedWrap(LBO) && Q.IIQ.hasNoUnsignedWrap(RBO);
       bool NSW = Q.IIQ.hasNoSignedWrap(LBO) && Q.IIQ.hasNoSignedWrap(RBO);
       if (!NUW || (ICmpInst::isSigned(Pred) && !NSW) ||
@@ -3436,6 +3436,32 @@ static Value *simplifyICmpWithBinOp(CmpInst::Predicate Pred, Value *LHS,
       if (Value *V = simplifyICmpInst(Pred, LBO->getOperand(1),
                                       RBO->getOperand(1), Q, MaxRecurse - 1))
         return V;
+      break;
+    }
+    // icmp X & C1, X & C2 where (C1 & C2) == C1/C2
+    // icmp X | C1, X | C2 where (C1 & C2) == C1/C2
+    case Instruction::And:
+    case Instruction::Or: {
+      if (ICmpInst::isUnsigned(Pred)) {
+        const APInt *C1, *C2;
+        if (match(LBO->getOperand(1), m_APInt(C1)) &&
+            match(RBO->getOperand(1), m_APInt(C2))) {
+          if (C1->isSubsetOf(*C2)) {
+            if (Pred == ICmpInst::ICMP_ULE)
+              return ConstantInt::getTrue(getCompareTy(LHS));
+            if (Pred == ICmpInst::ICMP_UGT)
+              return ConstantInt::getFalse(getCompareTy(LHS));
+          }
+          if (C2->isSubsetOf(*C1)) {
+            if (Pred == ICmpInst::ICMP_UGE)
+              return ConstantInt::getTrue(getCompareTy(LHS));
+            if (Pred == ICmpInst::ICMP_ULT)
+              return ConstantInt::getFalse(getCompareTy(LHS));
+          }
+        }
+      }
+      break;
+    }
     }
   }
 
diff --git a/llvm/test/Transforms/InstSimplify/compare.ll b/llvm/test/Transforms/InstSimplify/compare.ll
index c6c104a41c8be70..d21af97494c88bc 100644
--- a/llvm/test/Transforms/InstSimplify/compare.ll
+++ b/llvm/test/Transforms/InstSimplify/compare.ll
@@ -1919,6 +1919,200 @@ define i1 @tautological8(i32 %A, i32 %B) {
   ret i1 %D
 }
 
+define i1 @tautological9(i32 %A) {
+; CHECK-LABEL: @tautological9(
+; CHECK-NEXT:    ret i1 false
+;
+  %C1 = and i32 %A, 1
+  %C2 = and i32 %A, 3
+  %D = icmp ugt i32 %C1, %C2
+  ret i1 %D
+}
+
+define <2 x i1> @tautological9_vec(<2 x i32> %A) {
+; CHECK-LABEL: @tautological9_vec(
+; CHECK-NEXT:    ret <2 x i1> zeroinitializer
+;
+  %C1 = and <2 x i32> %A, <i32 1, i32 1>
+  %C2 = and <2 x i32> %A, <i32 3, i32 3>
+  %D = icmp ugt <2 x i32> %C1, %C2
+  ret <2 x i1> %D
+}
+
+define i1 @tautological10(i32 %A) {
+; CHECK-LABEL: @tautological10(
+; CHECK-NEXT:    ret i1 true
+;
+  %C1 = and i32 %A, 1
+  %C2 = and i32 %A, 3
+  %D = icmp ule i32 %C1, %C2
+  ret i1 %D
+}
+
+define i1 @tautological11(i32 %A) {
+; CHECK-LABEL: @tautological11(
+; CHECK-NEXT:    ret i1 true
+;
+  %C1 = or i32 %A, 1
+  %C2 = or i32 %A, 3
+  %D = icmp ule i32 %C1, %C2
+  ret i1 %D
+}
+
+define i1 @tautological12(i32 %A) {
+; CHECK-LABEL: @tautological12(
+; CHECK-NEXT:    ret i1 false
+;
+  %C1 = or i32 %A, 1
+  %C2 = or i32 %A, 3
+  %D = icmp ugt i32 %C1, %C2
+  ret i1 %D
+}
+
+define i1 @tautological13(i32 %A) {
+; CHECK-LABEL: @tautological13(
+; CHECK-NEXT:    ret i1 false
+;
+  %C1 = or i32 %A, 1
+  %C2 = or i32 %A, 3
+  %D = icmp ult i32 %C2, %C1
+  ret i1 %D
+}
+
+define i1 @tautological14(i32 %A) {
+; CHECK-LABEL: @tautological14(
+; CHECK-NEXT:    ret i1 true
+;
+  %C1 = or i32 %A, 1
+  %C2 = or i32 %A, 3
+  %D = icmp uge i32 %C2, %C1
+  ret i1 %D
+}
+
+define i1 @tautological15(i32 %A) {
+; CHECK-LABEL: @tautological15(
+; CHECK-NEXT:    ret i1 true
+;
+  %C1 = and i32 %A, 1
+  %C2 = and i32 %A, 3
+  %D = icmp uge i32 %C2, %C1
+  ret i1 %D
+}
+
+define i1 @tautological16(i32 %A) {
+; CHECK-LABEL: @tautological16(
+; CHECK-NEXT:    ret i1 false
+;
+  %C1 = and i32 %A, 1
+  %C2 = and i32 %A, 3
+  %D = icmp ult i32 %C2, %C1
+  ret i1 %D
+}
+
+define i1 @tautological9_negative(i32 %A) {
+; CHECK-LABEL: @tautological9_negative(
+; CHECK-NEXT:    [[C1:%.*]] = and i32 [[A:%.*]], 1
+; CHECK-NEXT:    [[C2:%.*]] = and i32 [[A]], 2
+; CHECK-NEXT:    [[D:%.*]] = icmp ugt i32 [[C1]], [[C2]]
+; CHECK-NEXT:    ret i1 [[D]]
+;
+  %C1 = and i32 %A, 1
+  %C2 = and i32 %A, 2
+  %D = icmp ugt i32 %C1, %C2
+  ret i1 %D
+}
+
+define i1 @tautological10_negative(i32 %A) {
+; CHECK-LABEL: @tautological10_negative(
+; CHECK-NEXT:    [[C1:%.*]] = and i32 [[A:%.*]], 1
+; CHECK-NEXT:    [[C2:%.*]] = and i32 [[A]], 2
+; CHECK-NEXT:    [[D:%.*]] = icmp ule i32 [[C1]], [[C2]]
+; CHECK-NEXT:    ret i1 [[D]]
+;
+  %C1 = and i32 %A, 1
+  %C2 = and i32 %A, 2
+  %D = icmp ule i32 %C1, %C2
+  ret i1 %D
+}
+
+define i1 @tautological11_negative(i32 %A) {
+; CHECK-LABEL: @tautological11_negative(
+; CHECK-NEXT:    [[C1:%.*]] = or i32 [[A:%.*]], 1
+; CHECK-NEXT:    [[C2:%.*]] = or i32 [[A]], 2
+; CHECK-NEXT:    [[D:%.*]] = icmp ule i32 [[C1]], [[C2]]
+; CHECK-NEXT:    ret i1 [[D]]
+;
+  %C1 = or i32 %A, 1
+  %C2 = or i32 %A, 2
+  %D = icmp ule i32 %C1, %C2
+  ret i1 %D
+}
+
+define i1 @tautological12_negative(i32 %A) {
+; CHECK-LABEL: @tautological12_negative(
+; CHECK-NEXT:    [[C1:%.*]] = or i32 [[A:%.*]], 1
+; CHECK-NEXT:    [[C2:%.*]] = or i32 [[A]], 2
+; CHECK-NEXT:    [[D:%.*]] = icmp ugt i32 [[C1]], [[C2]]
+; CHECK-NEXT:    ret i1 [[D]]
+;
+  %C1 = or i32 %A, 1
+  %C2 = or i32 %A, 2
+  %D = icmp ugt i32 %C1, %C2
+  ret i1 %D
+}
+
+define i1 @tautological13_negative(i32 %A) {
+; CHECK-LABEL: @tautological13_negative(
+; CHECK-NEXT:    [[C1:%.*]] = or i32 [[A:%.*]], 1
+; CHECK-NEXT:    [[C2:%.*]] = or i32 [[A]], 2
+; CHECK-NEXT:    [[D:%.*]] = icmp ult i32 [[C2]], [[C1]]
+; CHECK-NEXT:    ret i1 [[D]]
+;
+  %C1 = or i32 %A, 1
+  %C2 = or i32 %A, 2
+  %D = icmp ult i32 %C2, %C1
+  ret i1 %D
+}
+
+define i1 @tautological14_negative(i32 %A) {
+; CHECK-LABEL: @tautological14_negative(
+; CHECK-NEXT:    [[C1:%.*]] = or i32 [[A:%.*]], 1
+; CHECK-NEXT:    [[C2:%.*]] = or i32 [[A]], 2
+; CHECK-NEXT:    [[D:%.*]] = icmp uge i32 [[C2]], [[C1]]
+; CHECK-NEXT:    ret i1 [[D]]
+;
+  %C1 = or i32 %A, 1
+  %C2 = or i32 %A, 2
+  %D = icmp uge i32 %C2, %C1
+  ret i1 %D
+}
+
+define i1 @tautological15_negative(i32 %A) {
+; CHECK-LABEL: @tautological15_negative(
+; CHECK-NEXT:    [[C1:%.*]] = and i32 [[A:%.*]], 1
+; CHECK-NEXT:    [[C2:%.*]] = and i32 [[A]], 2
+; CHECK-NEXT:    [[D:%.*]] = icmp uge i32 [[C2]], [[C1]]
+; CHECK-NEXT:    ret i1 [[D]]
+;
+  %C1 = and i32 %A, 1
+  %C2 = and i32 %A, 2
+  %D = icmp uge i32 %C2, %C1
+  ret i1 %D
+}
+
+define i1 @tautological16_negative(i32 %A) {
+; CHECK-LABEL: @tautological16_negative(
+; CHECK-NEXT:    [[C1:%.*]] = and i32 [[A:%.*]], 1
+; CHECK-NEXT:    [[C2:%.*]] = and i32 [[A]], 2
+; CHECK-NEXT:    [[D:%.*]] = icmp ult i32 [[C2]], [[C1]]
+; CHECK-NEXT:    ret i1 [[D]]
+;
+  %C1 = and i32 %A, 1
+  %C2 = and i32 %A, 2
+  %D = icmp ult i32 %C2, %C1
+  ret i1 %D
+}
+
 declare void @helper_i1(i1)
 ; Series of tests for icmp s[lt|ge] (or A, B), A and icmp s[gt|le] A, (or A, B)
 define void @icmp_slt_sge_or(i32 %Ax, i32 %Bx) {
diff --git a/llvm/test/Transforms/InstSimplify/maxmin_intrinsics.ll b/llvm/test/Transforms/InstSimplify/maxmin_intrinsics.ll
index e7123b208084927..8828378b5315df0 100644
--- a/llvm/test/Transforms/InstSimplify/maxmin_intrinsics.ll
+++ b/llvm/test/Transforms/InstSimplify/maxmin_intrinsics.ll
@@ -2332,3 +2332,100 @@ false:
   %m2 = call i8 @llvm.smin.i8(i8 %x, i8 %y)
   ret i8 %m2
 }
+
+; Tests from PR65833
+define i8 @umin_and_mask(i8 %x) {
+; CHECK-LABEL: @umin_and_mask(
+; CHECK-NEXT:    [[AND1:%.*]] = and i8 [[X:%.*]], 1
+; CHECK-NEXT:    ret i8 [[AND1]]
+;
+  %and1 = and i8 %x, 1
+  %and2 = and i8 %x, 3
+  %val = call i8 @llvm.umin.i8(i8 %and1, i8 %and2)
+  ret i8 %val
+}
+
+define i8 @umax_and_mask(i8 %x) {
+; CHECK-LABEL: @umax_and_mask(
+; CHECK-NEXT:    [[AND2:%.*]] = and i8 [[X:%.*]], 3
+; CHECK-NEXT:    ret i8 [[AND2]]
+;
+  %and1 = and i8 %x, 1
+  %and2 = and i8 %x, 3
+  %val = call i8 @llvm.umax.i8(i8 %and1, i8 %and2)
+  ret i8 %val
+}
+
+define i8 @umin_or_mask(i8 %x) {
+; CHECK-LABEL: @umin_or_mask(
+; CHECK-NEXT:    [[AND1:%.*]] = or i8 [[X:%.*]], 1
+; CHECK-NEXT:    ret i8 [[AND1]]
+;
+  %and1 = or i8 %x, 1
+  %and2 = or i8 %x, 3
+  %val = call i8 @llvm.umin.i8(i8 %and1, i8 %and2)
+  ret i8 %val
+}
+
+define i8 @umax_or_mask(i8 %x) {
+; CHECK-LABEL: @umax_or_mask(
+; CHECK-NEXT:    [[AND2:%.*]] = or i8 [[X:%.*]], 3
+; CHECK-NEXT:    ret i8 [[AND2]]
+;
+  %and1 = or i8 %x, 1
+  %and2 = or i8 %x, 3
+  %val = call i8 @llvm.umax.i8(i8 %and1, i8 %and2)
+  ret i8 %val
+}
+
+define i8 @umin_and_mask_negative(i8 %x) {
+; CHECK-LABEL: @umin_and_mask_negative(
+; CHECK-NEXT:    [[AND1:%.*]] = and i8 [[X:%.*]], 1
+; CHECK-NEXT:    [[AND2:%.*]] = and i8 [[X]], 2
+; CHECK-NEXT:    [[VAL:%.*]] = call i8 @llvm.umin.i8(i8 [[AND1]], i8 [[AND2]])
+; CHECK-NEXT:    ret i8 [[VAL]]
+;
+  %and1 = and i8 %x, 1
+  %and2 = and i8 %x, 2
+  %val = call i8 @llvm.umin.i8(i8 %and1, i8 %and2)
+  ret i8 %val
+}
+
+define i8 @umax_and_mask_negative(i8 %x) {
+; CHECK-LABEL: @umax_and_mask_negative(
+; CHECK-NEXT:    [[AND1:%.*]] = and i8 [[X:%.*]], 1
+; CHECK-NEXT:    [[AND2:%.*]] = and i8 [[X]], 2
+; CHECK-NEXT:    [[VAL:%.*]] = call i8 @llvm.umax.i8(i8 [[AND1]], i8 [[AND2]])
+; CHECK-NEXT:    ret i8 [[VAL]]
+;
+  %and1 = and i8 %x, 1
+  %and2 = and i8 %x, 2
+  %val = call i8 @llvm.umax.i8(i8 %and1, i8 %and2)
+  ret i8 %val
+}
+
+define i8 @umin_or_mask_negative(i8 %x) {
+; CHECK-LABEL: @umin_or_mask_negative(
+; CHECK-NEXT:    [[AND1:%.*]] = or i8 [[X:%.*]], 1
+; CHECK-NEXT:    [[AND2:%.*]] = or i8 [[X]], 2
+; CHECK-NEXT:    [[VAL:%.*]] = call i8 @llvm.umin.i8(i8 [[AND1]], i8 [[AND2]])
+; CHECK-NEXT:    ret i8 [[VAL]]
+;
+  %and1 = or i8 %x, 1
+  %and2 = or i8 %x, 2
+  %val = call i8 @llvm.umin.i8(i8 %and1, i8 %and2)
+  ret i8 %val
+}
+
+define i8 @umax_or_mask_negative(i8 %x) {
+; CHECK-LABEL: @umax_or_mask_negative(
+; CHECK-NEXT:    [[AND1:%.*]] = or i8 [[X:%.*]], 1
+; CHECK-NEXT:    [[AND2:%.*]] = or i8 [[X]], 2
+; CHECK-NEXT:    [[VAL:%.*]] = call i8 @llvm.umax.i8(i8 [[AND1]], i8 [[AND2]])
+; CHECK-NEXT:    ret i8 [[VAL]]
+;
+  %and1 = or i8 %x, 1
+  %and2 = or i8 %x, 2
+  %val = call i8 @llvm.umax.i8(i8 %and1, i8 %and2)
+  ret i8 %val
+}

>From a2b454f8b914b84d8f8f9dda194e1c8335a997fb Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Mon, 18 Sep 2023 01:17:48 +0800
Subject: [PATCH 2/2] fixup! [InstSimplify] Simplify `icmp X & C1, X & C2` when
 `(C1 & C2) == C1/C2`

---
 llvm/lib/Analysis/InstructionSimplify.cpp     | 36 ++++++++++-------
 llvm/test/Transforms/InstSimplify/compare.ll  | 40 ++++---------------
 .../InstSimplify/maxmin_intrinsics.ll         | 40 ++++++-------------
 3 files changed, 41 insertions(+), 75 deletions(-)

diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 1ca1f27b9ab992d..e8f96e9f681f2d5 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -3438,24 +3438,30 @@ static Value *simplifyICmpWithBinOp(CmpInst::Predicate Pred, Value *LHS,
         return V;
       break;
     }
-    // icmp X & C1, X & C2 where (C1 & C2) == C1/C2
-    // icmp X | C1, X | C2 where (C1 & C2) == C1/C2
+    // If C1 & C2 == C1, A = X and/or C1, B = X and/or C2:
+    // icmp ule A, B -> true
+    // icmp ugt A, B -> false
+    // icmp sle A, B -> true (C1 and C2 are the same sign)
+    // icmp sgt A, B -> false (C1 and C2 are the same sign)
     case Instruction::And:
     case Instruction::Or: {
-      if (ICmpInst::isUnsigned(Pred)) {
-        const APInt *C1, *C2;
-        if (match(LBO->getOperand(1), m_APInt(C1)) &&
-            match(RBO->getOperand(1), m_APInt(C2))) {
-          if (C1->isSubsetOf(*C2)) {
-            if (Pred == ICmpInst::ICMP_ULE)
-              return ConstantInt::getTrue(getCompareTy(LHS));
-            if (Pred == ICmpInst::ICMP_UGT)
-              return ConstantInt::getFalse(getCompareTy(LHS));
-          }
-          if (C2->isSubsetOf(*C1)) {
-            if (Pred == ICmpInst::ICMP_UGE)
+      const APInt *C1, *C2;
+      if (ICmpInst::isRelational(Pred) &&
+          match(LBO->getOperand(1), m_APInt(C1)) &&
+          match(RBO->getOperand(1), m_APInt(C2))) {
+        if (!C1->isSubsetOf(*C2)) {
+          std::swap(C1, C2);
+          Pred = ICmpInst::getSwappedPredicate(Pred);
+        }
+        if (C1->isSubsetOf(*C2)) {
+          if (Pred == ICmpInst::ICMP_ULE)
+            return ConstantInt::getTrue(getCompareTy(LHS));
+          if (Pred == ICmpInst::ICMP_UGT)
+            return ConstantInt::getFalse(getCompareTy(LHS));
+          if (C1->isNonNegative() == C2->isNonNegative()) {
+            if (Pred == ICmpInst::ICMP_SLE)
               return ConstantInt::getTrue(getCompareTy(LHS));
-            if (Pred == ICmpInst::ICMP_ULT)
+            if (Pred == ICmpInst::ICMP_SGT)
               return ConstantInt::getFalse(getCompareTy(LHS));
           }
         }
diff --git a/llvm/test/Transforms/InstSimplify/compare.ll b/llvm/test/Transforms/InstSimplify/compare.ll
index a73e223f25b12e0..ac2ebf52ed6296e 100644
--- a/llvm/test/Transforms/InstSimplify/compare.ll
+++ b/llvm/test/Transforms/InstSimplify/compare.ll
@@ -2115,10 +2115,7 @@ define i1 @tautological16_negative(i32 %A) {
 
 define i1 @tautological17_subset1(i32 %A) {
 ; CHECK-LABEL: @tautological17_subset1(
-; CHECK-NEXT:    [[C1:%.*]] = and i32 [[A:%.*]], 1
-; CHECK-NEXT:    [[C2:%.*]] = and i32 [[A]], 3
-; CHECK-NEXT:    [[D:%.*]] = icmp sgt i32 [[C1]], [[C2]]
-; CHECK-NEXT:    ret i1 [[D]]
+; CHECK-NEXT:    ret i1 false
 ;
   %C1 = and i32 %A, 1
   %C2 = and i32 %A, 3
@@ -2128,10 +2125,7 @@ define i1 @tautological17_subset1(i32 %A) {
 
 define i1 @tautological17_subset2(i32 %A) {
 ; CHECK-LABEL: @tautological17_subset2(
-; CHECK-NEXT:    [[C1:%.*]] = and i32 [[A:%.*]], -4
-; CHECK-NEXT:    [[C2:%.*]] = and i32 [[A]], -3
-; CHECK-NEXT:    [[D:%.*]] = icmp sgt i32 [[C1]], [[C2]]
-; CHECK-NEXT:    ret i1 [[D]]
+; CHECK-NEXT:    ret i1 false
 ;
   %C1 = and i32 %A, -4
   %C2 = and i32 %A, -3
@@ -2154,10 +2148,7 @@ define i1 @tautological17_negative(i32 %A) {
 
 define i1 @tautological18_subset1(i32 %A) {
 ; CHECK-LABEL: @tautological18_subset1(
-; CHECK-NEXT:    [[C1:%.*]] = and i32 [[A:%.*]], 1
-; CHECK-NEXT:    [[C2:%.*]] = and i32 [[A]], 3
-; CHECK-NEXT:    [[D:%.*]] = icmp sle i32 [[C1]], [[C2]]
-; CHECK-NEXT:    ret i1 [[D]]
+; CHECK-NEXT:    ret i1 true
 ;
   %C1 = and i32 %A, 1
   %C2 = and i32 %A, 3
@@ -2167,10 +2158,7 @@ define i1 @tautological18_subset1(i32 %A) {
 
 define i1 @tautological18_subset2(i32 %A) {
 ; CHECK-LABEL: @tautological18_subset2(
-; CHECK-NEXT:    [[C1:%.*]] = and i32 [[A:%.*]], -4
-; CHECK-NEXT:    [[C2:%.*]] = and i32 [[A]], -3
-; CHECK-NEXT:    [[D:%.*]] = icmp sle i32 [[C1]], [[C2]]
-; CHECK-NEXT:    ret i1 [[D]]
+; CHECK-NEXT:    ret i1 true
 ;
   %C1 = and i32 %A, -4
   %C2 = and i32 %A, -3
@@ -2193,10 +2181,7 @@ define i1 @tautological18_negative(i32 %A) {
 
 define i1 @tautological19_subset1(i32 %A) {
 ; CHECK-LABEL: @tautological19_subset1(
-; CHECK-NEXT:    [[C1:%.*]] = or i32 [[A:%.*]], 1
-; CHECK-NEXT:    [[C2:%.*]] = or i32 [[A]], 3
-; CHECK-NEXT:    [[D:%.*]] = icmp sgt i32 [[C1]], [[C2]]
-; CHECK-NEXT:    ret i1 [[D]]
+; CHECK-NEXT:    ret i1 false
 ;
   %C1 = or i32 %A, 1
   %C2 = or i32 %A, 3
@@ -2206,10 +2191,7 @@ define i1 @tautological19_subset1(i32 %A) {
 
 define i1 @tautological19_subset2(i32 %A) {
 ; CHECK-LABEL: @tautological19_subset2(
-; CHECK-NEXT:    [[C1:%.*]] = and i32 [[A:%.*]], -4
-; CHECK-NEXT:    [[C2:%.*]] = and i32 [[A]], -3
-; CHECK-NEXT:    [[D:%.*]] = icmp sgt i32 [[C1]], [[C2]]
-; CHECK-NEXT:    ret i1 [[D]]
+; CHECK-NEXT:    ret i1 false
 ;
   %C1 = and i32 %A, -4
   %C2 = and i32 %A, -3
@@ -2232,10 +2214,7 @@ define i1 @tautological19_negative(i32 %A) {
 
 define i1 @tautological20_subset1(i32 %A) {
 ; CHECK-LABEL: @tautological20_subset1(
-; CHECK-NEXT:    [[C1:%.*]] = and i32 [[A:%.*]], 1
-; CHECK-NEXT:    [[C2:%.*]] = and i32 [[A]], 3
-; CHECK-NEXT:    [[D:%.*]] = icmp sle i32 [[C1]], [[C2]]
-; CHECK-NEXT:    ret i1 [[D]]
+; CHECK-NEXT:    ret i1 true
 ;
   %C1 = and i32 %A, 1
   %C2 = and i32 %A, 3
@@ -2245,10 +2224,7 @@ define i1 @tautological20_subset1(i32 %A) {
 
 define i1 @tautological20_subset2(i32 %A) {
 ; CHECK-LABEL: @tautological20_subset2(
-; CHECK-NEXT:    [[C1:%.*]] = and i32 [[A:%.*]], -4
-; CHECK-NEXT:    [[C2:%.*]] = and i32 [[A]], -3
-; CHECK-NEXT:    [[D:%.*]] = icmp sle i32 [[C1]], [[C2]]
-; CHECK-NEXT:    ret i1 [[D]]
+; CHECK-NEXT:    ret i1 true
 ;
   %C1 = and i32 %A, -4
   %C2 = and i32 %A, -3
diff --git a/llvm/test/Transforms/InstSimplify/maxmin_intrinsics.ll b/llvm/test/Transforms/InstSimplify/maxmin_intrinsics.ll
index 097b9076294b219..17f39a23d4f7a41 100644
--- a/llvm/test/Transforms/InstSimplify/maxmin_intrinsics.ll
+++ b/llvm/test/Transforms/InstSimplify/maxmin_intrinsics.ll
@@ -2433,9 +2433,7 @@ define i8 @umax_or_mask_negative(i8 %x) {
 define i8 @smin_and_mask_subset1(i8 %x) {
 ; CHECK-LABEL: @smin_and_mask_subset1(
 ; CHECK-NEXT:    [[AND1:%.*]] = and i8 [[X:%.*]], 1
-; CHECK-NEXT:    [[AND2:%.*]] = and i8 [[X]], 3
-; CHECK-NEXT:    [[VAL:%.*]] = call i8 @llvm.smin.i8(i8 [[AND1]], i8 [[AND2]])
-; CHECK-NEXT:    ret i8 [[VAL]]
+; CHECK-NEXT:    ret i8 [[AND1]]
 ;
   %and1 = and i8 %x, 1
   %and2 = and i8 %x, 3
@@ -2445,10 +2443,8 @@ define i8 @smin_and_mask_subset1(i8 %x) {
 
 define i8 @smax_and_mask_subset1(i8 %x) {
 ; CHECK-LABEL: @smax_and_mask_subset1(
-; CHECK-NEXT:    [[AND1:%.*]] = and i8 [[X:%.*]], 1
-; CHECK-NEXT:    [[AND2:%.*]] = and i8 [[X]], 3
-; CHECK-NEXT:    [[VAL:%.*]] = call i8 @llvm.smax.i8(i8 [[AND1]], i8 [[AND2]])
-; CHECK-NEXT:    ret i8 [[VAL]]
+; CHECK-NEXT:    [[AND2:%.*]] = and i8 [[X:%.*]], 3
+; CHECK-NEXT:    ret i8 [[AND2]]
 ;
   %and1 = and i8 %x, 1
   %and2 = and i8 %x, 3
@@ -2459,9 +2455,7 @@ define i8 @smax_and_mask_subset1(i8 %x) {
 define i8 @smin_or_mask_subset1(i8 %x) {
 ; CHECK-LABEL: @smin_or_mask_subset1(
 ; CHECK-NEXT:    [[AND1:%.*]] = or i8 [[X:%.*]], 1
-; CHECK-NEXT:    [[AND2:%.*]] = or i8 [[X]], 3
-; CHECK-NEXT:    [[VAL:%.*]] = call i8 @llvm.smin.i8(i8 [[AND1]], i8 [[AND2]])
-; CHECK-NEXT:    ret i8 [[VAL]]
+; CHECK-NEXT:    ret i8 [[AND1]]
 ;
   %and1 = or i8 %x, 1
   %and2 = or i8 %x, 3
@@ -2471,10 +2465,8 @@ define i8 @smin_or_mask_subset1(i8 %x) {
 
 define i8 @smax_or_mask_subset1(i8 %x) {
 ; CHECK-LABEL: @smax_or_mask_subset1(
-; CHECK-NEXT:    [[AND1:%.*]] = or i8 [[X:%.*]], 1
-; CHECK-NEXT:    [[AND2:%.*]] = or i8 [[X]], 3
-; CHECK-NEXT:    [[VAL:%.*]] = call i8 @llvm.smax.i8(i8 [[AND1]], i8 [[AND2]])
-; CHECK-NEXT:    ret i8 [[VAL]]
+; CHECK-NEXT:    [[AND2:%.*]] = or i8 [[X:%.*]], 3
+; CHECK-NEXT:    ret i8 [[AND2]]
 ;
   %and1 = or i8 %x, 1
   %and2 = or i8 %x, 3
@@ -2485,9 +2477,7 @@ define i8 @smax_or_mask_subset1(i8 %x) {
 define i8 @smin_and_mask_subset2(i8 %x) {
 ; CHECK-LABEL: @smin_and_mask_subset2(
 ; CHECK-NEXT:    [[AND1:%.*]] = and i8 [[X:%.*]], -4
-; CHECK-NEXT:    [[AND2:%.*]] = and i8 [[X]], -3
-; CHECK-NEXT:    [[VAL:%.*]] = call i8 @llvm.smin.i8(i8 [[AND1]], i8 [[AND2]])
-; CHECK-NEXT:    ret i8 [[VAL]]
+; CHECK-NEXT:    ret i8 [[AND1]]
 ;
   %and1 = and i8 %x, -4
   %and2 = and i8 %x, -3
@@ -2497,10 +2487,8 @@ define i8 @smin_and_mask_subset2(i8 %x) {
 
 define i8 @smax_and_mask_subset2(i8 %x) {
 ; CHECK-LABEL: @smax_and_mask_subset2(
-; CHECK-NEXT:    [[AND1:%.*]] = and i8 [[X:%.*]], -4
-; CHECK-NEXT:    [[AND2:%.*]] = and i8 [[X]], -3
-; CHECK-NEXT:    [[VAL:%.*]] = call i8 @llvm.smax.i8(i8 [[AND1]], i8 [[AND2]])
-; CHECK-NEXT:    ret i8 [[VAL]]
+; CHECK-NEXT:    [[AND2:%.*]] = and i8 [[X:%.*]], -3
+; CHECK-NEXT:    ret i8 [[AND2]]
 ;
   %and1 = and i8 %x, -4
   %and2 = and i8 %x, -3
@@ -2511,9 +2499,7 @@ define i8 @smax_and_mask_subset2(i8 %x) {
 define i8 @smin_or_mask_subset2(i8 %x) {
 ; CHECK-LABEL: @smin_or_mask_subset2(
 ; CHECK-NEXT:    [[AND1:%.*]] = or i8 [[X:%.*]], -4
-; CHECK-NEXT:    [[AND2:%.*]] = or i8 [[X]], -3
-; CHECK-NEXT:    [[VAL:%.*]] = call i8 @llvm.smin.i8(i8 [[AND1]], i8 [[AND2]])
-; CHECK-NEXT:    ret i8 [[VAL]]
+; CHECK-NEXT:    ret i8 [[AND1]]
 ;
   %and1 = or i8 %x, -4
   %and2 = or i8 %x, -3
@@ -2523,10 +2509,8 @@ define i8 @smin_or_mask_subset2(i8 %x) {
 
 define i8 @smax_or_mask_subset2(i8 %x) {
 ; CHECK-LABEL: @smax_or_mask_subset2(
-; CHECK-NEXT:    [[AND1:%.*]] = or i8 [[X:%.*]], -4
-; CHECK-NEXT:    [[AND2:%.*]] = or i8 [[X]], -3
-; CHECK-NEXT:    [[VAL:%.*]] = call i8 @llvm.smax.i8(i8 [[AND1]], i8 [[AND2]])
-; CHECK-NEXT:    ret i8 [[VAL]]
+; CHECK-NEXT:    [[AND2:%.*]] = or i8 [[X:%.*]], -3
+; CHECK-NEXT:    ret i8 [[AND2]]
 ;
   %and1 = or i8 %x, -4
   %and2 = or i8 %x, -3



More information about the cfe-commits mailing list