[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