[RFA][PATCH][PR rtl-optimization/47477] Type narrowing in match.pd

Jeff Law law@redhat.com
Wed Feb 11 17:05:00 GMT 2015


On 02/11/15 03:56, Richard Biener wrote:
>>
>>
>>
>>
>>
>>
>>
>>
>> diff --git a/gcc/ChangeLog b/gcc/ChangeLog
>> index 7f3816c..7a95029 100644
>> --- a/gcc/ChangeLog
>> +++ b/gcc/ChangeLog
>> @@ -1,3 +1,8 @@
>> +2015-02-10  Jeff Law  <law@redhat.com>
>> +
>> +       * match.pd (convert (plus/minus (convert @0) (convert @1): New
>> +       simplifier to narrow arithmetic.
>> +
>
> Please reference PR47477 from here
Doh.  Fixed.


>
>>   2015-02-10  Richard Biener  <rguenther@suse.de>
>>
>>          PR tree-optimization/64909
>> diff --git a/gcc/match.pd b/gcc/match.pd
>> index 81c4ee6..abc703e 100644
>> --- a/gcc/match.pd
>> +++ b/gcc/match.pd
>> @@ -1018,3 +1018,21 @@ along with GCC; see the file COPYING3.  If not see
>>      (logs (pows @0 @1))
>>      (mult @1 (logs @0)))))
>>
>> +/* If we have a narrowing conversion of an arithmetic operation where
>> +   both operands are widening conversions from the same type as the outer
>> +   narrowing conversion.  Then convert the innermost operands to a suitable
>> +   unsigned type (to avoid introducing undefined behaviour), perform the
>> +   operation and convert the result to the desired type.
>> +
>> +   This narrows the arithmetic operation.  */
>
> This is also a part of what shorten_binary_op does, so please refer to
> that in the comment so we can eventually complete this from there
> and remove shorten_binary_op.
Done.  I've created a block comment meant to cover this pattern and any 
additions we need along the way to moving shortening/narrowing out of 
the front-ends.


>
>> +(for op (plus minus)
>> +  (simplify
>> +    (convert (op (convert@2 @0) (convert @1)))
>> +    (if (TREE_TYPE (@0) == TREE_TYPE (@1)
>> +         && TREE_TYPE (@0) == type
>
> Otherwhere in match.pd we use
>
> (GIMPLE && types_compatible_p (TREE_TYPE (@0), TREE_TYPE (@1)))
>   || (GENERIC && TREE_TYPE (@0) == TREE_TYPE (@1))
>
> for type equality checks.  And I think even for GENERIC you want
> to ignore qualifiers and thus use TYPE_MAIN_VARIANT (TREE_TYPE (@0))
> == TYPE_MAIN_VARAINT (TREE_TYPE (@1)).
Seems reasonable.    Makes for some ugly formatting though.  It might 
make sense to factor that test so we don't end up repeating it senselessly.

>
>> +         && INTEGRAL_TYPE_P (type)
>
> So instead of testing TREE_TYPE (@0) == type we probably want
> to just assert that TYPE_PRECISON (TREE_TYPE (@0)) == TYPE_PRECISION
> (type) to allow sign-changes.  Say for
Yea, makes sense.

>
> short i, j;
> (unsigned short) (i + j)
>
> we still want to narrow the widened i and j.
Right.
>
>> +         && TYPE_PRECISION (TREE_TYPE (@2)) > TYPE_PRECISION (TREE_TYPE
>> (@0))
>> +        /* This prevents infinite recursion.  */
>> +        && unsigned_type_for (TREE_TYPE (@0)) != TREE_TYPE (@2))
>
> How can it recurse with the type precision constraint right above?
It may no longer be needed.  The precision check used to be >=, but that 
regressed some java codes.  So it got tightened in the last iteration 
before posting.

>
> Note that technically we don't need to perform the operation in an unsigned
> type iff TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0)).  Thus
>
>             (if (TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0))
>               (convert (op @0 @1)))
>             (with { tree utype = unsigned_type_for (TREE_TYPE (@0)); }
>               (convert (op (convert:utype @0) (convert:utype @1))))))
>
> You can see that GCC exploits that with -fwrapv.  Maybe this
> simplification should be split out into a separate pattern though,
> tacking sign-changes for binary ops only.
No strong opinion on separate pattern or integrating into existing pattern.

jeff



More information about the Gcc-patches mailing list