On Fri, Jan 30, 2026 at 9:20 AM Andrew Pinski
<[email protected]> wrote:
>
> 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.
I forgot to mention this patch looks ok otherwise.
Thanks,
Andrew
>
> 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