[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