(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
pr81165.c
       1  /* { dg-do compile } */
       2  /* { dg-options "-O3 -fdump-tree-optimized" } */
       3  /* { dg-final { scan-tree-dump-not " \[/%\] " "optimized" } } */
       4  
       5  /* Testcase submitted for PR81165, with its main function removed as
       6     it's turned into a compile test.  We want to make sure that all of
       7     the divide/remainder computations are removed by tree optimizers.
       8  
       9     We can figure out that we don't need to compute at runtime even the
      10     condition to enter the loop: the initial i==0 would have to be
      11     greater than the sum of two small unsigned values: 1U>>t1 is in the
      12     range 0..1, whereas the char value is bounded by the range 0..127,
      13     being 128 % a positive number (zero would invoke undefined
      14     behavior, so we can assume it doesn't happen).  (We know it's
      15     nonnegative because it's 10 times a number that has no more than
      16     the bits for 16, 8 and 1 set.)
      17  
      18     We don't realize that the loop is useless right away: jump
      19     threading helps remove some of the complexity, particularly of the
      20     computation within the loop: t1 is compared with 1, but it can
      21     never be 1.  (We could assume as much, since its being 1 would
      22     divide by zero, but we don't.)
      23  
      24     If we don't enter the conditional block, t1 remains at 2; if we do,
      25     it's set to either -1.  If we jump thread at the end of the
      26     conditional block, we can figure out the ranges exclude 1 and the
      27     jump body is completely optimized out.  However, we used to fail to
      28     consider the block for jump threading due to the amount of
      29     computation in it, without realizing most of it would die in
      30     consequence of the threading.
      31  
      32     We now take the dying code into account when deciding whether or
      33     not to try jump threading.  That might enable us to optimize the
      34     function into { if (x2 != 0 || (x1 & 1) == 0) abort (); }.  At the
      35     time of this writing, with the patch, we get close, but the test on
      36     x2 only gets as far as ((1 >> x2) == 0).  Without the patch, some
      37     of the loop remains.  */
      38  
      39  short x0 = 15;
      40  
      41  void func (){
      42    volatile int x1 = 1U;
      43    volatile char x2 = 0;
      44    char t0 = 0;
      45    unsigned long t1 = 2LU;
      46    int i = 0;
      47    
      48    if(1>>x2) {
      49      t0 = -1;
      50      t1 = (1&(short)(x1^8U))-1;
      51    }
      52  
      53    while(i > (int)((1U>>t1)+(char)(128%(10*(25LU&(29%x0)))))) {
      54      i += (int)(12L/(1!=(int)t1));
      55    }
      56  
      57    if (t0 != -1) __builtin_abort();
      58    if (t1 != 0L) __builtin_abort();
      59  }