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]>