Skip to content

Commit 56659c8

Browse files
committed
[GVN] Add additional tests for PRE with pointer selects.
Additional tests for D118143.
1 parent db49a78 commit 56659c8

File tree

1 file changed

+176
-7
lines changed

1 file changed

+176
-7
lines changed

llvm/test/Transforms/GVN/PRE/pre-loop-load-through-select.ll

Lines changed: 176 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -366,19 +366,106 @@ exit:
366366
ret i32 %res
367367
}
368368

369-
define i32 @test_pointer_phi_select_same_object_store(i32* %ptr, i32* %end) {
370-
; CHECK-LABEL: @test_pointer_phi_select_same_object_store(
369+
define i32 @test_pointer_phi_select_same_object_store_1(i32* %ptr, i32* %end) {
370+
; CHECK-LABEL: @test_pointer_phi_select_same_object_store_1(
371371
; CHECK-NEXT: entry:
372372
; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, i32* [[PTR:%.*]], i64 1
373373
; CHECK-NEXT: br label [[LOOP:%.*]]
374374
; CHECK: loop:
375375
; CHECK-NEXT: [[PTR_IV:%.*]] = phi i32* [ [[START_PTR]], [[ENTRY:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ]
376-
; CHECK-NEXT: store i32 0, i32* [[PTR]], align 4
376+
; CHECK-NEXT: [[MIN_PTR:%.*]] = phi i32* [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ]
377+
; CHECK-NEXT: store i32 3, i32* [[MIN_PTR]], align 4
378+
; CHECK-NEXT: [[L_1:%.*]] = load i32, i32* [[PTR_IV]], align 4
379+
; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], 3
380+
; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], i32* [[PTR_IV]], i32* [[MIN_PTR]]
381+
; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, i32* [[PTR_IV]], i64 1
382+
; CHECK-NEXT: [[EC:%.*]] = icmp eq i32* [[PTR_IV_NEXT]], [[END:%.*]]
383+
; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]
384+
; CHECK: exit:
385+
; CHECK-NEXT: [[RES:%.*]] = load i32, i32* [[MIN_SELECT]], align 4
386+
; CHECK-NEXT: ret i32 [[RES]]
387+
;
388+
entry:
389+
%start.ptr = getelementptr inbounds i32, i32* %ptr, i64 1
390+
br label %loop
391+
392+
loop:
393+
%ptr.iv = phi i32* [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ]
394+
%min.ptr = phi i32* [ %ptr, %entry ], [ %min.select, %loop ]
395+
store i32 3, i32* %min.ptr
396+
%l.1 = load i32, i32* %ptr.iv, align 4
397+
%l.2 = load i32, i32* %min.ptr, align 4
398+
%cmp.i.i.i = icmp ult i32 %l.1, %l.2
399+
%min.select = select i1 %cmp.i.i.i, i32* %ptr.iv, i32* %min.ptr
400+
%ptr.iv.next = getelementptr inbounds i32, i32* %ptr.iv, i64 1
401+
%ec = icmp eq i32* %ptr.iv.next, %end
402+
br i1 %ec, label %exit, label %loop
403+
404+
exit:
405+
%res = load i32, i32* %min.select, align 4
406+
ret i32 %res
407+
}
408+
409+
define i32 @test_pointer_phi_select_same_object_store_2(i32* %ptr, i32* %end) {
410+
; CHECK-LABEL: @test_pointer_phi_select_same_object_store_2(
411+
; CHECK-NEXT: entry:
412+
; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, i32* [[PTR:%.*]], i64 1
413+
; CHECK-NEXT: br label [[LOOP:%.*]]
414+
; CHECK: loop:
415+
; CHECK-NEXT: [[PTR_IV:%.*]] = phi i32* [ [[START_PTR]], [[ENTRY:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ]
416+
; CHECK-NEXT: [[MIN_PTR:%.*]] = phi i32* [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ]
417+
; CHECK-NEXT: [[L_1:%.*]] = load i32, i32* [[PTR_IV]], align 4
418+
; CHECK-NEXT: [[L_2:%.*]] = load i32, i32* [[MIN_PTR]], align 4
419+
; CHECK-NEXT: store i32 3, i32* [[MIN_PTR]], align 4
420+
; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
421+
; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], i32* [[PTR_IV]], i32* [[MIN_PTR]]
377422
; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, i32* [[PTR_IV]], i64 1
378423
; CHECK-NEXT: [[EC:%.*]] = icmp eq i32* [[PTR_IV_NEXT]], [[END:%.*]]
379424
; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]
380425
; CHECK: exit:
381-
; CHECK-NEXT: ret i32 0
426+
; CHECK-NEXT: [[RES:%.*]] = load i32, i32* [[MIN_SELECT]], align 4
427+
; CHECK-NEXT: ret i32 [[RES]]
428+
;
429+
entry:
430+
%start.ptr = getelementptr inbounds i32, i32* %ptr, i64 1
431+
br label %loop
432+
433+
loop:
434+
%ptr.iv = phi i32* [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ]
435+
%min.ptr = phi i32* [ %ptr, %entry ], [ %min.select, %loop ]
436+
%l.1 = load i32, i32* %ptr.iv, align 4
437+
%l.2 = load i32, i32* %min.ptr, align 4
438+
store i32 3, i32* %min.ptr
439+
%cmp.i.i.i = icmp ult i32 %l.1, %l.2
440+
%min.select = select i1 %cmp.i.i.i, i32* %ptr.iv, i32* %min.ptr
441+
%ptr.iv.next = getelementptr inbounds i32, i32* %ptr.iv, i64 1
442+
%ec = icmp eq i32* %ptr.iv.next, %end
443+
br i1 %ec, label %exit, label %loop
444+
445+
exit:
446+
%res = load i32, i32* %min.select, align 4
447+
ret i32 %res
448+
}
449+
450+
define i32 @test_pointer_phi_select_same_object_store_3(i32* %ptr, i32* %end) {
451+
; CHECK-LABEL: @test_pointer_phi_select_same_object_store_3(
452+
; CHECK-NEXT: entry:
453+
; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, i32* [[PTR:%.*]], i64 1
454+
; CHECK-NEXT: br label [[LOOP:%.*]]
455+
; CHECK: loop:
456+
; CHECK-NEXT: [[PTR_IV:%.*]] = phi i32* [ [[START_PTR]], [[ENTRY:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ]
457+
; CHECK-NEXT: [[MIN_PTR:%.*]] = phi i32* [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ]
458+
; CHECK-NEXT: [[L_1:%.*]] = load i32, i32* [[PTR_IV]], align 4
459+
; CHECK-NEXT: [[L_2:%.*]] = load i32, i32* [[MIN_PTR]], align 4
460+
; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
461+
; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], i32* [[PTR_IV]], i32* [[MIN_PTR]]
462+
; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, i32* [[PTR_IV]], i64 1
463+
; CHECK-NEXT: store i32 3, i32* [[MIN_PTR]], align 4
464+
; CHECK-NEXT: [[EC:%.*]] = icmp eq i32* [[PTR_IV_NEXT]], [[END:%.*]]
465+
; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]
466+
; CHECK: exit:
467+
; CHECK-NEXT: [[RES:%.*]] = load i32, i32* [[MIN_SELECT]], align 4
468+
; CHECK-NEXT: ret i32 [[RES]]
382469
;
383470
entry:
384471
%start.ptr = getelementptr inbounds i32, i32* %ptr, i64 1
@@ -387,12 +474,12 @@ entry:
387474
loop:
388475
%ptr.iv = phi i32* [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ]
389476
%min.ptr = phi i32* [ %ptr, %entry ], [ %min.select, %loop ]
390-
store i32 0, i32* %min.ptr
391477
%l.1 = load i32, i32* %ptr.iv, align 4
392478
%l.2 = load i32, i32* %min.ptr, align 4
393479
%cmp.i.i.i = icmp ult i32 %l.1, %l.2
394480
%min.select = select i1 %cmp.i.i.i, i32* %ptr.iv, i32* %min.ptr
395481
%ptr.iv.next = getelementptr inbounds i32, i32* %ptr.iv, i64 1
482+
store i32 3, i32* %min.ptr
396483
%ec = icmp eq i32* %ptr.iv.next, %end
397484
br i1 %ec, label %exit, label %loop
398485

@@ -403,8 +490,49 @@ exit:
403490

404491
declare void @may_write()
405492

406-
define i32 @test_pointer_phi_select_same_object_may_write_call(i32* %ptr, i32* %end) {
407-
; CHECK-LABEL: @test_pointer_phi_select_same_object_may_write_call(
493+
define i32 @test_pointer_phi_select_same_object_may_write_call_1(i32* %ptr, i32* %end) {
494+
; CHECK-LABEL: @test_pointer_phi_select_same_object_may_write_call_1(
495+
; CHECK-NEXT: entry:
496+
; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, i32* [[PTR:%.*]], i64 1
497+
; CHECK-NEXT: br label [[LOOP:%.*]]
498+
; CHECK: loop:
499+
; CHECK-NEXT: [[PTR_IV:%.*]] = phi i32* [ [[START_PTR]], [[ENTRY:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ]
500+
; CHECK-NEXT: [[MIN_PTR:%.*]] = phi i32* [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ]
501+
; CHECK-NEXT: call void @may_write()
502+
; CHECK-NEXT: [[L_1:%.*]] = load i32, i32* [[PTR_IV]], align 4
503+
; CHECK-NEXT: [[L_2:%.*]] = load i32, i32* [[MIN_PTR]], align 4
504+
; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
505+
; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], i32* [[PTR_IV]], i32* [[MIN_PTR]]
506+
; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, i32* [[PTR_IV]], i64 1
507+
; CHECK-NEXT: [[EC:%.*]] = icmp eq i32* [[PTR_IV_NEXT]], [[END:%.*]]
508+
; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]
509+
; CHECK: exit:
510+
; CHECK-NEXT: [[RES:%.*]] = load i32, i32* [[MIN_SELECT]], align 4
511+
; CHECK-NEXT: ret i32 [[RES]]
512+
;
513+
entry:
514+
%start.ptr = getelementptr inbounds i32, i32* %ptr, i64 1
515+
br label %loop
516+
517+
loop:
518+
%ptr.iv = phi i32* [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ]
519+
%min.ptr = phi i32* [ %ptr, %entry ], [ %min.select, %loop ]
520+
call void @may_write()
521+
%l.1 = load i32, i32* %ptr.iv, align 4
522+
%l.2 = load i32, i32* %min.ptr, align 4
523+
%cmp.i.i.i = icmp ult i32 %l.1, %l.2
524+
%min.select = select i1 %cmp.i.i.i, i32* %ptr.iv, i32* %min.ptr
525+
%ptr.iv.next = getelementptr inbounds i32, i32* %ptr.iv, i64 1
526+
%ec = icmp eq i32* %ptr.iv.next, %end
527+
br i1 %ec, label %exit, label %loop
528+
529+
exit:
530+
%res = load i32, i32* %min.select, align 4
531+
ret i32 %res
532+
}
533+
534+
define i32 @test_pointer_phi_select_same_object_may_write_call_2(i32* %ptr, i32* %end) {
535+
; CHECK-LABEL: @test_pointer_phi_select_same_object_may_write_call_2(
408536
; CHECK-NEXT: entry:
409537
; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, i32* [[PTR:%.*]], i64 1
410538
; CHECK-NEXT: br label [[LOOP:%.*]]
@@ -444,6 +572,47 @@ exit:
444572
ret i32 %res
445573
}
446574

575+
define i32 @test_pointer_phi_select_same_object_may_write_call_3(i32* %ptr, i32* %end) {
576+
; CHECK-LABEL: @test_pointer_phi_select_same_object_may_write_call_3(
577+
; CHECK-NEXT: entry:
578+
; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, i32* [[PTR:%.*]], i64 1
579+
; CHECK-NEXT: br label [[LOOP:%.*]]
580+
; CHECK: loop:
581+
; CHECK-NEXT: [[PTR_IV:%.*]] = phi i32* [ [[START_PTR]], [[ENTRY:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ]
582+
; CHECK-NEXT: [[MIN_PTR:%.*]] = phi i32* [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ]
583+
; CHECK-NEXT: [[L_1:%.*]] = load i32, i32* [[PTR_IV]], align 4
584+
; CHECK-NEXT: [[L_2:%.*]] = load i32, i32* [[MIN_PTR]], align 4
585+
; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
586+
; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], i32* [[PTR_IV]], i32* [[MIN_PTR]]
587+
; CHECK-NEXT: call void @may_write()
588+
; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, i32* [[PTR_IV]], i64 1
589+
; CHECK-NEXT: [[EC:%.*]] = icmp eq i32* [[PTR_IV_NEXT]], [[END:%.*]]
590+
; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]
591+
; CHECK: exit:
592+
; CHECK-NEXT: [[RES:%.*]] = load i32, i32* [[MIN_SELECT]], align 4
593+
; CHECK-NEXT: ret i32 [[RES]]
594+
;
595+
entry:
596+
%start.ptr = getelementptr inbounds i32, i32* %ptr, i64 1
597+
br label %loop
598+
599+
loop:
600+
%ptr.iv = phi i32* [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ]
601+
%min.ptr = phi i32* [ %ptr, %entry ], [ %min.select, %loop ]
602+
%l.1 = load i32, i32* %ptr.iv, align 4
603+
%l.2 = load i32, i32* %min.ptr, align 4
604+
%cmp.i.i.i = icmp ult i32 %l.1, %l.2
605+
%min.select = select i1 %cmp.i.i.i, i32* %ptr.iv, i32* %min.ptr
606+
call void @may_write()
607+
%ptr.iv.next = getelementptr inbounds i32, i32* %ptr.iv, i64 1
608+
%ec = icmp eq i32* %ptr.iv.next, %end
609+
br i1 %ec, label %exit, label %loop
610+
611+
exit:
612+
%res = load i32, i32* %min.select, align 4
613+
ret i32 %res
614+
}
615+
447616
define i32 @test_pointer_phi_select_same_object_header_exit(i32* %ptr, i32* %end) {
448617
; CHECK-LABEL: @test_pointer_phi_select_same_object_header_exit(
449618
; CHECK-NEXT: entry:

0 commit comments

Comments
 (0)