Skip to content

Commit e004839

Browse files
committed
[LV] Add early-exit-with-store tests
Adds some additional LoopVectorizeLegality tests for early exit loops with a store that we don't vectorize.
1 parent 651db24 commit e004839

File tree

1 file changed

+186
-0
lines changed

1 file changed

+186
-0
lines changed

llvm/test/Transforms/LoopVectorize/early_exit_legality.ll

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,192 @@ loop.end:
470470
ret i64 %retval
471471
}
472472

473+
define void @loop_contains_store_single_user(ptr dereferenceable(40) noalias %array, ptr align 2 dereferenceable(40) readonly %pred) {
474+
; CHECK-LABEL: LV: Checking a loop in 'loop_contains_store_single_user'
475+
; CHECK: LV: Not vectorizing: Writes to memory unsupported in early exit loops.
476+
entry:
477+
br label %for.body
478+
479+
for.body:
480+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]
481+
%st.addr = getelementptr inbounds nuw i16, ptr %array, i64 %iv
482+
%data = load i16, ptr %st.addr, align 2
483+
%inc = add nsw i16 %data, 1
484+
store i16 %inc, ptr %st.addr, align 2
485+
%ee.addr = getelementptr inbounds nuw i16, ptr %pred, i64 %iv
486+
%ee.val = load i16, ptr %ee.addr, align 2
487+
%ee.cond = icmp sgt i16 %ee.val, 500
488+
br i1 %ee.cond, label %exit, label %for.inc
489+
490+
for.inc:
491+
%iv.next = add nuw nsw i64 %iv, 1
492+
%counted.cond = icmp eq i64 %iv.next, 20
493+
br i1 %counted.cond, label %exit, label %for.body
494+
495+
exit:
496+
ret void
497+
}
498+
499+
define void @loop_contains_store_multi_user(ptr dereferenceable(40) noalias %array, ptr align 2 dereferenceable(40) readonly %pred) {
500+
; CHECK-LABEL: LV: Checking a loop in 'loop_contains_store_multi_user'
501+
; CHECK: LV: Not vectorizing: Writes to memory unsupported in early exit loops.
502+
entry:
503+
br label %for.body
504+
505+
for.body:
506+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]
507+
%st.addr = getelementptr inbounds nuw i16, ptr %array, i64 %iv
508+
%data = load i16, ptr %st.addr, align 2
509+
%inc = add nsw i16 %data, 1
510+
store i16 %inc, ptr %st.addr, align 2
511+
%ee.addr = getelementptr inbounds nuw i16, ptr %pred, i64 %iv
512+
%ee.val = load i16, ptr %ee.addr, align 2
513+
%ee.cond = icmp sgt i16 %ee.val, 500
514+
%unused = add i16 %ee.val, 42
515+
br i1 %ee.cond, label %exit, label %for.inc
516+
517+
for.inc:
518+
%iv.next = add nuw nsw i64 %iv, 1
519+
%counted.cond = icmp eq i64 %iv.next, 20
520+
br i1 %counted.cond, label %exit, label %for.body
521+
522+
exit:
523+
ret void
524+
}
525+
526+
define void @loop_contains_store_fcmp(ptr dereferenceable(40) noalias %array, ptr align 2 dereferenceable(40) readonly %pred) {
527+
; CHECK-LABEL: LV: Checking a loop in 'loop_contains_store_fcmp'
528+
; CHECK: LV: Not vectorizing: Writes to memory unsupported in early exit loops.
529+
entry:
530+
br label %for.body
531+
532+
for.body:
533+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]
534+
%st.addr = getelementptr inbounds nuw i16, ptr %array, i64 %iv
535+
%data = load i16, ptr %st.addr, align 2
536+
%inc = add nsw i16 %data, 1
537+
store i16 %inc, ptr %st.addr, align 2
538+
%ee.addr = getelementptr inbounds nuw half, ptr %pred, i64 %iv
539+
%ee.val = load half, ptr %ee.addr, align 2
540+
%ee.cond = fcmp ugt half %ee.val, 500.0
541+
br i1 %ee.cond, label %exit, label %for.inc
542+
543+
for.inc:
544+
%iv.next = add nuw nsw i64 %iv, 1
545+
%counted.cond = icmp eq i64 %iv.next, 20
546+
br i1 %counted.cond, label %exit, label %for.body
547+
548+
exit:
549+
ret void
550+
}
551+
552+
define void @loop_contains_store_safe_dependency(ptr dereferenceable(40) noalias %array, ptr align 2 dereferenceable(80) readonly %pred) {
553+
; CHECK-LABEL: LV: Checking a loop in 'loop_contains_store_safe_dependency'
554+
; CHECK: LV: Not vectorizing: Writes to memory unsupported in early exit loops.
555+
entry:
556+
%forward = getelementptr i16, ptr %pred, i64 -8
557+
br label %for.body
558+
559+
for.body:
560+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]
561+
%st.addr = getelementptr inbounds nuw i16, ptr %array, i64 %iv
562+
%data = load i16, ptr %st.addr, align 2
563+
%inc = add nsw i16 %data, 1
564+
store i16 %inc, ptr %st.addr, align 2
565+
%ee.addr = getelementptr inbounds nuw i16, ptr %pred, i64 %iv
566+
%ee.val = load i16, ptr %ee.addr, align 2
567+
%ee.cond = icmp sgt i16 %ee.val, 500
568+
%some.addr = getelementptr inbounds nuw i16, ptr %forward, i64 %iv
569+
store i16 42, ptr %some.addr, align 2
570+
br i1 %ee.cond, label %exit, label %for.inc
571+
572+
for.inc:
573+
%iv.next = add nuw nsw i64 %iv, 1
574+
%counted.cond = icmp eq i64 %iv.next, 20
575+
br i1 %counted.cond, label %exit, label %for.body
576+
577+
exit:
578+
ret void
579+
}
580+
581+
define void @loop_contains_store_assumed_bounds(ptr noalias %array, ptr readonly %pred, i32 %n) {
582+
; CHECK-LABEL: LV: Checking a loop in 'loop_contains_store_assumed_bounds'
583+
; CHECK: LV: Not vectorizing: Writes to memory unsupported in early exit loops.
584+
entry:
585+
%n_bytes = mul nuw nsw i32 %n, 2
586+
call void @llvm.assume(i1 true) [ "align"(ptr %pred, i64 2), "dereferenceable"(ptr %pred, i32 %n_bytes) ]
587+
%tc = sext i32 %n to i64
588+
br label %for.body
589+
590+
for.body:
591+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]
592+
%st.addr = getelementptr inbounds nuw i16, ptr %array, i64 %iv
593+
%data = load i16, ptr %st.addr, align 2
594+
%inc = add nsw i16 %data, 1
595+
store i16 %inc, ptr %st.addr, align 2
596+
%ee.addr = getelementptr inbounds nuw i16, ptr %pred, i64 %iv
597+
%ee.val = load i16, ptr %ee.addr, align 2
598+
%ee.cond = icmp sgt i16 %ee.val, 500
599+
br i1 %ee.cond, label %exit, label %for.inc
600+
601+
for.inc:
602+
%iv.next = add nuw nsw i64 %iv, 1
603+
%counted.cond = icmp eq i64 %iv.next, %tc
604+
br i1 %counted.cond, label %exit, label %for.body
605+
606+
exit:
607+
ret void
608+
}
609+
610+
define void @loop_contains_store_volatile(ptr dereferenceable(40) noalias %array, ptr align 2 dereferenceable(40) readonly %pred) {
611+
; CHECK-LABEL: LV: Checking a loop in 'loop_contains_store_volatile'
612+
; CHECK: LV: Not vectorizing: Writes to memory unsupported in early exit loops.
613+
entry:
614+
br label %for.body
615+
616+
for.body:
617+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]
618+
%st.addr = getelementptr inbounds nuw i16, ptr %array, i64 %iv
619+
%data = load i16, ptr %st.addr, align 2
620+
%inc = add nsw i16 %data, 1
621+
store volatile i16 %inc, ptr %st.addr, align 2
622+
%ee.addr = getelementptr inbounds nuw i16, ptr %pred, i64 %iv
623+
%ee.val = load i16, ptr %ee.addr, align 2
624+
%ee.cond = icmp sgt i16 %ee.val, 500
625+
br i1 %ee.cond, label %exit, label %for.inc
626+
627+
for.inc:
628+
%iv.next = add nuw nsw i64 %iv, 1
629+
%counted.cond = icmp eq i64 %iv.next, 20
630+
br i1 %counted.cond, label %exit, label %for.body
631+
632+
exit:
633+
ret void
634+
}
635+
636+
define void @exit_conditions_combined(ptr noalias dereferenceable(40) %array, ptr readonly align 2 dereferenceable(40) %pred) {
637+
; CHECK-LABEL: LV: Checking a loop in 'exit_conditions_combined'
638+
; CHECK: LV: Not vectorizing: Cannot vectorize uncountable loop.
639+
entry:
640+
br label %for.body
641+
642+
for.body: ; preds = %for.body, %entry
643+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
644+
%st.addr = getelementptr inbounds nuw i16, ptr %array, i64 %iv
645+
%data = load i16, ptr %st.addr, align 2
646+
%inc = add nsw i16 %data, 1
647+
store i16 %inc, ptr %st.addr, align 2
648+
%ee.addr = getelementptr inbounds nuw i16, ptr %pred, i64 %iv
649+
%ee.val = load i16, ptr %ee.addr, align 2
650+
%ee.cond = icmp sgt i16 %ee.val, 500
651+
%iv.next = add nuw nsw i64 %iv, 1
652+
%counted.cond = icmp eq i64 %iv.next, 20
653+
%or.cond = select i1 %ee.cond, i1 true, i1 %counted.cond
654+
br i1 %or.cond, label %exit, label %for.body
655+
656+
exit: ; preds = %for.body
657+
ret void
658+
}
473659

474660
define i64 @uncountable_exit_in_conditional_block(ptr %mask) {
475661
; CHECK-LABEL: LV: Checking a loop in 'uncountable_exit_in_conditional_block'

0 commit comments

Comments
 (0)