https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106594

            Bug ID: 106594
           Summary: [13 Regression] sign-extensions no longer merged into
                    addressing mode
           Product: gcc
           Version: 13.0
            Status: UNCONFIRMED
          Keywords: missed-optimization
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: tnfchris at gcc dot gnu.org
  Target Milestone: ---
            Target: aarch64*

Since around the 5th of August (need to bisect) we no longer generate
addressing modes on load merging the sign extends.

The following example:

extern const int constellation_64qam[64];

void foo(int nbits,
         const char *p_src,
         int *p_dst) {

  while (nbits > 0U) {
    char first = *p_src++;

    char index1 = ((first & 0x3) << 4) | (first >> 4);

    *p_dst++ = constellation_64qam[index1];

    nbits--;
  }
}

used to generate

        orr     w3, w4, w3, lsr 4
        ldr     w3, [x6, w3, sxtw 2]

and now generates:

        orr     w0, w4, w0, lsr 4
        sxtw    x0, w0
        ldr     w0, [x6, x0, lsl 2]

at -O2 (-O1 seems to still be fine).  This is causing a regression in perf in
some of our libraries.

Looks like there's a change in how the operation is expressed.  It used to be

  first_17 = *p_src_28;
  _1 = (int) first_17;
  _2 = _1 << 4;
  _3 = (signed char) _2;

where the shift is done as an int, whereas now it's

  first_16 = *p_src_27;
  first.1_1 = (signed char) first_16;
  _2 = first.1_1 << 4;

Reply via email to