Skip to content

Commit 6cd6e8b

Browse files
committed
[LV] Add additional tests for reasoning about dereferenceable loads.
Includes a test for the crash exposed by 08001cf. (cherry picked from commit b169302)
1 parent 75a5fcd commit 6cd6e8b

File tree

2 files changed

+294
-2
lines changed

2 files changed

+294
-2
lines changed

llvm/test/Transforms/LoopVectorize/single-early-exit-deref-assumptions.ll

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,62 @@ loop.end:
120120
ret i64 %retval
121121
}
122122

123-
define i64 @early_exit_alignment_and_deref_known_via_assumption(ptr noalias %p1, ptr noalias %p2, i64 %n) nofree nosync {
124-
; CHECK-LABEL: define i64 @early_exit_alignment_and_deref_known_via_assumption(
123+
define i64 @early_exit_alignment_and_deref_known_via_assumption_n_not_zero(ptr noalias %p1, ptr noalias %p2, i64 %n) nofree nosync {
124+
; CHECK-LABEL: define i64 @early_exit_alignment_and_deref_known_via_assumption_n_not_zero(
125+
; CHECK-SAME: ptr noalias [[P1:%.*]], ptr noalias [[P2:%.*]], i64 [[N:%.*]]) #[[ATTR0]] {
126+
; CHECK-NEXT: entry:
127+
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P1]], i64 4), "dereferenceable"(ptr [[P1]], i64 [[N]]) ]
128+
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P2]], i64 4), "dereferenceable"(ptr [[P2]], i64 [[N]]) ]
129+
; CHECK-NEXT: [[C:%.*]] = icmp ne i64 [[N]], 0
130+
; CHECK-NEXT: br i1 [[C]], label [[LOOP_PREHEADER:%.*]], label [[LOOP_END:%.*]]
131+
; CHECK: loop.preheader:
132+
; CHECK-NEXT: br label [[LOOP:%.*]]
133+
; CHECK: loop:
134+
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
135+
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX]]
136+
; CHECK-NEXT: [[LD1:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
137+
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[INDEX]]
138+
; CHECK-NEXT: [[LD2:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1
139+
; CHECK-NEXT: [[CMP3:%.*]] = icmp eq i8 [[LD1]], [[LD2]]
140+
; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_END_LOOPEXIT:%.*]]
141+
; CHECK: loop.inc:
142+
; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1
143+
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], [[N]]
144+
; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END_LOOPEXIT]]
145+
; CHECK: loop.end.loopexit:
146+
; CHECK-NEXT: [[RETVAL_PH:%.*]] = phi i64 [ -1, [[LOOP_INC]] ], [ [[INDEX]], [[LOOP]] ]
147+
; CHECK-NEXT: br label [[LOOP_END]]
148+
; CHECK: loop.end:
149+
; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[RETVAL_PH]], [[LOOP_END_LOOPEXIT]] ]
150+
; CHECK-NEXT: ret i64 [[RETVAL]]
151+
;
152+
entry:
153+
call void @llvm.assume(i1 true) [ "align"(ptr %p1, i64 4), "dereferenceable"(ptr %p1, i64 %n) ]
154+
call void @llvm.assume(i1 true) [ "align"(ptr %p2, i64 4), "dereferenceable"(ptr %p2, i64 %n) ]
155+
%c = icmp ne i64 %n, 0
156+
br i1 %c, label %loop, label %loop.end
157+
158+
loop:
159+
%index = phi i64 [ %index.next, %loop.inc ], [ 0, %entry ]
160+
%arrayidx = getelementptr inbounds i8, ptr %p1, i64 %index
161+
%ld1 = load i8, ptr %arrayidx, align 1
162+
%arrayidx1 = getelementptr inbounds i8, ptr %p2, i64 %index
163+
%ld2 = load i8, ptr %arrayidx1, align 1
164+
%cmp3 = icmp eq i8 %ld1, %ld2
165+
br i1 %cmp3, label %loop.inc, label %loop.end
166+
167+
loop.inc:
168+
%index.next = add i64 %index, 1
169+
%exitcond = icmp ne i64 %index.next, %n
170+
br i1 %exitcond, label %loop, label %loop.end
171+
172+
loop.end:
173+
%retval = phi i64 [ 0, %entry ], [ %index, %loop ], [ -1, %loop.inc ]
174+
ret i64 %retval
175+
}
176+
177+
define i64 @early_exit_alignment_and_deref_known_via_assumption_n_may_be_zero(ptr noalias %p1, ptr noalias %p2, i64 %n) nofree nosync {
178+
; CHECK-LABEL: define i64 @early_exit_alignment_and_deref_known_via_assumption_n_may_be_zero(
125179
; CHECK-SAME: ptr noalias [[P1:%.*]], ptr noalias [[P2:%.*]], i64 [[N:%.*]]) #[[ATTR0]] {
126180
; CHECK-NEXT: entry:
127181
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P1]], i64 4), "dereferenceable"(ptr [[P1]], i64 [[N]]) ]

llvm/test/Transforms/LoopVectorize/single_early_exit.ll

Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,244 @@ early.exit:
334334
for.end:
335335
ret i32 0
336336
}
337+
338+
define void @inner_loop_trip_count_depends_on_outer_iv(ptr align 8 dereferenceable(1792) %this, ptr %dst) {
339+
; CHECK-LABEL: define void @inner_loop_trip_count_depends_on_outer_iv(
340+
; CHECK-SAME: ptr align 8 dereferenceable(1792) [[THIS:%.*]], ptr [[DST:%.*]]) {
341+
; CHECK-NEXT: entry:
342+
; CHECK-NEXT: [[GEP_SRC:%.*]] = getelementptr i8, ptr [[THIS]], i64 1000
343+
; CHECK-NEXT: br label [[OUTER_HEADER:%.*]]
344+
; CHECK: outer.header:
345+
; CHECK-NEXT: [[OUTER_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[OUTER_IV_NEXT:%.*]], [[OUTER_LATCH:%.*]] ]
346+
; CHECK-NEXT: [[C_1:%.*]] = icmp eq i64 [[OUTER_IV]], 0
347+
; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[INNER_HEADER_PREHEADER:%.*]]
348+
; CHECK: inner.header.preheader:
349+
; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[OUTER_IV]], 4
350+
; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
351+
; CHECK: vector.ph:
352+
; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[OUTER_IV]], 4
353+
; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[OUTER_IV]], [[N_MOD_VF]]
354+
; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]
355+
; CHECK: vector.body:
356+
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
357+
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr ptr, ptr [[GEP_SRC]], i64 [[INDEX]]
358+
; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x ptr>, ptr [[TMP0]], align 8
359+
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x ptr> [[WIDE_LOAD]], zeroinitializer
360+
; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
361+
; CHECK-NEXT: [[TMP2:%.*]] = freeze <4 x i1> [[TMP1]]
362+
; CHECK-NEXT: [[TMP3:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP2]])
363+
; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
364+
; CHECK-NEXT: [[TMP5:%.*]] = or i1 [[TMP3]], [[TMP4]]
365+
; CHECK-NEXT: br i1 [[TMP5]], label [[MIDDLE_SPLIT:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP10:![0-9]+]]
366+
; CHECK: middle.split:
367+
; CHECK-NEXT: br i1 [[TMP3]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]]
368+
; CHECK: middle.block:
369+
; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[OUTER_IV]], [[N_VEC]]
370+
; CHECK-NEXT: br i1 [[CMP_N]], label [[OUTER_LATCH_LOOPEXIT:%.*]], label [[SCALAR_PH]]
371+
; CHECK: vector.early.exit:
372+
; CHECK-NEXT: br label [[THEN_LOOPEXIT:%.*]]
373+
; CHECK: scalar.ph:
374+
; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[INNER_HEADER_PREHEADER]] ]
375+
; CHECK-NEXT: br label [[INNER_HEADER:%.*]]
376+
; CHECK: inner.header:
377+
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[INNER_LATCH:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ]
378+
; CHECK-NEXT: [[GEP_IV:%.*]] = getelementptr ptr, ptr [[GEP_SRC]], i64 [[IV]]
379+
; CHECK-NEXT: [[L:%.*]] = load ptr, ptr [[GEP_IV]], align 8
380+
; CHECK-NEXT: [[C_2:%.*]] = icmp eq ptr [[L]], null
381+
; CHECK-NEXT: br i1 [[C_2]], label [[THEN_LOOPEXIT]], label [[INNER_LATCH]]
382+
; CHECK: inner.latch:
383+
; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
384+
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[OUTER_IV]]
385+
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[OUTER_LATCH_LOOPEXIT]], label [[INNER_HEADER]], !llvm.loop [[LOOP11:![0-9]+]]
386+
; CHECK: then.loopexit:
387+
; CHECK-NEXT: br label [[THEN]]
388+
; CHECK: then:
389+
; CHECK-NEXT: store i32 0, ptr [[DST]], align 4
390+
; CHECK-NEXT: br label [[OUTER_LATCH]]
391+
; CHECK: outer.latch.loopexit:
392+
; CHECK-NEXT: br label [[OUTER_LATCH]]
393+
; CHECK: outer.latch:
394+
; CHECK-NEXT: [[OUTER_IV_NEXT]] = add i64 [[OUTER_IV]], 1
395+
; CHECK-NEXT: [[OUTER_EC:%.*]] = icmp eq i64 [[OUTER_IV_NEXT]], 100
396+
; CHECK-NEXT: br i1 [[OUTER_EC]], label [[EXIT:%.*]], label [[OUTER_HEADER]]
397+
; CHECK: exit:
398+
; CHECK-NEXT: ret void
399+
;
400+
entry:
401+
%gep.src = getelementptr i8, ptr %this, i64 1000
402+
br label %outer.header
403+
404+
outer.header:
405+
%outer.iv = phi i64 [ 0, %entry ], [ %outer.iv.next, %outer.latch ]
406+
%c.1 = icmp eq i64 %outer.iv, 0
407+
br i1 %c.1, label %then, label %inner.header
408+
409+
inner.header:
410+
%iv = phi i64 [ %iv.next, %inner.latch ], [ 0, %outer.header ]
411+
%gep.iv = getelementptr ptr, ptr %gep.src, i64 %iv
412+
%l = load ptr, ptr %gep.iv, align 8
413+
%c.2 = icmp eq ptr %l, null
414+
br i1 %c.2, label %then, label %inner.latch
415+
416+
inner.latch:
417+
%iv.next = add i64 %iv, 1
418+
%ec = icmp eq i64 %iv.next, %outer.iv
419+
br i1 %ec, label %outer.latch, label %inner.header
420+
421+
then:
422+
store i32 0, ptr %dst, align 4
423+
br label %outer.latch
424+
425+
outer.latch:
426+
%outer.iv.next = add i64 %outer.iv, 1
427+
%outer.ec = icmp eq i64 %outer.iv.next, 100
428+
br i1 %outer.ec, label %exit, label %outer.header
429+
430+
exit:
431+
ret void
432+
}
433+
434+
define i64 @loop_guard_needed_to_prove_dereferenceable(i32 %x, i1 %cmp2) {
435+
; CHECK-LABEL: define i64 @loop_guard_needed_to_prove_dereferenceable(
436+
; CHECK-SAME: i32 [[X:%.*]], i1 [[CMP2:%.*]]) {
437+
; CHECK-NEXT: entry:
438+
; CHECK-NEXT: [[A:%.*]] = alloca [32 x i32], align 4
439+
; CHECK-NEXT: call void @init_mem(ptr [[A]], i64 128)
440+
; CHECK-NEXT: [[C_X:%.*]] = icmp sgt i32 [[X]], 0
441+
; CHECK-NEXT: br i1 [[C_X]], label [[PH:%.*]], label [[EXIT:%.*]]
442+
; CHECK: ph:
443+
; CHECK-NEXT: [[N:%.*]] = tail call i32 @llvm.smin.i32(i32 [[X]], i32 31)
444+
; CHECK-NEXT: [[N_EXT:%.*]] = zext i32 [[N]] to i64
445+
; CHECK-NEXT: [[TMP0:%.*]] = add nuw nsw i64 [[N_EXT]], 1
446+
; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP0]], 4
447+
; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
448+
; CHECK: vector.ph:
449+
; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP0]], 4
450+
; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP0]], [[N_MOD_VF]]
451+
; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]
452+
; CHECK: vector.body:
453+
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
454+
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr [32 x i32], ptr [[A]], i64 0, i64 [[INDEX]]
455+
; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i32>, ptr [[TMP1]], align 4
456+
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq <4 x i32> [[WIDE_LOAD]], zeroinitializer
457+
; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
458+
; CHECK-NEXT: [[TMP3:%.*]] = freeze <4 x i1> [[TMP2]]
459+
; CHECK-NEXT: [[TMP4:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP3]])
460+
; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
461+
; CHECK-NEXT: [[TMP6:%.*]] = or i1 [[TMP4]], [[TMP5]]
462+
; CHECK-NEXT: br i1 [[TMP6]], label [[MIDDLE_SPLIT:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP12:![0-9]+]]
463+
; CHECK: middle.split:
464+
; CHECK-NEXT: br i1 [[TMP4]], label [[VECTOR_EARLY_EXIT:%.*]], label [[MIDDLE_BLOCK:%.*]]
465+
; CHECK: middle.block:
466+
; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[TMP0]], [[N_VEC]]
467+
; CHECK-NEXT: br i1 [[CMP_N]], label [[EXIT_LOOPEXIT:%.*]], label [[SCALAR_PH]]
468+
; CHECK: vector.early.exit:
469+
; CHECK-NEXT: [[TMP7:%.*]] = call i64 @llvm.experimental.cttz.elts.i64.v4i1(<4 x i1> [[TMP2]], i1 true)
470+
; CHECK-NEXT: [[TMP8:%.*]] = add i64 [[INDEX]], [[TMP7]]
471+
; CHECK-NEXT: br label [[EXIT_LOOPEXIT]]
472+
; CHECK: scalar.ph:
473+
; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[PH]] ]
474+
; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
475+
; CHECK: loop.header:
476+
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
477+
; CHECK-NEXT: [[ARRAYIDX42:%.*]] = getelementptr [32 x i32], ptr [[A]], i64 0, i64 [[IV]]
478+
; CHECK-NEXT: [[TMP9:%.*]] = load i32, ptr [[ARRAYIDX42]], align 4
479+
; CHECK-NEXT: [[CMP43:%.*]] = icmp eq i32 [[TMP9]], 0
480+
; CHECK-NEXT: br i1 [[CMP43]], label [[EXIT_LOOPEXIT]], label [[LOOP_LATCH]]
481+
; CHECK: loop.latch:
482+
; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
483+
; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV]], [[N_EXT]]
484+
; CHECK-NEXT: br i1 [[EC]], label [[EXIT_LOOPEXIT]], label [[LOOP_HEADER]], !llvm.loop [[LOOP13:![0-9]+]]
485+
; CHECK: exit.loopexit:
486+
; CHECK-NEXT: [[RES_PH:%.*]] = phi i64 [ [[IV]], [[LOOP_HEADER]] ], [ -1, [[LOOP_LATCH]] ], [ -1, [[MIDDLE_BLOCK]] ], [ [[TMP8]], [[VECTOR_EARLY_EXIT]] ]
487+
; CHECK-NEXT: br label [[EXIT]]
488+
; CHECK: exit:
489+
; CHECK-NEXT: [[RES:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[RES_PH]], [[EXIT_LOOPEXIT]] ]
490+
; CHECK-NEXT: ret i64 [[RES]]
491+
;
492+
entry:
493+
%A = alloca [32 x i32], align 4
494+
call void @init_mem(ptr %A, i64 128)
495+
%c.x = icmp sgt i32 %x, 0
496+
br i1 %c.x, label %ph, label %exit
497+
498+
ph:
499+
%n = tail call i32 @llvm.smin.i32(i32 %x, i32 31)
500+
%n.ext = zext i32 %n to i64
501+
br label %loop.header
502+
503+
loop.header:
504+
%iv = phi i64 [ 0, %ph ], [ %iv.next, %loop.latch ]
505+
%arrayidx42 = getelementptr [32 x i32], ptr %A, i64 0, i64 %iv
506+
%0 = load i32, ptr %arrayidx42, align 4
507+
%cmp43 = icmp eq i32 %0, 0
508+
br i1 %cmp43, label %exit, label %loop.latch
509+
510+
loop.latch:
511+
%iv.next = add i64 %iv, 1
512+
%ec = icmp eq i64 %iv, %n.ext
513+
br i1 %ec, label %exit, label %loop.header
514+
515+
exit:
516+
%res = phi i64 [ 0, %entry ], [ -1, %loop.latch ], [ %iv, %loop.header ]
517+
ret i64 %res
518+
}
519+
520+
declare i32 @llvm.smin.i32(i32, i32)
521+
522+
@A = external global [100 x {i32, i8} ]
523+
524+
define ptr @btc_and_max_btc_require_predicates(ptr noalias %start, i64 %offset) {
525+
; CHECK-LABEL: define ptr @btc_and_max_btc_require_predicates(
526+
; CHECK-SAME: ptr noalias [[START:%.*]], i64 [[OFFSET:%.*]]) {
527+
; CHECK-NEXT: entry:
528+
; CHECK-NEXT: [[END:%.*]] = getelementptr i32, ptr [[START]], i64 [[OFFSET]]
529+
; CHECK-NEXT: [[PRE_1:%.*]] = icmp ult i64 [[OFFSET]], 100
530+
; CHECK-NEXT: call void @llvm.assume(i1 [[PRE_1]])
531+
; CHECK-NEXT: [[PRE_2:%.*]] = icmp ugt i64 [[OFFSET]], 1
532+
; CHECK-NEXT: call void @llvm.assume(i1 [[PRE_2]])
533+
; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
534+
; CHECK: loop.header:
535+
; CHECK-NEXT: [[IV_1:%.*]] = phi ptr [ @A, [[ENTRY:%.*]] ], [ [[IV_1_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
536+
; CHECK-NEXT: [[IV_2:%.*]] = phi ptr [ [[START]], [[ENTRY]] ], [ [[IV_2_NEXT:%.*]], [[LOOP_LATCH]] ]
537+
; CHECK-NEXT: [[L:%.*]] = load i32, ptr [[IV_1]], align 4
538+
; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[L]], 0
539+
; CHECK-NEXT: br i1 [[C]], label [[LOOP_LATCH]], label [[EXIT:%.*]]
540+
; CHECK: loop.latch:
541+
; CHECK-NEXT: [[IV_2_NEXT]] = getelementptr i8, ptr [[IV_2]], i64 40
542+
; CHECK-NEXT: [[IV_1_NEXT]] = getelementptr i8, ptr [[IV_1]], i64 40
543+
; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[IV_2]], [[END]]
544+
; CHECK-NEXT: br i1 [[EC]], label [[EXIT]], label [[LOOP_HEADER]]
545+
; CHECK: exit:
546+
; CHECK-NEXT: [[RES:%.*]] = phi ptr [ [[IV_1]], [[LOOP_HEADER]] ], [ [[IV_2]], [[LOOP_LATCH]] ]
547+
; CHECK-NEXT: ret ptr [[RES]]
548+
;
549+
entry:
550+
%end = getelementptr i32, ptr %start, i64 %offset
551+
%pre.1 = icmp ult i64 %offset, 100
552+
call void @llvm.assume(i1 %pre.1)
553+
%pre.2 = icmp ugt i64 %offset, 1
554+
call void @llvm.assume(i1 %pre.2)
555+
br label %loop.header
556+
557+
loop.header:
558+
%iv.1 = phi ptr [ @A, %entry ], [ %iv.1.next, %loop.latch ]
559+
%iv.2 = phi ptr [ %start, %entry ], [ %iv.2.next, %loop.latch ]
560+
%l = load i32, ptr %iv.1, align 4
561+
%c = icmp eq i32 %l, 0
562+
br i1 %c, label %loop.latch, label %exit
563+
564+
loop.latch:
565+
%iv.2.next = getelementptr i8, ptr %iv.2, i64 40
566+
%iv.1.next = getelementptr i8, ptr %iv.1, i64 40
567+
%ec = icmp eq ptr %iv.2, %end
568+
br i1 %ec, label %exit, label %loop.header
569+
570+
exit:
571+
%res = phi ptr [ %iv.1, %loop.header ], [ %iv.2, %loop.latch ]
572+
ret ptr %res
573+
}
574+
337575
;.
338576
; CHECK: [[LOOP0]] = distinct !{[[LOOP0]], [[META1:![0-9]+]], [[META2:![0-9]+]]}
339577
; CHECK: [[META1]] = !{!"llvm.loop.isvectorized", i32 1}

0 commit comments

Comments
 (0)