@@ -198,8 +198,57 @@ exit:
198198 ret void
199199}
200200
201- ; Fail to delinearize because the step recurrence of the j-loop is not
202- ; divisible by that of the k-loop.
201+ ; Fail to delinearize because the step recurrence value of the i-loop is not
202+ ; divisible by that of the j-loop.
203+ ;
204+ ; void f(int A[][8][32]) {
205+ ; for (i = 0; i < 42; i++)
206+ ; for (j = 0; j < 2; j++)
207+ ; for (k = 0; k < 42; k++)
208+ ; A[i][3*j][k] = 1;
209+ ; }
210+
211+ ; CHECK: Delinearization on function a_i_3j_k:
212+ ; CHECK: AccessFunction: {{...}}0,+,1024}<nuw><nsw><%for.i.header>,+,384}<nw><%for.j.header>,+,4}<nw><%for.k>
213+ ; CHECK-NEXT: failed to delinearize
214+ define void @a_i_3j_k (ptr %a ) {
215+ entry:
216+ br label %for.i.header
217+
218+ for.i.header:
219+ %i = phi i32 [ 0 , %entry ], [ %i.inc , %for.i.latch ]
220+ br label %for.j.header
221+
222+ for.j.header:
223+ %j = phi i32 [ 0 , %for.i.header ], [ %j.inc , %for.j.latch ]
224+ %j.subscript = mul i32 %j , 3
225+ br label %for.k
226+
227+ for.k:
228+ %k = phi i32 [ 0 , %for.j.header ], [ %k.inc , %for.k ]
229+ %idx = getelementptr [8 x [32 x i32 ]], ptr %a , i32 %i , i32 %j.subscript , i32 %k
230+ store i32 1 , ptr %idx
231+ %k.inc = add i32 %k , 1
232+ %cmp.k = icmp slt i32 %k.inc , 42
233+ br i1 %cmp.k , label %for.k , label %for.j.latch
234+
235+ for.j.latch:
236+ %j.inc = add i32 %j , 1
237+ %cmp.j = icmp slt i32 %j.inc , 2
238+ br i1 %cmp.j , label %for.j.header , label %for.i.latch
239+
240+ for.i.latch:
241+ %i.inc = add i32 %i , 1
242+ %cmp.i = icmp slt i32 %i.inc , 42
243+ br i1 %cmp.i , label %for.i.header , label %exit
244+
245+ exit:
246+ ret void
247+ }
248+
249+ ; Although the step recurrence value of j-loop is not divisible by that of the
250+ ; k-loop, delinearization is possible because we know that the "actual" stride
251+ ; width for the last dimension is 4 instead of 12.
203252;
204253; void f(int A[][8][32]) {
205254; for (i = 0; i < 42; i++)
@@ -209,8 +258,9 @@ exit:
209258; }
210259
211260; CHECK: Delinearization on function a_i_j_3k:
212- ; CHECK: AccessFunction: {{...}}0,+,1024}<nuw><nsw><%for.i.header>,+,128}<nw><%for.j.header>,+,12}<nw><%for.k>
213- ; CHECK-NEXT: failed to delinearize
261+ ; CHECK: Base offset: %a
262+ ; CHECK-NEXT: ArrayDecl[UnknownSize][8][32] with elements of 4 bytes.
263+ ; CHECK-NEXT: ArrayRef[{0,+,1}<nuw><nsw><%for.i.header>][{0,+,1}<nuw><nsw><%for.j.header>][{0,+,3}<nuw><nsw><%for.k>]
214264define void @a_i_j_3k (ptr %a ) {
215265entry:
216266 br label %for.i.header
@@ -250,15 +300,15 @@ exit:
250300;
251301; void f(int A[][8][32]) {
252302; for (i = 0; i < 32; i++)
253- ; for (j = 0; j < 4 ; j++)
303+ ; for (j = 0; j < 2 ; j++)
254304; for (k = 0; k < 4; k++)
255- ; A[i][j+k][i] = 1;
305+ ; A[i][2* j+k][i] = 1;
256306; }
257307
258- ; CHECK: Delinearization on function a_i_jk_i :
259- ; CHECK: AccessFunction: {{...}}0,+,1028}<%for.i.header>,+,128 }<nw><%for.j.header>,+,128}<nw><%for.k>
308+ ; CHECK: Delinearization on function a_i_j2k_i :
309+ ; CHECK: AccessFunction: {{...}}0,+,1028}<%for.i.header>,+,256 }<nw><%for.j.header>,+,128}<nw><%for.k>
260310; CHECK-NEXT: failed to delinearize
261- define void @a_i_jk_i (ptr %a ) {
311+ define void @a_i_j2k_i (ptr %a ) {
262312entry:
263313 br label %for.i.header
264314
@@ -272,16 +322,17 @@ for.j.header:
272322
273323for.k:
274324 %k = phi i32 [ 0 , %for.j.header ], [ %k.inc , %for.k ]
275- %jk = add i32 %j , %k
276- %idx = getelementptr [8 x [32 x i32 ]], ptr %a , i32 %i , i32 %jk , i32 %i
325+ %j2 = shl i32 %j , 1
326+ %j2.k = add i32 %j2 , %k
327+ %idx = getelementptr [8 x [32 x i32 ]], ptr %a , i32 %i , i32 %j2.k , i32 %i
277328 store i32 1 , ptr %idx
278329 %k.inc = add i32 %k , 1
279330 %cmp.k = icmp slt i32 %k.inc , 4
280331 br i1 %cmp.k , label %for.k , label %for.j.latch
281332
282333for.j.latch:
283334 %j.inc = add i32 %j , 1
284- %cmp.j = icmp slt i32 %j.inc , 4
335+ %cmp.j = icmp slt i32 %j.inc , 2
285336 br i1 %cmp.j , label %for.j.header , label %for.i.latch
286337
287338for.i.latch:
0 commit comments