This is the mail archive of the
mailing list for the GCC project.
Re: Validity of SUBREG+AND-imm transformations
- From: Jeff Law <law at redhat dot com>
- To: Kyrill Tkachov <kyrylo dot tkachov at foss dot arm dot com>, "gcc at gcc dot gnu dot org" <gcc at gcc dot gnu dot org>
- Date: Fri, 26 Feb 2016 14:24:49 -0700
- Subject: Re: Validity of SUBREG+AND-imm transformations
- Authentication-results: sourceware.org; auth=none
- References: <56D055C6 dot 6040800 at foss dot arm dot com>
On 02/26/2016 06:40 AM, Kyrill Tkachov wrote:
I can think of cases where the first is better and other cases where the
second is better -- a lot depends on context. I don't have a good sense
for which is better in general.
I'm looking at a case where some RTL passes create an RTL expression of
(subreg:QI (and:SI (reg:SI x1)
(const_int 31)) 0)
which I'd like to simplify to:
(and:QI (subreg:QI (reg:SI x1) 0)
Note that as-written these don't trigger the subtle issues in what
happens with upper bits. That's more for extensions.
(and:SI (subreg:SI (whatever:QI) (const_int 0x255)))
The first leave the bits beyond QI as "undefined" and sometimes (but I
doubt all that often in practice) the compiler will use the undefined
nature of those bits to enable optimizations.
The second & 3rd variants crisply define the upper bits.
That comment makes no sense. Unfortunately it goes back to a change
from Kenner in 1994 -- which predates having patch discussions here and
consistently adding tests to the testsuite.
It's easy enough to express in RTL but I'm trying to convince myself on
I know there are some subtle points in this area. combine_simplify_rtx
has a comment:
/* Note that we cannot do any narrowing for non-constants since
we might have been counting on using the fact that some bits were
zero. We now do this in the SET. */
The code used to do this:
- if (GET_MODE_CLASS (mode) == MODE_INT
- && GET_MODE_CLASS (GET_MODE (SUBREG_REG (x))) == MODE_INT
- && GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (SUBREG_REG
- && subreg_lowpart_p (x))
- return force_to_mode (SUBREG_REG (x), mode, GET_MODE_MASK (mode),
- NULL_RTX, 0);
Which appears to check that we've got a narrowing subreg expression, and
if we do try to force the SUBREG_REG into the right mode using
But if we had a narrowing SUBREG_REG, then I can't see how anything
would have been dependign on the upper bits being zero.
Right. I think you just end up ping-ponging between the two equivalent
representations. Which may indeed argue that the existing
representation is preferred and we should look deeper into why the
existing representation isn't being handled as well as it should be.
and if I try to implement this transformation in simplify_subreg from
I get some cases where combine goes into an infinite recursion in
because it tries to do:
/* If this is (and:M1 (subreg:M1 X:M2 0) (const_int C1)) where C1
fits in both M1 and M2 and the SUBREG is either paradoxical
or represents the low part, permute the SUBREG and the AND
and try again. */
How does it help recognition? What kinds of patterns are you trying to
Performing this transformation would help a lot with recognition of some
I'm working on, so would it be acceptable to teach combine or
simplify-rtx to do this?