[PATCH] [GCC 10 branch] tree-optimization: [PR102622]: wrong code due to signed one bit integer and "a?-1:0"
Richard Biener
richard.guenther@gmail.com
Mon Oct 11 06:40:34 GMT 2021
On Mon, Oct 11, 2021 at 1:20 AM apinski--- via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> From: Andrew Pinski <apinski@marvell.com>
>
> So here is the GCC 10 branch version which fixes the wrong code.
> The problem is we create a negation of an one bit signed integer type
> which is undefined if the value was -1.
> This is not needed for GCC 11 branch since the case is handled differently
> there and has been fixed there (and the trunk has now been fixed too).
> So for one bit types, there is no reason to create the negation so just
> setting neg to false for them, just works.
>
> OK? Bootstrapped and tested on x86_64-linux-gnu.
OK.
Thanks,
Richard.
> PR tree-optimization/102622
>
> gcc/ChangeLog:
>
> * tree-ssa-phiopt.c (conditional_replacement): Set neg
> to false for one bit signed types.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.c-torture/execute/bitfld-10.c: New test.
> ---
> gcc/testsuite/gcc.c-torture/execute/bitfld-10.c | 24 ++++++++++++++++++++++++
> gcc/tree-ssa-phiopt.c | 5 ++++-
> 2 files changed, 28 insertions(+), 1 deletion(-)
> create mode 100644 gcc/testsuite/gcc.c-torture/execute/bitfld-10.c
>
> diff --git a/gcc/testsuite/gcc.c-torture/execute/bitfld-10.c b/gcc/testsuite/gcc.c-torture/execute/bitfld-10.c
> new file mode 100644
> index 0000000..bdbf573
> --- /dev/null
> +++ b/gcc/testsuite/gcc.c-torture/execute/bitfld-10.c
> @@ -0,0 +1,24 @@
> +/* PR tree-optimization/102622 */
> +/* Wrong code introduced due to phi-opt
> + introducing undefined signed interger overflow
> + with one bit signed integer negation. */
> +
> +struct f{signed t:1;};
> +int g(struct f *a, int t) __attribute__((noipa));
> +int g(struct f *a, int t)
> +{
> + if (t)
> + a->t = -1;
> + else
> + a->t = 0;
> + int t1 = a->t;
> + if (t1) return 1;
> + return t1;
> +}
> +
> +int main(void)
> +{
> + struct f a;
> + if (!g(&a, 1)) __builtin_abort();
> + return 0;
> +}
> diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c
> index 9ed26a3..a6c197d 100644
> --- a/gcc/tree-ssa-phiopt.c
> +++ b/gcc/tree-ssa-phiopt.c
> @@ -770,9 +770,12 @@ conditional_replacement (basic_block cond_bb, basic_block middle_bb,
> if ((integer_zerop (arg0) && integer_onep (arg1))
> || (integer_zerop (arg1) && integer_onep (arg0)))
> neg = false;
> + /* For signed one bit types, the negation is not needed and
> + should be avoided and is the same as 1 case for non-signed
> + one bit types. */
> else if ((integer_zerop (arg0) && integer_all_onesp (arg1))
> || (integer_zerop (arg1) && integer_all_onesp (arg0)))
> - neg = true;
> + neg = TYPE_PRECISION (TREE_TYPE (arg0)) != 1;
> else
> return false;
>
> --
> 1.8.3.1
>
More information about the Gcc-patches
mailing list