On Fri, Jan 30, 2026 at 7:18 AM Richard Biener <[email protected]> wrote:
>
> The following properly checks expr_no_side_effects_p on two patterns
> that turns a conditionally evaluated operand into unconditonal.
>
> Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.
>
>         PR middle-end/123887
>         * match.pd ((zero_one ==/!= 0) ? .. z <op> y .. -> zero_one * z ..):
>         Check evaluating z unconditionally has no side-effects, like
>         trapping.

Looks like I had missed adding expr_no_side_effects_p to those
patterns when I did r15-3870-g6c5543d3d9c4bb.
The other patterns which have the same issue which is missed:
```
/* (a ? x : y) != (b ? x : y) --> (a^b & (x != y)) ? TRUE  : FALSE */
/* (a ? x : y) == (b ? x : y) --> (a^b & (x != y)) ? FALSE : TRUE  */
/* (a ? x : y) != (b ? y : x) --> (a^b | (x == y)) ? FALSE : TRUE  */
/* (a ? x : y) == (b ? y : x) --> (a^b | (x == y)) ? TRUE  : FALSE */
/* These are only valid if x and y don't have NaNs. */
```
With this testcase:
```
[[gnu::noipa]]
int f(int a, int b, int *x)
{
  return (a ? *x : 0) != (b ? *x : 0);
}
int main()
{
  f(0, 0, 0);
  return 0;
}
```

I audited the other patterns (that you did not change) and only could
find the above one.

Thanks,
Andrew



>
>         * gcc.dg/torture/pr123887.c: New testcase.
> ---
>  gcc/match.pd                            |  6 ++++--
>  gcc/testsuite/gcc.dg/torture/pr123887.c | 14 ++++++++++++++
>  2 files changed, 18 insertions(+), 2 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/torture/pr123887.c
>
> diff --git a/gcc/match.pd b/gcc/match.pd
> index 05e8ea7a229..9b2da2be4c5 100644
> --- a/gcc/match.pd
> +++ b/gcc/match.pd
> @@ -5178,7 +5178,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>          (op:c @2 @1))
>    (if (INTEGRAL_TYPE_P (type)
>         && TYPE_PRECISION (type) > 1
> -       && (INTEGRAL_TYPE_P (TREE_TYPE (@0))))
> +       && INTEGRAL_TYPE_P (TREE_TYPE (@0))
> +       && expr_no_side_effects_p (@2))
>         (op (mult (convert:type @0) @2) @1))))
>
>  /* (zero_one != 0) ? z <op> y : y -> ((typeof(y))zero_one * z) <op> y */
> @@ -5190,7 +5191,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>          @1)
>    (if (INTEGRAL_TYPE_P (type)
>         && TYPE_PRECISION (type) > 1
> -       && (INTEGRAL_TYPE_P (TREE_TYPE (@0))))
> +       && INTEGRAL_TYPE_P (TREE_TYPE (@0))
> +       && expr_no_side_effects_p (@2))
>         (op (mult (convert:type @0) @2) @1))))
>
>  /* ?: Value replacement. */
> diff --git a/gcc/testsuite/gcc.dg/torture/pr123887.c 
> b/gcc/testsuite/gcc.dg/torture/pr123887.c
> new file mode 100644
> index 00000000000..c2a9659c5b5
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/torture/pr123887.c
> @@ -0,0 +1,14 @@
> +/* { dg-do run } */
> +
> +typedef struct {
> +    unsigned s;
> +} struct_t;
> +
> +struct_t *p;
> +bool cond;
> +int v = 1;
> +int main()
> +{
> +  int u = 1 + (cond ? p->s : 0);
> +  return u - v;
> +}
> --
> 2.51.0

Reply via email to