This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Adding an extra fallback to emit_move_insn_1
- From: Richard Sandiford <rsandifo at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: 24 Sep 2003 21:24:41 +0100
- Subject: Adding an extra fallback to emit_move_insn_1
This patch is a tentative fix for:
typedef int v2hi __attribute__((mode (V2HI)));
void f (v2hi *x, v2hi *y) { *x = *y; }
...which ICEs on 64-bit mips targets. It's a cut-down version of
what's causing the compat/vector-* tests to fail.
The problem is that (1) there's no move pattern for V2SImode and
(2) the various fallbacks in emit_move_insn_1 don't cater for subword
vector modes. Thus we ICE at the end of emit_move_insn_1.
This patch survives testing on i686-pc-linux-gnu & various mips targets.
It also works with volatile v2his, something which I thought trip over
the subregs. Still, I'm not 100% sure whether it's right in principle.
Does it look OK?
Richard
[ An alternative would be to add the new fallback at the end of the
function. I've put it here on the principle that using a single
.md pattern should lead to better code. ]
* expr.c (emit_move_insn_1): If there is no move pattern for the
original mode, try using a pattern for the corresponding integer mode.
Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.c,v
retrieving revision 1.583
diff -c -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.583 expr.c
*** expr.c 7 Sep 2003 20:34:13 -0000 1.583
--- expr.c 24 Sep 2003 19:36:00 -0000
*************** emit_move_insn_1 (rtx x, rtx y)
*** 3490,3495 ****
--- 3490,3506 ----
return emit_insn (GEN_FCN (insn_code) (x, y));
}
+ /* Try using a move pattern for the corresponding integer mode. This is
+ only safe when simplify_subreg can convert MODE constants into integer
+ constants. At present, it can only do this reliably if the value
+ fits within a HOST_WIDE_INT. */
+ else if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
+ && (submode = int_mode_for_mode (mode)) != BLKmode
+ && mov_optab->handlers[submode].insn_code != CODE_FOR_nothing)
+ return emit_insn (GEN_FCN (mov_optab->handlers[submode].insn_code)
+ (simplify_gen_subreg (submode, x, mode, 0),
+ simplify_gen_subreg (submode, y, mode, 0)));
+
/* This will handle any multi-word or full-word mode that lacks a move_insn
pattern. However, you will get better code if you define such patterns,
even if they must turn into multiple assembler instructions. */