On Wed, 07 Oct 2026 23:51:40 -0300, Daniel Barboza 
<[email protected]> wrote:
> This is done by RTL.  Do it earlier in Gimple to potentially allow more
> optimizations opportunities.
> 
> Bootstrapped and regression tested in x86_64.
> 
>       PR 126644
> 
> gcc/ChangeLog:
> 
>       * match.pd:
> 
> gcc/testsuite/ChangeLog:
> 
>       * gcc.dg/tree-ssa/pr126644.c: New test.

Thanks for the patch.
The gcc/ChangeLog entry is incomplete, Please describe the new simplification.

>
>
> diff --git a/gcc/match.pd b/gcc/match.pd
> index 2d1161b860b..06bbe32c029 100644
> --- a/gcc/match.pd
> +++ b/gcc/match.pd
> @@ -1561,6 +1561,25 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
> [ ... skip 16 lines ... ]
> +                             true, prec);
> +    }
> +    (if ((tree_nonzero_bits (@0) & mask) == 0)
> +     @0))))
> +#endif
> +

It would be incorrect for signed types when signed left shifts wrap including 
-fwrapv and C++20.
The mask checks only the upper N bits but arithmetic right shift also 
propagates bit prec - 1 - N.
That bit can be set even when the upper N bits are zero producing a wrong 
result.

Requiring TYPE_OVERFLOW_UNDEFINED (type) || TYPE_UNSIGNED (type) handles 
-fwrapv but not C++20.
Please require one additional known zero bit for signed shifts or otherwise 
account for the language’s shift semantics.

>
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr126644.c 
> b/gcc/testsuite/gcc.dg/tree-ssa/pr126644.c
> new file mode 100644
> index 00000000000..73286cd5a1e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr126644.c
> @@ -0,0 +1,18 @@
> [ ... skip 12 lines ... ]
> +{
> +  return a << 3 >> 3;
> +}
> +
> +/* { dg-final { scan-tree-dump-times " << " 1 "optimized" } } */
> +/* { dg-final { scan-tree-dump-times " >> " 1 "optimized" } } */

Its better to add unsigned, C++20, and -fwrapv regression tests.

-- 
Naveen <[email protected]>

Reply via email to