This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
RFA: Another TRULY_NOOP_TRUNCATION problem
- From: Richard Sandiford <rsandifo at nildram dot co dot uk>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 17 Sep 2007 23:16:25 +0100
- Subject: RFA: Another TRULY_NOOP_TRUNCATION problem
The recent dse.c patch showed up a latent bug. If we have a register
parameter that is (a) BLKmode, (b) a power of 2 in size and (c) smaller
than a word, the caller passes the parameter as word_mode, but the
callee generates a store in the integer mode corresponding to the size
of the type. The callee is effectively introducing an implicit
truncation on !TRULY_NOOP_TRUNCATION targets.
This has (apparently) worked until now because the store itself doesn't
need the value to be correctly truncated, and because the optimisers
haven't tried to reuse the stored register. DSE now does that.
The patch below introduces an explicit conversion if the callee's
truncation is not a no-op. If a target defines TRULY_NOOP_TRUNCATION,
its truncate pattern should generally allow a memory destination,
so combine can still reconstitute the original store if the truncation
is not used again. This does indeed happen on MIPS.
The patch below fixes gcc.c-torture/execute/20040709-[12].c at -O
for little-endian MIPS o64 targets. Regression-tested on mipsisa64-elfoabi.
Bootstrapped & regression-tested on x86_64-linux-gnu. OK to install?
Richard
gcc/
* function.c (assign_parm_setup_block): Explicitly convert BLKmode
parameters from word_mode to the subword type if such a truncation
is not a no-op.
Index: gcc/function.c
===================================================================
--- gcc/function.c 2007-09-17 23:00:33.000000000 +0100
+++ gcc/function.c 2007-09-17 23:02:08.000000000 +0100
@@ -2591,7 +2591,21 @@ assign_parm_setup_block (struct assign_p
#endif
)
{
- rtx reg = gen_rtx_REG (mode, REGNO (entry_parm));
+ rtx reg;
+
+ /* We are really truncating a word_mode value containing
+ SIZE bytes into a value of mode MODE. If such an
+ operation requires no actual instructions, we can refer
+ to the value directly in mode MODE, otherwise we must
+ start with the register in word_mode and explicitly
+ convert it. */
+ if (TRULY_NOOP_TRUNCATION (size * BITS_PER_UNIT, BITS_PER_WORD))
+ reg = gen_rtx_REG (mode, REGNO (entry_parm));
+ else
+ {
+ reg = gen_rtx_REG (word_mode, REGNO (entry_parm));
+ reg = convert_to_mode (mode, copy_to_reg (reg), 1);
+ }
emit_move_insn (change_address (mem, mode, 0), reg);
}