Skip to content

Commit 3f401f8

Browse files
committed
* Move tests directly related to store functionality to a new file
* Improved test function names to clarify * Removed redundant test
1 parent e004839 commit 3f401f8

File tree

2 files changed

+170
-193
lines changed

2 files changed

+170
-193
lines changed

llvm/test/Transforms/LoopVectorize/early_exit_legality.ll

Lines changed: 2 additions & 193 deletions
Original file line numberDiff line numberDiff line change
@@ -442,199 +442,8 @@ loop.end:
442442
ret i64 %retval
443443
}
444444

445-
446-
define i64 @loop_contains_store(ptr %dest) {
447-
; CHECK-LABEL: LV: Checking a loop in 'loop_contains_store'
448-
; CHECK: LV: Not vectorizing: Writes to memory unsupported in early exit loops
449-
entry:
450-
%p1 = alloca [1024 x i8]
451-
call void @init_mem(ptr %p1, i64 1024)
452-
br label %loop
453-
454-
loop:
455-
%index = phi i64 [ %index.next, %loop.inc ], [ 3, %entry ]
456-
%arrayidx = getelementptr inbounds i32, ptr %p1, i64 %index
457-
%ld1 = load i32, ptr %arrayidx, align 1
458-
%arrayidx2 = getelementptr inbounds i32, ptr %dest, i64 %index
459-
store i32 %ld1, ptr %arrayidx2, align 4
460-
%cmp = icmp eq i32 %ld1, 1
461-
br i1 %cmp, label %loop.inc, label %loop.end
462-
463-
loop.inc:
464-
%index.next = add i64 %index, 1
465-
%exitcond = icmp ne i64 %index.next, 67
466-
br i1 %exitcond, label %loop, label %loop.end
467-
468-
loop.end:
469-
%retval = phi i64 [ %index, %loop ], [ 67, %loop.inc ]
470-
ret i64 %retval
471-
}
472-
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'
445+
define void @exit_conditions_combined_in_single_branch(ptr noalias dereferenceable(40) %array, ptr readonly align 2 dereferenceable(40) %pred) {
446+
; CHECK-LABEL: LV: Checking a loop in 'exit_conditions_combined_in_single_branch'
638447
; CHECK: LV: Not vectorizing: Cannot vectorize uncountable loop.
639448
entry:
640449
br label %for.body
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
2+
; REQUIRES: asserts
3+
; RUN: opt -S < %s -p loop-vectorize -debug-only=loop-vectorize -enable-early-exit-vectorization -force-vector-width=4 -disable-output 2>&1 | FileCheck %s
4+
5+
define i64 @loop_contains_store(ptr %dest) {
6+
; CHECK-LABEL: LV: Checking a loop in 'loop_contains_store'
7+
; CHECK: LV: Not vectorizing: Writes to memory unsupported in early exit loops
8+
entry:
9+
%p1 = alloca [1024 x i8]
10+
call void @init_mem(ptr %p1, i64 1024)
11+
br label %loop
12+
13+
loop:
14+
%index = phi i64 [ %index.next, %loop.inc ], [ 3, %entry ]
15+
%arrayidx = getelementptr inbounds i32, ptr %p1, i64 %index
16+
%ld1 = load i32, ptr %arrayidx, align 1
17+
%arrayidx2 = getelementptr inbounds i32, ptr %dest, i64 %index
18+
store i32 %ld1, ptr %arrayidx2, align 4
19+
%cmp = icmp eq i32 %ld1, 1
20+
br i1 %cmp, label %loop.inc, label %loop.end
21+
22+
loop.inc:
23+
%index.next = add i64 %index, 1
24+
%exitcond = icmp ne i64 %index.next, 67
25+
br i1 %exitcond, label %loop, label %loop.end
26+
27+
loop.end:
28+
%retval = phi i64 [ %index, %loop ], [ 67, %loop.inc ]
29+
ret i64 %retval
30+
}
31+
32+
define void @loop_contains_store_condition_load_has_single_user(ptr dereferenceable(40) noalias %array, ptr align 2 dereferenceable(40) readonly %pred) {
33+
; CHECK-LABEL: LV: Checking a loop in 'loop_contains_store_condition_load_has_single_user'
34+
; CHECK: LV: Not vectorizing: Writes to memory unsupported in early exit loops.
35+
entry:
36+
br label %for.body
37+
38+
for.body:
39+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]
40+
%st.addr = getelementptr inbounds nuw i16, ptr %array, i64 %iv
41+
%data = load i16, ptr %st.addr, align 2
42+
%inc = add nsw i16 %data, 1
43+
store i16 %inc, ptr %st.addr, align 2
44+
%ee.addr = getelementptr inbounds nuw i16, ptr %pred, i64 %iv
45+
%ee.val = load i16, ptr %ee.addr, align 2
46+
%ee.cond = icmp sgt i16 %ee.val, 500
47+
br i1 %ee.cond, label %exit, label %for.inc
48+
49+
for.inc:
50+
%iv.next = add nuw nsw i64 %iv, 1
51+
%counted.cond = icmp eq i64 %iv.next, 20
52+
br i1 %counted.cond, label %exit, label %for.body
53+
54+
exit:
55+
ret void
56+
}
57+
58+
define void @loop_contains_store_fcmp_condition(ptr dereferenceable(40) noalias %array, ptr align 2 dereferenceable(40) readonly %pred) {
59+
; CHECK-LABEL: LV: Checking a loop in 'loop_contains_store_fcmp_condition'
60+
; CHECK: LV: Not vectorizing: Writes to memory unsupported in early exit loops.
61+
entry:
62+
br label %for.body
63+
64+
for.body:
65+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]
66+
%st.addr = getelementptr inbounds nuw i16, ptr %array, i64 %iv
67+
%data = load i16, ptr %st.addr, align 2
68+
%inc = add nsw i16 %data, 1
69+
store i16 %inc, ptr %st.addr, align 2
70+
%ee.addr = getelementptr inbounds nuw half, ptr %pred, i64 %iv
71+
%ee.val = load half, ptr %ee.addr, align 2
72+
%ee.cond = fcmp ugt half %ee.val, 500.0
73+
br i1 %ee.cond, label %exit, label %for.inc
74+
75+
for.inc:
76+
%iv.next = add nuw nsw i64 %iv, 1
77+
%counted.cond = icmp eq i64 %iv.next, 20
78+
br i1 %counted.cond, label %exit, label %for.body
79+
80+
exit:
81+
ret void
82+
}
83+
84+
define void @loop_contains_store_safe_dependency(ptr dereferenceable(40) noalias %array, ptr align 2 dereferenceable(80) readonly %pred) {
85+
; CHECK-LABEL: LV: Checking a loop in 'loop_contains_store_safe_dependency'
86+
; CHECK: LV: Not vectorizing: Writes to memory unsupported in early exit loops.
87+
entry:
88+
%forward = getelementptr i16, ptr %pred, i64 -8
89+
br label %for.body
90+
91+
for.body:
92+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]
93+
%st.addr = getelementptr inbounds nuw i16, ptr %array, i64 %iv
94+
%data = load i16, ptr %st.addr, align 2
95+
%inc = add nsw i16 %data, 1
96+
store i16 %inc, ptr %st.addr, align 2
97+
%ee.addr = getelementptr inbounds nuw i16, ptr %pred, i64 %iv
98+
%ee.val = load i16, ptr %ee.addr, align 2
99+
%ee.cond = icmp sgt i16 %ee.val, 500
100+
%some.addr = getelementptr inbounds nuw i16, ptr %forward, i64 %iv
101+
store i16 42, ptr %some.addr, align 2
102+
br i1 %ee.cond, label %exit, label %for.inc
103+
104+
for.inc:
105+
%iv.next = add nuw nsw i64 %iv, 1
106+
%counted.cond = icmp eq i64 %iv.next, 20
107+
br i1 %counted.cond, label %exit, label %for.body
108+
109+
exit:
110+
ret void
111+
}
112+
113+
define void @loop_contains_store_assumed_bounds(ptr noalias %array, ptr readonly %pred, i32 %n) {
114+
; CHECK-LABEL: LV: Checking a loop in 'loop_contains_store_assumed_bounds'
115+
; CHECK: LV: Not vectorizing: Writes to memory unsupported in early exit loops.
116+
entry:
117+
%n_bytes = mul nuw nsw i32 %n, 2
118+
call void @llvm.assume(i1 true) [ "align"(ptr %pred, i64 2), "dereferenceable"(ptr %pred, i32 %n_bytes) ]
119+
%tc = sext i32 %n to i64
120+
br label %for.body
121+
122+
for.body:
123+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]
124+
%st.addr = getelementptr inbounds nuw i16, ptr %array, i64 %iv
125+
%data = load i16, ptr %st.addr, align 2
126+
%inc = add nsw i16 %data, 1
127+
store i16 %inc, ptr %st.addr, align 2
128+
%ee.addr = getelementptr inbounds nuw i16, ptr %pred, i64 %iv
129+
%ee.val = load i16, ptr %ee.addr, align 2
130+
%ee.cond = icmp sgt i16 %ee.val, 500
131+
br i1 %ee.cond, label %exit, label %for.inc
132+
133+
for.inc:
134+
%iv.next = add nuw nsw i64 %iv, 1
135+
%counted.cond = icmp eq i64 %iv.next, %tc
136+
br i1 %counted.cond, label %exit, label %for.body
137+
138+
exit:
139+
ret void
140+
}
141+
142+
define void @loop_contains_store_volatile(ptr dereferenceable(40) noalias %array, ptr align 2 dereferenceable(40) readonly %pred) {
143+
; CHECK-LABEL: LV: Checking a loop in 'loop_contains_store_volatile'
144+
; CHECK: LV: Not vectorizing: Writes to memory unsupported in early exit loops.
145+
entry:
146+
br label %for.body
147+
148+
for.body:
149+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]
150+
%st.addr = getelementptr inbounds nuw i16, ptr %array, i64 %iv
151+
%data = load i16, ptr %st.addr, align 2
152+
%inc = add nsw i16 %data, 1
153+
store volatile i16 %inc, ptr %st.addr, align 2
154+
%ee.addr = getelementptr inbounds nuw i16, ptr %pred, i64 %iv
155+
%ee.val = load i16, ptr %ee.addr, align 2
156+
%ee.cond = icmp sgt i16 %ee.val, 500
157+
br i1 %ee.cond, label %exit, label %for.inc
158+
159+
for.inc:
160+
%iv.next = add nuw nsw i64 %iv, 1
161+
%counted.cond = icmp eq i64 %iv.next, 20
162+
br i1 %counted.cond, label %exit, label %for.body
163+
164+
exit:
165+
ret void
166+
}
167+
168+
declare void @init_mem(ptr, i64);

0 commit comments

Comments
 (0)