@@ -129,9 +129,108 @@ return:
129129 ret i64 %res
130130}
131131
132+ define ptr @std_find_caller (ptr noundef %first , ptr noundef %last ) {
133+ ; CHECK-LABEL: define noundef ptr @std_find_caller(
134+ ; CHECK-SAME: ptr noundef [[FIRST:%.*]], ptr noundef [[LAST:%.*]]) local_unnamed_addr #[[ATTR0]] {
135+ ; CHECK-NEXT: [[ENTRY:.*]]:
136+ ; CHECK-NEXT: [[FIRST3:%.*]] = ptrtoint ptr [[FIRST]] to i64
137+ ; CHECK-NEXT: [[LAST_I64:%.*]] = ptrtoint ptr [[LAST]] to i64
138+ ; CHECK-NEXT: [[PTR_SUB:%.*]] = sub i64 [[LAST_I64]], [[FIRST3]]
139+ ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[FIRST]], i64 2) ]
140+ ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[LAST]], i64 2) ]
141+ ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[FIRST]], i64 [[PTR_SUB]]) ]
142+ ; CHECK-NEXT: [[PRE_I:%.*]] = icmp eq ptr [[FIRST]], [[LAST]]
143+ ; CHECK-NEXT: br i1 [[PRE_I]], label %[[STD_FIND_GENERIC_IMPL_EXIT:.*]], label %[[LOOP_HEADER_I_PREHEADER:.*]]
144+ ; CHECK: [[LOOP_HEADER_I_PREHEADER]]:
145+ ; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, ptr [[FIRST]], i64 [[PTR_SUB]]
146+ ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[LAST_I64]], -2
147+ ; CHECK-NEXT: [[TMP1:%.*]] = sub i64 [[TMP0]], [[FIRST3]]
148+ ; CHECK-NEXT: [[TMP2:%.*]] = lshr exact i64 [[TMP1]], 1
149+ ; CHECK-NEXT: [[TMP3:%.*]] = add nuw i64 [[TMP2]], 1
150+ ; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP1]], 158
151+ ; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label %[[LOOP_HEADER_I_PREHEADER2:.*]], label %[[VECTOR_PH:.*]]
152+ ; CHECK: [[VECTOR_PH]]:
153+ ; CHECK-NEXT: [[XTRAITER:%.*]] = and i64 [[TMP3]], -8
154+ ; CHECK-NEXT: [[OFFSET_IDX:%.*]] = shl i64 [[XTRAITER]], 1
155+ ; CHECK-NEXT: [[NEXT_GEP:%.*]] = getelementptr i8, ptr [[FIRST]], i64 [[OFFSET_IDX]]
156+ ; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
157+ ; CHECK: [[VECTOR_BODY]]:
158+ ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[PROL_ITER_NEXT:%.*]], %[[VECTOR_BODY]] ]
159+ ; CHECK-NEXT: [[OFFSET_IDX1:%.*]] = shl i64 [[INDEX]], 1
160+ ; CHECK-NEXT: [[NEXT_GEP1:%.*]] = getelementptr i8, ptr [[FIRST]], i64 [[OFFSET_IDX1]]
161+ ; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <8 x i16>, ptr [[NEXT_GEP1]], align 2
162+ ; CHECK-NEXT: [[WIDE_LOAD_FR:%.*]] = freeze <8 x i16> [[WIDE_LOAD]]
163+ ; CHECK-NEXT: [[TMP4:%.*]] = icmp eq <8 x i16> [[WIDE_LOAD_FR]], splat (i16 1)
164+ ; CHECK-NEXT: [[PROL_ITER_NEXT]] = add nuw i64 [[INDEX]], 8
165+ ; CHECK-NEXT: [[TMP5:%.*]] = bitcast <8 x i1> [[TMP4]] to i8
166+ ; CHECK-NEXT: [[TMP6:%.*]] = icmp ne i8 [[TMP5]], 0
167+ ; CHECK-NEXT: [[PROL_ITER_CMP_NOT:%.*]] = icmp eq i64 [[PROL_ITER_NEXT]], [[XTRAITER]]
168+ ; CHECK-NEXT: [[TMP8:%.*]] = or i1 [[TMP6]], [[PROL_ITER_CMP_NOT]]
169+ ; CHECK-NEXT: br i1 [[TMP8]], label %[[MIDDLE_SPLIT:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP3:![0-9]+]]
170+ ; CHECK: [[MIDDLE_SPLIT]]:
171+ ; CHECK-NEXT: br i1 [[TMP6]], label %[[VECTOR_EARLY_EXIT:.*]], label %[[MIDDLE_BLOCK:.*]]
172+ ; CHECK: [[MIDDLE_BLOCK]]:
173+ ; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[TMP3]], [[XTRAITER]]
174+ ; CHECK-NEXT: br i1 [[CMP_N]], label %[[STD_FIND_GENERIC_IMPL_EXIT]], label %[[LOOP_HEADER_I_PREHEADER2]]
175+ ; CHECK: [[LOOP_HEADER_I_PREHEADER2]]:
176+ ; CHECK-NEXT: [[PTR_IV_I_PH:%.*]] = phi ptr [ [[FIRST]], %[[LOOP_HEADER_I_PREHEADER]] ], [ [[NEXT_GEP]], %[[MIDDLE_BLOCK]] ]
177+ ; CHECK-NEXT: br label %[[LOOP_HEADER_I:.*]]
178+ ; CHECK: [[VECTOR_EARLY_EXIT]]:
179+ ; CHECK-NEXT: [[TMP11:%.*]] = tail call i64 @llvm.experimental.cttz.elts.i64.v8i1(<8 x i1> [[TMP4]], i1 true)
180+ ; CHECK-NEXT: [[TMP12:%.*]] = add i64 [[INDEX]], [[TMP11]]
181+ ; CHECK-NEXT: [[TMP13:%.*]] = shl i64 [[TMP12]], 1
182+ ; CHECK-NEXT: [[TMP14:%.*]] = getelementptr i8, ptr [[FIRST]], i64 [[TMP13]]
183+ ; CHECK-NEXT: br label %[[STD_FIND_GENERIC_IMPL_EXIT]]
184+ ; CHECK: [[LOOP_HEADER_I]]:
185+ ; CHECK-NEXT: [[PTR_IV_I:%.*]] = phi ptr [ [[PTR_IV_NEXT_I:%.*]], %[[LOOP_LATCH_I:.*]] ], [ [[PTR_IV_I_PH]], %[[LOOP_HEADER_I_PREHEADER2]] ]
186+ ; CHECK-NEXT: [[L_I:%.*]] = load i16, ptr [[PTR_IV_I]], align 2
187+ ; CHECK-NEXT: [[C_1_I:%.*]] = icmp eq i16 [[L_I]], 1
188+ ; CHECK-NEXT: br i1 [[C_1_I]], label %[[STD_FIND_GENERIC_IMPL_EXIT]], label %[[LOOP_LATCH_I]]
189+ ; CHECK: [[LOOP_LATCH_I]]:
190+ ; CHECK-NEXT: [[PTR_IV_NEXT_I]] = getelementptr inbounds nuw i8, ptr [[PTR_IV_I]], i64 2
191+ ; CHECK-NEXT: [[EC_I:%.*]] = icmp eq ptr [[PTR_IV_NEXT_I]], [[LAST]]
192+ ; CHECK-NEXT: br i1 [[EC_I]], label %[[STD_FIND_GENERIC_IMPL_EXIT]], label %[[LOOP_HEADER_I]], !llvm.loop [[LOOP4:![0-9]+]]
193+ ; CHECK: [[STD_FIND_GENERIC_IMPL_EXIT]]:
194+ ; CHECK-NEXT: [[RES_I:%.*]] = phi ptr [ [[FIRST]], %[[ENTRY]] ], [ [[SCEVGEP]], %[[MIDDLE_BLOCK]] ], [ [[TMP14]], %[[VECTOR_EARLY_EXIT]] ], [ [[SCEVGEP]], %[[LOOP_LATCH_I]] ], [ [[PTR_IV_I]], %[[LOOP_HEADER_I]] ]
195+ ; CHECK-NEXT: ret ptr [[RES_I]]
196+ ;
197+ entry:
198+ %last.i64 = ptrtoint ptr %last to i64
199+ %first.i64 = ptrtoint ptr %first to i64
200+ %ptr.sub = sub i64 %last.i64 , %first.i64
201+ call void @llvm.assume (i1 true ) [ "align" (ptr %first , i64 2 ) ]
202+ call void @llvm.assume (i1 true ) [ "align" (ptr %last , i64 2 ) ]
203+ call void @llvm.assume (i1 true ) [ "dereferenceable" (ptr %first , i64 %ptr.sub ) ]
204+ %call = call noundef ptr @std_find_generic_impl (ptr noundef nonnull %first , ptr noundef %last , i16 noundef signext 1 )
205+ ret ptr %call
206+ }
207+
208+ define linkonce_odr noundef ptr @std_find_generic_impl (ptr noundef %first , ptr noundef %last , i16 noundef %value ) {
209+ entry:
210+ %pre = icmp eq ptr %first , %last
211+ br i1 %pre , label %exit , label %loop.header
212+
213+ loop.header:
214+ %ptr.iv = phi ptr [ %ptr.iv.next , %loop.latch ], [ %first , %entry ]
215+ %l = load i16 , ptr %ptr.iv , align 2
216+ %c.1 = icmp eq i16 %l , %value
217+ br i1 %c.1 , label %exit , label %loop.latch
218+
219+ loop.latch:
220+ %ptr.iv.next = getelementptr inbounds nuw i8 , ptr %ptr.iv , i64 2
221+ %ec = icmp eq ptr %ptr.iv.next , %last
222+ br i1 %ec , label %exit , label %loop.header
223+
224+ exit:
225+ %res = phi ptr [ %first , %entry ], [ %ptr.iv , %loop.header ], [ %ptr.iv.next , %loop.latch ]
226+ ret ptr %res
227+ }
228+
132229declare void @llvm.assume (i1 noundef)
133230;.
134231; CHECK: [[LOOP0]] = distinct !{[[LOOP0]], [[META1:![0-9]+]], [[META2:![0-9]+]]}
135232; CHECK: [[META1]] = !{!"llvm.loop.isvectorized", i32 1}
136233; CHECK: [[META2]] = !{!"llvm.loop.unroll.runtime.disable"}
234+ ; CHECK: [[LOOP3]] = distinct !{[[LOOP3]], [[META1]], [[META2]]}
235+ ; CHECK: [[LOOP4]] = distinct !{[[LOOP4]], [[META2]], [[META1]]}
137236;.
0 commit comments