This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [patch] adjust make_range

On Wed, 2004-06-09 at 17:19, Eric Christopher wrote:
> In looking at a missed optimization from a customer request:
> unsigned char cond;
> foo (void)
> {
>    if (cond <= 2 || (cond-2) > 100)
>         return 7;
>    return 0;
> }
> We were turning it into a pair of branches and failing to merge the
> ranges of the comparison. After this patch it completes and breaks the
> previous 11 instruction two branch sequence into a 5 instruction no
> branch sequence. Muuuch better.
> With this small change we actually complete the merge of the ranges
> since we're in the range at the time of the call, and then we should
> adjust afterwards, I think. I also believe we should be using orig_type
> instead of the long expansion in the type precision check.
> Bootstrapped and regression tested on x86-linux. Tested on
> mipsisa64-elf. No regressions.
I don't see how this can be correct.  For your testcase we are
passed a tree like this:

 <gt_expr 0x5500818c
    type <integer_type 0x55009488 int SI
        size <integer_cst 0x550059f0 constant invariant 32>
        unit size <integer_cst 0x55005a98 constant invariant 4>
        align 32 symtab 0 alias set -1 precision 32 min <integer_cst
0x55005a68 -2147483648> max <integer_cst 0x55005a80 2147483647>
        pointer_to_this <pointer_type 0x55011a6c>>
    arg 0 <minus_expr 0x55008168 type <integer_type 0x55009488 int>
        arg 0 <nop_expr 0x55007360 type <integer_type 0x55009488 int>
            arg 0 <var_decl 0x550c5c3c cond>>
        arg 1 <integer_cst 0x550cb060 constant invariant 2>>
    arg 1 <integer_cst 0x550cb090 type <integer_type 0x55009488 int>
constant invariant 100>>


   ((int)cond - 2) > 100   /* Were cond is an unsigned char type */

It doesn't take a rocket scientist to determine that cond must be in
the range 103-255 to satisfy that condition.

Putting a breakpoint at the proper location at the end of make_range
we see:
(gdb) p debug_tree (low)
 <integer_cst 0x550cb150 type <integer_type 0x550092b8 unsigned char>
constant invariant 103>
(gdb) p debug_tree (high)
 <integer_cst 0x55005930 type <integer_type 0x550092b8 unsigned char>
constant invariant 255>
(gdb) p in_p

Which is precisely correct.

With your change we get the wrong result:

(gdb) p debug_tree (low)
 <integer_cst 0x550cb0f0 type <integer_type 0x550092b8 unsigned char>
constant invariant 0>
$79 = void
(gdb) p debug_tree (high)
 <integer_cst 0x550cb0d8 type <integer_type 0x550092b8 unsigned char>
constant invariant 102>
$80 = void
(gdb) p in_p
$81 = 1

ie, with your change we compute that cond must be in the range 0-102
which is totally wrong.

Sorry, but you're going to have to dig deeper.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]