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
30 changes: 22 additions & 8 deletions llvm/test/Transforms/InstCombine/icmp-of-and-x.ll
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

declare i1 @barrier()
declare void @llvm.assume(i1)
declare void @use.i8(i8)

define i1 @icmp_ult_x_y(i8 %x, i8 %y) {
; CHECK-LABEL: @icmp_ult_x_y(
Expand Down Expand Up @@ -238,9 +239,9 @@ define i1 @icmp_sle_negx_y_fail_maybe_zero(i8 %x, i8 %y) {

define i1 @icmp_eq_x_invertable_y_todo(i8 %x, i1 %y) {
; CHECK-LABEL: @icmp_eq_x_invertable_y_todo(
; CHECK-NEXT: [[YY:%.*]] = select i1 [[Y:%.*]], i8 7, i8 24
; CHECK-NEXT: [[YY:%.*]] = select i1 [[Y:%.*]], i8 -8, i8 -25
; CHECK-NEXT: [[AND:%.*]] = and i8 [[YY]], [[X:%.*]]
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[AND]], [[X]]
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[AND]], 0
; CHECK-NEXT: ret i1 [[R]]
;
%yy = select i1 %y, i8 7, i8 24
Expand All @@ -251,22 +252,36 @@ define i1 @icmp_eq_x_invertable_y_todo(i8 %x, i1 %y) {

define i1 @icmp_eq_x_invertable_y(i8 %x, i8 %y) {
; CHECK-LABEL: @icmp_eq_x_invertable_y(
; CHECK-NEXT: [[AND:%.*]] = and i8 [[YY:%.*]], [[X:%.*]]
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[AND]], 0
; CHECK-NEXT: ret i1 [[R]]
;
%yy = xor i8 %y, -1
%and = and i8 %x, %yy
%r = icmp eq i8 %x, %and
ret i1 %r
}

define i1 @icmp_eq_x_invertable_y_fail_multiuse(i8 %x, i8 %y) {
; CHECK-LABEL: @icmp_eq_x_invertable_y_fail_multiuse(
; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], -1
; CHECK-NEXT: [[AND:%.*]] = and i8 [[YY]], [[X:%.*]]
; CHECK-NEXT: call void @use.i8(i8 [[AND]])
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[AND]], [[X]]
; CHECK-NEXT: ret i1 [[R]]
;
%yy = xor i8 %y, -1
%and = and i8 %x, %yy
call void @use.i8(i8 %and)
%r = icmp eq i8 %x, %and
ret i1 %r
}

define i1 @icmp_eq_x_invertable_y2_todo(i8 %x, i1 %y) {
; CHECK-LABEL: @icmp_eq_x_invertable_y2_todo(
; CHECK-NEXT: [[YY:%.*]] = select i1 [[Y:%.*]], i8 7, i8 24
; CHECK-NEXT: [[AND:%.*]] = and i8 [[YY]], [[X:%.*]]
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[YY]], [[AND]]
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[Y:%.*]], i8 -8, i8 -25
; CHECK-NEXT: [[TMP2:%.*]] = or i8 [[TMP1]], [[X:%.*]]
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[TMP2]], -1
; CHECK-NEXT: ret i1 [[R]]
;
%yy = select i1 %y, i8 7, i8 24
Expand All @@ -277,9 +292,8 @@ define i1 @icmp_eq_x_invertable_y2_todo(i8 %x, i1 %y) {

define i1 @icmp_eq_x_invertable_y2(i8 %x, i8 %y) {
; CHECK-LABEL: @icmp_eq_x_invertable_y2(
; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], -1
; CHECK-NEXT: [[AND:%.*]] = and i8 [[YY]], [[X:%.*]]
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[AND]], [[YY]]
; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[TMP1]], -1
; CHECK-NEXT: ret i1 [[R]]
;
%yy = xor i8 %y, -1
Expand Down