On Mon, 6 Sep 2021, Jakub Jelinek wrote:

> Hi!
> 
> My earlier patch to demote arguments of __builtin_*_overflow unfortunately
> caused a wrong-code regression.  The builtins operate on infinite precision
> arguments, outer_prec > inner_prec signed -> signed, unsigned -> unsigned
> promotions there are just repeating the sign or 0s and can be demoted,
> similarly unsigned -> signed which also is repeating 0s, but as the
> testcase shows, signed -> unsigned promotions need to be preserved (unless
> we'd know the inner arguments can't be negative), because for negative
> numbers such promotion sets the outer_prec -> inner_prec bits to 1 bit the
> bits above that to 0 in the infinite precision.
> 
> So, the following patch avoids the demotions for the signed -> unsigned
> promotions.
> 
> Bootstrapped/regtested on x86_64-linux, ok for trunk?

OK.

Richard.

> 2021-09-06  Jakub Jelinek  <ja...@redhat.com>
> 
>       PR tree-optimization/102207
>       * match.pd: Don't demote operands of IFN_{ADD,SUB,MUL}_OVERFLOW if they
>       were promoted from signed to wider unsigned type.
> 
>       * gcc.dg/pr102207.c: New test.
> 
> --- gcc/match.pd.jj   2021-09-02 22:49:34.963322655 +0200
> +++ gcc/match.pd      2021-09-05 12:23:23.878476233 +0200
> @@ -5593,13 +5593,15 @@ (define_operator_list COND_TERNARY
>    (ovf (convert@2 @0) @1)
>    (if (INTEGRAL_TYPE_P (TREE_TYPE (@0))
>         && INTEGRAL_TYPE_P (TREE_TYPE (@2))
> -       && TYPE_PRECISION (TREE_TYPE (@2)) > TYPE_PRECISION (TREE_TYPE (@0)))
> +       && TYPE_PRECISION (TREE_TYPE (@2)) > TYPE_PRECISION (TREE_TYPE (@0))
> +       && (!TYPE_UNSIGNED (TREE_TYPE (@2)) || TYPE_UNSIGNED (TREE_TYPE 
> (@0))))
>     (ovf @0 @1)))
>   (simplify
>    (ovf @1 (convert@2 @0))
>    (if (INTEGRAL_TYPE_P (TREE_TYPE (@0))
>         && INTEGRAL_TYPE_P (TREE_TYPE (@2))
> -       && TYPE_PRECISION (TREE_TYPE (@2)) > TYPE_PRECISION (TREE_TYPE (@0)))
> +       && TYPE_PRECISION (TREE_TYPE (@2)) > TYPE_PRECISION (TREE_TYPE (@0))
> +       && (!TYPE_UNSIGNED (TREE_TYPE (@2)) || TYPE_UNSIGNED (TREE_TYPE 
> (@0))))
>     (ovf @1 @0))))
>  
>  /* Simplification of math builtins.  These rules must all be optimizations
> --- gcc/testsuite/gcc.dg/pr102207.c.jj        2021-09-05 12:31:38.967509895 
> +0200
> +++ gcc/testsuite/gcc.dg/pr102207.c   2021-09-05 12:31:12.136887427 +0200
> @@ -0,0 +1,24 @@
> +/* PR tree-optimization/102207 */
> +/* { dg-do run { target int128 } } */
> +/* { dg-options "-O2" } */
> +
> +typedef unsigned __int128 u128;
> +
> +u128
> +foo (unsigned short a)
> +{
> +  u128 g;
> +  __builtin_sub_overflow ((unsigned long long) -a, 1, &g);
> +  return g;
> +}
> +
> +int
> +main ()
> +{
> +  if (__SIZEOF_LONG_LONG__ * __CHAR_BIT__ != 64
> +      || __SIZEOF_SHORT__ * __CHAR_BIT__ != 16)
> +    return 0;
> +  if (foo (1) != 0xfffffffffffffffeULL)
> +    __builtin_abort ();
> +  return 0;
> +}
> 
>       Jakub
> 
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)

Reply via email to