On Tue, Sep 24, 2024 at 2:59 AM Andrew Pinski <quic_apin...@quicinc.com> wrote:
>
> For generic, `a != 0 ? a * b : 0` would match where `b` would be an expression
> which trap (in the case of the testcase, it was an integer division but it 
> could be any).
>
> This adds a new helper function, expr_no_side_effects_p which tests if there 
> is no side effects
> and the expression is not trapping which might be used in other locations.
>
> Changes since v1:
> * v2: Add move check to helper function instead of inlining it.
>
>         PR middle-end/116772

OK.

Thanks,
Richard.

> gcc/ChangeLog:
>
>         * generic-match-head.cc (expr_no_side_effects_p): New function
>         * gimple-match-head.cc (expr_no_side_effects_p): New function
>         * match.pd (`a != 0 ? a / b : 0`): Check expr_no_side_effects_p.
>         (`a != 0 ? a * b : 0`, `a != 0 ? a & b : 0`): Likewise.
>
> gcc/testsuite/ChangeLog:
>
>         * gcc.dg/torture/pr116772-1.c: New test.
>
> Signed-off-by: Andrew Pinski <quic_apin...@quicinc.com>
> ---
>  gcc/generic-match-head.cc                 | 12 ++++++++++++
>  gcc/gimple-match-head.cc                  | 10 ++++++++++
>  gcc/match.pd                              | 10 ++++++++--
>  gcc/testsuite/gcc.dg/torture/pr116772-1.c | 24 +++++++++++++++++++++++
>  4 files changed, 54 insertions(+), 2 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/torture/pr116772-1.c
>
> diff --git a/gcc/generic-match-head.cc b/gcc/generic-match-head.cc
> index 641d8e9b2de..42dee626613 100644
> --- a/gcc/generic-match-head.cc
> +++ b/gcc/generic-match-head.cc
> @@ -115,6 +115,18 @@ optimize_successive_divisions_p (tree, tree)
>    return false;
>  }
>
> +/* Returns true if the expression T has no side effects
> +   including not trapping. */
> +static inline bool
> +expr_no_side_effects_p (tree t)
> +{
> +  if (TREE_SIDE_EFFECTS (t))
> +    return false;
> +  if (generic_expr_could_trap_p (t))
> +    return false;
> +  return true;
> +}
> +
>  /* Return true if EXPR1 and EXPR2 have the same value, but not necessarily
>     same type.  The types can differ through nop conversions.  */
>
> diff --git a/gcc/gimple-match-head.cc b/gcc/gimple-match-head.cc
> index b5d4a71ddc5..4147a0eb38a 100644
> --- a/gcc/gimple-match-head.cc
> +++ b/gcc/gimple-match-head.cc
> @@ -145,6 +145,16 @@ optimize_vectors_before_lowering_p ()
>    return !cfun || (cfun->curr_properties & PROP_gimple_lvec) == 0;
>  }
>
> +/* Returns true if the expression T has no side effects
> +   including not trapping. */
> +static inline bool
> +expr_no_side_effects_p (tree t)
> +{
> +  /* For gimple, there should only be gimple val's here. */
> +  gcc_assert (is_gimple_val (t));
> +  return true;
> +}
> +
>  /* Return true if pow(cst, x) should be optimized into exp(log(cst) * x).
>     As a workaround for SPEC CPU2017 628.pop2_s, don't do it if arg0
>     is an exact integer, arg1 = phi_res +/- cst1 and phi_res = PHI <cst2, ...>
> diff --git a/gcc/match.pd b/gcc/match.pd
> index 940292d0d49..1b88168532d 100644
> --- a/gcc/match.pd
> +++ b/gcc/match.pd
> @@ -4679,7 +4679,10 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>   (simplify
>    (cond (ne @0 integer_zerop) (op@2 @3 @1) integer_zerop )
>     (if (bitwise_equal_p (@0, @3)
> -        && tree_expr_nonzero_p (@1))
> +        && tree_expr_nonzero_p (@1)
> +       /* Cannot make a expression with side effects
> +          unconditional. */
> +       && expr_no_side_effects_p (@3))
>      @2)))
>
>  /* Note we prefer the != case here
> @@ -4689,7 +4692,10 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>  (for op (mult bit_and)
>   (simplify
>    (cond (ne @0 integer_zerop) (op:c@2 @1 @3) integer_zerop)
> -  (if (bitwise_equal_p (@0, @3))
> +  (if (bitwise_equal_p (@0, @3)
> +       /* Cannot make a expression with side effects
> +          unconditional. */
> +       && expr_no_side_effects_p (@1))
>     @2)))
>
>  /* Simplifications of shift and rotates.  */
> diff --git a/gcc/testsuite/gcc.dg/torture/pr116772-1.c 
> b/gcc/testsuite/gcc.dg/torture/pr116772-1.c
> new file mode 100644
> index 00000000000..eedd0398af1
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/torture/pr116772-1.c
> @@ -0,0 +1,24 @@
> +/* { dg-do run } */
> +/* PR middle-end/116772  */
> +/* The division by `/b` should not
> +   be made uncondtional. */
> +
> +int mult0(int a,int b) __attribute__((noipa));
> +
> +int mult0(int a,int b){
> +  return (b!=0 ? (a/b)*b : 0);
> +}
> +
> +int bit_and0(int a,int b) __attribute__((noipa));
> +
> +int bit_and0(int a,int b){
> +  return (b!=0 ? (a/b)&b : 0);
> +}
> +
> +int main() {
> +  if (mult0(3, 0) != 0)
> +    __builtin_abort();
> +  if (bit_and0(3, 0) != 0)
> +    __builtin_abort();
> +  return 0;
> +}
> --
> 2.43.0
>

Reply via email to