On May 5, 2015 2:49:55 PM GMT+02:00, Richard Earnshaw 
<richard.earns...@foss.arm.com> wrote:
>On 05/05/15 13:46, Richard Earnshaw wrote:
>> On 05/05/15 13:37, Richard Biener wrote:
>>> On May 5, 2015 1:01:59 PM GMT+02:00, Richard Earnshaw
><richard.earns...@foss.arm.com> wrote:
>>>> On 05/05/15 11:54, Richard Earnshaw wrote:
>>>>> On 05/05/15 08:32, Jakub Jelinek wrote:
>>>>>> On Mon, May 04, 2015 at 05:00:11PM +0200, Jakub Jelinek wrote:
>>>>>>> So at least changing arm_needs_doubleword_align for
>non-aggregates
>>>> would
>>>>>>> likely not break anything that hasn't been broken already and
>would
>>>> unbreak
>>>>>>> the majority of cases.
>>>>>>
>>>>>> Attached (untested so far).  It indeed changes code generated for
>>>>>> over-aligned va_arg, but as I believe you can't properly pass
>those
>>>> in the
>>>>>> ... caller, this should just fix it so that va_arg handling
>matches
>>>> the
>>>>>> caller (and likewise for callees for named argument passing).
>>>>>>
>>>>>>> The following testcase shows that eipa_sra changes alignment
>even
>>>> for the
>>>>>>> aggregates.  Change aligned (8) to aligned (4) to see another
>>>> possibility.
>>>>>>
>>>>>> Actually I misread it, for the aggregates esra actually doesn't
>>>> change
>>>>>> anything, which is the reason why the testcase doesn't fail.
>>>>>> The problem with the scalars is that esra first changed it to the
>>>>>> over-aligned MEM_REFs and then later on eipa_sra used the types
>of
>>>> the
>>>>>> MEM_REFs created by esra.
>>>>>>
>>>>>> 2015-05-05  Jakub Jelinek  <ja...@redhat.com>
>>>>>>
>>>>>>  PR target/65956
>>>>>>  * config/arm/arm.c (arm_needs_doubleword_align): For
>non-aggregate
>>>>>>  types check TYPE_ALIGN of TYPE_MAIN_VARIANT rather than type
>>>> itself.
>>>>>>
>>>>>>  * gcc.c-torture/execute/pr65956.c: New test.
>>>>>>
>>>>>> --- gcc/config/arm/arm.c.jj      2015-05-04 21:51:42.000000000 +0200
>>>>>> +++ gcc/config/arm/arm.c 2015-05-05 09:20:52.481693337 +0200
>>>>>> @@ -6063,8 +6063,13 @@ arm_init_cumulative_args (CUMULATIVE_ARG
>>>>>>  static bool
>>>>>>  arm_needs_doubleword_align (machine_mode mode, const_tree type)
>>>>>>  {
>>>>>> -  return (GET_MODE_ALIGNMENT (mode) > PARM_BOUNDARY
>>>>>> -          || (type && TYPE_ALIGN (type) > PARM_BOUNDARY));
>>>>>> +  if (GET_MODE_ALIGNMENT (mode) > PARM_BOUNDARY)
>>>>>> +    return true;
>>>>>
>>>>> I don't think this is right (though I suspect the existing code
>has
>>>> the
>>>>> same problem).  We should only look at mode if there is no type
>>>>> information.  The problem is that GCC has a nasty habit of
>assigning
>>>>> real machine modes to things that are really BLKmode and we've run
>>>> into
>>>>> several cases where this has royally screwed things up.  So for
>>>>> consistency in the ARM back-end we are careful to only use mode
>when
>>>>> type is NULL (=> it's a libcall).
>>>>>
>>>>>> +  if (type == NULL_TREE)
>>>>>> +    return false;
>>>>>> +  if (AGGREGATE_TYPE_P (type))
>>>>>> +    return TYPE_ALIGN (type) > PARM_BOUNDARY;
>>>>>> +  return TYPE_ALIGN (TYPE_MAIN_VARIANT (type)) > PARM_BOUNDARY;
>>>>>>  }
>>>>>>  
>>>>>
>>>>>
>>>>>
>>>>> It ought to be possible to re-order this, though, to
>>>>>
>>>>>  static bool
>>>>>  arm_needs_doubleword_align (machine_mode mode, const_tree type)
>>>>>  {
>>>>> -  return (GET_MODE_ALIGNMENT (mode) > PARM_BOUNDARY
>>>>> -   || (type && TYPE_ALIGN (type) > PARM_BOUNDARY));
>>>>> +  if (type != NULL_TREE)
>>>>> +    {
>>>>> +      if (AGGREGATE_TYPE_P (type))
>>>>> +        return TYPE_ALIGN (type) > PARM_BOUNDARY;
>>>>> +      return TYPE_ALIGN (TYPE_MAIN_VARIANT (type)) >
>PARM_BOUNDARY;
>>>>> +    }
>>>>> +  return (GET_MODE_ALIGNMENT (mode) > PARM_BOUNDARY);
>>>>>  }
>>>>>
>>>>>
>>>>> Either way, this would need careful cross-testing against an
>existing
>>>>> compiler.
>>>>>
>>>>
>>>> It looks as though either patch would cause ABI incompatibility for
>>>>
>>>> typedef int alignedint __attribute__((aligned((8))));
>>>>
>>>> int  __attribute__((weak)) foo (int a, alignedint b)
>>>> {return b;}
>>>>
>>>> void bar (alignedint x)
>>>> {
>>>>  foo (1, x);
>>>> }
>>>>
>>>> Where currently gcc uses r2 as the argument register for b in foo.
>>>
>>> And for foo (1,2) or an int typed 2nd arg?
>>>
>>> Richard.
>>>
>>>> R.
>>>
>>>
>> 
>> 
>> As is
>> 
>> int foo2 (int a, int b);
>> 
>> void bar2 (alignedint x)
>> {
>>   foo2 (1, x);
>> }
>> 
>
>The real question here is why is TYPE the type of the value, rather
>than
>the type of the formal as expressed by the prototype (or implicit
>prototype in the case of variadics or K&R)?  Surely this is the mid-end
>passing the wrong information to the back-end.

No - the issue is you are looking at the type of the value at all, instead of 
at the type of the formal.

Richard.

>R.
>
>> ...
>> 
>> R
>> 


Reply via email to