This is the mail archive of the 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]

Re: [Patch, middle-end] Fix PR 44878, IA64 build failure, partial inlining

Here is more analysis of where I think we might be going wrong.  The basic problem is that we get into
expand_value_return with val equal to:

(subreg/s/v:SI (reg/f:DI 341 [ <retval>+-4 ]) 4)

and a return_reg of:

(reg/f:DI 341 [ <retval>+-4 ])

The problem, of course, is the mode mismatch.  Since we are returning a reference and promote_mode explicitly
promotes references to Pmode (DImode) I think both of these should be DImode (and that is what they were before
the partial inline checkin that broke things).

So I looked at where val was set and I get to expand_expr_real_1 with an SSA_NAME and an rtx of:

(reg/f:DI 341 [ <retval>+-4 ])

which is good.  But then we execute 'goto expand_decl_rtl' and it is there that we convert our DImode register
to a SImode subreg.  We have:

 8472       /* If the mode of DECL_RTL does not match that of the decl, it
 8473          must be a promoted value.  We return a SUBREG of the wanted mode,
 8474          but mark it so that we know that it was already extended.  */
 8475       if (REG_P (decl_rtl) && GET_MODE (decl_rtl) != DECL_MODE (exp))
 8476         {
 8477           enum machine_mode pmode;
 8479           /* Get the signedness to be used for this variable.  Ensure we g      et
 8480              the same mode we got when the variable was declared.  */
 8481           if (code == SSA_NAME
 8482               && (g = SSA_NAME_DEF_STMT (ssa_name))
 8483               && gimple_code (g) == GIMPLE_CALL) 
 8484             pmode = promote_function_mode (type, mode, &unsignedp,
 8485                                            TREE_TYPE
 8486                                            (TREE_TYPE (gimple_call_fn (g))      ),
 8487                                            2);
 8488           else 
 8489             pmode = promote_decl_mode (exp, &unsignedp);
 8490           gcc_assert (GET_MODE (decl_rtl) == pmode);
 8492           temp = gen_lowpart_SUBREG (mode, decl_rtl);
 8493           SUBREG_PROMOTED_VAR_P (temp) = 1;
 8494           SUBREG_PROMOTED_UNSIGNED_SET (temp, unsignedp);
 8495           return temp;

decl_rtl is:

(reg/f:DI 341 [ <retval>+-4 ])

and exp is:

 <result_decl 65876460 D.1760
    type <reference_type 65888780
        type <record_type 6587aea0 e addressable needs-constructing type_1 type_5 BLK
            size <integer_cst 657d17a0 constant 8>
            unit size <integer_cst 657d17c0 constant 1>
            align 8 symtab 0 alias set -1 canonical type 6587aea0 fields <type_decl 65885070 e>
            full-name "class e"
            needs-constructor X(constX&) this=(X&) n_parents=0 use_template=0 interface-unknown
            pointer_to_this <pointer_type 65888060> reference_to_this <reference_type 65888780> chain <type_decl 65885000 e>>
        public unsigned SI
        size <integer_cst 657d1960 constant 32>
        unit size <integer_cst 657d1700 constant 4>
        align 32 symtab 0 alias set -1 canonical type 65888780>
   used unsigned ignored SI passed-by-reference file line 9 col 7 size <integer_cst 657d1960 32> unit size <integer_cst 657d1700 4>
    align 32 context <function_decl 6587bf00 foo>
    (reg/f:DI 341 [ <retval>+-4 ])>

The modes don't match and so we enter the if statement and generate a subreg of r341:

(subreg/s/v:SI (reg/f:DI 341 [ <retval>+-4 ]) 4)

and this results in the problem in expand_value_return.

Is the answer simply that we shouldn't enter this
if statement with a result_decl?

Steve Ellcey

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