1 /* { dg-do run } */
2 /* { dg-options "-O2 -floop-interchange -fdump-tree-linterchange-details" } */
3 /* { dg-require-effective-target size20plus } */
4 /* { dg-skip-if "too big data segment" { visium-*-* } } */
5 
6 #define M 256
7 int a[M][M], b[M][M], c[M], d[M];
8 void __attribute__((noinline))
simple_reduc_1(int n)9 simple_reduc_1 (int n)
10 {
11   for (int j = 0; j < n; j++)
12     {
13       int sum = c[j];
14       for (int i = 0; i < n; i++)
15 	sum = sum + a[i][j]*b[i][j];
16 
17       c[j] = sum;
18     }
19 }
20 
21 void __attribute__((noinline))
simple_reduc_2(int n)22 simple_reduc_2 (int n)
23 {
24   for (int j = 0; j < n; j++)
25     {
26       int sum = d[j];
27       for (int i = 0; i < n; i++)
28 	sum = sum + a[i][j]*b[i][j];
29 
30       asm volatile ("" ::: "memory");
31       d[j] = sum;
32     }
33 }
34 
35 extern void abort ();
36 
37 static void __attribute__((noinline))
init(int i)38 init (int i)
39 {
40   c[i] = 0;
41   d[i] = 0;
42   for (int j = 0; j < M; j++)
43     {
44       a[i][j] = i;
45       b[i][j] = j;
46     }
47 }
48 
main(void)49 int main (void)
50 {
51   for (int i = 0; i < M; ++i)
52     init (i);
53 
54   simple_reduc_1 (M);
55   simple_reduc_2 (M);
56 
57   for (int i = 0; i < M; ++i)
58     if (c[i] != d[i])
59       abort ();
60 
61   return 0;
62 }
63 
64 /* { dg-final { scan-tree-dump-times "Loop_pair<outer:., inner:.> is interchanged" 1 "linterchange" } } */
65