This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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.  */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]