comparison gcc/testsuite/gcc.dg/pr81165.c @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents
children
comparison
equal deleted inserted replaced
111:04ced10e8804 131:84e7813d76e9
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 }