• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: opt -mtriple=aarch64--linux-gnueabi -loop-vectorize -force-vector-width=4 -force-vector-interleave=1 < %s -S | FileCheck %s
2
3; The following tests contain loops for which SCEV cannot determine the backedge
4; taken count. This is because the backedge taken condition is produced by an
5; icmp with one of the sides being a loop varying non-AddRec expression.
6; However, there is a possibility to normalize this to an AddRec expression
7; using SCEV predicates. This allows us to compute a 'guarded' backedge count.
8; The Loop Vectorizer is able to version to loop in order to use this guarded
9; backedge count and vectorize more loops.
10
11
12; CHECK-LABEL: test_sge
13; CHECK-LABEL: vector.scevcheck
14; CHECK-LABEL: vector.body
15define void @test_sge(i32* noalias %A,
16                      i32* noalias %B,
17                      i32* noalias %C, i32 %N) {
18entry:
19  %cmp13 = icmp eq i32 %N, 0
20  br i1 %cmp13, label %for.end, label %for.body.preheader
21
22for.body.preheader:
23  br label %for.body
24
25for.body:
26  %indvars.iv = phi i16 [ %indvars.next, %for.body ], [ 0, %for.body.preheader ]
27  %indvars.next = add i16 %indvars.iv, 1
28  %indvars.ext = zext i16 %indvars.iv to i32
29
30  %arrayidx = getelementptr inbounds i32, i32* %B, i32 %indvars.ext
31  %0 = load i32, i32* %arrayidx, align 4
32  %arrayidx3 = getelementptr inbounds i32, i32* %C, i32 %indvars.ext
33  %1 = load i32, i32* %arrayidx3, align 4
34
35  %mul4 = mul i32 %1, %0
36
37  %arrayidx7 = getelementptr inbounds i32, i32* %A, i32 %indvars.ext
38  store i32 %mul4, i32* %arrayidx7, align 4
39
40  %exitcond = icmp sge i32 %indvars.ext, %N
41  br i1 %exitcond, label %for.end.loopexit, label %for.body
42
43for.end.loopexit:
44  br label %for.end
45
46for.end:
47  ret void
48}
49
50; CHECK-LABEL: test_uge
51; CHECK-LABEL: vector.scevcheck
52; CHECK-LABEL: vector.body
53define void @test_uge(i32* noalias %A,
54                      i32* noalias %B,
55                      i32* noalias %C, i32 %N, i32 %Offset) {
56entry:
57  %cmp13 = icmp eq i32 %N, 0
58  br i1 %cmp13, label %for.end, label %for.body.preheader
59
60for.body.preheader:
61  br label %for.body
62
63for.body:
64  %indvars.iv = phi i16 [ %indvars.next, %for.body ], [ 0, %for.body.preheader ]
65  %indvars.next = add i16 %indvars.iv, 1
66
67  %indvars.ext = sext i16 %indvars.iv to i32
68  %indvars.access = add i32 %Offset, %indvars.ext
69
70  %arrayidx = getelementptr inbounds i32, i32* %B, i32 %indvars.access
71  %0 = load i32, i32* %arrayidx, align 4
72  %arrayidx3 = getelementptr inbounds i32, i32* %C, i32 %indvars.access
73  %1 = load i32, i32* %arrayidx3, align 4
74
75  %mul4 = add i32 %1, %0
76
77  %arrayidx7 = getelementptr inbounds i32, i32* %A, i32 %indvars.access
78  store i32 %mul4, i32* %arrayidx7, align 4
79
80  %exitcond = icmp uge i32 %indvars.ext, %N
81  br i1 %exitcond, label %for.end.loopexit, label %for.body
82
83for.end.loopexit:
84  br label %for.end
85
86for.end:
87  ret void
88}
89
90; CHECK-LABEL: test_ule
91; CHECK-LABEL: vector.scevcheck
92; CHECK-LABEL: vector.body
93define void @test_ule(i32* noalias %A,
94                      i32* noalias %B,
95                      i32* noalias %C, i32 %N,
96                      i16 %M) {
97entry:
98  %cmp13 = icmp eq i32 %N, 0
99  br i1 %cmp13, label %for.end, label %for.body.preheader
100
101for.body.preheader:
102  br label %for.body
103
104for.body:
105  %indvars.iv = phi i16 [ %indvars.next, %for.body ], [ %M, %for.body.preheader ]
106  %indvars.next = sub i16 %indvars.iv, 1
107  %indvars.ext = zext i16 %indvars.iv to i32
108
109  %arrayidx = getelementptr inbounds i32, i32* %B, i32 %indvars.ext
110  %0 = load i32, i32* %arrayidx, align 4
111  %arrayidx3 = getelementptr inbounds i32, i32* %C, i32 %indvars.ext
112  %1 = load i32, i32* %arrayidx3, align 4
113
114  %mul4 = mul i32 %1, %0
115
116  %arrayidx7 = getelementptr inbounds i32, i32* %A, i32 %indvars.ext
117  store i32 %mul4, i32* %arrayidx7, align 4
118
119  %exitcond = icmp ule i32 %indvars.ext, %N
120  br i1 %exitcond, label %for.end.loopexit, label %for.body
121
122for.end.loopexit:
123  br label %for.end
124
125for.end:
126  ret void
127}
128
129; CHECK-LABEL: test_sle
130; CHECK-LABEL: vector.scevcheck
131; CHECK-LABEL: vector.body
132define void @test_sle(i32* noalias %A,
133                   i32* noalias %B,
134                   i32* noalias %C, i32 %N,
135                   i16 %M) {
136entry:
137  %cmp13 = icmp eq i32 %N, 0
138  br i1 %cmp13, label %for.end, label %for.body.preheader
139
140for.body.preheader:
141  br label %for.body
142
143for.body:
144  %indvars.iv = phi i16 [ %indvars.next, %for.body ], [ %M, %for.body.preheader ]
145  %indvars.next = sub i16 %indvars.iv, 1
146  %indvars.ext = sext i16 %indvars.iv to i32
147
148  %arrayidx = getelementptr inbounds i32, i32* %B, i32 %indvars.ext
149  %0 = load i32, i32* %arrayidx, align 4
150  %arrayidx3 = getelementptr inbounds i32, i32* %C, i32 %indvars.ext
151  %1 = load i32, i32* %arrayidx3, align 4
152
153  %mul4 = mul i32 %1, %0
154
155  %arrayidx7 = getelementptr inbounds i32, i32* %A, i32 %indvars.ext
156  store i32 %mul4, i32* %arrayidx7, align 4
157
158  %exitcond = icmp sle i32 %indvars.ext, %N
159  br i1 %exitcond, label %for.end.loopexit, label %for.body
160
161for.end.loopexit:
162  br label %for.end
163
164for.end:
165  ret void
166}
167