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();