Skip to content

[InstCombine] Make the (icmp eq/ne (and X, Y), X) canonicalization work for non-const operands #84688

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 20 additions & 15 deletions llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4724,6 +4724,26 @@ static Instruction *foldICmpAndXX(ICmpInst &I, const SimplifyQuery &Q,
if (Pred == ICmpInst::ICMP_UGE)
return new ICmpInst(ICmpInst::ICMP_EQ, Op0, Op1);

if (ICmpInst::isEquality(Pred) && Op0->hasOneUse()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need a multi-use test.

// icmp (X & Y) eq/ne Y --> (X | ~Y) eq/ne -1 if Y is freely invertible and
// Y is non-constant. If Y is constant the `X & C == C` form is preferable
// so don't do this fold.
if (!match(Op1, m_ImmConstant()))
if (auto *NotOp1 =
IC.getFreelyInverted(Op1, !Op1->hasNUsesOrMore(3), &IC.Builder))
return new ICmpInst(Pred, IC.Builder.CreateOr(A, NotOp1),
Constant::getAllOnesValue(Op1->getType()));
// icmp (X & Y) eq/ne Y --> (~X & Y) eq/ne 0 if X is freely invertible.
// Since we may be consuming a `not` here, first check if we match
// `foldICmpWithLowBitMaskedVal` as it is a "better" user of `not`
// instructions.
if (Value *R = foldICmpWithLowBitMaskedVal(Pred, Op0, Op1, Q, IC))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add some tests to demonstrate this behavior.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just split it into a 3rd commit, so you can see the regressions/fixups between commit 2/3

return IC.replaceInstUsesWith(I, R);
if (auto *NotA = IC.getFreelyInverted(A, A->hasOneUse(), &IC.Builder))
return new ICmpInst(Pred, IC.Builder.CreateAnd(Op1, NotA),
Constant::getNullValue(Op1->getType()));
}

return nullptr;
}

Expand Down Expand Up @@ -5498,21 +5518,6 @@ Instruction *InstCombinerImpl::foldICmpEquality(ICmpInst &I) {
}
}

// canoncalize:
// (icmp eq/ne (and X, C), X)
// -> (icmp eq/ne (and X, ~C), 0)
{
Constant *CMask;
A = nullptr;
if (match(Op0, m_OneUse(m_And(m_Specific(Op1), m_ImmConstant(CMask)))))
A = Op1;
else if (match(Op1, m_OneUse(m_And(m_Specific(Op0), m_ImmConstant(CMask)))))
A = Op0;
if (A)
return new ICmpInst(Pred, Builder.CreateAnd(A, Builder.CreateNot(CMask)),
Constant::getNullValue(A->getType()));
}

if (match(Op1, m_Xor(m_Value(A), m_Value(B))) && (A == Op0 || B == Op0)) {
// A == (A^B) -> B == 0
Value *OtherVal = A == Op0 ? B : A;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,9 +269,8 @@ define i1 @n0(i8 %x, i8 %y, i8 %notx) {
define i1 @n1(i8 %x, i8 %y) {
; CHECK-LABEL: @n1(
; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[Y:%.*]]
; CHECK-NEXT: [[T1:%.*]] = xor i8 [[T0]], -1
; CHECK-NEXT: [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
; CHECK-NEXT: [[RET:%.*]] = icmp eq i8 [[T2]], [[X]]
; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[T0]], [[X:%.*]]
; CHECK-NEXT: [[RET:%.*]] = icmp eq i8 [[TMP1]], 0
; CHECK-NEXT: ret i1 [[RET]]
;
%t0 = shl i8 1, %y ; not -1
Expand All @@ -284,9 +283,9 @@ define i1 @n1(i8 %x, i8 %y) {
define i1 @n2(i8 %x, i8 %y) {
; CHECK-LABEL: @n2(
; CHECK-NEXT: [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
; CHECK-NEXT: [[T1:%.*]] = xor i8 [[T0]], 1
; CHECK-NEXT: [[T1:%.*]] = xor i8 [[T0]], -2
; CHECK-NEXT: [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
; CHECK-NEXT: [[RET:%.*]] = icmp eq i8 [[T2]], [[X]]
; CHECK-NEXT: [[RET:%.*]] = icmp eq i8 [[T2]], 0
; CHECK-NEXT: ret i1 [[RET]]
;
%t0 = shl i8 -1, %y
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,9 +269,8 @@ define i1 @n0(i8 %x, i8 %y, i8 %notx) {
define i1 @n1(i8 %x, i8 %y) {
; CHECK-LABEL: @n1(
; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[Y:%.*]]
; CHECK-NEXT: [[T1:%.*]] = xor i8 [[T0]], -1
; CHECK-NEXT: [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
; CHECK-NEXT: [[RET:%.*]] = icmp ne i8 [[T2]], [[X]]
; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[T0]], [[X:%.*]]
; CHECK-NEXT: [[RET:%.*]] = icmp ne i8 [[TMP1]], 0
; CHECK-NEXT: ret i1 [[RET]]
;
%t0 = shl i8 1, %y ; not -1
Expand All @@ -284,9 +283,9 @@ define i1 @n1(i8 %x, i8 %y) {
define i1 @n2(i8 %x, i8 %y) {
; CHECK-LABEL: @n2(
; CHECK-NEXT: [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
; CHECK-NEXT: [[T1:%.*]] = xor i8 [[T0]], 1
; CHECK-NEXT: [[T1:%.*]] = xor i8 [[T0]], -2
; CHECK-NEXT: [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
; CHECK-NEXT: [[RET:%.*]] = icmp ne i8 [[T2]], [[X]]
; CHECK-NEXT: [[RET:%.*]] = icmp ne i8 [[T2]], 0
; CHECK-NEXT: ret i1 [[RET]]
;
%t0 = shl i8 -1, %y
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,9 +251,9 @@ define i1 @n1(i8 %x, i8 %y) {
; CHECK-LABEL: @n1(
; CHECK-NEXT: [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
; CHECK-NEXT: call void @use8(i8 [[T0]])
; CHECK-NEXT: [[T1:%.*]] = add i8 [[T0]], -1
; CHECK-NEXT: [[T1:%.*]] = sub i8 0, [[T0]]
; CHECK-NEXT: [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
; CHECK-NEXT: [[RET:%.*]] = icmp eq i8 [[T2]], [[X]]
; CHECK-NEXT: [[RET:%.*]] = icmp eq i8 [[T2]], 0
; CHECK-NEXT: ret i1 [[RET]]
;
%t0 = shl i8 -1, %y ; not 1
Expand All @@ -268,9 +268,9 @@ define i1 @n2(i8 %x, i8 %y) {
; CHECK-LABEL: @n2(
; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[Y:%.*]]
; CHECK-NEXT: call void @use8(i8 [[T0]])
; CHECK-NEXT: [[T1:%.*]] = add nuw i8 [[T0]], 1
; CHECK-NEXT: [[T1:%.*]] = sub nuw i8 -2, [[T0]]
; CHECK-NEXT: [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
; CHECK-NEXT: [[RET:%.*]] = icmp eq i8 [[T2]], [[X]]
; CHECK-NEXT: [[RET:%.*]] = icmp eq i8 [[T2]], 0
; CHECK-NEXT: ret i1 [[RET]]
;
%t0 = shl i8 1, %y
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,9 +251,9 @@ define i1 @n1(i8 %x, i8 %y) {
; CHECK-LABEL: @n1(
; CHECK-NEXT: [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
; CHECK-NEXT: call void @use8(i8 [[T0]])
; CHECK-NEXT: [[T1:%.*]] = add i8 [[T0]], -1
; CHECK-NEXT: [[T1:%.*]] = sub i8 0, [[T0]]
; CHECK-NEXT: [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
; CHECK-NEXT: [[RET:%.*]] = icmp ne i8 [[T2]], [[X]]
; CHECK-NEXT: [[RET:%.*]] = icmp ne i8 [[T2]], 0
; CHECK-NEXT: ret i1 [[RET]]
;
%t0 = shl i8 -1, %y ; not 1
Expand All @@ -268,9 +268,9 @@ define i1 @n2(i8 %x, i8 %y) {
; CHECK-LABEL: @n2(
; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[Y:%.*]]
; CHECK-NEXT: call void @use8(i8 [[T0]])
; CHECK-NEXT: [[T1:%.*]] = add nuw i8 [[T0]], 1
; CHECK-NEXT: [[T1:%.*]] = sub nuw i8 -2, [[T0]]
; CHECK-NEXT: [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
; CHECK-NEXT: [[RET:%.*]] = icmp ne i8 [[T2]], [[X]]
; CHECK-NEXT: [[RET:%.*]] = icmp ne i8 [[T2]], 0
; CHECK-NEXT: ret i1 [[RET]]
;
%t0 = shl i8 1, %y
Expand Down
59 changes: 29 additions & 30 deletions llvm/test/Transforms/InstCombine/icmp-and-lowbit-mask.ll
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ declare void @use.i8(i8)
declare void @use.i16(i16)
define i1 @src_is_mask_zext(i16 %x_in, i8 %y) {
; CHECK-LABEL: @src_is_mask_zext(
; CHECK-NEXT: [[X:%.*]] = xor i16 [[X_IN:%.*]], 123
; CHECK-NEXT: [[M_IN:%.*]] = lshr i8 -1, [[Y:%.*]]
; CHECK-NEXT: [[MASK:%.*]] = zext i8 [[M_IN]] to i16
; CHECK-NEXT: [[X:%.*]] = xor i16 [[X_IN:%.*]], 123
; CHECK-NEXT: [[R:%.*]] = icmp ule i16 [[X]], [[MASK]]
; CHECK-NEXT: ret i1 [[R]]
;
Expand All @@ -22,11 +22,11 @@ define i1 @src_is_mask_zext(i16 %x_in, i8 %y) {

define i1 @src_is_mask_zext_fail_not_mask(i16 %x_in, i8 %y) {
; CHECK-LABEL: @src_is_mask_zext_fail_not_mask(
; CHECK-NEXT: [[X:%.*]] = xor i16 [[X_IN:%.*]], 123
; CHECK-NEXT: [[M_IN:%.*]] = lshr i8 -2, [[Y:%.*]]
; CHECK-NEXT: [[MASK:%.*]] = zext i8 [[M_IN]] to i16
; CHECK-NEXT: [[AND:%.*]] = and i16 [[X]], [[MASK]]
; CHECK-NEXT: [[R:%.*]] = icmp eq i16 [[AND]], [[X]]
; CHECK-NEXT: [[TMP1:%.*]] = xor i16 [[X_IN:%.*]], -124
; CHECK-NEXT: [[TMP2:%.*]] = or i16 [[TMP1]], [[MASK]]
; CHECK-NEXT: [[R:%.*]] = icmp eq i16 [[TMP2]], -1
; CHECK-NEXT: ret i1 [[R]]
;
%x = xor i16 %x_in, 123
Expand Down Expand Up @@ -80,10 +80,10 @@ define i1 @src_is_mask_sext_fail_multiuse(i16 %x_in, i8 %y) {

define i1 @src_is_mask_and(i8 %x_in, i8 %y, i8 %z) {
; CHECK-LABEL: @src_is_mask_and(
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
; CHECK-NEXT: [[MY:%.*]] = lshr i8 7, [[Y:%.*]]
; CHECK-NEXT: [[MZ:%.*]] = lshr i8 -1, [[Z:%.*]]
; CHECK-NEXT: [[MASK:%.*]] = and i8 [[MY]], [[MZ]]
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
; CHECK-NEXT: [[R:%.*]] = icmp ule i8 [[X]], [[MASK]]
; CHECK-NEXT: ret i1 [[R]]
;
Expand All @@ -99,12 +99,12 @@ define i1 @src_is_mask_and(i8 %x_in, i8 %y, i8 %z) {

define i1 @src_is_mask_and_fail_mixed(i8 %x_in, i8 %y, i8 %z) {
; CHECK-LABEL: @src_is_mask_and_fail_mixed(
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
; CHECK-NEXT: [[MY:%.*]] = ashr i8 -8, [[Y:%.*]]
; CHECK-NEXT: [[MZ:%.*]] = lshr i8 -1, [[Z:%.*]]
; CHECK-NEXT: [[MASK:%.*]] = and i8 [[MY]], [[MZ]]
; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], [[MASK]]
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[X]], [[AND]]
; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[X_IN:%.*]], -124
; CHECK-NEXT: [[TMP2:%.*]] = or i8 [[MASK]], [[TMP1]]
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[TMP2]], -1
; CHECK-NEXT: ret i1 [[R]]
;
%x = xor i8 %x_in, 123
Expand All @@ -119,9 +119,9 @@ define i1 @src_is_mask_and_fail_mixed(i8 %x_in, i8 %y, i8 %z) {

define i1 @src_is_mask_or(i8 %x_in, i8 %y) {
; CHECK-LABEL: @src_is_mask_or(
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
; CHECK-NEXT: [[MY:%.*]] = lshr i8 -1, [[Y:%.*]]
; CHECK-NEXT: [[MASK:%.*]] = and i8 [[MY]], 7
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
; CHECK-NEXT: [[R:%.*]] = icmp ule i8 [[X]], [[MASK]]
; CHECK-NEXT: ret i1 [[R]]
;
Expand All @@ -136,9 +136,9 @@ define i1 @src_is_mask_or(i8 %x_in, i8 %y) {

define i1 @src_is_mask_xor(i8 %x_in, i8 %y) {
; CHECK-LABEL: @src_is_mask_xor(
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
; CHECK-NEXT: [[Y_M1:%.*]] = add i8 [[Y:%.*]], -1
; CHECK-NEXT: [[MASK:%.*]] = xor i8 [[Y_M1]], [[Y]]
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[X]], [[MASK]]
; CHECK-NEXT: ret i1 [[R]]
;
Expand All @@ -152,11 +152,11 @@ define i1 @src_is_mask_xor(i8 %x_in, i8 %y) {

define i1 @src_is_mask_xor_fail_notmask(i8 %x_in, i8 %y) {
; CHECK-LABEL: @src_is_mask_xor_fail_notmask(
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
; CHECK-NEXT: [[TMP1:%.*]] = sub i8 0, [[Y:%.*]]
; CHECK-NEXT: [[NOTMASK:%.*]] = xor i8 [[TMP1]], [[Y]]
; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], [[NOTMASK]]
; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[AND]], [[X]]
; CHECK-NEXT: [[TMP2:%.*]] = xor i8 [[X_IN:%.*]], -124
; CHECK-NEXT: [[TMP3:%.*]] = or i8 [[NOTMASK]], [[TMP2]]
; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[TMP3]], -1
; CHECK-NEXT: ret i1 [[R]]
;
%x = xor i8 %x_in, 123
Expand All @@ -170,10 +170,10 @@ define i1 @src_is_mask_xor_fail_notmask(i8 %x_in, i8 %y) {

define i1 @src_is_mask_select(i8 %x_in, i8 %y, i1 %cond) {
; CHECK-LABEL: @src_is_mask_select(
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
; CHECK-NEXT: [[Y_M1:%.*]] = add i8 [[Y:%.*]], -1
; CHECK-NEXT: [[YMASK:%.*]] = xor i8 [[Y_M1]], [[Y]]
; CHECK-NEXT: [[MASK:%.*]] = select i1 [[COND:%.*]], i8 [[YMASK]], i8 15
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[X]], [[MASK]]
; CHECK-NEXT: ret i1 [[R]]
;
Expand Down Expand Up @@ -245,11 +245,11 @@ define i1 @src_is_mask_shl_lshr_fail_not_allones(i8 %x_in, i8 %y, i1 %cond) {

define i1 @src_is_mask_lshr(i8 %x_in, i8 %y, i8 %z, i1 %cond) {
; CHECK-LABEL: @src_is_mask_lshr(
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
; CHECK-NEXT: [[Y_M1:%.*]] = add i8 [[Y:%.*]], -1
; CHECK-NEXT: [[YMASK:%.*]] = xor i8 [[Y_M1]], [[Y]]
; CHECK-NEXT: [[SMASK:%.*]] = select i1 [[COND:%.*]], i8 [[YMASK]], i8 15
; CHECK-NEXT: [[MASK:%.*]] = lshr i8 [[SMASK]], [[Z:%.*]]
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[X]], [[MASK]]
; CHECK-NEXT: ret i1 [[R]]
;
Expand All @@ -265,11 +265,11 @@ define i1 @src_is_mask_lshr(i8 %x_in, i8 %y, i8 %z, i1 %cond) {

define i1 @src_is_mask_ashr(i8 %x_in, i8 %y, i8 %z, i1 %cond) {
; CHECK-LABEL: @src_is_mask_ashr(
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
; CHECK-NEXT: [[Y_M1:%.*]] = add i8 [[Y:%.*]], -1
; CHECK-NEXT: [[YMASK:%.*]] = xor i8 [[Y_M1]], [[Y]]
; CHECK-NEXT: [[SMASK:%.*]] = select i1 [[COND:%.*]], i8 [[YMASK]], i8 15
; CHECK-NEXT: [[MASK:%.*]] = ashr i8 [[SMASK]], [[Z:%.*]]
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[X]], [[MASK]]
; CHECK-NEXT: ret i1 [[R]]
;
Expand All @@ -285,9 +285,9 @@ define i1 @src_is_mask_ashr(i8 %x_in, i8 %y, i8 %z, i1 %cond) {

define i1 @src_is_mask_p2_m1(i8 %x_in, i8 %y) {
; CHECK-LABEL: @src_is_mask_p2_m1(
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
; CHECK-NEXT: [[P2ORZ:%.*]] = shl i8 2, [[Y:%.*]]
; CHECK-NEXT: [[MASK:%.*]] = add i8 [[P2ORZ]], -1
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[X]], [[MASK]]
; CHECK-NEXT: ret i1 [[R]]
;
Expand All @@ -301,10 +301,10 @@ define i1 @src_is_mask_p2_m1(i8 %x_in, i8 %y) {

define i1 @src_is_mask_umax(i8 %x_in, i8 %y) {
; CHECK-LABEL: @src_is_mask_umax(
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
; CHECK-NEXT: [[Y_M1:%.*]] = add i8 [[Y:%.*]], -1
; CHECK-NEXT: [[YMASK:%.*]] = xor i8 [[Y_M1]], [[Y]]
; CHECK-NEXT: [[MASK:%.*]] = call i8 @llvm.umax.i8(i8 [[YMASK]], i8 3)
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[X]], [[MASK]]
; CHECK-NEXT: ret i1 [[R]]
;
Expand All @@ -320,11 +320,11 @@ define i1 @src_is_mask_umax(i8 %x_in, i8 %y) {

define i1 @src_is_mask_umin(i8 %x_in, i8 %y, i8 %z) {
; CHECK-LABEL: @src_is_mask_umin(
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
; CHECK-NEXT: [[Y_M1:%.*]] = add i8 [[Y:%.*]], -1
; CHECK-NEXT: [[YMASK:%.*]] = xor i8 [[Y_M1]], [[Y]]
; CHECK-NEXT: [[ZMASK:%.*]] = lshr i8 15, [[Z:%.*]]
; CHECK-NEXT: [[MASK:%.*]] = call i8 @llvm.umin.i8(i8 [[YMASK]], i8 [[ZMASK]])
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[X]], [[MASK]]
; CHECK-NEXT: ret i1 [[R]]
;
Expand All @@ -341,12 +341,12 @@ define i1 @src_is_mask_umin(i8 %x_in, i8 %y, i8 %z) {

define i1 @src_is_mask_umin_fail_mismatch(i8 %x_in, i8 %y) {
; CHECK-LABEL: @src_is_mask_umin_fail_mismatch(
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
; CHECK-NEXT: [[Y_M1:%.*]] = add i8 [[Y:%.*]], -1
; CHECK-NEXT: [[YMASK:%.*]] = xor i8 [[Y_M1]], [[Y]]
; CHECK-NEXT: [[MASK:%.*]] = call i8 @llvm.umin.i8(i8 [[YMASK]], i8 -32)
; CHECK-NEXT: [[AND:%.*]] = and i8 [[MASK]], [[X]]
; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[AND]], [[X]]
; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[X_IN:%.*]], -124
; CHECK-NEXT: [[TMP2:%.*]] = or i8 [[MASK]], [[TMP1]]
; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[TMP2]], -1
; CHECK-NEXT: ret i1 [[R]]
;
%x = xor i8 %x_in, 123
Expand All @@ -361,10 +361,10 @@ define i1 @src_is_mask_umin_fail_mismatch(i8 %x_in, i8 %y) {

define i1 @src_is_mask_smax(i8 %x_in, i8 %y) {
; CHECK-LABEL: @src_is_mask_smax(
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
; CHECK-NEXT: [[Y_M1:%.*]] = add i8 [[Y:%.*]], -1
; CHECK-NEXT: [[YMASK:%.*]] = xor i8 [[Y_M1]], [[Y]]
; CHECK-NEXT: [[MASK:%.*]] = call i8 @llvm.smax.i8(i8 [[YMASK]], i8 -1)
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
; CHECK-NEXT: [[R:%.*]] = icmp ule i8 [[X]], [[MASK]]
; CHECK-NEXT: ret i1 [[R]]
;
Expand All @@ -380,10 +380,10 @@ define i1 @src_is_mask_smax(i8 %x_in, i8 %y) {

define i1 @src_is_mask_smin(i8 %x_in, i8 %y) {
; CHECK-LABEL: @src_is_mask_smin(
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
; CHECK-NEXT: [[Y_M1:%.*]] = add i8 [[Y:%.*]], -1
; CHECK-NEXT: [[YMASK:%.*]] = xor i8 [[Y_M1]], [[Y]]
; CHECK-NEXT: [[MASK:%.*]] = call i8 @llvm.smin.i8(i8 [[YMASK]], i8 0)
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
; CHECK-NEXT: [[R:%.*]] = icmp ule i8 [[X]], [[MASK]]
; CHECK-NEXT: ret i1 [[R]]
;
Expand All @@ -399,9 +399,9 @@ define i1 @src_is_mask_smin(i8 %x_in, i8 %y) {

define i1 @src_is_mask_bitreverse_not_mask(i8 %x_in, i8 %y) {
; CHECK-LABEL: @src_is_mask_bitreverse_not_mask(
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
; CHECK-NEXT: [[NMASK:%.*]] = shl nsw i8 -1, [[Y:%.*]]
; CHECK-NEXT: [[MASK:%.*]] = call i8 @llvm.bitreverse.i8(i8 [[NMASK]])
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
; CHECK-NEXT: [[R:%.*]] = icmp ule i8 [[X]], [[MASK]]
; CHECK-NEXT: ret i1 [[R]]
;
Expand All @@ -417,7 +417,7 @@ define i1 @src_is_mask_bitreverse_not_mask(i8 %x_in, i8 %y) {
define i1 @src_is_notmask_sext(i16 %x_in, i8 %y) {
; CHECK-LABEL: @src_is_notmask_sext(
; CHECK-NEXT: [[M_IN:%.*]] = shl i8 -8, [[Y:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = xor i16 [[X_IN:%.*]], -124
; CHECK-NEXT: [[TMP1:%.*]] = xor i16 [[X_IN:%.*]], -128
; CHECK-NEXT: [[TMP2:%.*]] = sext i8 [[M_IN]] to i16
; CHECK-NEXT: [[R:%.*]] = icmp uge i16 [[TMP1]], [[TMP2]]
; CHECK-NEXT: ret i1 [[R]]
Expand Down Expand Up @@ -529,12 +529,11 @@ define i1 @src_is_notmask_lshr_shl(i8 %x_in, i8 %y) {

define i1 @src_is_notmask_lshr_shl_fail_mismatch_shifts(i8 %x_in, i8 %y, i8 %z) {
; CHECK-LABEL: @src_is_notmask_lshr_shl_fail_mismatch_shifts(
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
; CHECK-NEXT: [[MASK_SHR:%.*]] = lshr i8 -1, [[Y:%.*]]
; CHECK-NEXT: [[NMASK:%.*]] = shl i8 [[MASK_SHR]], [[Z:%.*]]
; CHECK-NEXT: [[MASK:%.*]] = xor i8 [[NMASK]], -1
; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], [[MASK]]
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[AND]], [[X]]
; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[X_IN:%.*]], 123
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[NMASK]]
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[TMP2]], 0
; CHECK-NEXT: ret i1 [[R]]
;
%x = xor i8 %x_in, 123
Expand Down
Loading