@@ -3183,3 +3183,109 @@ 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: [[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