@@ -95,6 +95,127 @@ exit:
95
95
ret void
96
96
}
97
97
98
+ define void @single_stride_castexpr (i32 %offset , ptr %src , ptr %dst , i1 %cond ) {
99
+ ; CHECK-LABEL: 'single_stride_castexpr'
100
+ ; CHECK-NEXT: inner.loop:
101
+ ; CHECK-NEXT: Memory dependences are safe with run-time checks
102
+ ; CHECK-NEXT: Dependences:
103
+ ; CHECK-NEXT: Run-time memory checks:
104
+ ; CHECK-NEXT: Check 0:
105
+ ; CHECK-NEXT: Comparing group ([[GRP1:0x[0-9a-f]+]]):
106
+ ; CHECK-NEXT: %gep.dst = getelementptr i32, ptr %dst, i64 %iv.2
107
+ ; CHECK-NEXT: Against group ([[GRP2:0x[0-9a-f]+]]):
108
+ ; CHECK-NEXT: %gep.src = getelementptr inbounds i32, ptr %src, i32 %iv.3
109
+ ; CHECK-NEXT: Grouped accesses:
110
+ ; CHECK-NEXT: Group [[GRP1]]:
111
+ ; CHECK-NEXT: (Low: ((4 * %iv.1) + %dst) High: (804 + (4 * %iv.1) + %dst))
112
+ ; CHECK-NEXT: Member: {((4 * %iv.1) + %dst),+,4}<%inner.loop>
113
+ ; CHECK-NEXT: Group [[GRP2]]:
114
+ ; CHECK-NEXT: (Low: %src High: (804 + %src))
115
+ ; CHECK-NEXT: Member: {%src,+,4}<nuw><%inner.loop>
116
+ ; CHECK-EMPTY:
117
+ ; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
118
+ ; CHECK-NEXT: SCEV assumptions:
119
+ ; CHECK-NEXT: Equal predicate: %offset == 1
120
+ ; CHECK-EMPTY:
121
+ ; CHECK-NEXT: Expressions re-written:
122
+ ; CHECK-NEXT: [PSE] %gep.dst = getelementptr i32, ptr %dst, i64 %iv.2:
123
+ ; CHECK-NEXT: {((4 * %iv.1) + %dst),+,(4 * (sext i32 %offset to i64))<nsw>}<%inner.loop>
124
+ ; CHECK-NEXT: --> {((4 * %iv.1) + %dst),+,4}<%inner.loop>
125
+ ; CHECK-NEXT: outer.header:
126
+ ; CHECK-NEXT: Report: loop is not the innermost loop
127
+ ; CHECK-NEXT: Dependences:
128
+ ; CHECK-NEXT: Run-time memory checks:
129
+ ; CHECK-NEXT: Grouped accesses:
130
+ ; CHECK-EMPTY:
131
+ ; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
132
+ ; CHECK-NEXT: SCEV assumptions:
133
+ ; CHECK-EMPTY:
134
+ ; CHECK-NEXT: Expressions re-written:
135
+ ;
136
+ entry:
137
+ %offset.ext = sext i32 %offset to i64
138
+ br label %outer.header
139
+
140
+ outer.header:
141
+ %iv.1 = phi i64 [ 0 , %entry ], [ %iv.2.next , %inner.loop ]
142
+ br i1 %cond , label %inner.loop , label %exit
143
+
144
+ inner.loop:
145
+ %iv.2 = phi i64 [ %iv.1 , %outer.header ], [ %iv.2.next , %inner.loop ]
146
+ %iv.3 = phi i32 [ 0 , %outer.header ], [ %iv.3.next , %inner.loop ]
147
+ %gep.src = getelementptr inbounds i32 , ptr %src , i32 %iv.3
148
+ %load = load i32 , ptr %gep.src , align 8
149
+ %gep.dst = getelementptr i32 , ptr %dst , i64 %iv.2
150
+ store i32 %load , ptr %gep.dst , align 8
151
+ %iv.2.next = add i64 %iv.2 , %offset.ext
152
+ %iv.3.next = add i32 %iv.3 , 1
153
+ %ec = icmp eq i32 %iv.3 , 200
154
+ br i1 %ec , label %outer.header , label %inner.loop
155
+
156
+ exit:
157
+ ret void
158
+ }
159
+
160
+ define void @single_stride_castexpr_multiuse (i32 %offset , ptr %src , ptr %dst , i1 %cond ) {
161
+ ; CHECK-LABEL: 'single_stride_castexpr_multiuse'
162
+ ; CHECK-NEXT: inner.loop:
163
+ ; CHECK-NEXT: Memory dependences are safe with run-time checks
164
+ ; CHECK-NEXT: Dependences:
165
+ ; CHECK-NEXT: Run-time memory checks:
166
+ ; CHECK-NEXT: Check 0:
167
+ ; CHECK-NEXT: Comparing group ([[GRP3:0x[0-9a-f]+]]):
168
+ ; CHECK-NEXT: %gep.dst = getelementptr i32, ptr %dst, i64 %iv.2
169
+ ; CHECK-NEXT: Against group ([[GRP4:0x[0-9a-f]+]]):
170
+ ; CHECK-NEXT: %gep.src = getelementptr inbounds i32, ptr %src, i64 %iv.3
171
+ ; CHECK-NEXT: Grouped accesses:
172
+ ; CHECK-NEXT: Group [[GRP3]]:
173
+ ; CHECK-NEXT: (Low: (((4 * %iv.1) + %dst) umin ((4 * %iv.1) + (4 * (sext i32 %offset to i64) * (200 + (-1 * (zext i32 %offset to i64))<nsw>)<nsw>) + %dst)) High: (4 + (((4 * %iv.1) + %dst) umax ((4 * %iv.1) + (4 * (sext i32 %offset to i64) * (200 + (-1 * (zext i32 %offset to i64))<nsw>)<nsw>) + %dst))))
174
+ ; CHECK-NEXT: Member: {((4 * %iv.1) + %dst),+,(4 * (sext i32 %offset to i64))<nsw>}<%inner.loop>
175
+ ; CHECK-NEXT: Group [[GRP4]]:
176
+ ; CHECK-NEXT: (Low: ((4 * (zext i32 %offset to i64))<nuw><nsw> + %src) High: (804 + %src))
177
+ ; CHECK-NEXT: Member: {((4 * (zext i32 %offset to i64))<nuw><nsw> + %src),+,4}<%inner.loop>
178
+ ; CHECK-EMPTY:
179
+ ; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
180
+ ; CHECK-NEXT: SCEV assumptions:
181
+ ; CHECK-EMPTY:
182
+ ; CHECK-NEXT: Expressions re-written:
183
+ ; CHECK-NEXT: outer.header:
184
+ ; CHECK-NEXT: Report: loop is not the innermost loop
185
+ ; CHECK-NEXT: Dependences:
186
+ ; CHECK-NEXT: Run-time memory checks:
187
+ ; CHECK-NEXT: Grouped accesses:
188
+ ; CHECK-EMPTY:
189
+ ; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
190
+ ; CHECK-NEXT: SCEV assumptions:
191
+ ; CHECK-EMPTY:
192
+ ; CHECK-NEXT: Expressions re-written:
193
+ ;
194
+ entry:
195
+ %offset.ext = sext i32 %offset to i64
196
+ %offset.zext = zext i32 %offset to i64
197
+ br label %outer.header
198
+
199
+ outer.header:
200
+ %iv.1 = phi i64 [ 0 , %entry ], [ %iv.2.next , %inner.loop ]
201
+ br i1 %cond , label %inner.loop , label %exit
202
+
203
+ inner.loop:
204
+ %iv.2 = phi i64 [ %iv.1 , %outer.header ], [ %iv.2.next , %inner.loop ]
205
+ %iv.3 = phi i64 [ %offset.zext , %outer.header ], [ %iv.3.next , %inner.loop ]
206
+ %gep.src = getelementptr inbounds i32 , ptr %src , i64 %iv.3
207
+ %load = load i32 , ptr %gep.src , align 8
208
+ %gep.dst = getelementptr i32 , ptr %dst , i64 %iv.2
209
+ store i32 %load , ptr %gep.dst , align 8
210
+ %iv.2.next = add i64 %iv.2 , %offset.ext
211
+ %iv.3.next = add i64 %iv.3 , 1
212
+ %ec = icmp eq i64 %iv.3 , 200
213
+ br i1 %ec , label %outer.header , label %inner.loop
214
+
215
+ exit:
216
+ ret void
217
+ }
218
+
98
219
; A loop with two symbolic strides.
99
220
define void @two_strides (ptr noalias %A , ptr noalias %B , i64 %N , i64 %stride.1 , i64 %stride.2 ) {
100
221
; CHECK-LABEL: 'two_strides'
0 commit comments