On Thu, May 15, 2025 at 5:55 AM Andrew Pinski <[email protected]> wrote:
>
> On Wed, May 14, 2025 at 7:39 PM Andrew Pinski <[email protected]>
> wrote:
> >
> > This is the next step in removing forward_propagate_into_comparison
> > and forward_propagate_into_gimple_cond; In the case of `((int)(a cmp b)) !=
> > 0`
> > we want to do the transformation to `a cmp b` even if the cast is used
> > twice.
> > This is exactly what
> > forward_propagate_into_comparison/forward_propagate_into_gimple_cond
> > do and does the copy.
>
> Actually I am thinking we should change:
> this set of patterns:
> ```
> (for cmp (simple_comparison)
> (simplify
> (cmp (convert@0 @00) (convert?@1 @10))
> (if (INTEGRAL_TYPE_P (TREE_TYPE (@0))
> /* Disable this optimization if we're casting a function pointer
> type on targets that require function pointer canonicalization. */
> && !(targetm.have_canonicalize_funcptr_for_compare ()
> && ((POINTER_TYPE_P (TREE_TYPE (@00))
> && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (@00))))
> || (POINTER_TYPE_P (TREE_TYPE (@10))
> && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (@10))))))
> && single_use (@0))
> ```
> In the case of:
> (if (TREE_CODE (@1) == INTEGER_CST)
> (cmp @00 ...)
> We don't need to care if @0 is single_use or not as we remove one cast.
> Plus all of the cases where we produce constants don't care about
> single_use either.
>
> So let's ignore this patch for now. I will get back to it tomorrow.
I have a recollection that I changed exactly one similar place to defer
the single_use () checks to the result expressions that are not "simple" ...
IIRC I had that changed :S flag handling for this - enforce single-use
when the result isn't "simple" (much similar to how we have ! now),
but IIRC we concluded we don't need this.
PR118483 was the PR where this mattered, the match.pd change I
had for this was the following:
diff --git a/gcc/match.pd b/gcc/match.pd
index f4050687647..8ad574e7404 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -7562,7 +7562,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
FIXME: the lack of symmetry is disturbing. */
(for cmp (simple_comparison)
(simplify
- (cmp (convert@0 @00) (convert?@1 @10))
+ (cmp (convert:S@0 @00) (convert?@1 @10))
(if (INTEGRAL_TYPE_P (TREE_TYPE (@0))
/* Disable this optimization if we're casting a function pointer
type on targets that require function pointer canonicalization. */
@@ -7570,8 +7570,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
&& ((POINTER_TYPE_P (TREE_TYPE (@00))
&& FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (@00))))
|| (POINTER_TYPE_P (TREE_TYPE (@10))
- && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (@10))))))
- && single_use (@0))
+ && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (@10)))))))
(if (TYPE_PRECISION (TREE_TYPE (@00)) == TYPE_PRECISION (TREE_TYPE (@0))
&& (TREE_CODE (@10) == INTEGER_CST
|| @1 != @10)
because the
(if (above || below)
(if (cmp == EQ_EXPR || cmp == NE_EXPR)
{ constant_boolean_node (cmp == EQ_EXPR ? false : true, type); }
(if (cmp == LT_EXPR || cmp == LE_EXPR)
{ constant_boolean_node (above ? true : false, type); }
(if (cmp == GT_EXPR || cmp == GE_EXPR)
{ constant_boolean_node (above ? false : true, type); })))))))))
cases at least would be unproblematic and OK when !single_use. That's exactly
what you noticed. So moving that check down to where it matters works as well
and is pre-approved.
Richard.
>
> Thanks,
> Andrew
>
> >
> > Bootstrapped and tested on x86_64-linux-gnu.
> >
> > gcc/ChangeLog:
> >
> > * match.pd (`(a cmp b) != false`, `(a cmp b) == true`,
> > `(a cmp b) != true`, `(a cmp b) == false`): Allow an
> > optional cast between the comparison and the eq/ne.
> > (`bool_val != false`, `bool_val == true`): Allow an optional
> > cast between the bool_val and the ne/eq.
> >
> > Signed-off-by: Andrew Pinski <[email protected]>
> > ---
> > gcc/match.pd | 12 ++++++------
> > 1 file changed, 6 insertions(+), 6 deletions(-)
> >
> > diff --git a/gcc/match.pd b/gcc/match.pd
> > index 79485f9678a..ffb1695e6e6 100644
> > --- a/gcc/match.pd
> > +++ b/gcc/match.pd
> > @@ -6913,15 +6913,15 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
> > (ncmp @0 @1)))))
> > /* The following bits are handled by fold_binary_op_with_conditional_arg.
> > */
> > (simplify
> > - (ne (cmp@2 @0 @1) integer_zerop)
> > + (ne (convert? (cmp@2 @0 @1)) integer_zerop)
> > (if (types_match (type, TREE_TYPE (@2)))
> > (cmp @0 @1)))
> > (simplify
> > - (eq (cmp@2 @0 @1) integer_truep)
> > + (eq (convert? (cmp@2 @0 @1)) integer_truep)
> > (if (types_match (type, TREE_TYPE (@2)))
> > (cmp @0 @1)))
> > (simplify
> > - (ne (cmp@2 @0 @1) integer_truep)
> > + (ne (convert? (cmp@2 @0 @1)) integer_truep)
> > (if (types_match (type, TREE_TYPE (@2)))
> > (with { enum tree_code ic = invert_tree_comparison
> > (cmp, HONOR_NANS (@0)); }
> > @@ -6930,7 +6930,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
> > (if (ic == ncmp)
> > (ncmp @0 @1))))))
> > (simplify
> > - (eq (cmp@2 @0 @1) integer_zerop)
> > + (eq (convert? (cmp@2 @0 @1)) integer_zerop)
> > (if (types_match (type, TREE_TYPE (@2)))
> > (with { enum tree_code ic = invert_tree_comparison
> > (cmp, HONOR_NANS (@0)); }
> > @@ -8104,13 +8104,13 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
> >
> > /* bool_var != 0 becomes bool_var. */
> > (simplify
> > - (ne @0 integer_zerop)
> > + (ne (convert? @0) integer_zerop)
> > (if (TREE_CODE (TREE_TYPE (@0)) == BOOLEAN_TYPE
> > && types_match (type, TREE_TYPE (@0)))
> > (non_lvalue @0)))
> > /* bool_var == 1 becomes bool_var. */
> > (simplify
> > - (eq @0 integer_onep)
> > + (eq (convert? @0) integer_onep)
> > (if (TREE_CODE (TREE_TYPE (@0)) == BOOLEAN_TYPE
> > && types_match (type, TREE_TYPE (@0)))
> > (non_lvalue @0)))
> > --
> > 2.43.0
> >