This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Canonicalization of compares performed as side-effect operations
On Tue, Aug 06, 2019 at 05:22:48PM +0100, Richard Earnshaw (lists) wrote:
> On 06/08/2019 17:17, Segher Boessenkool wrote:
> >Hi Richard,
> >
> >On Tue, Aug 06, 2019 at 04:35:04PM +0100, Richard Earnshaw (lists) wrote:
> >>Arm has an instruction that performs the following operation:
> >>
> >>(parallel [
> >> (set (reg:CC 100 cc)
> >> (compare:CC (const_int 0 [0])
> >> (reg:SI 121)))
> >> (set (reg:SI 113)
> >> (neg:SI (reg:SI 121)))
> >> ])
> >>
> >>This is simply a reverse subtract from the constant zero, and setting
> >>the condition flags. It's the low part of a negdi2 expansion.
> >>
> >>However, combine will rip this up and try to transform the compare into
> >>'canonical' form, ie
> >>
> >>(parallel [
> >> (set (reg:CC 100 cc)
> >> (compare:CC (reg:SI 121)
> >> (const_int 0 [0])))
> >> (set (reg:SI 113)
> >> (neg:SI (reg:SI 121)))
> >> ])
> >>
> >>(and obviously swapping the condition on the instruction that uses the
> >>comparison result).
> >>
> >>This, of course, doesn't match the behaviour of the instruction and
> >>no-longer matches the pattern in the md file.
> >
> >It is, however, canonical RTL:
> >
> >(from md.texi:)
> >
> > In addition to algebraic simplifications, following canonicalizations
> > are performed:
> >
> > @itemize @bullet
> > @item
> > For commutative and comparison operators, a constant is always made the
> > second operand. If a machine only supports a constant as the second
> > operand, only patterns that match a constant in the second operand need
> > be supplied.
> >
> >Putting the constant first is non-canonical RTL and will in general not
> >match any instructions generated by GCC.
> >
> >>So is there a way to describe this instruction within the compiler, or a
> >>way to stop simplify_set from making this sort of simplification?
> >
> >What's wrong with describing the canonical form in your MD? You'll need
> >some reversed condition code thingy, but that's it?
>
> It doesn't describe what the instruction does. The negation has a side
> effect of setting the flags, but the flags are swapped because the
> side-effect comparison is swapped from a normal compare. As I
> mentioned, SELECT_CC_MODE doesn't help because it can't see the context
> and the comparison just looks 'normal'.
Sure, and we can work on making combine do what you want, but your existing
pattern is *incorrect*. It needs fixing, and probably before we do other
things.
Segher