@@ -877,6 +877,104 @@ exit: ; preds = %loop
877
877
ret void
878
878
}
879
879
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
+
880
978
define void @fold_phi_multiple_insts (i32 %init , i32 %n ) {
881
979
; CHECK-LABEL: @fold_phi_multiple_insts(
882
980
; CHECK-NEXT: entry:
0 commit comments