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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: paradoxical subreg problem


In article <200201282147.NAA19688@rtl.cygnus.com> you write:
>In article <16350.1012242676@porcupine.cygnus.com> you write:
>2) The extra bits are known to be zero or one, depending on whether loads
>   zero or sign extend by default.  This is only used for values smaller than
>   or equal to the the word size, and I think this also requires that the
>   operand be a MEM, but I'm not positive about the last condition.  For
>   instance, on a 32-bit target with zero-extending loads, given
>   (subreg:SI (mem:QI ...)), the extra 24-bits are known to be zero.  This
>   usage occurs only between combine and reload.

I left out an important piece.  This is only true if WORD_REGISTER_OPERATIONS
is defined.  If WORD_REGISTER_OPERATIONS is not defined, then the upper
24 bits of (subreg:SI (mem:QI ...)) are undefined.  A QImode load on a CISC
tends to modify the low 8-bits of the register, and leave the upper 24-bit
unchanged, which means they have no useful value.  If WORD_REGISTER_OPERATIONS
is defined, then the upper 24 bits of (subreg:SI (mem:QI ...)) are defined,
and are known to be zero or one depending on the value of LOAD_EXTEND_OP.
A QImode load on a RISC tends to set the entire 32-bits of a register, so we
want to use that knowledge to optimize away unnecessary zero/sign extend
instructions.  Except that these paradoxical subregs prevent us from
properly scheduling memory operations, so we try to avoid recognizing them when
INSN_SCHEDULING, which partially defeats the purpose of creating them when
WORD_REGISTER_OPERATIONS is true, since most any target that has one of
these defined has the other one defined too.  They still are created and
used inside combine though, and help with some simplications inside combine,
but I think we would get the same effect by using explicit zero/sign extend
operators.

Searching combine.c for WORD_REGISTER_OPERATIONS shows that it does some
interesting things, some of them in conjunction with LOAD_EXTEND_OP.

Curiously, I just noticed that the INSN_SCHEDULING code in combine.c looks
wrong.  It has:
          /* If *SPLIT is a paradoxical SUBREG, when we split it, it should
             be written as a ZERO_EXTEND.  */
          if (split_code == SUBREG && GET_CODE (SUBREG_REG (*split)) == MEM)
            SUBST (*split, gen_rtx_ZERO_EXTEND  (split_mode,
                                                 SUBREG_REG (*split)));
I think it should be using LOAD_EXTEND_OP instead of assuming a ZERO_EXTEND,
but that code has been there for about 10 years, so if it was wrong, we
should have noticed long ago.

>(eq (subreg:SI (mem/s:QI (plus:SI (reg:SI 3 %r3)
>                (const_int 15 [0xf])) 1) 0)
>    (mem/s:SI (plus:SI (reg:SI 3 %r3)
>            (const_int 12 [0xc])) 1))

If the word size is 32-bits or more, and WORD_REGISTER_OPERATIONS is defined,
and LOAD_EXTEND_OP is defined, then this is a 32-bit compare.  It can not
be simplified at compile time unless we know the values in the memory locations
at offsets 12, 13, and 14, and know that these values match the value of
the byte at offset 15 extended as per LOAD_EXTEND_OP.

>Can someone explain to me clearly what the semantics of a paradoxical
>subreg really are?

No, because the use of subregs has gotten too complicated over time.
They are used for more than one purpose, and have more than one meaning,
depending on the context, and depending on the value of some target macros.

Jim


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]