[llvm] 62da6ec - [InstCombine] substitute equivalent constant to reduce logic-of-icmps

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 23 07:19:26 PDT 2020


Author: Sanjay Patel
Date: 2020-04-23T10:19:16-04:00
New Revision: 62da6ecea298739ad59c0563ce6d9493804ef1f0

URL: https://github.com/llvm/llvm-project/commit/62da6ecea298739ad59c0563ce6d9493804ef1f0
DIFF: https://github.com/llvm/llvm-project/commit/62da6ecea298739ad59c0563ce6d9493804ef1f0.diff

LOG: [InstCombine] substitute equivalent constant to reduce logic-of-icmps

(X == C) && (Y Pred1 X) --> (X == C) && (Y Pred1 C)
(X != C) || (Y Pred1 X) --> (X != C) || (Y Pred1 C)

This cooperates/overlaps with D78430, but it is a more general transform
that gets us most of the expected simplifications and several other
improvements.
http://volta.cs.utah.edu:8080/z/5gxjjc

PR45618:
https://bugs.llvm.org/show_bug.cgi?id=45618

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

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
    llvm/test/Transforms/InstCombine/and-or-icmp-min-max.ll
    llvm/test/Transforms/InstCombine/and-or-icmp-nullptr.ll
    llvm/test/Transforms/InstCombine/and-or-icmps.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index fd325bb9698d..d0af69f47114 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -1137,6 +1137,51 @@ static Value *foldUnsignedUnderflowCheck(ICmpInst *ZeroICmp,
   return nullptr;
 }
 
+/// Reduce logic-of-compares with equality to a constant by substituting a
+/// common operand with the constant. Callers are expected to call this with
+/// Cmp0/Cmp1 switched to handle logic op commutativity.
+static Value *foldAndOrOfICmpsWithConstEq(ICmpInst *Cmp0, ICmpInst *Cmp1,
+                                          BinaryOperator &Logic,
+                                          InstCombiner::BuilderTy &Builder,
+                                          const SimplifyQuery &Q) {
+  bool IsAnd = Logic.getOpcode() == Instruction::And;
+  assert(IsAnd || Logic.getOpcode() == Instruction::Or && "Wrong logic op");
+
+  // Match an equality compare with a non-poison constant as Cmp0.
+  ICmpInst::Predicate Pred0;
+  Value *X;
+  Constant *C;
+  if (!match(Cmp0, m_ICmp(Pred0, m_Value(X), m_Constant(C))) ||
+      !isGuaranteedNotToBeUndefOrPoison(C))
+    return nullptr;
+  if ((IsAnd && Pred0 != ICmpInst::ICMP_EQ) ||
+      (!IsAnd && Pred0 != ICmpInst::ICMP_NE))
+    return nullptr;
+
+  // The other compare must include a common operand (X). Canonicalize the
+  // common operand as operand 1 (Pred1 is swapped if the common operand was
+  // operand 0).
+  Value *Y;
+  ICmpInst::Predicate Pred1;
+  if (!match(Cmp1, m_c_ICmp(Pred1, m_Value(Y), m_Deferred(X))))
+    return nullptr;
+
+  // Replace variable with constant value equivalence to remove a variable use:
+  // (X == C) && (Y Pred1 X) --> (X == C) && (Y Pred1 C)
+  // (X != C) || (Y Pred1 X) --> (X != C) || (Y Pred1 C)
+  // Can think of the 'or' substitution with the 'and' bool equivalent:
+  // A || B --> A || (!A && B)
+  Value *SubstituteCmp = SimplifyICmpInst(Pred1, Y, C, Q);
+  if (!SubstituteCmp) {
+    // If we need to create a new instruction, require that the old compare can
+    // be removed.
+    if (!Cmp1->hasOneUse())
+      return nullptr;
+    SubstituteCmp = Builder.CreateICmp(Pred1, Y, C);
+  }
+  return Builder.CreateBinOp(Logic.getOpcode(), Cmp0, SubstituteCmp);
+}
+
 /// Fold (icmp)&(icmp) if possible.
 Value *InstCombiner::foldAndOfICmps(ICmpInst *LHS, ICmpInst *RHS,
                                     BinaryOperator &And) {
@@ -1167,6 +1212,11 @@ Value *InstCombiner::foldAndOfICmps(ICmpInst *LHS, ICmpInst *RHS,
   if (Value *V = foldLogOpOfMaskedICmps(LHS, RHS, true, Builder))
     return V;
 
+  if (Value *V = foldAndOrOfICmpsWithConstEq(LHS, RHS, And, Builder, Q))
+    return V;
+  if (Value *V = foldAndOrOfICmpsWithConstEq(RHS, LHS, And, Builder, Q))
+    return V;
+
   // E.g. (icmp sge x, 0) & (icmp slt x, n) --> icmp ult x, n
   if (Value *V = simplifyRangeCheck(LHS, RHS, /*Inverted=*/false))
     return V;
@@ -2295,6 +2345,11 @@ Value *InstCombiner::foldOrOfICmps(ICmpInst *LHS, ICmpInst *RHS,
           Builder.CreateAdd(B, ConstantInt::getSigned(B->getType(), -1)), A);
   }
 
+  if (Value *V = foldAndOrOfICmpsWithConstEq(LHS, RHS, Or, Builder, Q))
+    return V;
+  if (Value *V = foldAndOrOfICmpsWithConstEq(RHS, LHS, Or, Builder, Q))
+    return V;
+
   // E.g. (icmp slt x, 0) | (icmp sgt x, n) --> icmp ugt x, n
   if (Value *V = simplifyRangeCheck(LHS, RHS, /*Inverted=*/true))
     return V;

diff  --git a/llvm/test/Transforms/InstCombine/and-or-icmp-min-max.ll b/llvm/test/Transforms/InstCombine/and-or-icmp-min-max.ll
index 170021ebc1b8..7f07147b14ff 100644
--- a/llvm/test/Transforms/InstCombine/and-or-icmp-min-max.ll
+++ b/llvm/test/Transforms/InstCombine/and-or-icmp-min-max.ll
@@ -15,10 +15,7 @@
 
 define i1 @slt_and_max(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @slt_and_max(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X]], 127
-; CHECK-NEXT:    [[R:%.*]] = and i1 [[CMP]], [[CMPEQ]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 false
 ;
   %cmp = icmp slt i8 %x, %y
   %cmpeq = icmp eq i8 %x, 127
@@ -28,10 +25,7 @@ define i1 @slt_and_max(i8 %x, i8 %y)  {
 
 define <2 x i1> @slt_and_max_commute(<2 x i8> %x, <2 x i8> %y)  {
 ; CHECK-LABEL: @slt_and_max_commute(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i8> [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq <2 x i8> [[X]], <i8 127, i8 127>
-; CHECK-NEXT:    [[R:%.*]] = and <2 x i1> [[CMPEQ]], [[CMP]]
-; CHECK-NEXT:    ret <2 x i1> [[R]]
+; CHECK-NEXT:    ret <2 x i1> zeroinitializer
 ;
   %cmp = icmp slt <2 x i8> %x, %y
   %cmpeq = icmp eq <2 x i8> %x, <i8 127, i8 127>
@@ -41,10 +35,7 @@ define <2 x i1> @slt_and_max_commute(<2 x i8> %x, <2 x i8> %y)  {
 
 define i1 @slt_swap_and_max(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @slt_swap_and_max(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X]], 127
-; CHECK-NEXT:    [[R:%.*]] = and i1 [[CMP]], [[CMPEQ]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 false
 ;
   %cmp = icmp sgt i8 %y, %x
   %cmpeq = icmp eq i8 %x, 127
@@ -54,10 +45,7 @@ define i1 @slt_swap_and_max(i8 %x, i8 %y)  {
 
 define i1 @slt_swap_and_max_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @slt_swap_and_max_commute(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X]], 127
-; CHECK-NEXT:    [[R:%.*]] = and i1 [[CMPEQ]], [[CMP]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 false
 ;
   %cmp = icmp sgt i8 %y, %x
   %cmpeq = icmp eq i8 %x, 127
@@ -67,10 +55,7 @@ define i1 @slt_swap_and_max_commute(i8 %x, i8 %y)  {
 
 define i1 @ult_and_max(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @ult_and_max(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X]], -1
-; CHECK-NEXT:    [[R:%.*]] = and i1 [[CMP]], [[CMPEQ]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 false
 ;
   %cmp = icmp ult i8 %x, %y
   %cmpeq = icmp eq i8 %x, 255
@@ -80,10 +65,7 @@ define i1 @ult_and_max(i8 %x, i8 %y)  {
 
 define i1 @ult_and_max_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @ult_and_max_commute(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X]], -1
-; CHECK-NEXT:    [[R:%.*]] = and i1 [[CMPEQ]], [[CMP]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 false
 ;
   %cmp = icmp ult i8 %x, %y
   %cmpeq = icmp eq i8 %x, 255
@@ -93,10 +75,7 @@ define i1 @ult_and_max_commute(i8 %x, i8 %y)  {
 
 define i1 @ult_swap_and_max(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @ult_swap_and_max(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X]], -1
-; CHECK-NEXT:    [[R:%.*]] = and i1 [[CMP]], [[CMPEQ]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 false
 ;
   %cmp = icmp ugt i8 %y, %x
   %cmpeq = icmp eq i8 %x, 255
@@ -106,10 +85,7 @@ define i1 @ult_swap_and_max(i8 %x, i8 %y)  {
 
 define i1 @ult_swap_and_max_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @ult_swap_and_max_commute(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X]], -1
-; CHECK-NEXT:    [[R:%.*]] = and i1 [[CMPEQ]], [[CMP]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 false
 ;
   %cmp = icmp ugt i8 %y, %x
   %cmpeq = icmp eq i8 %x, 255
@@ -125,10 +101,7 @@ define i1 @ult_swap_and_max_commute(i8 %x, i8 %y)  {
 
 define i1 @sgt_and_min(i9 %x, i9 %y)  {
 ; CHECK-LABEL: @sgt_and_min(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i9 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i9 [[X]], -256
-; CHECK-NEXT:    [[R:%.*]] = and i1 [[CMP]], [[CMPEQ]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 false
 ;
   %cmp = icmp sgt i9 %x, %y
   %cmpeq = icmp eq i9 %x, 256
@@ -138,10 +111,7 @@ define i1 @sgt_and_min(i9 %x, i9 %y)  {
 
 define i1 @sgt_and_min_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sgt_and_min_commute(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X]], -128
-; CHECK-NEXT:    [[R:%.*]] = and i1 [[CMPEQ]], [[CMP]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 false
 ;
   %cmp = icmp sgt i8 %x, %y
   %cmpeq = icmp eq i8 %x, 128
@@ -151,10 +121,7 @@ define i1 @sgt_and_min_commute(i8 %x, i8 %y)  {
 
 define i1 @sgt_swap_and_min(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sgt_swap_and_min(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X]], -128
-; CHECK-NEXT:    [[R:%.*]] = and i1 [[CMP]], [[CMPEQ]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 false
 ;
   %cmp = icmp slt i8 %y, %x
   %cmpeq = icmp eq i8 %x, 128
@@ -164,10 +131,7 @@ define i1 @sgt_swap_and_min(i8 %x, i8 %y)  {
 
 define i1 @sgt_swap_and_min_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sgt_swap_and_min_commute(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X]], -128
-; CHECK-NEXT:    [[R:%.*]] = and i1 [[CMPEQ]], [[CMP]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 false
 ;
   %cmp = icmp slt i8 %y, %x
   %cmpeq = icmp eq i8 %x, 128
@@ -223,10 +187,7 @@ define i1 @ugt_swap_and_min_commute(i8 %x, i8 %y)  {
 
 define i1 @sge_or_not_max(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sge_or_not_max(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i8 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X]], 127
-; CHECK-NEXT:    [[R:%.*]] = or i1 [[CMP]], [[CMPEQ]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 true
 ;
   %cmp = icmp sge i8 %x, %y
   %cmpeq = icmp ne i8 %x, 127
@@ -236,10 +197,7 @@ define i1 @sge_or_not_max(i8 %x, i8 %y)  {
 
 define i1 @sge_or_not_max_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sge_or_not_max_commute(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i8 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X]], 127
-; CHECK-NEXT:    [[R:%.*]] = or i1 [[CMPEQ]], [[CMP]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 true
 ;
   %cmp = icmp sge i8 %x, %y
   %cmpeq = icmp ne i8 %x, 127
@@ -249,10 +207,7 @@ define i1 @sge_or_not_max_commute(i8 %x, i8 %y)  {
 
 define i1 @sge_swap_or_not_max(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sge_swap_or_not_max(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i8 [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X]], 127
-; CHECK-NEXT:    [[R:%.*]] = or i1 [[CMP]], [[CMPEQ]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 true
 ;
   %cmp = icmp sle i8 %y, %x
   %cmpeq = icmp ne i8 %x, 127
@@ -262,10 +217,7 @@ define i1 @sge_swap_or_not_max(i8 %x, i8 %y)  {
 
 define i1 @sge_swap_or_not_max_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sge_swap_or_not_max_commute(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i8 [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X]], 127
-; CHECK-NEXT:    [[R:%.*]] = or i1 [[CMPEQ]], [[CMP]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 true
 ;
   %cmp = icmp sle i8 %y, %x
   %cmpeq = icmp ne i8 %x, 127
@@ -275,10 +227,7 @@ define i1 @sge_swap_or_not_max_commute(i8 %x, i8 %y)  {
 
 define i1 @uge_or_not_max(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @uge_or_not_max(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i8 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X]], -1
-; CHECK-NEXT:    [[R:%.*]] = or i1 [[CMP]], [[CMPEQ]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 true
 ;
   %cmp = icmp uge i8 %x, %y
   %cmpeq = icmp ne i8 %x, 255
@@ -288,10 +237,7 @@ define i1 @uge_or_not_max(i8 %x, i8 %y)  {
 
 define i1 @uge_or_not_max_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @uge_or_not_max_commute(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i8 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X]], -1
-; CHECK-NEXT:    [[R:%.*]] = or i1 [[CMPEQ]], [[CMP]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 true
 ;
   %cmp = icmp uge i8 %x, %y
   %cmpeq = icmp ne i8 %x, 255
@@ -301,10 +247,7 @@ define i1 @uge_or_not_max_commute(i8 %x, i8 %y)  {
 
 define i1 @uge_swap_or_not_max(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @uge_swap_or_not_max(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i8 [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X]], -1
-; CHECK-NEXT:    [[R:%.*]] = or i1 [[CMP]], [[CMPEQ]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 true
 ;
   %cmp = icmp ule i8 %y, %x
   %cmpeq = icmp ne i8 %x, 255
@@ -314,10 +257,7 @@ define i1 @uge_swap_or_not_max(i8 %x, i8 %y)  {
 
 define i1 @uge_swap_or_not_max_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @uge_swap_or_not_max_commute(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i8 [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X]], -1
-; CHECK-NEXT:    [[R:%.*]] = or i1 [[CMPEQ]], [[CMP]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 true
 ;
   %cmp = icmp ule i8 %y, %x
   %cmpeq = icmp ne i8 %x, 255
@@ -333,10 +273,7 @@ define i1 @uge_swap_or_not_max_commute(i8 %x, i8 %y)  {
 
 define i1 @sle_or_not_min(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sle_or_not_min(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i8 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X]], -128
-; CHECK-NEXT:    [[R:%.*]] = or i1 [[CMP]], [[CMPEQ]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 true
 ;
   %cmp = icmp sle i8 %x, %y
   %cmpeq = icmp ne i8 %x, 128
@@ -346,10 +283,7 @@ define i1 @sle_or_not_min(i8 %x, i8 %y)  {
 
 define i1 @sle_or_not_min_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sle_or_not_min_commute(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i8 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X]], -128
-; CHECK-NEXT:    [[R:%.*]] = or i1 [[CMPEQ]], [[CMP]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 true
 ;
   %cmp = icmp sle i8 %x, %y
   %cmpeq = icmp ne i8 %x, 128
@@ -359,10 +293,7 @@ define i1 @sle_or_not_min_commute(i8 %x, i8 %y)  {
 
 define i1 @sle_swap_or_not_min(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sle_swap_or_not_min(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i8 [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X]], -128
-; CHECK-NEXT:    [[R:%.*]] = or i1 [[CMP]], [[CMPEQ]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 true
 ;
   %cmp = icmp sge i8 %y, %x
   %cmpeq = icmp ne i8 %x, 128
@@ -372,10 +303,7 @@ define i1 @sle_swap_or_not_min(i8 %x, i8 %y)  {
 
 define i1 @sle_swap_or_not_min_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sle_swap_or_not_min_commute(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i8 [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X]], -128
-; CHECK-NEXT:    [[R:%.*]] = or i1 [[CMPEQ]], [[CMP]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 true
 ;
   %cmp = icmp sge i8 %y, %x
   %cmpeq = icmp ne i8 %x, 128
@@ -431,10 +359,8 @@ define i1 @ule_swap_or_not_min_commute(i8 %x, i8 %y)  {
 
 define i1 @sge_and_max(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sge_and_max(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i8 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X]], 127
-; CHECK-NEXT:    [[R:%.*]] = and i1 [[CMP]], [[CMPEQ]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X:%.*]], 127
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
 ;
   %cmp = icmp sge i8 %x, %y
   %cmpeq = icmp eq i8 %x, 127
@@ -444,10 +370,8 @@ define i1 @sge_and_max(i8 %x, i8 %y)  {
 
 define i1 @sge_and_max_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sge_and_max_commute(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i8 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X]], 127
-; CHECK-NEXT:    [[R:%.*]] = and i1 [[CMPEQ]], [[CMP]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X:%.*]], 127
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
 ;
   %cmp = icmp sge i8 %x, %y
   %cmpeq = icmp eq i8 %x, 127
@@ -457,10 +381,8 @@ define i1 @sge_and_max_commute(i8 %x, i8 %y)  {
 
 define i1 @sge_swap_and_max(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sge_swap_and_max(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i8 [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X]], 127
-; CHECK-NEXT:    [[R:%.*]] = and i1 [[CMP]], [[CMPEQ]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X:%.*]], 127
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
 ;
   %cmp = icmp sle i8 %y, %x
   %cmpeq = icmp eq i8 %x, 127
@@ -470,10 +392,8 @@ define i1 @sge_swap_and_max(i8 %x, i8 %y)  {
 
 define i1 @sge_swap_and_max_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sge_swap_and_max_commute(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i8 [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X]], 127
-; CHECK-NEXT:    [[R:%.*]] = and i1 [[CMPEQ]], [[CMP]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X:%.*]], 127
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
 ;
   %cmp = icmp sle i8 %y, %x
   %cmpeq = icmp eq i8 %x, 127
@@ -483,10 +403,8 @@ define i1 @sge_swap_and_max_commute(i8 %x, i8 %y)  {
 
 define i1 @uge_and_max(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @uge_and_max(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i8 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X]], -1
-; CHECK-NEXT:    [[R:%.*]] = and i1 [[CMP]], [[CMPEQ]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X:%.*]], -1
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
 ;
   %cmp = icmp uge i8 %x, %y
   %cmpeq = icmp eq i8 %x, 255
@@ -496,10 +414,8 @@ define i1 @uge_and_max(i8 %x, i8 %y)  {
 
 define i1 @uge_and_max_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @uge_and_max_commute(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i8 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X]], -1
-; CHECK-NEXT:    [[R:%.*]] = and i1 [[CMPEQ]], [[CMP]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X:%.*]], -1
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
 ;
   %cmp = icmp uge i8 %x, %y
   %cmpeq = icmp eq i8 %x, 255
@@ -509,10 +425,8 @@ define i1 @uge_and_max_commute(i8 %x, i8 %y)  {
 
 define i1 @uge_swap_and_max(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @uge_swap_and_max(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i8 [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X]], -1
-; CHECK-NEXT:    [[R:%.*]] = and i1 [[CMP]], [[CMPEQ]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X:%.*]], -1
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
 ;
   %cmp = icmp ule i8 %y, %x
   %cmpeq = icmp eq i8 %x, 255
@@ -522,10 +436,8 @@ define i1 @uge_swap_and_max(i8 %x, i8 %y)  {
 
 define i1 @uge_swap_and_max_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @uge_swap_and_max_commute(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i8 [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X]], -1
-; CHECK-NEXT:    [[R:%.*]] = and i1 [[CMPEQ]], [[CMP]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X:%.*]], -1
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
 ;
   %cmp = icmp ule i8 %y, %x
   %cmpeq = icmp eq i8 %x, 255
@@ -541,10 +453,8 @@ define i1 @uge_swap_and_max_commute(i8 %x, i8 %y)  {
 
 define i1 @sle_and_min(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sle_and_min(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i8 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X]], -128
-; CHECK-NEXT:    [[R:%.*]] = and i1 [[CMP]], [[CMPEQ]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X:%.*]], -128
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
 ;
   %cmp = icmp sle i8 %x, %y
   %cmpeq = icmp eq i8 %x, 128
@@ -554,10 +464,8 @@ define i1 @sle_and_min(i8 %x, i8 %y)  {
 
 define i1 @sle_and_min_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sle_and_min_commute(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i8 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X]], -128
-; CHECK-NEXT:    [[R:%.*]] = and i1 [[CMPEQ]], [[CMP]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X:%.*]], -128
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
 ;
   %cmp = icmp sle i8 %x, %y
   %cmpeq = icmp eq i8 %x, 128
@@ -567,10 +475,8 @@ define i1 @sle_and_min_commute(i8 %x, i8 %y)  {
 
 define i1 @sle_swap_and_min(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sle_swap_and_min(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i8 [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X]], -128
-; CHECK-NEXT:    [[R:%.*]] = and i1 [[CMP]], [[CMPEQ]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X:%.*]], -128
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
 ;
   %cmp = icmp sge i8 %y, %x
   %cmpeq = icmp eq i8 %x, 128
@@ -580,10 +486,8 @@ define i1 @sle_swap_and_min(i8 %x, i8 %y)  {
 
 define i1 @sle_swap_and_min_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sle_swap_and_min_commute(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i8 [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X]], -128
-; CHECK-NEXT:    [[R:%.*]] = and i1 [[CMPEQ]], [[CMP]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X:%.*]], -128
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
 ;
   %cmp = icmp sge i8 %y, %x
   %cmpeq = icmp eq i8 %x, 128
@@ -1019,10 +923,8 @@ define i1 @ugt_swap_and_not_min_commute(i8 %x, i8 %y)  {
 
 define i1 @slt_or_not_max(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @slt_or_not_max(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X]], 127
-; CHECK-NEXT:    [[R:%.*]] = or i1 [[CMP]], [[CMPEQ]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X:%.*]], 127
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
 ;
   %cmp = icmp slt i8 %x, %y
   %cmpeq = icmp ne i8 %x, 127
@@ -1032,10 +934,8 @@ define i1 @slt_or_not_max(i8 %x, i8 %y)  {
 
 define i1 @slt_or_not_max_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @slt_or_not_max_commute(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X]], 127
-; CHECK-NEXT:    [[R:%.*]] = or i1 [[CMPEQ]], [[CMP]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X:%.*]], 127
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
 ;
   %cmp = icmp slt i8 %x, %y
   %cmpeq = icmp ne i8 %x, 127
@@ -1045,10 +945,8 @@ define i1 @slt_or_not_max_commute(i8 %x, i8 %y)  {
 
 define i1 @slt_swap_or_not_max(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @slt_swap_or_not_max(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X]], 127
-; CHECK-NEXT:    [[R:%.*]] = or i1 [[CMP]], [[CMPEQ]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X:%.*]], 127
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
 ;
   %cmp = icmp sgt i8 %y, %x
   %cmpeq = icmp ne i8 %x, 127
@@ -1058,10 +956,8 @@ define i1 @slt_swap_or_not_max(i8 %x, i8 %y)  {
 
 define i1 @slt_swap_or_not_max_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @slt_swap_or_not_max_commute(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X]], 127
-; CHECK-NEXT:    [[R:%.*]] = or i1 [[CMPEQ]], [[CMP]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X:%.*]], 127
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
 ;
   %cmp = icmp sgt i8 %y, %x
   %cmpeq = icmp ne i8 %x, 127
@@ -1071,10 +967,8 @@ define i1 @slt_swap_or_not_max_commute(i8 %x, i8 %y)  {
 
 define i1 @ult_or_not_max(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @ult_or_not_max(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X]], -1
-; CHECK-NEXT:    [[R:%.*]] = or i1 [[CMP]], [[CMPEQ]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X:%.*]], -1
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
 ;
   %cmp = icmp ult i8 %x, %y
   %cmpeq = icmp ne i8 %x, 255
@@ -1084,10 +978,8 @@ define i1 @ult_or_not_max(i8 %x, i8 %y)  {
 
 define i1 @ult_or_not_max_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @ult_or_not_max_commute(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X]], -1
-; CHECK-NEXT:    [[R:%.*]] = or i1 [[CMPEQ]], [[CMP]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X:%.*]], -1
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
 ;
   %cmp = icmp ult i8 %x, %y
   %cmpeq = icmp ne i8 %x, 255
@@ -1097,10 +989,8 @@ define i1 @ult_or_not_max_commute(i8 %x, i8 %y)  {
 
 define i1 @ult_swap_or_not_max(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @ult_swap_or_not_max(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X]], -1
-; CHECK-NEXT:    [[R:%.*]] = or i1 [[CMP]], [[CMPEQ]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X:%.*]], -1
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
 ;
   %cmp = icmp ugt i8 %y, %x
   %cmpeq = icmp ne i8 %x, 255
@@ -1110,10 +1000,8 @@ define i1 @ult_swap_or_not_max(i8 %x, i8 %y)  {
 
 define i1 @ult_swap_or_not_max_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @ult_swap_or_not_max_commute(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X]], -1
-; CHECK-NEXT:    [[R:%.*]] = or i1 [[CMPEQ]], [[CMP]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X:%.*]], -1
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
 ;
   %cmp = icmp ugt i8 %y, %x
   %cmpeq = icmp ne i8 %x, 255
@@ -1129,10 +1017,8 @@ define i1 @ult_swap_or_not_max_commute(i8 %x, i8 %y)  {
 
 define i1 @sgt_or_not_min(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sgt_or_not_min(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X]], -128
-; CHECK-NEXT:    [[R:%.*]] = or i1 [[CMP]], [[CMPEQ]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X:%.*]], -128
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
 ;
   %cmp = icmp sgt i8 %x, %y
   %cmpeq = icmp ne i8 %x, 128
@@ -1142,10 +1028,8 @@ define i1 @sgt_or_not_min(i8 %x, i8 %y)  {
 
 define i1 @sgt_or_not_min_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sgt_or_not_min_commute(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X]], -128
-; CHECK-NEXT:    [[R:%.*]] = or i1 [[CMPEQ]], [[CMP]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X:%.*]], -128
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
 ;
   %cmp = icmp sgt i8 %x, %y
   %cmpeq = icmp ne i8 %x, 128
@@ -1155,10 +1039,8 @@ define i1 @sgt_or_not_min_commute(i8 %x, i8 %y)  {
 
 define i1 @sgt_swap_or_not_min(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sgt_swap_or_not_min(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X]], -128
-; CHECK-NEXT:    [[R:%.*]] = or i1 [[CMP]], [[CMPEQ]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X:%.*]], -128
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
 ;
   %cmp = icmp slt i8 %y, %x
   %cmpeq = icmp ne i8 %x, 128
@@ -1168,10 +1050,8 @@ define i1 @sgt_swap_or_not_min(i8 %x, i8 %y)  {
 
 define i1 @sgt_swap_or_not_min_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sgt_swap_or_not_min_commute(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X]], -128
-; CHECK-NEXT:    [[R:%.*]] = or i1 [[CMPEQ]], [[CMP]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X:%.*]], -128
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
 ;
   %cmp = icmp slt i8 %y, %x
   %cmpeq = icmp ne i8 %x, 128

diff  --git a/llvm/test/Transforms/InstCombine/and-or-icmp-nullptr.ll b/llvm/test/Transforms/InstCombine/and-or-icmp-nullptr.ll
index 15e79c33b943..be573281eb8c 100644
--- a/llvm/test/Transforms/InstCombine/and-or-icmp-nullptr.ll
+++ b/llvm/test/Transforms/InstCombine/and-or-icmp-nullptr.ll
@@ -304,10 +304,10 @@ define i1 @ugt_swap_or_not_min_commute(i823* %x, i823* %y)  {
 
 define i1 @sgt_and_min(i9* %x, i9* %y)  {
 ; CHECK-LABEL: @sgt_and_min(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i9* [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i9* [[X]], null
-; CHECK-NEXT:    [[R:%.*]] = and i1 [[CMP]], [[CMPEQ]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i9* [[X:%.*]], null
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i9* [[Y:%.*]], null
+; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[CMPEQ]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[TMP2]]
 ;
   %cmp = icmp sgt i9* %x, %y
   %cmpeq = icmp eq i9* %x, null
@@ -317,10 +317,10 @@ define i1 @sgt_and_min(i9* %x, i9* %y)  {
 
 define i1 @sle_or_not_min(i427* %x, i427* %y)  {
 ; CHECK-LABEL: @sle_or_not_min(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i427* [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i427* [[X]], null
-; CHECK-NEXT:    [[R:%.*]] = or i1 [[CMP]], [[CMPEQ]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i427* [[X:%.*]], null
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp sge i427* [[Y:%.*]], null
+; CHECK-NEXT:    [[TMP2:%.*]] = or i1 [[CMPEQ]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[TMP2]]
 ;
   %cmp = icmp sle i427* %x, %y
   %cmpeq = icmp ne i427* %x, null
@@ -330,10 +330,10 @@ define i1 @sle_or_not_min(i427* %x, i427* %y)  {
 
 define i1 @sle_and_min(i8* %x, i8* %y)  {
 ; CHECK-LABEL: @sle_and_min(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i8* [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8* [[X]], null
-; CHECK-NEXT:    [[R:%.*]] = and i1 [[CMP]], [[CMPEQ]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8* [[X:%.*]], null
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp sge i8* [[Y:%.*]], null
+; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[CMPEQ]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[TMP2]]
 ;
   %cmp = icmp sle i8* %x, %y
   %cmpeq = icmp eq i8* %x, null
@@ -356,10 +356,10 @@ define i1 @sgt_and_not_min(i8* %x, i8* %y)  {
 
 define i1 @sgt_or_not_min(i8* %x, i8* %y)  {
 ; CHECK-LABEL: @sgt_or_not_min(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8* [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8* [[X]], null
-; CHECK-NEXT:    [[R:%.*]] = or i1 [[CMP]], [[CMPEQ]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8* [[X:%.*]], null
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i8* [[Y:%.*]], null
+; CHECK-NEXT:    [[TMP2:%.*]] = or i1 [[CMPEQ]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[TMP2]]
 ;
   %cmp = icmp sgt i8* %x, %y
   %cmpeq = icmp ne i8* %x, null
@@ -370,9 +370,9 @@ define i1 @sgt_or_not_min(i8* %x, i8* %y)  {
 define i1 @slt_and_min(i8* %a, i8* %b) {
 ; CHECK-LABEL: @slt_and_min(
 ; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8* [[A:%.*]], null
-; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8* [[A]], [[B:%.*]]
-; CHECK-NEXT:    [[R:%.*]] = and i1 [[CMPEQ]], [[CMP]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i8* [[B:%.*]], null
+; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[CMPEQ]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[TMP2]]
 ;
   %cmpeq = icmp eq i8* %a, null
   %cmp = icmp slt i8* %a, %b

diff  --git a/llvm/test/Transforms/InstCombine/and-or-icmps.ll b/llvm/test/Transforms/InstCombine/and-or-icmps.ll
index 014df8c53b91..cf822751ae34 100644
--- a/llvm/test/Transforms/InstCombine/and-or-icmps.ll
+++ b/llvm/test/Transforms/InstCombine/and-or-icmps.ll
@@ -382,9 +382,9 @@ define i1 @PR42691_10(i32 %x) {
 define i1 @substitute_constant_and_eq_eq(i8 %x, i8 %y) {
 ; CHECK-LABEL: @substitute_constant_and_eq_eq(
 ; CHECK-NEXT:    [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42
-; CHECK-NEXT:    [[C2:%.*]] = icmp eq i8 [[X]], [[Y:%.*]]
-; CHECK-NEXT:    [[R:%.*]] = and i1 [[C1]], [[C2]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8 [[Y:%.*]], 42
+; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[C1]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[TMP2]]
 ;
   %c1 = icmp eq i8 %x, 42
   %c2 = icmp eq i8 %x, %y
@@ -395,9 +395,9 @@ define i1 @substitute_constant_and_eq_eq(i8 %x, i8 %y) {
 define i1 @substitute_constant_and_eq_eq_commute(i8 %x, i8 %y) {
 ; CHECK-LABEL: @substitute_constant_and_eq_eq_commute(
 ; CHECK-NEXT:    [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42
-; CHECK-NEXT:    [[C2:%.*]] = icmp eq i8 [[X]], [[Y:%.*]]
-; CHECK-NEXT:    [[R:%.*]] = and i1 [[C2]], [[C1]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8 [[Y:%.*]], 42
+; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[C1]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[TMP2]]
 ;
   %c1 = icmp eq i8 %x, 42
   %c2 = icmp eq i8 %x, %y
@@ -408,9 +408,9 @@ define i1 @substitute_constant_and_eq_eq_commute(i8 %x, i8 %y) {
 define i1 @substitute_constant_and_eq_ugt_swap(i8 %x, i8 %y) {
 ; CHECK-LABEL: @substitute_constant_and_eq_ugt_swap(
 ; CHECK-NEXT:    [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42
-; CHECK-NEXT:    [[C2:%.*]] = icmp ugt i8 [[Y:%.*]], [[X]]
-; CHECK-NEXT:    [[R:%.*]] = and i1 [[C2]], [[C1]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i8 [[Y:%.*]], 42
+; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[C1]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[TMP2]]
 ;
   %c1 = icmp eq i8 %x, 42
   %c2 = icmp ugt i8 %y, %x
@@ -421,9 +421,9 @@ define i1 @substitute_constant_and_eq_ugt_swap(i8 %x, i8 %y) {
 define <2 x i1> @substitute_constant_and_eq_ne_vec(<2 x i8> %x, <2 x i8> %y) {
 ; CHECK-LABEL: @substitute_constant_and_eq_ne_vec(
 ; CHECK-NEXT:    [[C1:%.*]] = icmp eq <2 x i8> [[X:%.*]], <i8 42, i8 97>
-; CHECK-NEXT:    [[C2:%.*]] = icmp ne <2 x i8> [[X]], [[Y:%.*]]
-; CHECK-NEXT:    [[R:%.*]] = and <2 x i1> [[C1]], [[C2]]
-; CHECK-NEXT:    ret <2 x i1> [[R]]
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne <2 x i8> [[Y:%.*]], <i8 42, i8 97>
+; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i1> [[C1]], [[TMP1]]
+; CHECK-NEXT:    ret <2 x i1> [[TMP2]]
 ;
   %c1 = icmp eq <2 x i8> %x, <i8 42, i8 97>
   %c2 = icmp ne <2 x i8> %x, %y
@@ -435,9 +435,9 @@ define i1 @substitute_constant_and_eq_sgt_use(i8 %x, i8 %y) {
 ; CHECK-LABEL: @substitute_constant_and_eq_sgt_use(
 ; CHECK-NEXT:    [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42
 ; CHECK-NEXT:    call void @use(i1 [[C1]])
-; CHECK-NEXT:    [[C2:%.*]] = icmp sgt i8 [[X]], [[Y:%.*]]
-; CHECK-NEXT:    [[R:%.*]] = and i1 [[C2]], [[C1]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i8 [[Y:%.*]], 42
+; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[C1]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[TMP2]]
 ;
   %c1 = icmp eq i8 %x, 42
   call void @use(i1 %c1)
@@ -446,6 +446,8 @@ define i1 @substitute_constant_and_eq_sgt_use(i8 %x, i8 %y) {
   ret i1 %r
 }
 
+; Negative test - extra use
+
 define i1 @substitute_constant_and_eq_sgt_use2(i8 %x, i8 %y) {
 ; CHECK-LABEL: @substitute_constant_and_eq_sgt_use2(
 ; CHECK-NEXT:    [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42
@@ -461,15 +463,14 @@ define i1 @substitute_constant_and_eq_sgt_use2(i8 %x, i8 %y) {
   ret i1 %r
 }
 
+; Extra use does not prevent transform if the expression simplifies:
 ; X == MAX && X < Y --> false
 
 define i1 @slt_and_max(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @slt_and_max(
-; CHECK-NEXT:    [[C1:%.*]] = icmp eq i8 [[X:%.*]], 127
-; CHECK-NEXT:    [[C2:%.*]] = icmp slt i8 [[X]], [[Y:%.*]]
+; CHECK-NEXT:    [[C2:%.*]] = icmp slt i8 [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    call void @use(i1 [[C2]])
-; CHECK-NEXT:    [[R:%.*]] = and i1 [[C2]], [[C1]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 false
 ;
   %c1 = icmp eq i8 %x, 127
   %c2 = icmp slt i8 %x, %y
@@ -478,6 +479,7 @@ define i1 @slt_and_max(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+; Extra use does not prevent transform if the expression simplifies:
 ; X == MAX && X >= Y --> X == MAX
 
 define i1 @sge_and_max(i8 %x, i8 %y)  {
@@ -485,8 +487,7 @@ define i1 @sge_and_max(i8 %x, i8 %y)  {
 ; CHECK-NEXT:    [[C1:%.*]] = icmp eq i8 [[X:%.*]], 127
 ; CHECK-NEXT:    [[C2:%.*]] = icmp sge i8 [[X]], [[Y:%.*]]
 ; CHECK-NEXT:    call void @use(i1 [[C2]])
-; CHECK-NEXT:    [[R:%.*]] = and i1 [[C2]], [[C1]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 [[C1]]
 ;
   %c1 = icmp eq i8 %x, 127
   %c2 = icmp sge i8 %x, %y
@@ -511,9 +512,9 @@ define i1 @substitute_constant_and_ne_ugt_swap(i8 %x, i8 %y) {
 define i1 @substitute_constant_or_ne_swap_sle(i8 %x, i8 %y) {
 ; CHECK-LABEL: @substitute_constant_or_ne_swap_sle(
 ; CHECK-NEXT:    [[C1:%.*]] = icmp ne i8 [[X:%.*]], 42
-; CHECK-NEXT:    [[C2:%.*]] = icmp sle i8 [[Y:%.*]], [[X]]
-; CHECK-NEXT:    [[R:%.*]] = or i1 [[C1]], [[C2]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i8 [[Y:%.*]], 43
+; CHECK-NEXT:    [[TMP2:%.*]] = or i1 [[C1]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[TMP2]]
 ;
   %c1 = icmp ne i8 %x, 42
   %c2 = icmp sle i8 %y, %x
@@ -524,9 +525,9 @@ define i1 @substitute_constant_or_ne_swap_sle(i8 %x, i8 %y) {
 define i1 @substitute_constant_or_ne_uge_commute(i8 %x, i8 %y) {
 ; CHECK-LABEL: @substitute_constant_or_ne_uge_commute(
 ; CHECK-NEXT:    [[C1:%.*]] = icmp ne i8 [[X:%.*]], 42
-; CHECK-NEXT:    [[C2:%.*]] = icmp uge i8 [[X]], [[Y:%.*]]
-; CHECK-NEXT:    [[R:%.*]] = or i1 [[C2]], [[C1]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i8 [[Y:%.*]], 43
+; CHECK-NEXT:    [[TMP2:%.*]] = or i1 [[C1]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[TMP2]]
 ;
   %c1 = icmp ne i8 %x, 42
   %c2 = icmp uge i8 %x, %y
@@ -534,6 +535,8 @@ define i1 @substitute_constant_or_ne_uge_commute(i8 %x, i8 %y) {
   ret i1 %r
 }
 
+; Negative test - not safe to substitute vector constant with undef element
+
 define <2 x i1> @substitute_constant_or_ne_slt_swap_vec(<2 x i8> %x, <2 x i8> %y) {
 ; CHECK-LABEL: @substitute_constant_or_ne_slt_swap_vec(
 ; CHECK-NEXT:    [[C1:%.*]] = icmp ne <2 x i8> [[X:%.*]], <i8 42, i8 undef>
@@ -564,9 +567,9 @@ define i1 @substitute_constant_or_ne_sge_use(i8 %x, i8 %y) {
 ; CHECK-LABEL: @substitute_constant_or_ne_sge_use(
 ; CHECK-NEXT:    [[C1:%.*]] = icmp ne i8 [[X:%.*]], 42
 ; CHECK-NEXT:    call void @use(i1 [[C1]])
-; CHECK-NEXT:    [[C2:%.*]] = icmp sge i8 [[X]], [[Y:%.*]]
-; CHECK-NEXT:    [[R:%.*]] = or i1 [[C2]], [[C1]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i8 [[Y:%.*]], 43
+; CHECK-NEXT:    [[TMP2:%.*]] = or i1 [[C1]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[TMP2]]
 ;
   %c1 = icmp ne i8 %x, 42
   call void @use(i1 %c1)
@@ -575,6 +578,8 @@ define i1 @substitute_constant_or_ne_sge_use(i8 %x, i8 %y) {
   ret i1 %r
 }
 
+; Negative test - extra use
+
 define i1 @substitute_constant_or_ne_ule_use2(i8 %x, i8 %y) {
 ; CHECK-LABEL: @substitute_constant_or_ne_ule_use2(
 ; CHECK-NEXT:    [[C1:%.*]] = icmp ne i8 [[X:%.*]], 42


        


More information about the llvm-commits mailing list