Re: [PATCH] ext-dce: Avoid multi-register paradoxical subregs for reload [PR122438]
Andrea Pinski <[email protected]>
| Newsgroups | gmane.comp.gcc.patches |
|---|---|
| Message-ID | <CALvbMcAyu1X21X0ekDz9iDxNa3s9zeXdP2vYdr4BTg9KrNGqAA@mail.gmail.com> |
On Fri, Jul 31, 2026 at 4:36 AM Karl Mehltretter <[email protected]> wrote: > > ext-dce can turn an extension into a paradoxical subreg when the > upper bits are dead. With classic reload, this can fail if the modes > use different numbers of hard registers. On m68k, SI-to-DI creates an > invalid overlap and an ICE in postreload. > > Skip the rewrite in that case. This change also fixes PR119953 > on MSP430. LRA and same-register-count cases are unchanged. > > Cross-tested on GCC trunk: > > 1) m68k-linux-gnu: the unpatched compiler reproduces PR122438. The > gcc.target/m68k suite changes from 128 PASS / 9 FAIL / 1 unsupported > to 129 PASS / 9 FAIL / 1 unsupported with the new test. > > 2) msp430-elf: the new PR119953 test passes. > > 3) alpha-linux-gnu and vax-netbsdelf: the tested same-register-count > extension cases produce identical assembly with and without the patch. > > Also tested on GCC 16.1.1 for m68k-linux-gnu. The unpatched compiler > reproduces PR122438 while the new test passes with the patch. > > Assisted-by: Codex gpt-5.6-terra > > gcc/ChangeLog: > > PR rtl-optimization/122438 > PR target/119953 > * ext-dce.cc: Include regs.h. > (ext_dce_try_optimize_extension): Avoid multi-register > paradoxical subregs with classic reload. > > gcc/testsuite/ChangeLog: > > PR rtl-optimization/122438 > PR target/119953 > * gcc.target/m68k/pr122438.c: New test. > * g++.target/msp430/pr119953.C: New test. > > Signed-off-by: Karl Mehltretter <[email protected]> > --- > OK for trunk? I am not sure if we want to add hacks still to support reload. It would be better if those targets are changed over to using LRA. There was a plan to remove reload for GCC 16 but it seems like it slipped until this year at the earliest. Though I have not seen any movement towards removing it but that is still the plan of record. Thanks, Andrea > > gcc/ext-dce.cc | 8 +++++ > gcc/testsuite/g++.target/msp430/pr119953.C | 40 ++++++++++++++++++++++ > gcc/testsuite/gcc.target/m68k/pr122438.c | 23 +++++++++++++ > 3 files changed, 71 insertions(+) > create mode 100644 gcc/testsuite/g++.target/msp430/pr119953.C > create mode 100644 gcc/testsuite/gcc.target/m68k/pr122438.c > > diff --git a/gcc/ext-dce.cc b/gcc/ext-dce.cc > index 9e4b0a429b..8e0c5ab9db 100644 > --- a/gcc/ext-dce.cc > +++ b/gcc/ext-dce.cc > @@ -26,6 +26,7 @@ along with GCC; see the file COPYING3. If not see > #include "memmodel.h" > #include "insn-config.h" > #include "emit-rtl.h" > +#include "regs.h" > #include "expr.h" > #include "recog.h" > #include "cfganal.h" > @@ -533,6 +534,13 @@ ext_dce_try_optimize_extension (rtx_insn *insn, rtx set) > return; > } > > + /* Avoid known classic-reload problems with multi-register paradoxical > + subregs (PR122438, PR119953). */ > + if (!targetm.lra_p () > + && (hard_regno_nregs (0, GET_MODE (src)) > + != hard_regno_nregs (0, GET_MODE (inner)))) > + return; > + > /* Avoid (subreg (mem)) and other constructs which may be valid RTL, but > not useful for this optimization. */ > if (!(REG_P (inner) || (SUBREG_P (inner) && REG_P (SUBREG_REG (inner))))) > diff --git a/gcc/testsuite/g++.target/msp430/pr119953.C b/gcc/testsuite/g++.target/msp430/pr119953.C > new file mode 100644 > index 0000000000..fd2562eff9 > --- /dev/null > +++ b/gcc/testsuite/g++.target/msp430/pr119953.C > @@ -0,0 +1,40 @@ > +/* PR target/119953 */ > +/* { dg-do compile } */ > +/* { dg-options "-O2" } */ > + > +bool equals_tmp; > +int native (); > + > +struct path > +{ > + class iterator; > + iterator begin (); > + iterator end (); > +} p, hash_path; > + > +struct path::iterator > +{ > + path operator* () { return p; } > + void operator++ () {} > + friend bool operator!= (iterator lhs, iterator rhs) > + { > + return lhs.equals (rhs); > + } > + bool equals (iterator rhs) > + { > + if (equals_tmp) > + return cur == rhs.cur; > + return at_end == rhs.at_end; > + } > + char cur; > + bool at_end; > +}; > + > +int > +hash_value () > +{ > + int seed; > + for (auto x : hash_path) > + seed ^= native () + 0x9e3779b9 + (seed << 6) + (seed >> 2); > + return seed; > +} > diff --git a/gcc/testsuite/gcc.target/m68k/pr122438.c b/gcc/testsuite/gcc.target/m68k/pr122438.c > new file mode 100644 > index 0000000000..353bcc1b8f > --- /dev/null > +++ b/gcc/testsuite/gcc.target/m68k/pr122438.c > @@ -0,0 +1,23 @@ > +/* PR rtl-optimization/122438 */ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -w" } */ > + > +long describeCell_nLocal; > +char describeCell_a; > +char describeCell_zDesc[]; > +int strlen (char *); > +void describeContent (char *, char *); > +void localPayload (void); > + > +void > +describeCell (char cType) > +{ > + long long nDesc; > + if (cType) > + nDesc += nDesc; > + localPayload (); > + if (describeCell_nLocal) > + nDesc += strlen (&describeCell_zDesc[nDesc]); > + if (cType) > + describeContent (&describeCell_a, &describeCell_zDesc[nDesc]); > +} > -- > 2.53.0