arm-eabi-gcc -Os -mthumb produces wrong code for the following testcase:

     void __attribute__((noinline))
     foo (int *p, int d1, int d2, int d3,
          short count, int s1, int s2, int s3, int s4, int s5)
     {
       int n = count;
       while (n--)
         {
           *p++ = s1;
           *p++ = s2;
           *p++ = s3;
           *p++ = s4;
           *p++ = s5;
         }
     }

The important things about the testcase are:

    (a) There must be a subword stack parameter P1 that we do not assume
        is already promoted.  This is "count" in the testcase above.

    (b) There must be later stack parameters whose pseudos do not get
        allocated a hard register.

Because Thumb doesn't have subword stack loads, the sequence to set up
P1's pseudo register must first load the argument pointer into a pseudo
(let's call it PA).  The gcse local-prop pass then replaces the argument
pointer with PA in the instructions related to later stack parameters.
The problem is that gcse does this in both the instruction bodies _and_
their REG_EQUIV notes, so we get things like:

     (set (reg P2) (mem (plus (reg PA) (const_int 4))))
     REG_EQUIV: (mem (plus (reg PA) (const_int 4)))

The change to the insn body is almost immediately undone by CSE
(that was worthwhile, wasn't it?) but the REG_EQUIV note remains.

The change to the note is bogus though.  A REG_EQUIV note is supposed
to say that all occurences of the register could be replaced with the
equivalent expression without affecting semantics.  However, when
gcse.c:try_replace_reg replaces FROM with TO in INSN, the equivalence
between FROM and TO is a local rather than a global property.

I'm not sure the replacement would be valid even if the equivalence
were global though.  Nothing ensures (or is supposed to ensure) that
PA's lifetime is extended to cover the lifetime of P2.

I'm testing a patch now.

Richard


-- 
           Summary: invalid gcse manipulation of REG_EQUIV notes
           Product: gcc
           Version: 4.2.0
            Status: UNCONFIRMED
          Keywords: wrong-code
          Severity: normal
          Priority: P3
         Component: rtl-optimization
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: rsandifo at gcc dot gnu dot org
GCC target triplet: arm-eabi


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27073

Reply via email to