@@ -371,3 +371,186 @@ define i1 @pr93017(i64 %idx) {
371
371
%cmp = icmp ne ptr %v , null
372
372
ret i1 %cmp
373
373
}
374
+
375
+ @g_i32_lo = internal constant [4 x i32 ] [i32 1 , i32 2 , i32 3 , i32 4 ]
376
+
377
+ ; Mask is 0b10101010
378
+ define i1 @load_vs_array_type_mismatch1 (i32 %idx ) {
379
+ ; CHECK-LABEL: @load_vs_array_type_mismatch1(
380
+ ; CHECK-NEXT: [[TMP2:%.*]] = shl nuw i32 1, [[TMP1:%.*]]
381
+ ; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], 170
382
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP3]], 0
383
+ ; CHECK-NEXT: ret i1 [[CMP]]
384
+ ;
385
+ %gep = getelementptr inbounds i16 , ptr @g_i32_lo , i32 %idx
386
+ %load = load i16 , ptr %gep
387
+ %cmp = icmp eq i16 %load , 0
388
+ ret i1 %cmp
389
+ }
390
+
391
+ @g_i32_hi = internal constant [4 x i32 ] [i32 u0x00010000, i32 u0x00020000, i32 u0x00030000, i32 u0x00040000]
392
+
393
+ ; Mask is 0b01010101
394
+ define i1 @load_vs_array_type_mismatch2 (i32 %idx ) {
395
+ ; CHECK-LABEL: @load_vs_array_type_mismatch2(
396
+ ; CHECK-NEXT: [[TMP2:%.*]] = shl nuw i32 1, [[TMP1:%.*]]
397
+ ; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], 85
398
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP3]], 0
399
+ ; CHECK-NEXT: ret i1 [[CMP]]
400
+ ;
401
+ %gep = getelementptr inbounds i16 , ptr @g_i32_hi , i32 %idx
402
+ %load = load i16 , ptr %gep
403
+ %cmp = icmp eq i16 %load , 0
404
+ ret i1 %cmp
405
+ }
406
+
407
+ @g_i16_1 = internal constant [8 x i16 ] [i16 0 , i16 1 , i16 1 , i16 0 , i16 0 , i16 1 , i16 1 , i16 0 ]
408
+
409
+ ; idx == 1 || idx == 3
410
+ define i1 @load_vs_array_type_mismatch_offset1 (i32 %idx ) {
411
+ ; CHECK-LABEL: @load_vs_array_type_mismatch_offset1(
412
+ ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[IDX:%.*]], -3
413
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 1
414
+ ; CHECK-NEXT: ret i1 [[CMP]]
415
+ ;
416
+ %gep = getelementptr inbounds {i16 , i16 }, ptr @g_i16_1 , i32 %idx , i32 1
417
+ %load = load i16 , ptr %gep
418
+ %cmp = icmp eq i16 %load , 0
419
+ ret i1 %cmp
420
+ }
421
+
422
+ @g_i16_2 = internal constant [8 x i16 ] [i16 1 , i16 0 , i16 0 , i16 1 , i16 1 , i16 0 , i16 0 , i16 1 ]
423
+
424
+ ; idx == 0 || idx == 2
425
+ define i1 @load_vs_array_type_mismatch_offset2 (i32 %idx ) {
426
+ ; CHECK-LABEL: @load_vs_array_type_mismatch_offset2(
427
+ ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[IDX:%.*]], -3
428
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
429
+ ; CHECK-NEXT: ret i1 [[CMP]]
430
+ ;
431
+ %gep = getelementptr inbounds {i16 , i16 }, ptr @g_i16_2 , i32 %idx , i32 1
432
+ %load = load i16 , ptr %gep
433
+ %cmp = icmp eq i16 %load , 0
434
+ ret i1 %cmp
435
+ }
436
+
437
+ define i1 @offset_larger_than_stride (i32 %idx ) {
438
+ ; CHECK-LABEL: @offset_larger_than_stride(
439
+ ; CHECK-NEXT: [[GEP:%.*]] = getelementptr [2 x i16], ptr @g_i16_1, i32 1, i32 [[TMP1:%.*]]
440
+ ; CHECK-NEXT: [[LOAD:%.*]] = load i16, ptr [[GEP]], align 2
441
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[LOAD]], 0
442
+ ; CHECK-NEXT: ret i1 [[CMP]]
443
+ ;
444
+ %gep = getelementptr [2 x i16 ], ptr @g_i16_1 , i64 1 , i32 %idx
445
+ %load = load i16 , ptr %gep
446
+ %cmp = icmp eq i16 %load , 0
447
+ ret i1 %cmp
448
+ }
449
+
450
+ define i1 @load_size_larger_stride (i32 %idx ) {
451
+ ; CHECK-LABEL: @load_size_larger_stride(
452
+ ; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr @g_i16_1, i32 [[IDX:%.*]]
453
+ ; CHECK-NEXT: [[LOAD:%.*]] = load i16, ptr [[GEP]], align 2
454
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[LOAD]], 0
455
+ ; CHECK-NEXT: ret i1 [[CMP]]
456
+ ;
457
+ %gep = getelementptr i8 , ptr @g_i16_1 , i32 %idx
458
+ %load = load i16 , ptr %gep
459
+ %cmp = icmp eq i16 %load , 0
460
+ ret i1 %cmp
461
+ }
462
+
463
+ @CG_MESSY = constant [9 x i32 ] [i32 1 , i32 7 , i32 -1 , i32 5 , i32 4 , i32 1 , i32 1 , i32 5 , i32 4 ]
464
+
465
+ define i1 @cmp_load_constant_array_messy (i32 %x ){
466
+ ; CHECK-LABEL: @cmp_load_constant_array_messy(
467
+ ; CHECK-NEXT: entry:
468
+ ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[TMP0:%.*]], 1073741823
469
+ ; CHECK-NEXT: [[TMP2:%.*]] = shl nuw i32 1, [[TMP1]]
470
+ ; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], 373
471
+ ; CHECK-NEXT: [[COND:%.*]] = icmp ne i32 [[TMP3]], 0
472
+ ; CHECK-NEXT: ret i1 [[COND]]
473
+ ;
474
+
475
+ entry:
476
+ %isOK_ptr = getelementptr i32 , ptr @CG_MESSY , i32 %x
477
+ %isOK = load i32 , ptr %isOK_ptr
478
+ %cond = icmp slt i32 %isOK , 5
479
+ ret i1 %cond
480
+ }
481
+
482
+ define i1 @cmp_diff_load_constant_array_messy0 (i32 %x ){
483
+ ; CHECK-LABEL: @cmp_diff_load_constant_array_messy0(
484
+ ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1:%.*]], 1073741823
485
+ ; CHECK-NEXT: [[TMP3:%.*]] = shl nuw i32 1, [[TMP2]]
486
+ ; CHECK-NEXT: [[TMP4:%.*]] = and i32 [[TMP3]], 373
487
+ ; CHECK-NEXT: [[COND:%.*]] = icmp ne i32 [[TMP4]], 0
488
+ ; CHECK-NEXT: ret i1 [[COND]]
489
+ ;
490
+ %isOK_ptr = getelementptr i32 , ptr @CG_MESSY , i32 %x
491
+ %isOK = load i16 , ptr %isOK_ptr
492
+ %cond = icmp slt i16 %isOK , 5
493
+ ret i1 %cond
494
+ }
495
+
496
+ ; Load size larger than store size currently not supported.
497
+ define i1 @cmp_diff_load_constant_array_messy1 (i32 %x ){
498
+ ; CHECK-LABEL: @cmp_diff_load_constant_array_messy1(
499
+ ; CHECK-NEXT: [[ISOK_PTR:%.*]] = getelementptr i6, ptr @CG_MESSY, i32 [[TMP1:%.*]]
500
+ ; CHECK-NEXT: [[ISOK:%.*]] = load i16, ptr [[ISOK_PTR]], align 2
501
+ ; CHECK-NEXT: [[COND:%.*]] = icmp slt i16 [[ISOK]], 5
502
+ ; CHECK-NEXT: ret i1 [[COND]]
503
+ ;
504
+ %isOK_ptr = getelementptr i6 , ptr @CG_MESSY , i32 %x
505
+ %isOK = load i16 , ptr %isOK_ptr
506
+ %cond = icmp slt i16 %isOK , 5
507
+ ret i1 %cond
508
+ }
509
+
510
+ define i1 @cmp_load_constant_array_variable_icmp (i32 %x , i32 %y ) {
511
+ ; CHECK-LABEL: @cmp_load_constant_array_variable_icmp(
512
+ ; CHECK-NEXT: entry:
513
+ ; CHECK-NEXT: [[ISOK_PTR:%.*]] = getelementptr inbounds i32, ptr @CG_MESSY, i32 [[X:%.*]]
514
+ ; CHECK-NEXT: [[ISOK:%.*]] = load i32, ptr [[ISOK_PTR]], align 4
515
+ ; CHECK-NEXT: [[COND:%.*]] = icmp ult i32 [[ISOK]], [[Y:%.*]]
516
+ ; CHECK-NEXT: ret i1 [[COND]]
517
+ ;
518
+ entry:
519
+ %isOK_ptr = getelementptr inbounds i32 , ptr @CG_MESSY , i32 %x
520
+ %isOK = load i32 , ptr %isOK_ptr
521
+ %cond = icmp ult i32 %isOK , %y
522
+ ret i1 %cond
523
+ }
524
+
525
+ @CG_CLEAR = constant [10 x i32 ] [i32 0 , i32 1 , i32 2 , i32 3 , i32 4 , i32 5 , i32 6 , i32 7 , i32 8 , i32 9 ]
526
+
527
+ ; Offsets not supported if negative or larger than stride.
528
+ define i1 @cmp_load_constant_additional_positive_offset (i32 %x ) {
529
+ ; CHECK-LABEL: @cmp_load_constant_additional_positive_offset(
530
+ ; CHECK-NEXT: entry:
531
+ ; CHECK-NEXT: [[ISOK_PTR:%.*]] = getelementptr inbounds [1 x i32], ptr @CG_CLEAR, i32 5, i32 [[X:%.*]]
532
+ ; CHECK-NEXT: [[ISOK:%.*]] = load i32, ptr [[ISOK_PTR]], align 4
533
+ ; CHECK-NEXT: [[COND:%.*]] = icmp ult i32 [[ISOK]], 5
534
+ ; CHECK-NEXT: ret i1 [[COND]]
535
+ ;
536
+ entry:
537
+ %isOK_ptr = getelementptr inbounds [1 x i32 ], ptr @CG_CLEAR , i32 5 , i32 %x
538
+ %isOK = load i32 , ptr %isOK_ptr
539
+ %cond = icmp ult i32 %isOK , 5
540
+ ret i1 %cond
541
+ }
542
+
543
+ define i1 @cmp_load_constant_additional_negative_offset (i32 %x ) {
544
+ ; CHECK-LABEL: @cmp_load_constant_additional_negative_offset(
545
+ ; CHECK-NEXT: entry:
546
+ ; CHECK-NEXT: [[ISOK_PTR:%.*]] = getelementptr inbounds [1 x i32], ptr @CG_CLEAR, i32 [[X:%.*]], i32 -5
547
+ ; CHECK-NEXT: [[ISOK:%.*]] = load i32, ptr [[ISOK_PTR]], align 4
548
+ ; CHECK-NEXT: [[COND:%.*]] = icmp ult i32 [[ISOK]], 5
549
+ ; CHECK-NEXT: ret i1 [[COND]]
550
+ ;
551
+ entry:
552
+ %isOK_ptr = getelementptr inbounds [1 x i32 ], ptr @CG_CLEAR , i32 %x , i32 -5
553
+ %isOK = load i32 , ptr %isOK_ptr
554
+ %cond = icmp ult i32 %isOK , 5
555
+ ret i1 %cond
556
+ }
0 commit comments