1 /* { dg-do run } */
2 /* { dg-options "-O2 -fsplit-loops -fdump-tree-lsplit-details" } */
3 /* { dg-require-effective-target int32plus } */
4 
5 #ifdef __cplusplus
6 extern "C" int printf (const char *, ...);
7 extern "C" void abort (void);
8 #else
9 extern int printf (const char *, ...);
10 extern void abort (void);
11 #endif
12 
13 /* Define TRACE to 1 or 2 to get detailed tracing.
14    Define SINGLE_TEST to 1 or 2 to get a simple routine with
15    just one loop, called only one time or with multiple parameters,
16    to make debugging easier.  */
17 #ifndef TRACE
18 #define TRACE 0
19 #endif
20 
21 #define loop(beg,step,beg2,cond1,cond2) \
22     do \
23       { \
24 	sum = 0; \
25         for (i = (beg), j = (beg2); (cond1); i+=(step),j+=(step)) \
26           { \
27             if (cond2) { \
28 	      if (TRACE > 1) printf ("a: %d %d\n", i, j); \
29               sum += a[i]; \
30 	    } else { \
31 	      if (TRACE > 1) printf ("b: %d %d\n", i, j); \
32               sum += b[i]; \
33 	    } \
34           } \
35 	if (TRACE > 0) printf ("sum: %d\n", sum); \
36 	check = check * 47 + sum; \
37       } while (0)
38 
39 #ifndef SINGLE_TEST
dotest(int beg,int end,int step,int c,int * a,int * b,int beg2)40 unsigned __attribute__((noinline, noclone)) dotest (int beg, int end, int step,
41 					       int c, int *a, int *b, int beg2)
42 {
43   unsigned check = 0;
44   int sum;
45   int i, j;
46   loop (beg, 1, beg2, i < end, j < c);
47   loop (beg, 1, beg2, i <= end, j < c);
48   loop (beg, 1, beg2, i < end, j <= c);
49   loop (beg, 1, beg2, i <= end, j <= c);
50   loop (beg, 1, beg2, i < end, j > c);
51   loop (beg, 1, beg2, i <= end, j > c);
52   loop (beg, 1, beg2, i < end, j >= c);
53   loop (beg, 1, beg2, i <= end, j >= c);
54   beg2 += end-beg;
55   loop (end, -1, beg2, i >= beg, j >= c);
56   loop (end, -1, beg2, i >= beg, j > c);
57   loop (end, -1, beg2, i > beg, j >= c);
58   loop (end, -1, beg2, i > beg, j > c);
59   loop (end, -1, beg2, i >= beg, j <= c);
60   loop (end, -1, beg2, i >= beg, j < c);
61   loop (end, -1, beg2, i > beg, j <= c);
62   loop (end, -1, beg2, i > beg, j < c);
63   return check;
64 }
65 
66 #else
67 
f(int beg,int end,int step,int c,int * a,int * b,int beg2)68 int __attribute__((noinline, noclone)) f (int beg, int end, int step,
69 					  int c, int *a, int *b, int beg2)
70 {
71   int sum = 0;
72   int i, j;
73   //for (i = beg, j = beg2; i < end; i += 1, j++ /*step*/)
74   for (i = end, j = beg2 + (end-beg); i > beg; i += -1, j-- /*step*/)
75     {
76       // i - j == X --> i = X + j
77       // --> i < end == X+j < end == j < end - X
78       // --> newend = end - (i_init - j_init)
79       // j < end-X && j < c --> j < min(end-X,c)
80       // j < end-X && j <= c --> j <= min(end-X-1,c) or j < min(end-X,c+1{OF!})
81       //if (j < c)
82       if (j >= c)
83 	printf ("a: %d %d\n", i, j);
84       /*else
85 	printf ("b: %d %d\n", i, j);*/
86 	/*sum += a[i];
87       else
88 	sum += b[i];*/
89     }
90   return sum;
91 }
92 
f2(int * beg,int * end,int step,int * c,int * a,int * b,int * beg2)93 int __attribute__((noinline, noclone)) f2 (int *beg, int *end, int step,
94 					  int *c, int *a, int *b, int *beg2)
95 {
96   int sum = 0;
97   int *i, *j;
98   for (i = beg, j = beg2; i < end; i += 1, j++ /*step*/)
99     {
100       if (j <= c)
101 	printf ("%d %d\n", i - beg, j - beg);
102 	/*sum += a[i];
103       else
104 	sum += b[i];*/
105     }
106   return sum;
107 }
108 #endif
109 
110 extern int printf (const char *, ...);
111 
main()112 int main ()
113 {
114   int a[] = {0,0,0,0,0, 1,2,3,4,5,6,7,8,9,          0,0,0,0,0};
115   int b[] = {0,0,0,0,0, -1,-2,-3,-4,-5,-6,-7,-8,-9, 0,0,0,0,0,};
116   int c;
117   int diff = 0;
118   unsigned check = 0;
119 #if defined(SINGLE_TEST) && (SINGLE_TEST == 1)
120   //dotest (0, 9, 1, -1, a+5, b+5, -1);
121   //return 0;
122   f (0, 9, 1, 5, a+5, b+5, -1);
123   return 0;
124 #endif
125   for (diff = -5; diff <= 5; diff++)
126     {
127       for (c = -1; c <= 10; c++)
128 	{
129 #ifdef SINGLE_TEST
130 	  int s = f (0, 9, 1, c, a+5, b+5, diff);
131 	  //int s = f2 (a+0, a+9, 1, a+c, a+5, b+5, a+diff);
132 	  printf ("%d ", s);
133 #else
134 	  if (TRACE > 0)
135 	    printf ("check %d %d\n", c, diff);
136 	  check = check * 51 + dotest (0, 9, 1, c, a+5, b+5, diff);
137 #endif
138 	}
139       //printf ("\n");
140     }
141   //printf ("%u\n", check);
142   if (check != 3213344948)
143     abort ();
144   return 0;
145 }
146 
147 /* All 16 loops in dotest should be split.  */
148 /* { dg-final { scan-tree-dump-times "Loop split" 16 "lsplit" } } */
149