Skip to content

Commit a161268

Browse files
authored
[InstCombine] Add test for freeze of GEP with recurrence offset (NFC) (#145541)
The freeze should be pushed through the GEP to the ptr like in: https://godbolt.org/z/jrcozT8rz
1 parent e9e25f0 commit a161268

File tree

1 file changed

+98
-0
lines changed

1 file changed

+98
-0
lines changed

llvm/test/Transforms/InstCombine/freeze.ll

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -877,6 +877,104 @@ exit: ; preds = %loop
877877
ret void
878878
}
879879

880+
; The recurrence for the GEP offset can't produce poison so the freeze should
881+
; be pushed through to the ptr, but this is not currently supported.
882+
define void @fold_phi_gep_phi_offset(ptr %init, ptr %end, i64 noundef %n) {
883+
; CHECK-LABEL: @fold_phi_gep_phi_offset(
884+
; CHECK-NEXT: entry:
885+
; CHECK-NEXT: br label [[LOOP:%.*]]
886+
; CHECK: loop:
887+
; CHECK-NEXT: [[I:%.*]] = phi ptr [ [[INIT:%.*]], [[ENTRY:%.*]] ], [ [[I_NEXT_FR:%.*]], [[LOOP]] ]
888+
; CHECK-NEXT: [[OFF:%.*]] = phi i64 [ [[N:%.*]], [[ENTRY]] ], [ [[OFF_NEXT:%.*]], [[LOOP]] ]
889+
; CHECK-NEXT: [[OFF_NEXT]] = shl i64 [[OFF]], 3
890+
; CHECK-NEXT: [[I_NEXT:%.*]] = getelementptr i8, ptr [[I]], i64 [[OFF_NEXT]]
891+
; CHECK-NEXT: [[I_NEXT_FR]] = freeze ptr [[I_NEXT]]
892+
; CHECK-NEXT: [[COND:%.*]] = icmp eq ptr [[I_NEXT_FR]], [[END:%.*]]
893+
; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
894+
; CHECK: exit:
895+
; CHECK-NEXT: ret void
896+
;
897+
entry:
898+
br label %loop
899+
900+
loop: ; preds = %loop, %entry
901+
%i = phi ptr [ %init, %entry ], [ %i.next.fr, %loop ]
902+
%off = phi i64 [ %n, %entry ], [ %off.next, %loop ]
903+
%off.next = shl i64 %off, 3
904+
%i.next = getelementptr i8, ptr %i, i64 %off.next
905+
%i.next.fr = freeze ptr %i.next
906+
%cond = icmp eq ptr %i.next.fr, %end
907+
br i1 %cond, label %loop, label %exit
908+
909+
exit: ; preds = %loop
910+
ret void
911+
}
912+
913+
; Offset is still guaranteed not to be poison, so the freeze could be moved
914+
; here if we strip inbounds from the GEP, but this is not currently supported.
915+
define void @fold_phi_gep_inbounds_phi_offset(ptr %init, ptr %end, i64 noundef %n) {
916+
; CHECK-LABEL: @fold_phi_gep_inbounds_phi_offset(
917+
; CHECK-NEXT: entry:
918+
; CHECK-NEXT: br label [[LOOP:%.*]]
919+
; CHECK: loop:
920+
; CHECK-NEXT: [[I:%.*]] = phi ptr [ [[INIT:%.*]], [[ENTRY:%.*]] ], [ [[I_NEXT_FR:%.*]], [[LOOP]] ]
921+
; CHECK-NEXT: [[OFF:%.*]] = phi i64 [ [[N:%.*]], [[ENTRY]] ], [ [[OFF_NEXT:%.*]], [[LOOP]] ]
922+
; CHECK-NEXT: [[OFF_NEXT]] = shl i64 [[OFF]], 3
923+
; CHECK-NEXT: [[I_NEXT:%.*]] = getelementptr inbounds i8, ptr [[I]], i64 [[OFF_NEXT]]
924+
; CHECK-NEXT: [[I_NEXT_FR]] = freeze ptr [[I_NEXT]]
925+
; CHECK-NEXT: [[COND:%.*]] = icmp eq ptr [[I_NEXT_FR]], [[END:%.*]]
926+
; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
927+
; CHECK: exit:
928+
; CHECK-NEXT: ret void
929+
;
930+
entry:
931+
br label %loop
932+
933+
loop: ; preds = %loop, %entry
934+
%i = phi ptr [ %init, %entry ], [ %i.next.fr, %loop ]
935+
%off = phi i64 [ %n, %entry ], [ %off.next, %loop ]
936+
%off.next = shl i64 %off, 3
937+
%i.next = getelementptr inbounds i8, ptr %i, i64 %off.next
938+
%i.next.fr = freeze ptr %i.next
939+
%cond = icmp eq ptr %i.next.fr, %end
940+
br i1 %cond, label %loop, label %exit
941+
942+
exit: ; preds = %loop
943+
ret void
944+
}
945+
946+
; GEP can produce poison, check freeze isn't moved.
947+
define void @cant_fold_phi_gep_phi_offset(ptr %init, ptr %end, i64 %n) {
948+
; CHECK-LABEL: @cant_fold_phi_gep_phi_offset(
949+
; CHECK-NEXT: entry:
950+
; CHECK-NEXT: br label [[LOOP:%.*]]
951+
; CHECK: loop:
952+
; CHECK-NEXT: [[I:%.*]] = phi ptr [ [[INIT:%.*]], [[ENTRY:%.*]] ], [ [[I_NEXT_FR:%.*]], [[LOOP]] ]
953+
; CHECK-NEXT: [[OFF:%.*]] = phi i64 [ [[N:%.*]], [[ENTRY]] ], [ [[OFF_NEXT:%.*]], [[LOOP]] ]
954+
; CHECK-NEXT: [[OFF_NEXT]] = shl i64 [[OFF]], 3
955+
; CHECK-NEXT: [[I_NEXT:%.*]] = getelementptr inbounds i8, ptr [[I]], i64 [[OFF_NEXT]]
956+
; CHECK-NEXT: [[I_NEXT_FR]] = freeze ptr [[I_NEXT]]
957+
; CHECK-NEXT: [[COND:%.*]] = icmp eq ptr [[I_NEXT_FR]], [[END:%.*]]
958+
; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
959+
; CHECK: exit:
960+
; CHECK-NEXT: ret void
961+
;
962+
entry:
963+
br label %loop
964+
965+
loop: ; preds = %loop, %entry
966+
%i = phi ptr [ %init, %entry ], [ %i.next.fr, %loop ]
967+
%off = phi i64 [ %n, %entry ], [ %off.next, %loop ]
968+
%off.next = shl i64 %off, 3
969+
%i.next = getelementptr inbounds i8, ptr %i, i64 %off.next
970+
%i.next.fr = freeze ptr %i.next
971+
%cond = icmp eq ptr %i.next.fr, %end
972+
br i1 %cond, label %loop, label %exit
973+
974+
exit: ; preds = %loop
975+
ret void
976+
}
977+
880978
define void @fold_phi_multiple_insts(i32 %init, i32 %n) {
881979
; CHECK-LABEL: @fold_phi_multiple_insts(
882980
; CHECK-NEXT: entry:

0 commit comments

Comments
 (0)