@@ -157,3 +157,105 @@ for.inc: ; preds = %cond.end5
157157for.end: ; preds = %for.cond.cleanup
158158 ret void
159159}
160+
161+ ; Pseudo-code for the following IR:
162+ ;
163+ ; void f(int A[][42]) {
164+ ; for (int i = 0; i < 100; i++)
165+ ; for (int j = 0; j < 41; j++)
166+ ; (j % 2 == 0 ? A[i][j] : A[i][j+1]) = 1;
167+ ; }
168+ ;
169+ ; FIXME: There are loop-carried dependencies between the store instruction. For
170+ ; example, the value of %ptr0 when (i, j) = (0, 1) is %A+8, which is the same
171+ ; as when (i, j) = (0, 2).
172+
173+ define void @non_invariant_baseptr_with_identical_obj (ptr %A ) {
174+ ; CHECK-LABEL: 'non_invariant_baseptr_with_identical_obj'
175+ ; CHECK-NEXT: Src: store i32 1, ptr %idx, align 4 --> Dst: store i32 1, ptr %idx, align 4
176+ ; CHECK-NEXT: da analyze - none!
177+ ;
178+ entry:
179+ br label %loop.i.header
180+
181+ loop.i.header:
182+ %i = phi i32 [ 0 , %entry ], [ %i.inc , %loop.i.latch ]
183+ %A1 = getelementptr i32 , ptr %A , i32 1
184+ br label %loop.j
185+
186+ loop.j:
187+ %j = phi i32 [ 0 , %loop.i.header ], [ %j.inc , %loop.j ]
188+ %ptr0 = phi ptr [ %A , %loop.i.header ], [ %ptr1 , %loop.j ]
189+ %ptr1 = phi ptr [ %A1 , %loop.i.header ], [ %ptr0 , %loop.j ]
190+ %idx = getelementptr [42 x i32 ], ptr %ptr0 , i32 %i , i32 %j
191+ store i32 1 , ptr %idx
192+ %j.inc = add i32 %j , 1
193+ %cmp.j = icmp slt i32 %j.inc , 41
194+ br i1 %cmp.j , label %loop.j , label %loop.i.latch
195+
196+ loop.i.latch:
197+ %i.inc = add i32 %i , 1
198+ %cmp.i = icmp slt i32 %i.inc , 100
199+ br i1 %cmp.i , label %loop.i.header , label %exit
200+
201+ exit:
202+ ret void
203+ }
204+
205+ ; Pseudo-code for the following IR:
206+ ;
207+ ; void f(int A[][42][42]) {
208+ ; for (int i = 0; i < 100; i++)
209+ ; for (int j = 0; j < 41; j++) {
210+ ; int *ptr0 = (j % 2 == 0 ? A[i][j] : A[i][j+1]);
211+ ; for (int k = 0; k < 42; k++)
212+ ; ptr0[k] = 1;
213+ ; }
214+ ; }
215+ ;
216+ ; Similar to the above case, but ptr0 is loop-invariant with respsect to the
217+ ; k-loop.
218+ ;
219+ ; FIXME: Same as the above case, there are loop-carried dependencies between
220+ ; the store.
221+
222+ define void @non_invariant_baseptr_with_identical_obj2 (ptr %A ) {
223+ ; CHECK-LABEL: 'non_invariant_baseptr_with_identical_obj2'
224+ ; CHECK-NEXT: Src: store i32 1, ptr %idx, align 4 --> Dst: store i32 1, ptr %idx, align 4
225+ ; CHECK-NEXT: da analyze - none!
226+ ;
227+ entry:
228+ br label %loop.i.header
229+
230+ loop.i.header:
231+ %i = phi i32 [ 0 , %entry ], [ %i.inc , %loop.i.latch ]
232+ %A1 = getelementptr i32 , ptr %A , i32 1
233+ br label %loop.j.header
234+
235+ loop.j.header:
236+ %j = phi i32 [ 0 , %loop.i.header ], [ %j.inc , %loop.j.latch ]
237+ %ptr0 = phi ptr [ %A , %loop.i.header ], [ %ptr1 , %loop.j.latch ]
238+ %ptr1 = phi ptr [ %A1 , %loop.i.header ], [ %ptr0 , %loop.j.latch ]
239+ br label %loop.k
240+
241+ loop.k:
242+ %k = phi i32 [ 0 , %loop.j.header ], [ %k.inc , %loop.k ]
243+ %idx = getelementptr [42 x [42 x i32 ]], ptr %ptr0 , i32 %i , i32 %k , i32 %j
244+ store i32 1 , ptr %idx
245+ %k.inc = add i32 %k , 1
246+ %cmp.k = icmp slt i32 %k.inc , 42
247+ br i1 %cmp.k , label %loop.k , label %loop.j.latch
248+
249+ loop.j.latch:
250+ %j.inc = add i32 %j , 1
251+ %cmp.j = icmp slt i32 %j.inc , 41
252+ br i1 %cmp.j , label %loop.j.header , label %loop.i.latch
253+
254+ loop.i.latch:
255+ %i.inc = add i32 %i , 1
256+ %cmp.i = icmp slt i32 %i.inc , 100
257+ br i1 %cmp.i , label %loop.i.header , label %exit
258+
259+ exit:
260+ ret void
261+ }
0 commit comments