(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
loop-split.c
       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
      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  
      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  
      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  
     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" } } */