@@ -327,6 +327,180 @@ if.end: ; preds = %entry
327
327
ret void
328
328
}
329
329
330
+ define void @test.not.uge.uge.nonconst (i8* %start , i8* %low , i8* %high , i64 %off ) {
331
+ ; CHECK-LABEL: @test.not.uge.uge.nonconst(
332
+ ; CHECK-NEXT: entry:
333
+ ; CHECK-NEXT: [[ADD_PTR_I:%.*]] = getelementptr inbounds i8, i8* [[START:%.*]], i64 [[OFF:%.*]]
334
+ ; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8* [[ADD_PTR_I]], [[HIGH:%.*]]
335
+ ; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
336
+ ; CHECK: if.then:
337
+ ; CHECK-NEXT: [[START_OFF_2:%.*]] = getelementptr inbounds i8, i8* [[START]], i64 [[OFF]]
338
+ ; CHECK-NEXT: [[T_0:%.*]] = icmp uge i8* [[START_OFF_2]], [[HIGH]]
339
+ ; CHECK-NEXT: call void @use(i1 true)
340
+ ; CHECK-NEXT: ret void
341
+ ; CHECK: if.end:
342
+ ; CHECK-NEXT: [[START_1:%.*]] = getelementptr inbounds i8, i8* [[START]], i64 1
343
+ ; CHECK-NEXT: [[C_0:%.*]] = icmp uge i8* [[START_1]], [[HIGH]]
344
+ ; CHECK-NEXT: call void @use(i1 [[C_0]])
345
+ ; CHECK-NEXT: [[START_OFF:%.*]] = getelementptr inbounds i8, i8* [[START]], i64 [[OFF]]
346
+ ; CHECK-NEXT: [[F_0:%.*]] = icmp uge i8* [[START_OFF]], [[HIGH]]
347
+ ; CHECK-NEXT: call void @use(i1 false)
348
+ ; CHECK-NEXT: ret void
349
+ ;
350
+ entry:
351
+ %add.ptr.i = getelementptr inbounds i8 , i8* %start , i64 %off
352
+ %c.1 = icmp uge i8* %add.ptr.i , %high
353
+ br i1 %c.1 , label %if.then , label %if.end
354
+
355
+ if.then: ; preds = %entry
356
+ %start.off.2 = getelementptr inbounds i8 , i8* %start , i64 %off
357
+ %t.0 = icmp uge i8* %start.off.2 , %high
358
+ call void @use (i1 %t.0 )
359
+
360
+ ret void
361
+
362
+ if.end: ; preds = %entry
363
+ %start.1 = getelementptr inbounds i8 , i8* %start , i64 1
364
+ %c.0 = icmp uge i8* %start.1 , %high
365
+ call void @use (i1 %c.0 )
366
+
367
+ %start.off = getelementptr inbounds i8 , i8* %start , i64 %off
368
+ %f.0 = icmp uge i8* %start.off , %high
369
+ call void @use (i1 %f.0 )
370
+
371
+ ret void
372
+ }
373
+
374
+ ; Test which requires decomposing GEP %ptr, SHL().
375
+ define void @test.ult.gep.shl (i32* readonly %src , i32* readnone %max , i32 %idx , i32 %j ) {
376
+ ; CHECK-LABEL: @test.ult.gep.shl(
377
+ ; CHECK-NEXT: check.0.min:
378
+ ; CHECK-NEXT: [[ADD_10:%.*]] = getelementptr inbounds i32, i32* [[SRC:%.*]], i32 10
379
+ ; CHECK-NEXT: [[C_ADD_10_MAX:%.*]] = icmp ugt i32* [[ADD_10]], [[MAX:%.*]]
380
+ ; CHECK-NEXT: br i1 [[C_ADD_10_MAX]], label [[TRAP:%.*]], label [[CHECK_IDX:%.*]]
381
+ ; CHECK: trap:
382
+ ; CHECK-NEXT: ret void
383
+ ; CHECK: check.idx:
384
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[IDX:%.*]], 5
385
+ ; CHECK-NEXT: br i1 [[CMP]], label [[CHECK_MAX:%.*]], label [[TRAP]]
386
+ ; CHECK: check.max:
387
+ ; CHECK-NEXT: [[IDX_SHL_1:%.*]] = shl nuw i32 [[IDX]], 1
388
+ ; CHECK-NEXT: [[ADD_PTR_SHL_1:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i32 [[IDX_SHL_1]]
389
+ ; CHECK-NEXT: [[C_MAX_0:%.*]] = icmp ult i32* [[ADD_PTR_SHL_1]], [[MAX]]
390
+ ; CHECK-NEXT: call void @use(i1 true)
391
+ ; CHECK-NEXT: [[IDX_SHL_2:%.*]] = shl nuw i32 [[IDX]], 2
392
+ ; CHECK-NEXT: [[ADD_PTR_SHL_2:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i32 [[IDX_SHL_2]]
393
+ ; CHECK-NEXT: [[C_MAX_1:%.*]] = icmp ult i32* [[ADD_PTR_SHL_2]], [[MAX]]
394
+ ; CHECK-NEXT: call void @use(i1 [[C_MAX_1]])
395
+ ; CHECK-NEXT: [[IDX_SHL_NOT_NUW:%.*]] = shl i32 [[IDX]], 1
396
+ ; CHECK-NEXT: [[ADD_PTR_SHL_NOT_NUW:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i32 [[IDX_SHL_NOT_NUW]]
397
+ ; CHECK-NEXT: [[C_MAX_2:%.*]] = icmp ult i32* [[ADD_PTR_SHL_NOT_NUW]], [[MAX]]
398
+ ; CHECK-NEXT: call void @use(i1 [[C_MAX_2]])
399
+ ; CHECK-NEXT: [[IDX_SHL_3:%.*]] = shl nuw i32 [[IDX]], 3
400
+ ; CHECK-NEXT: [[ADD_PTR_SHL_3:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i32 [[IDX_SHL_3]]
401
+ ; CHECK-NEXT: [[C_MAX_3:%.*]] = icmp ult i32* [[ADD_PTR_SHL_3]], [[MAX]]
402
+ ; CHECK-NEXT: call void @use(i1 [[C_MAX_3]])
403
+ ; CHECK-NEXT: ret void
404
+ ;
405
+ check.0 .min:
406
+ %add.10 = getelementptr inbounds i32 , i32* %src , i32 10
407
+ %c.add.10.max = icmp ugt i32* %add.10 , %max
408
+ br i1 %c.add.10.max , label %trap , label %check.idx
409
+
410
+ trap:
411
+ ret void
412
+
413
+ check.idx: ; preds = %check.0.min
414
+ %cmp = icmp ult i32 %idx , 5
415
+ br i1 %cmp , label %check.max , label %trap
416
+
417
+ check.max: ; preds = %check.0.min
418
+ %idx.shl.1 = shl nuw i32 %idx , 1
419
+ %add.ptr.shl.1 = getelementptr inbounds i32 , i32* %src , i32 %idx.shl.1
420
+ %c.max.0 = icmp ult i32* %add.ptr.shl.1 , %max
421
+ call void @use (i1 %c.max.0 )
422
+
423
+ %idx.shl.2 = shl nuw i32 %idx , 2
424
+ %add.ptr.shl.2 = getelementptr inbounds i32 , i32* %src , i32 %idx.shl.2
425
+ %c.max.1 = icmp ult i32* %add.ptr.shl.2 , %max
426
+ call void @use (i1 %c.max.1 )
427
+
428
+ %idx.shl.not.nuw = shl i32 %idx , 1
429
+ %add.ptr.shl.not.nuw = getelementptr inbounds i32 , i32* %src , i32 %idx.shl.not.nuw
430
+ %c.max.2 = icmp ult i32* %add.ptr.shl.not.nuw , %max
431
+ call void @use (i1 %c.max.2 )
432
+
433
+ %idx.shl.3 = shl nuw i32 %idx , 3
434
+ %add.ptr.shl.3 = getelementptr inbounds i32 , i32* %src , i32 %idx.shl.3
435
+ %c.max.3 = icmp ult i32* %add.ptr.shl.3 , %max
436
+ call void @use (i1 %c.max.3 )
437
+
438
+ ret void
439
+ }
440
+
441
+ ; Test which requires decomposing GEP %ptr, ZEXT(SHL()).
442
+ define void @test.ult.gep.shl.zext (i32* readonly %src , i32* readnone %max , i32 %idx , i32 %j ) {
443
+ ; CHECK-LABEL: @test.ult.gep.shl.zext(
444
+ ; CHECK-NEXT: check.0.min:
445
+ ; CHECK-NEXT: [[ADD_10:%.*]] = getelementptr inbounds i32, i32* [[SRC:%.*]], i32 10
446
+ ; CHECK-NEXT: [[C_ADD_10_MAX:%.*]] = icmp ugt i32* [[ADD_10]], [[MAX:%.*]]
447
+ ; CHECK-NEXT: br i1 [[C_ADD_10_MAX]], label [[TRAP:%.*]], label [[CHECK_IDX:%.*]]
448
+ ; CHECK: trap:
449
+ ; CHECK-NEXT: ret void
450
+ ; CHECK: check.idx:
451
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[IDX:%.*]], 5
452
+ ; CHECK-NEXT: br i1 [[CMP]], label [[CHECK_MAX:%.*]], label [[TRAP]]
453
+ ; CHECK: check.max:
454
+ ; CHECK-NEXT: [[IDX_SHL:%.*]] = shl nuw i32 [[IDX]], 1
455
+ ; CHECK-NEXT: [[EXT_1:%.*]] = zext i32 [[IDX_SHL]] to i64
456
+ ; CHECK-NEXT: [[ADD_PTR_SHL:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 [[EXT_1]]
457
+ ; CHECK-NEXT: [[C_MAX_0:%.*]] = icmp ult i32* [[ADD_PTR_SHL]], [[MAX]]
458
+ ; CHECK-NEXT: call void @use(i1 true)
459
+ ; CHECK-NEXT: [[IDX_SHL_NOT_NUW:%.*]] = shl i32 [[IDX]], 1
460
+ ; CHECK-NEXT: [[EXT_2:%.*]] = zext i32 [[IDX_SHL_NOT_NUW]] to i64
461
+ ; CHECK-NEXT: [[ADD_PTR_SHL_NOT_NUW:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 [[EXT_2]]
462
+ ; CHECK-NEXT: [[C_MAX_1:%.*]] = icmp ult i32* [[ADD_PTR_SHL_NOT_NUW]], [[MAX]]
463
+ ; CHECK-NEXT: call void @use(i1 [[C_MAX_1]])
464
+ ; CHECK-NEXT: [[IDX_SHL_3:%.*]] = shl nuw i32 [[IDX]], 2
465
+ ; CHECK-NEXT: [[EXT_3:%.*]] = zext i32 [[IDX_SHL_3]] to i64
466
+ ; CHECK-NEXT: [[ADD_PTR_SHL_3:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 [[EXT_3]]
467
+ ; CHECK-NEXT: [[C_MAX_2:%.*]] = icmp ult i32* [[ADD_PTR_SHL_3]], [[MAX]]
468
+ ; CHECK-NEXT: call void @use(i1 [[C_MAX_2]])
469
+ ; CHECK-NEXT: ret void
470
+ ;
471
+ check.0 .min:
472
+ %add.10 = getelementptr inbounds i32 , i32* %src , i32 10
473
+ %c.add.10.max = icmp ugt i32* %add.10 , %max
474
+ br i1 %c.add.10.max , label %trap , label %check.idx
475
+
476
+ trap:
477
+ ret void
478
+
479
+ check.idx: ; preds = %check.0.min
480
+ %cmp = icmp ult i32 %idx , 5
481
+ br i1 %cmp , label %check.max , label %trap
482
+
483
+ check.max: ; preds = %check.0.min
484
+ %idx.shl = shl nuw i32 %idx , 1
485
+ %ext.1 = zext i32 %idx.shl to i64
486
+ %add.ptr.shl = getelementptr inbounds i32 , i32* %src , i64 %ext.1
487
+ %c.max.0 = icmp ult i32* %add.ptr.shl , %max
488
+ call void @use (i1 %c.max.0 )
489
+
490
+ %idx.shl.not.nuw = shl i32 %idx , 1
491
+ %ext.2 = zext i32 %idx.shl.not.nuw to i64
492
+ %add.ptr.shl.not.nuw = getelementptr inbounds i32 , i32* %src , i64 %ext.2
493
+ %c.max.1 = icmp ult i32* %add.ptr.shl.not.nuw , %max
494
+ call void @use (i1 %c.max.1 )
495
+
496
+ %idx.shl.3 = shl nuw i32 %idx , 2
497
+ %ext.3 = zext i32 %idx.shl.3 to i64
498
+ %add.ptr.shl.3 = getelementptr inbounds i32 , i32* %src , i64 %ext.3
499
+ %c.max.2 = icmp ult i32* %add.ptr.shl.3 , %max
500
+ call void @use (i1 %c.max.2 )
501
+
502
+ ret void
503
+ }
330
504
331
505
declare void @use (i1 )
332
506
declare void @llvm.trap ()
0 commit comments