[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
This commit is contained in:
Sanjay Patel 2020-04-23 09:59:41 -04:00
parent 2c99a3b86e
commit 234627a72c
4 changed files with 181 additions and 241 deletions

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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