This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [patch] adjust make_range
- From: Jeffrey A Law <law at redhat dot com>
- To: Eric Christopher <echristo at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Thu, 10 Jun 2004 22:09:59 -0600
- Subject: Re: [patch] adjust make_range
- Organization: Red Hat, Inc
- References: <1086823189.2516.16.camel@dzur.sfbay.redhat.com>
- Reply-to: law at redhat dot com
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>>
ie
((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.
jeff