On 9/21/2021 6:01 AM, Richard Sandiford via Gcc-patches wrote:
[Using this is a convenient place to reply to the thread as a whole]

Richard Biener via Gcc-patches <gcc-patches@gcc.gnu.org> writes:
On Mon, Sep 6, 2021 at 12:15 PM Segher Boessenkool
<seg...@kernel.crashing.org> wrote:
On Sun, Sep 05, 2021 at 11:28:30PM +0100, Roger Sayle wrote:
This patch simplifies the RTX (subreg:HI (truncate:QI (reg:SI))) as
(truncate:HI (reg:SI)), and closely related variants.
Subregs of other than regs are undefined in RTL.  You will first have to
define this (in documentation as well as in other code that handles
subregs).  I doubt this is possible to do, subreg have so many
overloaded meanings already.
I suppose (subreg:MODE1 (xyz:MODE2 ..)) where xyz is not REG or MEM
is equal to

   (set (reg:MODE2) (xyz:MODE2 ..))
   (subreg:MODE1 (reg:MODE2) ...)

with 'reg' being a pseudo reg is the (only?) sensible way of defining it.
Agreed.  And I think that's already the de facto definition (and has been
for a long time).  Subreg as an operation has to have defined semantics
for all the cases that simplify_subreg handles, otherwise we have GIGO
and a lot of the function could be deleted.  We can (and do) choose
to prevent some of those operations becoming actual rtxes, but even there,
the de facto rules are quite broad.  E.g.:

- Like you said later, simplify_gen_subreg is opt-out rather than opt-in
   in terms of the subreg rtxes that it's prepared to create.

- Even rs6000.md has:

     (define_insn "*<su>mul<mode>3_highpart"
       [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
             (subreg:GPR
               (mult:<DMODE> (any_extend:<DMODE>
                               (match_operand:GPR 1 "gpc_reg_operand" "r"))
                             (any_extend:<DMODE>
                               (match_operand:GPR 2 "gpc_reg_operand" "r")))
              0))]
       "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
       "mulh<wd><u> %0,%1,%2"
       [(set_attr "type" "mul")
        (set_attr "size" "<bits>")])

   Many other ports have similar patterns.

The problem with “combine can generate invalid rtl but backends
should reject it” is that, generally, people write combine patterns
by looking at what combine _wants_ to generate and then writing
.md patterns to match that.  In other words, combine in practice
defines the (de facto) correct rtl representation of a combined
sequence.
Yup.   In fact, I'm having this exact concern with an internal chunk of work right now :-)



Given:

Trying 10 -> 15:
    10: r29:QI=trunc(r32:SI)
       REG_DEAD r32:SI
    15: r38:HI=r29:QI#0
       REG_DEAD r29:QI
Failed to match this instruction:
(set (reg:HI 38)
     (subreg:HI (truncate:QI (reg:SI 32)) 0))

I'm sure there's a temptation to add an .md pattern that matches
the subreg. :-)
And that's why my stated position is that any subreg in a backend pattern needs to be justified.  Obviously all kinds exist, but when I see them I ask for a justification.

Jeff

Reply via email to