This is the mail archive of the gcc-bugs@gcc.gnu.org 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]

Re: c/2100: -fstrength-reduce (is active with -O2) produces wrong code


At 17:29 26.02.2001, dllorens@inf.uji.es wrote:

> >Number:         2100
> >Category:       c
> >Synopsis:       -fstrength-reduce (is active with -O2) produces wrong code
> >Confidential:   no
> >Severity:       serious
> >Priority:       medium
> >Responsible:    unassigned
> >State:          open
> >Class:          wrong-code
> >Submitter-Id:   net
> >Arrival-Date:   Mon Feb 26 08:36:03 PST 2001
> >Closed-Date:
> >Last-Modified:
> >Originator:     David Llorens
> >Release:        gcc version 2.95.2 19991024 (release)
> >Organization:
> >Environment:
>Linux 2.2.16-3smp
> >Description:
>The -fstrength-reduce optimization flag (which is active
>with the common -O2 option), produces wrong code.
>
>I have tested two gcc versions, both fail:
>  - gcc version 2.95.2 19991024 (release)
>  - egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)

Wow, this seems to be a long-standing bug in check_final_value()/loop.c, 
the testcase shows it nicely on x86-linux. Look at this check in 
check_final_value():

   if ((final_value = final_giv_value (loop, v))
       && (v->always_computable || last_use_this_basic_block (v->dest_reg, 
v->insn)))
     {

We reach here with this GIV for posGreatest:

(gdb) p *v
$8 = {insn = 0x8271228, new_reg = 0x0, src_reg = 0x82704dc, giv_type = 
DEST_REG, dest_reg = 0x827054c, location = 0x0,
   mode = SImode, mem_mode = 135364066, mult_val = 0x822b6a8, add_val = 
0x822b6a0, benefit = 1, final_value = 0x0,
   combined_with = 0, replaceable = 0, not_replaceable = 0, ignore = 0, 
always_computable = 0, always_executed = 0,
   maybe_multiple = 0, cant_derive = 1, maybe_dead = 0, auto_inc_opt = 0, 
unrolled = 0, shared = 0, no_const_addval = 1,
   lifetime = 38, derive_adjustment = 0x0, next_iv = 0x8274bac, same = 0x0, 
derived_from = 0x0, const_adjust = -1073747912,
   ix = 0, same_insn = 0x0, last_use = 0x0}

That means last_use_this_basic_block() gets called and correctly detects 
that this is the last use of the GIV until the next CODE_LABEL. But this 
check is apparently not strong enough :-( for this kind of loop. Because 
check_final_value() returns TRUE for this GIV, posGreatest is _always_ 
assigned the final value of the loop minus 1 after the loop, which in this 
case breaks the surrounding loop.

Possible fixes:
- don't check last_use_this_basic_block() at all in check_final_value()
- don't call last_use_this_basic_block() for GIVs of type DEST_REG (hmm?)
- check the surrounding loop (if any) for uses of the GIV too?

Opinions?

Franz.


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