@@ -3183,3 +3183,109 @@ define i1 @icmp_of_ucmp_plus_const_with_const(i32 %x, i32 %y) {
31833183 %cmp2 = icmp ult i8 %add , 2
31843184 ret i1 %cmp2
31853185}
3186+
3187+ define i1 @zext_range_check_ult (i8 %x ) {
3188+ ; CHECK-LABEL: @zext_range_check_ult(
3189+ ; CHECK-NEXT: entry:
3190+ ; CHECK-NEXT: [[TMP0:%.*]] = add i8 [[X:%.*]], -4
3191+ ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[TMP0]], 3
3192+ ; CHECK-NEXT: ret i1 [[CMP]]
3193+ ;
3194+ entry:
3195+ %conv = zext i8 %x to i32
3196+ %add = add i32 %conv , -4
3197+ %cmp = icmp ult i32 %add , 3
3198+ ret i1 %cmp
3199+ }
3200+
3201+ ; TODO: should be canonicalized to (x - 4) u> 2
3202+ define i1 @zext_range_check_ugt (i8 %x ) {
3203+ ; CHECK-LABEL: @zext_range_check_ugt(
3204+ ; CHECK-NEXT: entry:
3205+ ; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[X:%.*]] to i32
3206+ ; CHECK-NEXT: [[TMP0:%.*]] = add nsw i32 [[CONV]], -7
3207+ ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[TMP0]], -3
3208+ ; CHECK-NEXT: ret i1 [[CMP]]
3209+ ;
3210+ entry:
3211+ %conv = zext i8 %x to i32
3212+ %add = add i32 %conv , -4
3213+ %cmp = icmp ugt i32 %add , 2
3214+ ret i1 %cmp
3215+ }
3216+
3217+ ; TODO: should be canonicalized to (x - 4) u> 2
3218+ define i1 @zext_range_check_ult_alter (i8 %x ) {
3219+ ; CHECK-LABEL: @zext_range_check_ult_alter(
3220+ ; CHECK-NEXT: entry:
3221+ ; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[X:%.*]] to i32
3222+ ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[CONV]], -7
3223+ ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ADD]], -3
3224+ ; CHECK-NEXT: ret i1 [[CMP]]
3225+ ;
3226+ entry:
3227+ %conv = zext i8 %x to i32
3228+ %add = add i32 %conv , -7
3229+ %cmp = icmp ult i32 %add , -3
3230+ ret i1 %cmp
3231+ }
3232+
3233+ define i1 @zext_range_check_mergable (i8 %x ) {
3234+ ; CHECK-LABEL: @zext_range_check_mergable(
3235+ ; CHECK-NEXT: [[COND:%.*]] = icmp slt i8 [[X:%.*]], 7
3236+ ; CHECK-NEXT: ret i1 [[COND]]
3237+ ;
3238+ %conv = zext i8 %x to i32
3239+ %add = add nsw i32 %conv , -4
3240+ %cmp1 = icmp ult i32 %add , 3
3241+ %cmp2 = icmp slt i8 %x , 4
3242+ %cond = select i1 %cmp2 , i1 true , i1 %cmp1
3243+ ret i1 %cond
3244+ }
3245+
3246+ ; Negative tests
3247+
3248+ define i1 @sext_range_check_ult (i8 %x ) {
3249+ ; CHECK-LABEL: @sext_range_check_ult(
3250+ ; CHECK-NEXT: entry:
3251+ ; CHECK-NEXT: [[CONV:%.*]] = sext i8 [[X:%.*]] to i32
3252+ ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[CONV]], -4
3253+ ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ADD]], 3
3254+ ; CHECK-NEXT: ret i1 [[CMP]]
3255+ ;
3256+ entry:
3257+ %conv = sext i8 %x to i32
3258+ %add = add i32 %conv , -4
3259+ %cmp = icmp ult i32 %add , 3
3260+ ret i1 %cmp
3261+ }
3262+
3263+ define i1 @zext_range_check_ult_illegal_type (i7 %x ) {
3264+ ; CHECK-LABEL: @zext_range_check_ult_illegal_type(
3265+ ; CHECK-NEXT: entry:
3266+ ; CHECK-NEXT: [[CONV:%.*]] = zext i7 [[X:%.*]] to i32
3267+ ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[CONV]], -4
3268+ ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ADD]], 3
3269+ ; CHECK-NEXT: ret i1 [[CMP]]
3270+ ;
3271+ entry:
3272+ %conv = zext i7 %x to i32
3273+ %add = add i32 %conv , -4
3274+ %cmp = icmp ult i32 %add , 3
3275+ ret i1 %cmp
3276+ }
3277+
3278+ define i1 @zext_range_check_ult_range_check_failure (i8 %x ) {
3279+ ; CHECK-LABEL: @zext_range_check_ult_range_check_failure(
3280+ ; CHECK-NEXT: entry:
3281+ ; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[X:%.*]] to i32
3282+ ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[CONV]], -4
3283+ ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ADD]], 253
3284+ ; CHECK-NEXT: ret i1 [[CMP]]
3285+ ;
3286+ entry:
3287+ %conv = zext i8 %x to i32
3288+ %add = add i32 %conv , -4
3289+ %cmp = icmp ult i32 %add , 253
3290+ ret i1 %cmp
3291+ }
0 commit comments