blob: 81fdb700f0aac6c13ab9dba680f50c7f459cb05b [file] [log] [blame]
/* { dg-do run } */
/* { dg-options "-O2 -fsplit-loops -fdump-tree-lsplit-details" } */
/* { dg-require-effective-target int32plus } */
#ifdef __cplusplus
extern "C" int printf (const char *, ...);
extern "C" void abort (void);
#else
extern int printf (const char *, ...);
extern void abort (void);
#endif
/* Define TRACE to 1 or 2 to get detailed tracing.
Define SINGLE_TEST to 1 or 2 to get a simple routine with
just one loop, called only one time or with multiple parameters,
to make debugging easier. */
#ifndef TRACE
#define TRACE 0
#endif
#define loop(beg,step,beg2,cond1,cond2) \
do \
{ \
sum = 0; \
for (i = (beg), j = (beg2); (cond1); i+=(step),j+=(step)) \
{ \
if (cond2) { \
if (TRACE > 1) printf ("a: %d %d\n", i, j); \
sum += a[i]; \
} else { \
if (TRACE > 1) printf ("b: %d %d\n", i, j); \
sum += b[i]; \
} \
} \
if (TRACE > 0) printf ("sum: %d\n", sum); \
check = check * 47 + sum; \
} while (0)
#ifndef SINGLE_TEST
unsigned __attribute__((noinline, noclone)) dotest (int beg, int end, int step,
int c, int *a, int *b, int beg2)
{
unsigned check = 0;
int sum;
int i, j;
loop (beg, 1, beg2, i < end, j < c);
loop (beg, 1, beg2, i <= end, j < c);
loop (beg, 1, beg2, i < end, j <= c);
loop (beg, 1, beg2, i <= end, j <= c);
loop (beg, 1, beg2, i < end, j > c);
loop (beg, 1, beg2, i <= end, j > c);
loop (beg, 1, beg2, i < end, j >= c);
loop (beg, 1, beg2, i <= end, j >= c);
beg2 += end-beg;
loop (end, -1, beg2, i >= beg, j >= c);
loop (end, -1, beg2, i >= beg, j > c);
loop (end, -1, beg2, i > beg, j >= c);
loop (end, -1, beg2, i > beg, j > c);
loop (end, -1, beg2, i >= beg, j <= c);
loop (end, -1, beg2, i >= beg, j < c);
loop (end, -1, beg2, i > beg, j <= c);
loop (end, -1, beg2, i > beg, j < c);
return check;
}
#else
int __attribute__((noinline, noclone)) f (int beg, int end, int step,
int c, int *a, int *b, int beg2)
{
int sum = 0;
int i, j;
//for (i = beg, j = beg2; i < end; i += 1, j++ /*step*/)
for (i = end, j = beg2 + (end-beg); i > beg; i += -1, j-- /*step*/)
{
// i - j == X --> i = X + j
// --> i < end == X+j < end == j < end - X
// --> newend = end - (i_init - j_init)
// j < end-X && j < c --> j < min(end-X,c)
// j < end-X && j <= c --> j <= min(end-X-1,c) or j < min(end-X,c+1{OF!})
//if (j < c)
if (j >= c)
printf ("a: %d %d\n", i, j);
/*else
printf ("b: %d %d\n", i, j);*/
/*sum += a[i];
else
sum += b[i];*/
}
return sum;
}
int __attribute__((noinline, noclone)) f2 (int *beg, int *end, int step,
int *c, int *a, int *b, int *beg2)
{
int sum = 0;
int *i, *j;
for (i = beg, j = beg2; i < end; i += 1, j++ /*step*/)
{
if (j <= c)
printf ("%d %d\n", i - beg, j - beg);
/*sum += a[i];
else
sum += b[i];*/
}
return sum;
}
#endif
extern int printf (const char *, ...);
int main ()
{
int a[] = {0,0,0,0,0, 1,2,3,4,5,6,7,8,9, 0,0,0,0,0};
int b[] = {0,0,0,0,0, -1,-2,-3,-4,-5,-6,-7,-8,-9, 0,0,0,0,0,};
int c;
int diff = 0;
unsigned check = 0;
#if defined(SINGLE_TEST) && (SINGLE_TEST == 1)
//dotest (0, 9, 1, -1, a+5, b+5, -1);
//return 0;
f (0, 9, 1, 5, a+5, b+5, -1);
return 0;
#endif
for (diff = -5; diff <= 5; diff++)
{
for (c = -1; c <= 10; c++)
{
#ifdef SINGLE_TEST
int s = f (0, 9, 1, c, a+5, b+5, diff);
//int s = f2 (a+0, a+9, 1, a+c, a+5, b+5, a+diff);
printf ("%d ", s);
#else
if (TRACE > 0)
printf ("check %d %d\n", c, diff);
check = check * 51 + dotest (0, 9, 1, c, a+5, b+5, diff);
#endif
}
//printf ("\n");
}
//printf ("%u\n", check);
if (check != 3213344948)
abort ();
return 0;
}
/* All 16 loops in dotest should be split. */
/* { dg-final { scan-tree-dump-times "Loop split" 16 "lsplit" } } */