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.

Reply via email to