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;