This is the mail archive of the
`gcc@gcc.gnu.org`
mailing list for the GCC project.

# Validity of SUBREG+AND-imm transformations

*From*: Kyrill Tkachov <kyrylo dot tkachov at foss dot arm dot com>
*To*: "gcc at gcc dot gnu dot org" <gcc at gcc dot gnu dot org>
*Date*: Fri, 26 Feb 2016 13:40:22 +0000
*Subject*: Validity of SUBREG+AND-imm transformations
*Authentication-results*: sourceware.org; auth=none

Hi all,
I'm looking at a case where some RTL passes create an RTL expression of the form:
(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)
(const_int 31))
Because (const_int 31) masks out the upper bits after the 5th one, we should be able
to safely perform the operation in QImode.
It's easy enough to express in RTL but I'm trying to convince myself on its validity.
I know there are some subtle points in this area. combine_simplify_rtx in combine.c
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. */
and if I try to implement this transformation in simplify_subreg from simplify-rtx.c
I get some cases where combine goes into an infinite recursion in simplify_comparison
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. */
I think the transformation is valid in general because in the original case we
care only about the bits within QImode which are well defined by the wider
inner operation, and in the transformed case the same bits are also well-defined
because of the narrow bitmask.
Performing this transformation would help a lot with recognition of some patterns that
I'm working on, so would it be acceptable to teach combine or simplify-rtx to do this?
Thanks,
Kyrill