> On 1 Aug 2024, at 10:46 pm, Richard Biener <richard.guent...@gmail.com> wrote:
> 
> External email: Use caution opening links or attachments
> 
> 
> On Thu, Aug 1, 2024 at 5:31 AM Kugan Vivekanandarajah
> <kvivekana...@nvidia.com> wrote:
>> 
>> 
>> On Mon, Jul 29, 2024 at 10:11 AM Andrew Pinski <pins...@gmail.com> wrote:
>>> 
>>> On Mon, Jul 29, 2024 at 12:57 AM Kugan Vivekanandarajah
>>> <kugan...@gmail.com> wrote:
>>>> 
>>>> On Thu, Jul 25, 2024 at 10:19 PM Richard Biener
>>>> <richard.guent...@gmail.com> wrote:
>>>>> 
>>>>> On Thu, Jul 25, 2024 at 4:42 AM Kugan Vivekanandarajah
>>>>> <kugan...@gmail.com> wrote:
>>>>>> 
>>>>>> On Tue, Jul 23, 2024 at 11:56 PM Richard Biener
>>>>>> <richard.guent...@gmail.com> wrote:
>>>>>>> 
>>>>>>> On Tue, Jul 23, 2024 at 10:27 AM Kugan Vivekanandarajah
>>>>>>> <kugan...@gmail.com> wrote:
>>>>>>>> 
>>>>>>>> On Tue, Jul 23, 2024 at 10:35 AM Andrew Pinski <pins...@gmail.com> 
>>>>>>>> wrote:
>>>>>>>>> 
>>>>>>>>> On Mon, Jul 22, 2024 at 5:26 PM Kugan Vivekanandarajah
>>>>>>>>> <kvivekana...@nvidia.com> wrote:
>>>>>>>>>> 
>>>>>>>>>> Revised based on the comment and moved it into existing patterns as.
>>>>>>>>>> 
>>>>>>>>>> gcc/ChangeLog:
>>>>>>>>>> 
>>>>>>>>>> * match.pd: Extend A CMP 0 ? A : -A into (type)A CMP 0 ? A : -A.
>>>>>>>>>> Extend A CMP 0 ? A : -A into (type) A CMP 0 ? A : -A.
>>>>>>>>>> 
>>>>>>>>>> gcc/testsuite/ChangeLog:
>>>>>>>>>> 
>>>>>>>>>> * gcc.dg/tree-ssa/absfloat16.c: New test.
>>>>>>>>> 
>>>>>>>>> The testcase needs to make sure it runs only for targets that support
>>>>>>>>> float16 so like:
>>>>>>>>> 
>>>>>>>>> /* { dg-require-effective-target float16 } */
>>>>>>>>> /* { dg-add-options float16 } */
>>>>>>>> Added in the attached version.
>>>>>>> 
>>>>>>> + /* (type)A >=/> 0 ? A : -A    same as abs (A) */
>>>>>>>  (for cmp (ge gt)
>>>>>>>   (simplify
>>>>>>> -   (cnd (cmp @0 zerop) @1 (negate @1))
>>>>>>> -    (if (!HONOR_SIGNED_ZEROS (TREE_TYPE(@0))
>>>>>>> -        && !TYPE_UNSIGNED (TREE_TYPE(@0))
>>>>>>> -        && bitwise_equal_p (@0, @1))
>>>>>>> +   (cnd (cmp (convert?@0 @1) zerop) @2 (negate @2))
>>>>>>> +    (if (!HONOR_SIGNED_ZEROS (TREE_TYPE (@1))
>>>>>>> +        && !TYPE_UNSIGNED (TREE_TYPE (@1))
>>>>>>> +        && ((VECTOR_TYPE_P (type)
>>>>>>> +             && tree_nop_conversion_p (TREE_TYPE (@0), TREE_TYPE (@1)))
>>>>>>> +           || (!VECTOR_TYPE_P (type)
>>>>>>> +               && (TYPE_PRECISION (TREE_TYPE (@1))
>>>>>>> +                   <= TYPE_PRECISION (TREE_TYPE (@0)))))
>>>>>>> +        && bitwise_equal_p (@1, @2))
>>>>>>> 
>>>>>>> I wonder about the bitwise_equal_p which tests @1 against @2 now
>>>>>>> with the convert still applied to @1 - that looks odd.  You are allowing
>>>>>>> sign-changing conversions but doesn't that change ge/gt behavior?
>>>>>>> Also why are sign/zero-extensions not OK for vector types?
>>>>>> Thanks for the review.
>>>>>> My main motivation here is for _Float16  as below.
>>>>>> 
>>>>>> _Float16 absfloat16 (_Float16 x)
>>>>>> {
>>>>>>  float _1;
>>>>>>  _Float16 _2;
>>>>>>  _Float16 _4;
>>>>>>  <bb 2> [local count: 1073741824]:
>>>>>>  _1 = (float) x_3(D);
>>>>>>  if (_1 < 0.0)
>>>>>>    goto <bb 3>; [41.00%]
>>>>>>  else
>>>>>>    goto <bb 4>; [59.00%]
>>>>>>  <bb 3> [local count: 440234144]:\
>>>>>>  _4 = -x_3(D);
>>>>>>  <bb 4> [local count: 1073741824]:
>>>>>>  # _2 = PHI <_4(3), x_3(D)(2)>
>>>>>>  return _2;
>>>>>> }
>>>>>> 
>>>>>> This is why I added  bitwise_equal_p test of @1 against @2 with
>>>>>> TYPE_PRECISION checks.
>>>>>> I agree that I will have to check for sign-changing conversions.
>>>>>> 
>>>>>> Just to keep it simple, I disallowed vector types. I am not sure if
>>>>>> this would  hit vec types. I am happy to handle this if that is
>>>>>> needed.
>>>>> 
>>>>> I think with __builtin_convertvector you should be able to construct
>>>>> a testcase that does
>>>> Thanks.
>>>> 
>>>> For the pattern,
>>>> ```
>>>> /* A >=/> 0 ? A : -A    same as abs (A) */
>>>> (for cmp (ge gt)
>>>>  (simplify
>>>>   (cnd (cmp @0 zerop) @1 (negate @1))
>>>>    (if (!HONOR_SIGNED_ZEROS (TREE_TYPE(@0))
>>>>         && !TYPE_UNSIGNED (TREE_TYPE(@0))
>>>>         && bitwise_equal_p (@0, @1))
>>>>     (if (TYPE_UNSIGNED (type))
>>>>      (absu:type @0)
>>>>      (abs @0)))))
>>>> ```
>>>> the vector type doesn't seem right. For example, if we have a 4
>>>> element vector with some negative and positive, I don't think  it
>>>> makes sense. Also, we dont seem to generate  (cmp @0 zerop). Am I
>>>> missing it completely?
>>> 
>>> Looks like I missed adding some vector testcases anyways here is one
>>> to get this, note it is C++ due to the C front-end not support `?:`
>>> for vectors yet (there is a patch).
>>> ```
>>> #define vect8 __attribute__((vector_size(8)))
>>> vect8 int f(vect8 int a)
>>> {
>>>  vect8 int na = -a;
>>>  return (a > 0) ? a : na;
>>> }
>>> ```
>>> At -O2 before forwprop1, we have:
>>> ```
>>>  vector(2) intD.9 a_2(D) = aD.2796;
>>>  vector(2) intD.9 naD.2799;
>>>  vector(2) <signed-boolean:32> _1;
>>>  vector(2) intD.9 _4;
>>> 
>>>  na_3 = -a_2(D);
>>>  _1 = a_2(D) > { 0, 0 };
>>>  _4 = VEC_COND_EXPR <_1, a_2(D), na_3>;
>>> ```
>>> And forwprop using match is able to do:
>>> ```
>>> Applying pattern match.pd:6306, gimple-match-10.cc:19843
>>> gimple_simplified to _4 = ABS_EXPR <a_2(D)>;
>>> Removing dead stmt:_1 = a_2(D) > { 0, 0 };
>>> Removing dead stmt:na_3 = -a_2(D);
>>> ```
>>> (replace int with float and add  -fno-signed-zeros you can get the ABS 
>>> also).
>>> 
>>> Note comparisons with vector types always generate a vector boolean
>>> type. So cond_expr will never show up with a vector comparison; only
>>> vec_cond.
>> 
>> 
>> Thanks for the information. I have revised the patch by adding test case for 
>> the vector type. I will look at removing the VEC_COND_EXPR as a follow up.
> 
> This is likely a major task so do not get you distracted - I just mentioned 
> it.
> 
>> This is still rejected by the type checker.
>> v2hi  absvect2 (v2hi x, int i) {
>>    v2hi neg = -x;
>>    v2si tmp = __builtin_convertvector (x, v2si);
>>    return (tmp > 0) ? x : neg;
>> }
>> as:
>> error: incompatible vector types in conditional expression: '__vector(2) 
>> int', 'v2hi' {aka '__vector(2) short int'} and 'v2hi' {aka '__vector(2) 
>> short int'}
>> 8 |     return (tmp > 0) ? x : neg;
>>    |            ~~~~~~~~~~^~~~~~~~~
>> 
>> Also
>> 
>> -      (absu:type @0)
>> -      (abs @0)))))
>> +      (absu:type @1)
>> +      (abs @1)))))
>> 
>> Changing the @1 to @2  is resulting in failures.  Existing tests like  the 
>> following would be optimized away in this case.
>> ```
>> unsigned abs_with_convert0 (int x)
>> {
>>    unsigned int y = x;
>> 
>>    if (x < 0)
>>        y = -y;
>> 
>>  return y;
>> }
> 
> How so - the TYPE_UNSIGNED tests should make the pattern not trigger here?
> 
>> ```
>> This follows the same intent as the original pattern.
>> 
>> Bootstrapped and regression tested on aarch64-linux-gnu. Is this OK for 
>> trunk.
> 
> 
> 
> -   (cnd (cmp @0 zerop) @1 (negate @1))
> -    (if (!HONOR_SIGNED_ZEROS (TREE_TYPE(@0))
> -        && !TYPE_UNSIGNED (TREE_TYPE(@0))
> -        && bitwise_equal_p (@0, @1))
> +   (cnd (cmp (convert?@0 @1) zerop) @2 (negate @2))
> +    (if (!HONOR_SIGNED_ZEROS (TREE_TYPE (@1))
> +        && !TYPE_UNSIGNED (TREE_TYPE (@1))
> +        && !TYPE_UNSIGNED (TREE_TYPE (@0))
> 
> I think the outer type could be allowed signed if ...
> 
> +        && ((VECTOR_TYPE_P (TREE_TYPE (@0))
> +             && VECTOR_TYPE_P (TREE_TYPE (@1))
> +             && known_eq (TYPE_VECTOR_SUBPARTS (TREE_TYPE (@0)),
> +                          TYPE_VECTOR_SUBPARTS (TREE_TYPE (@1)))
> 
> this is always true
> 
> +             && element_precision (TREE_TYPE (@1))
> +                 <= element_precision (TREE_TYPE (@0)))
> +           || (!VECTOR_TYPE_P (TREE_TYPE (@0))
> +               && (TYPE_PRECISION (TREE_TYPE (@1))
> +                   <= TYPE_PRECISION (TREE_TYPE (@0)))))
> 
> ... you make the precision strictly larger.  With both unsigned the same
> precision case should have been stripped anyway.
> 
> You can use element_precision for both vector and non-vector so I think this
> should simplify to just checking element_precision.
> 
> +      (absu:type @1)
> +      (abs @1)))))
> 
> I still think this needs to be @2 for type correctness.  @1 is only
> bitwise equal,
> it could have different sign.  I think we should drop bitwise_equal_p with the
> convert now in and instead have a matching constraint.

Thanks, so this should translate to: 

/* (type)A >=/> 0 ? A : -A    same as abs (A) */
 (for cmp (ge gt)
  (simplify
   (cnd (cmp (convert?@0 @1) zerop) @2 (negate @2))
    (if (!HONOR_SIGNED_ZEROS (TREE_TYPE (@1))
         && !TYPE_UNSIGNED (TREE_TYPE (@1))
         && !TYPE_UNSIGNED (TREE_TYPE (@2))
         && ((element_precision (TREE_TYPE (@1))
                < element_precision (TREE_TYPE (@0))
              || operand_equal_p (@1, @0)))
         && bitwise_equal_p (@1, @2))
     (if (TYPE_UNSIGNED (type))
      (absu:type @2)
      (abs @2)))))

However with this, I am seeing: Note that the @2 for these are unsigned.

Tests that now fail, but worked before (4 tests):

gcc: gcc.dg/tree-ssa/phi-opt-36.c scan-tree-dump-not phiopt2 "if "
gcc: gcc.dg/tree-ssa/phi-opt-36.c scan-tree-dump-times phiopt1 "if " 2
gcc: gcc.dg/tree-ssa/phi-opt-37.c scan-tree-dump-not phiopt1 "if "gcc: 
gcc.dg/tree-ssa/phi-opt-37.c scan-tree-dump-times phiopt1 "ABSU_EXPR <" 2


unsigned f2(int A)
{
  unsigned t = A;
//     A >= 0? A : -A    same as abs (A)
  if (A >= 0)  return t;
  return -t;
}

unsigned abs_with_convert0 (int x)
{
    unsigned int y = x;

    if (x < 0)
        y = -y;

  return y;
}
unsigned abs_with_convert1 (unsigned x)
{
    int y = x;

    if (y < 0)
        x = -x;

  return x;
}

In the original pattern, we have check for  !TYPE_UNSIGNED (TREE_TYPE(@0)) and  
(absu:type @0)

Shouldnt that translate !TYPE_UNSIGNED (TREE_TYPE(@1)) and  (absu:type @1) in 
the new pattern

Thanks,
Kugan

> 
> Same comments apply to the 2nd pattern update.
> 
> Richard.
> 
>> Thanks,
>> Kugan
>> 
>> gcc/ChangeLog:
>> 
>>        * match.pd: Extend A CMP 0 ? A : -A into (type)A CMP 0 ? A : -A.
>>        Extend A CMP 0 ? A : -A into (type) A CMP 0 ? A : -A.
>> 
>> gcc/testsuite/ChangeLog:
>> 
>>        * g++.dg/absvect.C: New test.
>>        * gcc.dg/tree-ssa/absfloat16.c: New test.
>> 
>> 
>> signed-off-by: Kugan Vivekanandarajah <kvivekana...@nvidia.com>
>> 
>> 
>> Note I think we should be able to merge VEC_COND_EXPR and COND_EXPR
>> codes by instead looking whether the condition is vector or scalar.  Fallout
>> might be a bit too big, but it might be a thing to try.
>> 
>> Richard.
>> 
>>> Thanks,
>>> Andrew Pinski
>>> 
>>>> 
>>>> Thanks,
>>>> Kugan
>>>> 
>>>>> 
>>>>>> 
>>>>>>> 
>>>>>>> +      (absu:type @1)
>>>>>>> +      (abs @1)))))
>>>>>>> 
>>>>>>> I think this should use @2 now.
>>>>>> I will change this.
>>>>>> 
>>>>>> Thanks,
>>>>>> Kugan
>>>>>> 
>>>>>>> 
>>>>>>>> Thanks.
>>>>>>>> Kugan
>>>>>>>>> 
>>>>>>>>> (like what is in gcc.dg/c11-floatn-3.c and others).
>>>>>>>>> 
>>>>>>>>> Other than that it looks good but I can't approve it.
>>>>>>>>> 
>>>>>>>>> Thanks,
>>>>>>>>> Andrew Pinski
>>>>>>>>> 
>>>>>>>>>> 
>>>>>>>>>> Signed-off-by: Kugan Vivekanandarajah <kvivekana...@nvidia.com>
>>>>>>>>>> 
>>>>>>>>>> Bootstrapped and regression test on aarch64-linux-gnu. Is this OK 
>>>>>>>>>> for trunk?
>>>>>>>>>> Thanks,
>>>>>>>>>> Kugan
>>>>>>>>>> 
>>>>>>>>>> ________________________________
>>>>>>>>>> From: Andrew Pinski <pins...@gmail.com>
>>>>>>>>>> Sent: Monday, 15 July 2024 5:30 AM
>>>>>>>>>> To: Kugan Vivekanandarajah <kvivekana...@nvidia.com>
>>>>>>>>>> Cc: gcc-patches@gcc.gnu.org <gcc-patches@gcc.gnu.org>; 
>>>>>>>>>> richard.guent...@gmail.com <richard.guent...@gmail.com>
>>>>>>>>>> Subject: Re: [PATCH] MATCH: add abs support for half float
>>>>>>>>>> 
>>>>>>>>>> External email: Use caution opening links or attachments
>>>>>>>>>> 
>>>>>>>>>> 
>>>>>>>>>> On Sun, Jul 14, 2024 at 1:12 AM Kugan Vivekanandarajah
>>>>>>>>>> <kvivekana...@nvidia.com> wrote:
>>>>>>>>>>> 
>>>>>>>>>>> This patch extends abs detection in matched for half float.
>>>>>>>>>>> 
>>>>>>>>>>> Bootstrapped and regression test on aarch64-linux-gnu. Is this OK 
>>>>>>>>>>> for trunk?
>>>>>>>>>> 
>>>>>>>>>> This is basically this pattern:
>>>>>>>>>> ```
>>>>>>>>>> /* A >=/> 0 ? A : -A    same as abs (A) */
>>>>>>>>>> (for cmp (ge gt)
>>>>>>>>>>  (simplify
>>>>>>>>>>   (cnd (cmp @0 zerop) @1 (negate @1))
>>>>>>>>>>    (if (!HONOR_SIGNED_ZEROS (TREE_TYPE(@0))
>>>>>>>>>>         && !TYPE_UNSIGNED (TREE_TYPE(@0))
>>>>>>>>>>         && bitwise_equal_p (@0, @1))
>>>>>>>>>>     (if (TYPE_UNSIGNED (type))
>>>>>>>>>>      (absu:type @0)
>>>>>>>>>>      (abs @0)))))
>>>>>>>>>> ```
>>>>>>>>>> 
>>>>>>>>>> except extended to handle an optional convert. Why didn't you just
>>>>>>>>>> extend the above pattern to handle the convert instead? Also I think
>>>>>>>>>> you have an issue with unsigned types with the comparison.
>>>>>>>>>> Also you should extend the -abs(A) pattern right below it in a 
>>>>>>>>>> similar fashion.
>>>>>>>>>> 
>>>>>>>>>> Thanks,
>>>>>>>>>> Andrew Pinski
>>>>>>>>>> 
>>>>>>>>>> 
>>>>>>>>>>> 
>>>>>>>>>>> gcc/ChangeLog:
>>>>>>>>>>> 
>>>>>>>>>>> * match.pd: Add pattern to convert (type)A >=/> 0 ? A : -A into abs 
>>>>>>>>>>> (A) for half float.
>>>>>>>>>>> 
>>>>>>>>>>> gcc/testsuite/ChangeLog:
>>>>>>>>>>> 
>>>>>>>>>>> * gcc.dg/tree-ssa/absfloat16.c: New test.
>>>>>>>>>>> 
>>>>>>>>>>> Signed-off-by: Kugan Vivekanandarajah <kvivekana...@nvidia.com>


Reply via email to