@@ -910,6 +910,39 @@ exit: ; preds = %loop
910910 ret void
911911}
912912
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+
913946; GEP can produce poison, check freeze isn't moved.
914947define void @cant_fold_phi_gep_phi_offset (ptr %init , ptr %end , i64 %n ) {
915948; CHECK-LABEL: @cant_fold_phi_gep_phi_offset(
0 commit comments