blob: 8508d893bed6fbae74a3bc3d9172e1d3e152f009 [file] [log] [blame]
 /* { dg-do compile } */ /* { dg-options "-O3 -fdump-tree-optimized" } */ /* { dg-final { scan-tree-dump-not " \[/%\] " "optimized" } } */ /* Testcase submitted for PR81165, with its main function removed as it's turned into a compile test. We want to make sure that all of the divide/remainder computations are removed by tree optimizers. We can figure out that we don't need to compute at runtime even the condition to enter the loop: the initial i==0 would have to be greater than the sum of two small unsigned values: 1U>>t1 is in the range 0..1, whereas the char value is bounded by the range 0..127, being 128 % a positive number (zero would invoke undefined behavior, so we can assume it doesn't happen). (We know it's nonnegative because it's 10 times a number that has no more than the bits for 16, 8 and 1 set.) We don't realize that the loop is useless right away: jump threading helps remove some of the complexity, particularly of the computation within the loop: t1 is compared with 1, but it can never be 1. (We could assume as much, since its being 1 would divide by zero, but we don't.) If we don't enter the conditional block, t1 remains at 2; if we do, it's set to either -1. If we jump thread at the end of the conditional block, we can figure out the ranges exclude 1 and the jump body is completely optimized out. However, we used to fail to consider the block for jump threading due to the amount of computation in it, without realizing most of it would die in consequence of the threading. We now take the dying code into account when deciding whether or not to try jump threading. That might enable us to optimize the function into { if (x2 != 0 || (x1 & 1) == 0) abort (); }. At the time of this writing, with the patch, we get close, but the test on x2 only gets as far as ((1 >> x2) == 0). Without the patch, some of the loop remains. */ short x0 = 15; void func (){ volatile int x1 = 1U; volatile char x2 = 0; char t0 = 0; unsigned long t1 = 2LU; int i = 0; if(1>>x2) { t0 = -1; t1 = (1&(short)(x1^8U))-1; } while(i > (int)((1U>>t1)+(char)(128%(10*(25LU&(29%x0)))))) { i += (int)(12L/(1!=(int)t1)); } if (t0 != -1) __builtin_abort(); if (t1 != 0L) __builtin_abort(); }