@@ -95,6 +95,127 @@ exit:
9595 ret void
9696}
9797
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+
98219; A loop with two symbolic strides.
99220define void @two_strides (ptr noalias %A , ptr noalias %B , i64 %N , i64 %stride.1 , i64 %stride.2 ) {
100221; CHECK-LABEL: 'two_strides'
0 commit comments