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