http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51895
--- Comment #1 from Peter Bergner <bergner at gcc dot gnu.org> 2012-01-19 02:42:44 UTC --- We ICE when we try and do a BLK move from a reg:TI. In GCC 4.6, we don't see this, since the args[i].tree_value is different: (gdb-gcc4.6) ptree args[i].tree_value <var_decl 0xfffaa5703c0 Ptr1 type <record_type 0xfffafd6f960 SDValue sizes-gimplified needs-constructing type_1 type_5 type_6 TI size <integer_cst 0xfffb6d50a00 constant 128> unit size <integer_cst 0xfffb6d50a28 constant 16> align 64 symtab 0 alias set 43 canonical type 0xfffafd6f960 fields <field_decl 0xfffaec22ee8 Node type <pointer_type 0xfffafd6fab0> used private unsigned nonlocal decl_3 DI file t.ii line 30433 col 11 size <integer_cst 0xfffb6d50870 constant 64> unit size <integer_cst 0xfffb6d50898 constant 8> align 64 offset_align 128 offset <integer_cst 0xfffb6d504d8 constant 0> bit offset <integer_cst 0xfffb6d50fa0 constant 0> context <record_type 0xfffafd6f960 SDValue> chain <field_decl 0xfffaec22f80 ResNo>> context <namespace_decl 0xfffb2ef1368 llvm> full-name "class llvm::SDValue" needs-constructor X() X(constX&) this=(X&) n_parents=0 use_template=0 interface-unknown pointer_to_this <pointer_type 0xfffafd6fca8> reference_to_this <reference_type 0xfffafe27818> chain <type_decl 0xfffaebe9d68 SDValue>> used TI file t.ii line 45352 col 9 size <integer_cst 0xfffb6d50a00 128> unit size <integer_cst 0xfffb6d50a28 16> align 64 context <function_decl 0xffface9a300 FindBetterChain> abstract_origin <parm_decl 0xfffae3bf1b8 Ptr1> (reg/v:TI 306 [ Ptr1 ])> versus for gcc 4.7: (gdb-gc4.7) ptree args[i].tree_value <mem_ref 0xfffa8e935a0 type <array_type 0xfffb0cac198 type <integer_type 0xfffb5e403f0 char sizes-gimplified public unsigned string-flag type_6 QI size <integer_cst 0xfffb5d527e0 constant 8> unit size <integer_cst 0xfffb5d52800 constant 1> align 8 symtab 0 alias set -1 canonical type 0xfffb5e403f0 precision 8 min <integer_cst 0xfffb5d52860 0> max <integer_cst 0xfffb5d52880 255> pointer_to_this <pointer_type 0xfffb5e43288> reference_to_this <reference_type 0xfffb5e4e700>> BLK size <integer_cst 0xfffb2c63bc0 constant 96> unit size <integer_cst 0xfffb2c63540 constant 12> align 8 symtab 0 alias set 0 canonical type 0xfffb0cac198 domain <integer_type 0xfffb0cac0f0 type <integer_type 0xfffb5e40000 sizetype> DI size <integer_cst 0xfffb5d52600 constant 64> unit size <integer_cst 0xfffb5d52620 constant 8> align 64 symtab 0 alias set -1 canonical type 0xfffb0cac0f0 precision 64 min <integer_cst 0xfffb5d52640 0> max <integer_cst 0xfffb2c6f020 11>> pointer_to_this <pointer_type 0xfffa2f99cd8>> arg 0 <addr_expr 0xfffa3d2a708 type <pointer_type 0xfffa8d50b28 type <record_type 0xfffa8d505e8 SDValue> sizes-gimplified public unsigned type_6 DI size <integer_cst 0xfffb5d52600 64> unit size <integer_cst 0xfffb5d52620 8> align 64 symtab 0 alias set 2 canonical type 0xfffa8d50b28 pointer_to_this <pointer_type 0xfffa3834cc8>> arg 0 <var_decl 0xfffa362ee20 Ptr1 type <record_type 0xfffa8d505e8 SDValue> used TI file t.ii line 45286 col 6 size <integer_cst 0xfffb5d526a0 constant 128> unit size <integer_cst 0xfffb5d526c0 constant 16> align 64 context <function_decl 0xfffa2db2700 GatherAllAliases> abstract_origin <parm_decl 0xfffa32f8ff8 Ptr1> (reg/v:TI 279 [ Ptr1 ])>> arg 1 <integer_cst 0xfffa9014f00 type <pointer_type 0xfffa8d50b28> constant 0>> That difference forces us down different paths starting at this load_register_parameters() test: else if (TYPE_MODE (TREE_TYPE (args[i].tree_value)) == BLKmode) For 4.6, the mode is a TImode and for 4.7, it's a BLKmode. The following patch seems to fix it: Index: gcc/emit-rtl.c =================================================================== --- gcc/emit-rtl.c (revision 183280) +++ gcc/emit-rtl.c (working copy) @@ -1401,6 +1401,9 @@ operand_subword (rtx op, unsigned int of return replace_equiv_address (new_rtx, XEXP (new_rtx, 0)); } + if (REG_P (op) && mode == BLKmode) + mode = GET_MODE (op); + /* Rest can be handled by simplify_subreg. */ return simplify_gen_subreg (word_mode, op, mode, (offset * UNITS_PER_WORD)); } I'm bootstraping/regtesting this patch now.