[Bug rtl-optimization/83565] RTL combine pass breaks shift result (at least on ia64)

segher at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Sun Dec 24 18:36:00 GMT 2017


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83565

--- Comment #14 from Segher Boessenkool <segher at gcc dot gnu.org> ---
(In reply to Jim Wilson from comment #11)

> This part
> 
> >r358 is known to have the high half zero:
> >   22: r358:DI=r357:SI#0^r341:SI#0
> 
> is wrong.  The upper bits of both registers are unknown bits, and xor of
> unknown bits does not return zero.

Yup, I don't know what I was thinking.

> I think the problem is in nonzero_bits1 in rtlanal.c, in the SUBREG case. 
> On ia64, we have WORD_REGISTER_OPERATIONS true, and load_extend_op of SImode
> is ZERO_EXTEND, so the code decides that the upper bits must be zero.  But
> LOAD_EXTEND_OP only applies to memory operations, and we do not have a
> subreg of memory here, we have a subreg of a register.

Right, that should be changed, that makes no sense at all.

Will that fix the problem here?

> When we have a
> subreg of a reg, on itanium, the upper bits are unknown.  So the
> optimization performed here is wrong.  Though one could perhaps argue that
> the ia64 port is using WORD_REGISTER_OPERATIONS wrong I suppose.

WORD_REGISTER_OPERATIONS isn't well-defined.

"""
@defmac WORD_REGISTER_OPERATIONS
Define this macro to 1 if operations between registers with integral mode
smaller than a word are always performed on the entire register.
Most RISC machines have this property and most CISC machines do not.
"""

What operations?  For some operations it can never be true (rotates, shifts,
all slightly more complex operations).  For machines that have explicit
operations in more than one size it cannot be true, either.

> I'm not sure what would happen if we removed that define.

When I removed WORD_REGISTER_OPERATIONS from the rs6000 backend a few things
regressed, but more things improved.


More information about the Gcc-bugs mailing list