This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: regression for 3.1: bad sign extension?
Geoff Keating wrote:
>>Roughly the expand_compound_operation first generates an ASHIFT by 16
>>and then an LSHIFTRT by 16 and simplify_shift_const reduces the whole
>>thing down to "(subreg:SI (reg:HI 54) 0))". I'm not sure if this is
>>correct or not. It certainly doesn't fit the description in the comment
>>of "something that is known to have the high parts zero".
>
>
> Yes, this is certainly incorrect. '(set (subreg:SI (reg:HI 54) 0)'
> implies 'clobber the high 16 bits of reg 54', and we don't want to
> clobber them, we want to set them to 0. [This assumes your words are
>
>>= 32 bits wide.] It would be worthwhile checking that
>
> expand_compound_operation is doing the shifts in SImode not HImode.
Yes, expand_compound_operation is doing the shift in SImode.
The problem is that the combiner (in expand_field_assignment()) moves a
subreg from the dest to the source, changing the SImode load from the
constant pool into an HImode load. Xtensa does not support HImode loads
from the constant pool, but this is supposed to be OK because the
pattern will later be rejected. Wrong. Because LOAD_EXTEND_OP is set
to ZERO_EXTEND, the nonzero_bits() function sees the HImode load and
concludes that the upper bits of a register are zero. This is wrong
because the load will actually be an SImode load.
I do not understand the combiner well enough to know how to fix this,
but it definitely seems broken to me. Maybe someone else can fix it.
Fortunately, it appears that I can work around this problem for Xtensa
by defining GO_IF_MODE_DEPENDENT_ADDRESS to mark constant-pool loads as
"mode-dependent". (Or maybe the real bug was that I hadn't already
defined GO_IF_MODE_DEPENDENT_ADDRESS in this way?)