On Tue, Nov 25, 2014 at 7:04 AM, Richard Biener
<richard.guent...@gmail.com> wrote:
> On Tue, Nov 25, 2014 at 4:01 PM, Richard Biener
> <richard.guent...@gmail.com> wrote:
>> On Tue, Nov 25, 2014 at 1:57 PM, H.J. Lu <hongjiu...@intel.com> wrote:
>>> Hi,
>>>
>>> The enclosed testcase fails on x86 when compiled with -Os since we pass
>>> a byte parameter with a byte load in caller and read it as an int in
>>> callee.  The reason it only shows up with -Os is x86 backend encodes
>>> a byte load with an int load if -O isn't used.  When a byte load is
>>> used, the upper 24 bits of the register have random value for none
>>> WORD_REGISTER_OPERATIONS targets.
>>>
>>> It happens because setup_incoming_promotions in combine.c has
>>>
>>>       /* The mode and signedness of the argument before any promotions 
>>> happen
>>>          (equal to the mode of the pseudo holding it at that stage).  */
>>>       mode1 = TYPE_MODE (TREE_TYPE (arg));
>>>       uns1 = TYPE_UNSIGNED (TREE_TYPE (arg));
>>>
>>>       /* The mode and signedness of the argument after any source language 
>>> and
>>>          TARGET_PROMOTE_PROTOTYPES-driven promotions.  */
>>>       mode2 = TYPE_MODE (DECL_ARG_TYPE (arg));
>>>       uns3 = TYPE_UNSIGNED (DECL_ARG_TYPE (arg));
>>>
>>>       /* The mode and signedness of the argument as it is actually passed,
>>>          after any TARGET_PROMOTE_FUNCTION_ARGS-driven ABI promotions.  */
>>>       mode3 = promote_function_mode (DECL_ARG_TYPE (arg), mode2, &uns3,
>>>                                      TREE_TYPE (cfun->decl), 0);
>>>
>>> while they are actually passed in register by assign_parm_setup_reg in
>>> function.c:
>>>
>>>   /* Store the parm in a pseudoregister during the function, but we may
>>>      need to do it in a wider mode.  Using 2 here makes the result
>>>      consistent with promote_decl_mode and thus expand_expr_real_1.  */
>>>   promoted_nominal_mode
>>>     = promote_function_mode (data->nominal_type, data->nominal_mode, 
>>> &unsignedp,
>>>                              TREE_TYPE (current_function_decl), 2);
>>>
>>> where nominal_type and nominal_mode are set up with TREE_TYPE (parm)
>>> and TYPE_MODE (nominal_type). TREE_TYPE here is
>>
>> I think the bug is here, not in combine.c.  Can you try going back in history
>> for both snippets and see if they matched at some point?
>
> Oh, and note that I think DECL_ARG_TYPE is sth dangerous - it's meant
> to be a source language "ABI" kind-of-thing.  Or rather an optimization
> hit.  For example in C when integral promotions happen to call arguments
> this can be used to optimize sign-/zero-extensions in the callee.  Unless
> something else overrides this (like the target which specifies the real ABI).
> IIRC.
>

PROMOTE_MODE is a performance hint, not an ABI requirement.
i386.h has

#define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE)             \
do {                                                    \
  if (((MODE) == HImode && TARGET_PROMOTE_HI_REGS)      \
      || ((MODE) == QImode && TARGET_PROMOTE_QI_REGS))  \
    (MODE) = SImode;                                    \
} while (0)

We may promote QI/HI to SI, depending on optimization.

On the other hand, TARGET_PROMOTE_FUNCTION_MODE is
determined by psABI.

I am enclosing the missing ChangeLog entries.


-- 
H.J.
---
gcc/

PR rtl-optimization/64037
* combine.c (setup_incoming_promotions): Pass the argument
before any promotions happen to promote_function_mode.

gcc/testsuite/

PR rtl-optimization/64037
* g++.dg/pr64037.C: New test.

Reply via email to