[PATCH] ext-dce: Avoid multi-register paradoxical subregs for reload [PR122438]
Karl Mehltretter <[email protected]>
| Newsgroups | gmane.comp.gcc.patches |
|---|---|
| Message-ID | <[email protected]> |
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? 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