@@ -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+
880978define void @fold_phi_multiple_insts (i32 %init , i32 %n ) {
881979; CHECK-LABEL: @fold_phi_multiple_insts(
882980; CHECK-NEXT: entry:
0 commit comments