@@ -3491,3 +3491,198 @@ define i1 @and_icmp_eq_with_binary_range_operands(i8 range(i8 0, 2) %x, i8 range
34913491 %ret = and i1 %icmp1 , %icmp2
34923492 ret i1 %ret
34933493}
3494+
3495+ define i1 @or_icmp_eq_and_pow2 (i32 %x ) {
3496+ ; CHECK-LABEL: @or_icmp_eq_and_pow2(
3497+ ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -127
3498+ ; CHECK-NEXT: [[RET:%.*]] = icmp ult i32 [[TMP1]], 33
3499+ ; CHECK-NEXT: ret i1 [[RET]]
3500+ ;
3501+ %icmp1 = icmp eq i32 %x , 127
3502+ %and = and i32 %x , -32
3503+ %icmp2 = icmp eq i32 %and , 128
3504+ %ret = or i1 %icmp1 , %icmp2
3505+ ret i1 %ret
3506+ }
3507+
3508+ define i1 @or_icmp_eq_and_pow2_mask_equal_to_icmp (i32 %x ) {
3509+ ; CHECK-LABEL: @or_icmp_eq_and_pow2_mask_equal_to_icmp(
3510+ ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -63
3511+ ; CHECK-NEXT: [[RET:%.*]] = icmp ult i32 [[TMP1]], 65
3512+ ; CHECK-NEXT: ret i1 [[RET]]
3513+ ;
3514+ %icmp1 = icmp eq i32 %x , 63
3515+ %and = and i32 %x , -64
3516+ %icmp2 = icmp eq i32 %and , 64
3517+ %ret = or i1 %icmp1 , %icmp2
3518+ ret i1 %ret
3519+ }
3520+
3521+ define i1 @and_icmp_ne_and_pow2 (i32 %x ) {
3522+ ; CHECK-LABEL: @and_icmp_ne_and_pow2(
3523+ ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -160
3524+ ; CHECK-NEXT: [[RET:%.*]] = icmp ult i32 [[TMP1]], -33
3525+ ; CHECK-NEXT: ret i1 [[RET]]
3526+ ;
3527+ %icmp1 = icmp ne i32 %x , 127
3528+ %and = and i32 %x , -32
3529+ %icmp2 = icmp ne i32 %and , 128
3530+ %ret = and i1 %icmp1 , %icmp2
3531+ ret i1 %ret
3532+ }
3533+
3534+ define i1 @and_icmp_ne_and_pow2_mask_equal_to_icmp (i32 %x ) {
3535+ ; CHECK-LABEL: @and_icmp_ne_and_pow2_mask_equal_to_icmp(
3536+ ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -128
3537+ ; CHECK-NEXT: [[RET:%.*]] = icmp ult i32 [[TMP1]], -65
3538+ ; CHECK-NEXT: ret i1 [[RET]]
3539+ ;
3540+ %icmp1 = icmp ne i32 %x , 63
3541+ %and = and i32 %x , -64
3542+ %icmp2 = icmp ne i32 %and , 64
3543+ %ret = and i1 %icmp1 , %icmp2
3544+ ret i1 %ret
3545+ }
3546+
3547+ define i1 @or_icmp_eq_and_pow2_commute (i32 %x ) {
3548+ ; CHECK-LABEL: @or_icmp_eq_and_pow2_commute(
3549+ ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -127
3550+ ; CHECK-NEXT: [[TMP4:%.*]] = icmp ult i32 [[TMP1]], 33
3551+ ; CHECK-NEXT: ret i1 [[TMP4]]
3552+ ;
3553+ %and = and i32 %x , -32
3554+ %icmp1 = icmp eq i32 %and , 128
3555+ %icmp2 = icmp eq i32 %x , 127
3556+ %ret = or i1 %icmp1 , %icmp2
3557+ ret i1 %ret
3558+ }
3559+
3560+ define i1 @and_icmp_ne_and_pow2_commute (i32 %x ) {
3561+ ; CHECK-LABEL: @and_icmp_ne_and_pow2_commute(
3562+ ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -160
3563+ ; CHECK-NEXT: [[RET:%.*]] = icmp ult i32 [[TMP1]], -33
3564+ ; CHECK-NEXT: ret i1 [[RET]]
3565+ ;
3566+ %and = and i32 %x , -32
3567+ %icmp1 = icmp ne i32 %and , 128
3568+ %icmp2 = icmp ne i32 %x , 127
3569+ %ret = and i1 %icmp1 , %icmp2
3570+ ret i1 %ret
3571+ }
3572+
3573+ define i1 @neg_or_icmp_eq_and_pow2_multi_use (i32 %x ) {
3574+ ; CHECK-LABEL: @neg_or_icmp_eq_and_pow2_multi_use(
3575+ ; CHECK-NEXT: [[ICMP1:%.*]] = icmp eq i32 [[X:%.*]], 127
3576+ ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], -32
3577+ ; CHECK-NEXT: call void @use32(i32 [[AND]])
3578+ ; CHECK-NEXT: [[ICMP2:%.*]] = icmp eq i32 [[AND]], 128
3579+ ; CHECK-NEXT: [[RET:%.*]] = or i1 [[ICMP1]], [[ICMP2]]
3580+ ; CHECK-NEXT: ret i1 [[RET]]
3581+ ;
3582+ %icmp1 = icmp eq i32 %x , 127
3583+ %and = and i32 %x , -32
3584+ call void @use32 (i32 %and )
3585+ %icmp2 = icmp eq i32 %and , 128
3586+ %ret = or i1 %icmp1 , %icmp2
3587+ ret i1 %ret
3588+ }
3589+
3590+ define i1 @neg_and_icmp_eq_and_pow2 (i32 %x ) {
3591+ ; CHECK-LABEL: @neg_and_icmp_eq_and_pow2(
3592+ ; CHECK-NEXT: ret i1 false
3593+ ;
3594+ %icmp1 = icmp eq i32 %x , 127
3595+ %and = and i32 %x , -32
3596+ %icmp2 = icmp eq i32 %and , 128
3597+ %ret = and i1 %icmp1 , %icmp2
3598+ ret i1 %ret
3599+ }
3600+
3601+ define i1 @neg_or_icmp_eq_and_non_pow2_mask (i32 %x ) {
3602+ ; CHECK-LABEL: @neg_or_icmp_eq_and_non_pow2_mask(
3603+ ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[X:%.*]], 127
3604+ ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[X]], -33
3605+ ; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 128
3606+ ; CHECK-NEXT: [[TMP4:%.*]] = or i1 [[TMP1]], [[TMP3]]
3607+ ; CHECK-NEXT: ret i1 [[TMP4]]
3608+ ;
3609+ %icmp1 = icmp eq i32 %x , 127
3610+ %and = and i32 %x , -33
3611+ %icmp2 = icmp eq i32 %and , 128
3612+ %ret = or i1 %icmp1 , %icmp2
3613+ ret i1 %ret
3614+ }
3615+
3616+ define i1 @neg_and_icmp_ne_and_non_pow2_icmp (i32 %x ) {
3617+ ; CHECK-LABEL: @neg_and_icmp_ne_and_non_pow2_icmp(
3618+ ; CHECK-NEXT: [[ICMP1:%.*]] = icmp ne i32 [[X:%.*]], 127
3619+ ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], -33
3620+ ; CHECK-NEXT: [[ICMP2:%.*]] = icmp ne i32 [[AND]], 128
3621+ ; CHECK-NEXT: [[RET:%.*]] = and i1 [[ICMP1]], [[ICMP2]]
3622+ ; CHECK-NEXT: ret i1 [[RET]]
3623+ ;
3624+ %icmp1 = icmp ne i32 %x , 127
3625+ %and = and i32 %x , -33
3626+ %icmp2 = icmp ne i32 %and , 128
3627+ %ret = and i1 %icmp1 , %icmp2
3628+ ret i1 %ret
3629+ }
3630+
3631+ define i1 @neg_or_icmp_eq_and_const_less_than_mask (i32 %x ) {
3632+ ; CHECK-LABEL: @neg_or_icmp_eq_and_const_less_than_mask(
3633+ ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[X:%.*]], 15
3634+ ; CHECK-NEXT: ret i1 [[TMP1]]
3635+ ;
3636+ %icmp1 = icmp eq i32 %x , 15
3637+ %and = and i32 %x , -32
3638+ %icmp2 = icmp eq i32 %and , 16
3639+ %ret = or i1 %icmp1 , %icmp2
3640+ ret i1 %ret
3641+ }
3642+
3643+ define i1 @neg_and_icmp_ne_and_pow2_disjoint (i32 %x ) {
3644+ ; CHECK-LABEL: @neg_and_icmp_ne_and_pow2_disjoint(
3645+ ; CHECK-NEXT: [[ICMP1:%.*]] = icmp ne i32 [[X:%.*]], 126
3646+ ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], -32
3647+ ; CHECK-NEXT: [[ICMP2:%.*]] = icmp ne i32 [[AND]], 128
3648+ ; CHECK-NEXT: [[RET:%.*]] = and i1 [[ICMP1]], [[ICMP2]]
3649+ ; CHECK-NEXT: ret i1 [[RET]]
3650+ ;
3651+ %icmp1 = icmp ne i32 %x , 126
3652+ %and = and i32 %x , -32
3653+ %icmp2 = icmp ne i32 %and , 128
3654+ %ret = and i1 %icmp1 , %icmp2
3655+ ret i1 %ret
3656+ }
3657+
3658+ define i1 @neg_or_icmp_eq_double_and_pow2 (i32 %x ) {
3659+ ; CHECK-LABEL: @neg_or_icmp_eq_double_and_pow2(
3660+ ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -16
3661+ ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 64
3662+ ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[X]], -32
3663+ ; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[AND2]], 128
3664+ ; CHECK-NEXT: [[TMP5:%.*]] = or i1 [[TMP2]], [[TMP4]]
3665+ ; CHECK-NEXT: ret i1 [[TMP5]]
3666+ ;
3667+ %and1 = and i32 %x , -16
3668+ %icmp1 = icmp eq i32 %and1 , 64
3669+ %and2 = and i32 %x , -32
3670+ %icmp2 = icmp eq i32 %and2 , 128
3671+ %ret = or i1 %icmp1 , %icmp2
3672+ ret i1 %ret
3673+ }
3674+
3675+ define i1 @neg_select_icmp_eq_and_pow2 (i32 %x ) {
3676+ ; CHECK-LABEL: @neg_select_icmp_eq_and_pow2(
3677+ ; CHECK-NEXT: [[ICMP1:%.*]] = icmp sgt i32 [[X:%.*]], 127
3678+ ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], -32
3679+ ; CHECK-NEXT: [[ICMP2:%.*]] = icmp eq i32 [[AND]], 128
3680+ ; CHECK-NEXT: [[TMP1:%.*]] = and i1 [[ICMP1]], [[ICMP2]]
3681+ ; CHECK-NEXT: ret i1 [[TMP1]]
3682+ ;
3683+ %icmp1 = icmp sgt i32 %x , 127
3684+ %and = and i32 %x , -32
3685+ %icmp2 = icmp eq i32 %and , 128
3686+ %1 = select i1 %icmp1 , i1 %icmp2 , i1 false
3687+ ret i1 %1
3688+ }
0 commit comments