mips16_gp_pseudo_reg emits the $gp load in the topmost sequence before
its first real insn. The scan skips CODE_LABELs, so the load can land
in a later block, and since r16-1398 that block can be expanded but not
BB_RTL yet, where add_insn_after crashes on BB_END.
Emit the load and the clobbers after entry_of_function () instead, as
other ports do. Before construct_init_block that is not usable, but
the topmost sequence then only holds the parameter setup, so emit
after its first insn. The entry edge does not work: pass_expand puts
those insns after the parameter setup, which can itself use $gp.
Assisted-by: Claude:claude-opus-5-5
PR target/125582
gcc/ChangeLog:
* config/mips/mips.cc (mips16_gp_pseudo_reg): Emit the $gp load
and the clobbers after entry_of_function (), or after the first
insn before the init block exists.
gcc/testsuite/ChangeLog:
* gcc.target/mips/pr125582.c: New test.
Suggested-by: Jakub Jelinek <[email protected]>
Signed-off-by: Julius Bairaktaris <[email protected]>
---
v2: Fix it in mips16_gp_pseudo_reg as Jakub suggested, instead of in
add_insn_after/add_insn_before.
Tested with a mipsel-linux-musl cross compiler, binutils and qemu-user,
compared with unpatched master:
- gcc.target/mips/mips.exp: no regressions. Fixes the new test and
gcc.target/mips/pr59317.c, which ICEs on master.
- gcc.c-torture/execute and compile with -mips16 -mabicalls -fpic
-static: no regressions, 2480 -> 17 failures.
- gcc.c-torture/execute with -mips16 -minterlink-mips16 -mabicalls
-fPIC -static: no regressions, 1799 -> 5 failures.
The remaining failures fail the same way without the patch.
gcc/config/mips/mips.cc | 18 ++++++++---------
gcc/testsuite/gcc.target/mips/pr125582.c | 25 ++++++++++++++++++++++++
2 files changed, 34 insertions(+), 9 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/mips/pr125582.c
diff --git a/gcc/config/mips/mips.cc b/gcc/config/mips/mips.cc
index e54a310b2b4..3ff5e9ef500 100644
--- a/gcc/config/mips/mips.cc
+++ b/gcc/config/mips/mips.cc
@@ -3400,18 +3400,11 @@ mips16_gp_pseudo_reg (void)
{
if (cfun->machine->mips16_gp_pseudo_rtx == NULL_RTX)
{
- rtx_insn *scan;
-
cfun->machine->mips16_gp_pseudo_rtx = gen_reg_rtx (Pmode);
- push_topmost_sequence ();
-
- scan = get_insns ();
- while (NEXT_INSN (scan) && !INSN_P (NEXT_INSN (scan)))
- scan = NEXT_INSN (scan);
-
+ start_sequence ();
rtx set = gen_load_const_gp (cfun->machine->mips16_gp_pseudo_rtx);
- rtx_insn *insn = emit_insn_after (set, scan);
+ rtx_insn *insn = emit_insn (set);
INSN_LOCATION (insn) = 0;
/* NewABI support hasn't been implement. NewABI should generate RTL
sequence instead of ASM sequence directly. */
@@ -3420,6 +3413,13 @@ mips16_gp_pseudo_reg (void)
emit_clobber (MIPS16_PIC_TEMP);
emit_clobber (MIPS_PROLOGUE_TEMP (Pmode));
}
+ rtx_insn *seq = end_sequence ();
+
+ /* Until construct_init_block, the topmost sequence is just the
+ parameter setup, all of which goes into the init block. */
+ push_topmost_sequence ();
+ emit_insn_after (seq, (ENTRY_BLOCK_PTR_FOR_FN (cfun)->flags & BB_RTL
+ ? entry_of_function () : get_insns ()));
pop_topmost_sequence ();
}
diff --git a/gcc/testsuite/gcc.target/mips/pr125582.c
b/gcc/testsuite/gcc.target/mips/pr125582.c
new file mode 100644
index 00000000000..524ef4bdf4d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/pr125582.c
@@ -0,0 +1,25 @@
+/* PR target/125582 */
+/* { dg-do compile } */
+/* { dg-options "-mabicalls -fpic -mips16" } */
+
+int foo (void *, unsigned, unsigned);
+
+static int
+bar (int *p)
+{
+ int ret;
+
+ do
+ ret = foo (p, sizeof (*p), 1);
+ while (ret == -1);
+
+ return ret;
+}
+
+int
+baz (void)
+{
+ int x = 1;
+
+ return bar (&x);
+}
--
2.53.0