This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PR target/15869: Fix filling of MIPS1 load delay slots
- From: Richard Sandiford <rsandifo at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: mmitchel at gcc dot gnu dot org
- Date: Tue, 22 Jun 2004 22:29:43 +0100
- Subject: PR target/15869: Fix filling of MIPS1 load delay slots
PR target/15869 is about the MIPS backend failing to fill a load delay
slot with a nop. In the test case, the hazard-avoidance code in
machine_dependent_reorg() saw a load, followed by two no-op moves,
followed by a use of the loaded value. It therefore didn't think there
was any need for a nop. Unfortunately, the moves were later deleted by
split_all_insns_noflow() (in preperation for shorten_branches()).
The hazard avoidance code needs to have the final instruction selection,
so this patch makes sure that all instructions have been fully split
beforehand. Bootstrapped and regression tested on mips64el-linux-gnu,
applied to HEAD.
It's very difficult to test this sort of thing with a compile or
scan-assembler-type test. The only sure way is to run execution
tests on affected h/w (of which I have none). I'm pretty certain
that existing execution tests would show up the bug, so I haven't
added a new testcase.
Mark, is this OK for 3.4? It's a serious regression for MIPS1, and I
think the fix is safe. It also can't affect any other targets.
Richard
PR target/15869
* config/mips/mips.c (mips_avoid_hazards): Call split_all_insns_noflow.
Index: config/mips/mips.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mips/mips.c,v
retrieving revision 1.362.4.12
diff -c -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.362.4.12 mips.c
*** config/mips/mips.c 17 Mar 2004 07:03:38 -0000 1.362.4.12
--- config/mips/mips.c 22 Jun 2004 08:26:43 -0000
*************** mips_avoid_hazards (void)
*** 8756,8761 ****
--- 8756,8764 ----
rtx insn, last_insn, lo_reg, delayed_reg;
int hilo_delay, i;
+ /* Force all instructions to be split into their final form. */
+ split_all_insns_noflow ();
+
/* Recalculate instruction lengths without taking nops into account. */
cfun->machine->ignore_hazard_length_p = true;
shorten_branches (get_insns ());