@@ -633,6 +633,66 @@ loop.end:
633633 ret i64 %retval
634634}
635635
636+ ; Test with an invoke terminator between the block containing the assume and loop.
637+ ; This should NOT vectorize because the invoke could free memory.
638+ define i64 @early_exit_alignment_and_deref_known_via_assumption_with_constant_size_invoke_may_free (ptr noalias %p1 , ptr noalias %p2 ) nosync personality ptr @__gxx_personality_v0 {
639+ ; CHECK-LABEL: define i64 @early_exit_alignment_and_deref_known_via_assumption_with_constant_size_invoke_may_free(
640+ ; CHECK-SAME: ptr noalias [[P1:%.*]], ptr noalias [[P2:%.*]]) #[[ATTR1]] personality ptr @__gxx_personality_v0 {
641+ ; CHECK-NEXT: [[ENTRY:.*:]]
642+ ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P1]], i64 4), "dereferenceable"(ptr [[P1]], i64 1024) ]
643+ ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P2]], i64 4), "dereferenceable"(ptr [[P2]], i64 1024) ]
644+ ; CHECK-NEXT: invoke void @may_free()
645+ ; CHECK-NEXT: to label %[[LOOP_PREHEADER:.*]] unwind label %[[LPAD:.*]]
646+ ; CHECK: [[LOOP_PREHEADER]]:
647+ ; CHECK-NEXT: br label %[[LOOP:.*]]
648+ ; CHECK: [[LOOP]]:
649+ ; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], %[[LOOP_INC:.*]] ], [ 0, %[[LOOP_PREHEADER]] ]
650+ ; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX1]]
651+ ; CHECK-NEXT: [[LD1:%.*]] = load i8, ptr [[TMP0]], align 1
652+ ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[INDEX1]]
653+ ; CHECK-NEXT: [[LD2:%.*]] = load i8, ptr [[TMP1]], align 1
654+ ; CHECK-NEXT: [[CMP3:%.*]] = icmp eq i8 [[LD1]], [[LD2]]
655+ ; CHECK-NEXT: br i1 [[CMP3]], label %[[LOOP_INC]], label %[[LOOP_END:.*]]
656+ ; CHECK: [[LOOP_INC]]:
657+ ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX1]], 1
658+ ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 1024
659+ ; CHECK-NEXT: br i1 [[EXITCOND]], label %[[LOOP]], label %[[LOOP_END]]
660+ ; CHECK: [[LOOP_END]]:
661+ ; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX1]], %[[LOOP]] ], [ -1, %[[LOOP_INC]] ]
662+ ; CHECK-NEXT: ret i64 [[RETVAL]]
663+ ; CHECK: [[LPAD]]:
664+ ; CHECK-NEXT: [[LP:%.*]] = landingpad { ptr, i32 }
665+ ; CHECK-NEXT: cleanup
666+ ; CHECK-NEXT: resume { ptr, i32 } [[LP]]
667+ ;
668+ entry:
669+ call void @llvm.assume (i1 true ) [ "align" (ptr %p1 , i64 4 ), "dereferenceable" (ptr %p1 , i64 1024 ) ]
670+ call void @llvm.assume (i1 true ) [ "align" (ptr %p2 , i64 4 ), "dereferenceable" (ptr %p2 , i64 1024 ) ]
671+ invoke void @may_free () to label %loop unwind label %lpad
672+
673+ loop:
674+ %index = phi i64 [ %index.next , %loop.inc ], [ 0 , %entry ]
675+ %arrayidx = getelementptr inbounds i8 , ptr %p1 , i64 %index
676+ %ld1 = load i8 , ptr %arrayidx , align 1
677+ %arrayidx1 = getelementptr inbounds i8 , ptr %p2 , i64 %index
678+ %ld2 = load i8 , ptr %arrayidx1 , align 1
679+ %cmp3 = icmp eq i8 %ld1 , %ld2
680+ br i1 %cmp3 , label %loop.inc , label %loop.end
681+
682+ loop.inc:
683+ %index.next = add i64 %index , 1
684+ %exitcond = icmp ne i64 %index.next , 1024
685+ br i1 %exitcond , label %loop , label %loop.end
686+
687+ loop.end:
688+ %retval = phi i64 [ %index , %loop ], [ -1 , %loop.inc ]
689+ ret i64 %retval
690+
691+ lpad:
692+ %lp = landingpad { ptr , i32 } cleanup
693+ resume { ptr , i32 } %lp
694+ }
695+
636696define i64 @find_if_pointer_distance_deref_via_assumption (ptr %vec ) nofree nosync {
637697; CHECK-LABEL: define i64 @find_if_pointer_distance_deref_via_assumption(
638698; CHECK-SAME: ptr [[VEC:%.*]]) #[[ATTR0]] {
@@ -650,18 +710,55 @@ define i64 @find_if_pointer_distance_deref_via_assumption(ptr %vec) nofree nosyn
650710; CHECK-NEXT: br i1 [[IS_EMPTY]], label %[[EXIT:.*]], label %[[LOOP_PREHEADER:.*]]
651711; CHECK: [[LOOP_PREHEADER]]:
652712; CHECK-NEXT: [[END_PTR:%.*]] = getelementptr i8, ptr [[BEGIN]], i64 [[DISTANCE]]
713+ ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[END_INT]], -2
714+ ; CHECK-NEXT: [[TMP1:%.*]] = sub i64 [[TMP0]], [[BEGIN_INT]]
715+ ; CHECK-NEXT: [[TMP2:%.*]] = lshr i64 [[TMP1]], 1
716+ ; CHECK-NEXT: [[TMP3:%.*]] = add nuw i64 [[TMP2]], 1
717+ ; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP3]], 4
718+ ; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
719+ ; CHECK: [[VECTOR_PH]]:
720+ ; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP3]], 4
721+ ; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP3]], [[N_MOD_VF]]
722+ ; CHECK-NEXT: [[TMP4:%.*]] = mul i64 [[N_VEC]], 2
723+ ; CHECK-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[BEGIN]], i64 [[TMP4]]
724+ ; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
725+ ; CHECK: [[VECTOR_BODY]]:
726+ ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
727+ ; CHECK-NEXT: [[OFFSET_IDX:%.*]] = mul i64 [[INDEX]], 2
728+ ; CHECK-NEXT: [[NEXT_GEP:%.*]] = getelementptr i8, ptr [[BEGIN]], i64 [[OFFSET_IDX]]
729+ ; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i16>, ptr [[NEXT_GEP]], align 2
730+ ; CHECK-NEXT: [[TMP6:%.*]] = icmp eq <4 x i16> [[WIDE_LOAD]], splat (i16 1)
731+ ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
732+ ; CHECK-NEXT: [[TMP7:%.*]] = freeze <4 x i1> [[TMP6]]
733+ ; CHECK-NEXT: [[TMP8:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP7]])
734+ ; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
735+ ; CHECK-NEXT: [[TMP10:%.*]] = or i1 [[TMP8]], [[TMP9]]
736+ ; CHECK-NEXT: br i1 [[TMP10]], label %[[MIDDLE_SPLIT:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP12:![0-9]+]]
737+ ; CHECK: [[MIDDLE_SPLIT]]:
738+ ; CHECK-NEXT: br i1 [[TMP8]], label %[[VECTOR_EARLY_EXIT:.*]], label %[[MIDDLE_BLOCK:.*]]
739+ ; CHECK: [[MIDDLE_BLOCK]]:
740+ ; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[TMP3]], [[N_VEC]]
741+ ; CHECK-NEXT: br i1 [[CMP_N]], label %[[EXIT_LOOPEXIT:.*]], label %[[SCALAR_PH]]
742+ ; CHECK: [[VECTOR_EARLY_EXIT]]:
743+ ; CHECK-NEXT: [[TMP11:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP6]], i1 true)
744+ ; CHECK-NEXT: [[TMP12:%.*]] = add i64 [[INDEX]], [[TMP11]]
745+ ; CHECK-NEXT: [[TMP13:%.*]] = mul i64 [[TMP12]], 2
746+ ; CHECK-NEXT: [[TMP14:%.*]] = getelementptr i8, ptr [[BEGIN]], i64 [[TMP13]]
747+ ; CHECK-NEXT: br label %[[EXIT_LOOPEXIT]]
748+ ; CHECK: [[SCALAR_PH]]:
749+ ; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi ptr [ [[TMP5]], %[[MIDDLE_BLOCK]] ], [ [[BEGIN]], %[[LOOP_PREHEADER]] ]
653750; CHECK-NEXT: br label %[[LOOP_HEADER:.*]]
654751; CHECK: [[LOOP_HEADER]]:
655- ; CHECK-NEXT: [[PTR:%.*]] = phi ptr [ [[PTR_NEXT:%.*]], %[[LOOP_LATCH:.*]] ], [ [[BEGIN ]], %[[LOOP_PREHEADER ]] ]
752+ ; CHECK-NEXT: [[PTR:%.*]] = phi ptr [ [[PTR_NEXT:%.*]], %[[LOOP_LATCH:.*]] ], [ [[BC_RESUME_VAL ]], %[[SCALAR_PH ]] ]
656753; CHECK-NEXT: [[VAL:%.*]] = load i16, ptr [[PTR]], align 2
657754; CHECK-NEXT: [[FOUND:%.*]] = icmp eq i16 [[VAL]], 1
658- ; CHECK-NEXT: br i1 [[FOUND]], label %[[EXIT_LOOPEXIT:.* ]], label %[[LOOP_LATCH]]
755+ ; CHECK-NEXT: br i1 [[FOUND]], label %[[EXIT_LOOPEXIT]], label %[[LOOP_LATCH]]
659756; CHECK: [[LOOP_LATCH]]:
660757; CHECK-NEXT: [[PTR_NEXT]] = getelementptr inbounds nuw i8, ptr [[PTR]], i64 2
661758; CHECK-NEXT: [[DONE:%.*]] = icmp eq ptr [[PTR_NEXT]], [[END]]
662- ; CHECK-NEXT: br i1 [[DONE]], label %[[EXIT_LOOPEXIT]], label %[[LOOP_HEADER]]
759+ ; CHECK-NEXT: br i1 [[DONE]], label %[[EXIT_LOOPEXIT]], label %[[LOOP_HEADER]], !llvm.loop [[LOOP13:![0-9]+]]
663760; CHECK: [[EXIT_LOOPEXIT]]:
664- ; CHECK-NEXT: [[RESULT_PH:%.*]] = phi ptr [ [[END_PTR]], %[[LOOP_LATCH]] ], [ [[PTR]], %[[LOOP_HEADER]] ]
761+ ; CHECK-NEXT: [[RESULT_PH:%.*]] = phi ptr [ [[END_PTR]], %[[LOOP_LATCH]] ], [ [[PTR]], %[[LOOP_HEADER]] ], [ [[END_PTR]], %[[MIDDLE_BLOCK]] ], [ [[TMP14]], %[[VECTOR_EARLY_EXIT]] ]
665762; CHECK-NEXT: [[DOTRESULT_INT:%.*]] = ptrtoint ptr [[RESULT_PH]] to i64
666763; CHECK-NEXT: br label %[[EXIT]]
667764; CHECK: [[EXIT]]:
@@ -782,3 +879,177 @@ exit:
782879 %result.int = phi i64 [ %.result.int , %exit.loopexit ], [ %begin.int , %entry ]
783880 ret i64 %result.int
784881}
882+
883+ ; Test with an invoke terminator between the block containing the assume and loop.
884+ ; This should NOT vectorize because the invoke could free memory.
885+ define i64 @find_if_deref_via_assumption_invoke_may_free_in_assume_block (ptr %vec ) nofree nosync personality ptr @__gxx_personality_v0 {
886+ ; CHECK-LABEL: define i64 @find_if_deref_via_assumption_invoke_may_free_in_assume_block(
887+ ; CHECK-SAME: ptr [[VEC:%.*]]) #[[ATTR0]] personality ptr @__gxx_personality_v0 {
888+ ; CHECK-NEXT: [[ENTRY:.*:]]
889+ ; CHECK-NEXT: [[BEGIN:%.*]] = load ptr, ptr [[VEC]], align 8
890+ ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[BEGIN]], i64 2) ]
891+ ; CHECK-NEXT: [[BEGIN_INT:%.*]] = ptrtoint ptr [[BEGIN]] to i64
892+ ; CHECK-NEXT: [[END_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[VEC]], i64 8
893+ ; CHECK-NEXT: [[END:%.*]] = load ptr, ptr [[END_GEP]], align 8
894+ ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[END]], i64 2) ]
895+ ; CHECK-NEXT: [[END_INT:%.*]] = ptrtoint ptr [[END]] to i64
896+ ; CHECK-NEXT: [[DISTANCE:%.*]] = sub i64 [[END_INT]], [[BEGIN_INT]]
897+ ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[BEGIN]], i64 [[DISTANCE]]) ]
898+ ; CHECK-NEXT: [[NOT_EMPTY:%.*]] = icmp ne ptr [[BEGIN]], [[END]]
899+ ; CHECK-NEXT: call void @llvm.assume(i1 [[NOT_EMPTY]])
900+ ; CHECK-NEXT: invoke void @may_free()
901+ ; CHECK-NEXT: to label %[[LOOP_PREHEADER:.*]] unwind label %[[LPAD:.*]]
902+ ; CHECK: [[LOOP_PREHEADER]]:
903+ ; CHECK-NEXT: [[END_PTR:%.*]] = getelementptr i8, ptr [[BEGIN]], i64 [[DISTANCE]]
904+ ; CHECK-NEXT: br label %[[LOOP:.*]]
905+ ; CHECK: [[LOOP]]:
906+ ; CHECK-NEXT: [[PTR:%.*]] = phi ptr [ [[PTR_NEXT:%.*]], %[[LOOP_INC:.*]] ], [ [[BEGIN]], %[[LOOP_PREHEADER]] ]
907+ ; CHECK-NEXT: [[VAL:%.*]] = load i16, ptr [[PTR]], align 2
908+ ; CHECK-NEXT: [[FOUND:%.*]] = icmp eq i16 [[VAL]], 1
909+ ; CHECK-NEXT: br i1 [[FOUND]], label %[[EXIT_LOOPEXIT:.*]], label %[[LOOP_INC]]
910+ ; CHECK: [[LOOP_INC]]:
911+ ; CHECK-NEXT: [[PTR_NEXT]] = getelementptr inbounds nuw i8, ptr [[PTR]], i64 2
912+ ; CHECK-NEXT: [[DONE:%.*]] = icmp eq ptr [[PTR_NEXT]], [[END]]
913+ ; CHECK-NEXT: br i1 [[DONE]], label %[[EXIT_LOOPEXIT]], label %[[LOOP]]
914+ ; CHECK: [[LPAD]]:
915+ ; CHECK-NEXT: [[LP:%.*]] = landingpad { ptr, i32 }
916+ ; CHECK-NEXT: cleanup
917+ ; CHECK-NEXT: resume { ptr, i32 } [[LP]]
918+ ; CHECK: [[EXIT_LOOPEXIT]]:
919+ ; CHECK-NEXT: [[RESULT_PH:%.*]] = phi ptr [ [[END_PTR]], %[[LOOP_INC]] ], [ [[PTR]], %[[LOOP]] ]
920+ ; CHECK-NEXT: [[DOTRESULT_INT:%.*]] = ptrtoint ptr [[RESULT_PH]] to i64
921+ ; CHECK-NEXT: br label %[[EXIT:.*]]
922+ ; CHECK: [[EXIT]]:
923+ ; CHECK-NEXT: [[RESULT_INT:%.*]] = phi i64 [ [[DOTRESULT_INT]], %[[EXIT_LOOPEXIT]] ]
924+ ; CHECK-NEXT: ret i64 [[RESULT_INT]]
925+ ;
926+ entry:
927+ %begin = load ptr , ptr %vec , align 8
928+ call void @llvm.assume (i1 true ) [ "align" (ptr %begin , i64 2 ) ]
929+ %begin.int = ptrtoint ptr %begin to i64
930+ %end.gep = getelementptr inbounds nuw i8 , ptr %vec , i64 8
931+ %end = load ptr , ptr %end.gep , align 8
932+ call void @llvm.assume (i1 true ) [ "align" (ptr %end , i64 2 ) ]
933+ %end.int = ptrtoint ptr %end to i64
934+ %distance = sub i64 %end.int , %begin.int
935+ call void @llvm.assume (i1 true ) [ "dereferenceable" (ptr %begin , i64 %distance ) ]
936+ %not.empty = icmp ne ptr %begin , %end
937+ call void @llvm.assume (i1 %not.empty )
938+ invoke void @may_free () to label %loop.preheader unwind label %lpad
939+
940+ loop.preheader:
941+ %end.ptr = getelementptr i8 , ptr %begin , i64 %distance
942+ br label %loop
943+
944+ loop:
945+ %ptr = phi ptr [ %ptr.next , %loop.inc ], [ %begin , %loop.preheader ]
946+ %val = load i16 , ptr %ptr , align 2
947+ %found = icmp eq i16 %val , 1
948+ br i1 %found , label %exit.loopexit , label %loop.inc
949+
950+ loop.inc:
951+ %ptr.next = getelementptr inbounds nuw i8 , ptr %ptr , i64 2
952+ %done = icmp eq ptr %ptr.next , %end
953+ br i1 %done , label %exit.loopexit , label %loop
954+
955+ lpad:
956+ %lp = landingpad { ptr , i32 } cleanup
957+ resume { ptr , i32 } %lp
958+
959+ exit.loopexit:
960+ %result.ph = phi ptr [ %end.ptr , %loop.inc ], [ %ptr , %loop ]
961+ %.result.int = ptrtoint ptr %result.ph to i64
962+ br label %exit
963+
964+ exit:
965+ %result.int = phi i64 [ %.result.int , %exit.loopexit ]
966+ ret i64 %result.int
967+ }
968+
969+ ; Test with an invoke terminator between the block containing the assume and loop.
970+ ; This should NOT vectorize because the invoke could free memory.
971+ define i64 @find_if_deref_via_assumption_invoke_may_free_in_preheader (ptr %vec ) nofree nosync personality ptr @__gxx_personality_v0 {
972+ ; CHECK-LABEL: define i64 @find_if_deref_via_assumption_invoke_may_free_in_preheader(
973+ ; CHECK-SAME: ptr [[VEC:%.*]]) #[[ATTR0]] personality ptr @__gxx_personality_v0 {
974+ ; CHECK-NEXT: [[ENTRY:.*]]:
975+ ; CHECK-NEXT: [[BEGIN:%.*]] = load ptr, ptr [[VEC]], align 8
976+ ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[BEGIN]], i64 2) ]
977+ ; CHECK-NEXT: [[BEGIN_INT:%.*]] = ptrtoint ptr [[BEGIN]] to i64
978+ ; CHECK-NEXT: [[END_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[VEC]], i64 8
979+ ; CHECK-NEXT: [[END:%.*]] = load ptr, ptr [[END_GEP]], align 8
980+ ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[END]], i64 2) ]
981+ ; CHECK-NEXT: [[END_INT:%.*]] = ptrtoint ptr [[END]] to i64
982+ ; CHECK-NEXT: [[DISTANCE:%.*]] = sub i64 [[END_INT]], [[BEGIN_INT]]
983+ ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[BEGIN]], i64 [[DISTANCE]]) ]
984+ ; CHECK-NEXT: [[IS_EMPTY:%.*]] = icmp eq ptr [[BEGIN]], [[END]]
985+ ; CHECK-NEXT: br i1 [[IS_EMPTY]], label %[[EXIT:.*]], label %[[LOOP_PREHEADER:.*]]
986+ ; CHECK: [[LOOP_PREHEADER]]:
987+ ; CHECK-NEXT: [[END_PTR:%.*]] = getelementptr i8, ptr [[BEGIN]], i64 [[DISTANCE]]
988+ ; CHECK-NEXT: invoke void @may_free()
989+ ; CHECK-NEXT: to label %[[LOOP_PREHEADER1:.*]] unwind label %[[LPAD:.*]]
990+ ; CHECK: [[LOOP_PREHEADER1]]:
991+ ; CHECK-NEXT: br label %[[LOOP:.*]]
992+ ; CHECK: [[LOOP]]:
993+ ; CHECK-NEXT: [[PTR:%.*]] = phi ptr [ [[PTR_NEXT:%.*]], %[[LOOP_INC:.*]] ], [ [[BEGIN]], %[[LOOP_PREHEADER1]] ]
994+ ; CHECK-NEXT: [[VAL:%.*]] = load i16, ptr [[PTR]], align 2
995+ ; CHECK-NEXT: [[FOUND:%.*]] = icmp eq i16 [[VAL]], 1
996+ ; CHECK-NEXT: br i1 [[FOUND]], label %[[EXIT_LOOPEXIT:.*]], label %[[LOOP_INC]]
997+ ; CHECK: [[LOOP_INC]]:
998+ ; CHECK-NEXT: [[PTR_NEXT]] = getelementptr inbounds nuw i8, ptr [[PTR]], i64 2
999+ ; CHECK-NEXT: [[DONE:%.*]] = icmp eq ptr [[PTR_NEXT]], [[END]]
1000+ ; CHECK-NEXT: br i1 [[DONE]], label %[[EXIT_LOOPEXIT]], label %[[LOOP]]
1001+ ; CHECK: [[LPAD]]:
1002+ ; CHECK-NEXT: [[LP:%.*]] = landingpad { ptr, i32 }
1003+ ; CHECK-NEXT: cleanup
1004+ ; CHECK-NEXT: resume { ptr, i32 } [[LP]]
1005+ ; CHECK: [[EXIT_LOOPEXIT]]:
1006+ ; CHECK-NEXT: [[RESULT_PH:%.*]] = phi ptr [ [[END_PTR]], %[[LOOP_INC]] ], [ [[PTR]], %[[LOOP]] ]
1007+ ; CHECK-NEXT: [[DOTRESULT_INT:%.*]] = ptrtoint ptr [[RESULT_PH]] to i64
1008+ ; CHECK-NEXT: br label %[[EXIT]]
1009+ ; CHECK: [[EXIT]]:
1010+ ; CHECK-NEXT: [[RESULT_INT:%.*]] = phi i64 [ [[DOTRESULT_INT]], %[[EXIT_LOOPEXIT]] ], [ [[BEGIN_INT]], %[[ENTRY]] ]
1011+ ; CHECK-NEXT: ret i64 [[RESULT_INT]]
1012+ ;
1013+ entry:
1014+ %begin = load ptr , ptr %vec , align 8
1015+ call void @llvm.assume (i1 true ) [ "align" (ptr %begin , i64 2 ) ]
1016+ %begin.int = ptrtoint ptr %begin to i64
1017+ %end.gep = getelementptr inbounds nuw i8 , ptr %vec , i64 8
1018+ %end = load ptr , ptr %end.gep , align 8
1019+ call void @llvm.assume (i1 true ) [ "align" (ptr %end , i64 2 ) ]
1020+ %end.int = ptrtoint ptr %end to i64
1021+ %distance = sub i64 %end.int , %begin.int
1022+ call void @llvm.assume (i1 true ) [ "dereferenceable" (ptr %begin , i64 %distance ) ]
1023+ %is.empty = icmp eq ptr %begin , %end
1024+ br i1 %is.empty , label %exit , label %loop.preheader
1025+
1026+ loop.preheader:
1027+ %end.ptr = getelementptr i8 , ptr %begin , i64 %distance
1028+ invoke void @may_free () to label %loop unwind label %lpad
1029+
1030+ loop:
1031+ %ptr = phi ptr [ %ptr.next , %loop.inc ], [ %begin , %loop.preheader ]
1032+ %val = load i16 , ptr %ptr , align 2
1033+ %found = icmp eq i16 %val , 1
1034+ br i1 %found , label %exit.loopexit , label %loop.inc
1035+
1036+ loop.inc:
1037+ %ptr.next = getelementptr inbounds nuw i8 , ptr %ptr , i64 2
1038+ %done = icmp eq ptr %ptr.next , %end
1039+ br i1 %done , label %exit.loopexit , label %loop
1040+
1041+ lpad:
1042+ %lp = landingpad { ptr , i32 } cleanup
1043+ resume { ptr , i32 } %lp
1044+
1045+ exit.loopexit:
1046+ %result.ph = phi ptr [ %end.ptr , %loop.inc ], [ %ptr , %loop ]
1047+ %.result.int = ptrtoint ptr %result.ph to i64
1048+ br label %exit
1049+
1050+ exit:
1051+ %result.int = phi i64 [ %.result.int , %exit.loopexit ], [ %begin.int , %entry ]
1052+ ret i64 %result.int
1053+ }
1054+
1055+ declare i32 @__gxx_personality_v0 (...)
0 commit comments