This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Extend tree code folds to IFN_COND_*


On Wed, Jul 4, 2018 at 8:46 PM Richard Sandiford
<richard.sandiford@linaro.org> wrote:
>
> Finally getting back to this...
>
> Richard Biener <richard.guenther@gmail.com> writes:
> > On Wed, Jun 6, 2018 at 10:16 PM Richard Sandiford
> > <richard.sandiford@linaro.org> wrote:
> >>
> >> > On Thu, May 24, 2018 at 11:36 AM Richard Sandiford
> >> > <richard.sandiford@linaro.org> wrote:
> >> >>
> >> >> This patch adds match.pd support for applying normal folds to their
> >> >> IFN_COND_* forms.  E.g. the rule:
> >> >>
> >> >>   (plus @0 (negate @1)) -> (minus @0 @1)
> >> >>
> >> >> also allows the fold:
> >> >>
> >> >>   (IFN_COND_ADD @0 @1 (negate @2) @3) -> (IFN_COND_SUB @0 @1 @2 @3)
> >> >>
> >> >> Actually doing this by direct matches in gimple-match.c would
> >> >> probably lead to combinatorial explosion, so instead, the patch
> >> >> makes gimple_match_op carry a condition under which the operation
> >> >> happens ("cond"), and the value to use when the condition is false
> >> >> ("else_value").  Thus in the example above we'd do the following
> >> >>
> >> >> (a) convert:
> >> >>
> >> >>       cond:NULL_TREE (IFN_COND_ADD @0 @1 @4 @3) else_value:NULL_TREE
> >> >>
> >> >>     to:
> >> >>
> >> >>       cond:@0 (plus @1 @4) else_value:@3
> >> >>
> >> >> (b) apply gimple_resimplify to (plus @1 @4)
> >> >>
> >> >> (c) reintroduce cond and else_value when constructing the result.
> >> >>
> >> >> Nested operations inherit the condition of the outer operation
> >> >> (so that we don't introduce extra faults) but have a null else_value.
> >> >> If we try to build such an operation, the target gets to choose what
> >> >> else_value it can handle efficiently: obvious choices include one of
> >> >> the operands or a zero constant.  (The alternative would be to have some
> >> >> representation for an undefined value, but that seems a bit invasive,
> >> >> and isn't likely to be useful here.)
> >> >>
> >> >> I've made the condition a mandatory part of the gimple_match_op
> >> >> constructor so that it doesn't accidentally get dropped.
> >> >>
> >> >> Tested on aarch64-linux-gnu (with and without SVE), aarch64_be-elf
> >> >> and x86_64-linux-gnu.  OK to install?
> >> >
> >> > It looks somewhat clever but after looking for a while it doesn't handle
> >> > simplifying
> >> >
> >> >  (IFN_COND_ADD @0 @1 (IFN_COND_SUB @0 @2 @1 @3) @3)
> >> >
> >> > to
> >> >
> >> >  (cond @0 @2 @3)
> >> >
> >> > right?  Because while the conditional gimple_match_op is built
> >> > by try_conditional_simplification it isn't built when doing
> >> > SSA use->def following in the generated matching code?
> >>
> >> Right.  This would be easy to add, but there's no motivating case yet.
> >
> > ...
> >
> >> > So it looks like a bit much noise for this very special case?
> >> >
> >> > I suppose you ran into the need of these foldings from looking
> >> > at real code - which foldings specifically were appearing here?
> >> > Usually code is well optimized before if-conversion/vectorization
> >> > so we shouldn't need full-blown handling?
> >>
> >> It's needed to get the FMA, FMS, FNMA and FNMS folds for IFN_COND_* too.
> >> I thought it'd be better to do it "automatically" rather than add specific
> >> folds, since if we don't do it automatically now, it's going to end up
> >> being a precedent for not doing it automatically in future either.
> >
> > ... not like above isn't a similar precedent ;)  But OK, given...
>
> But we're not doing the above case manually either yet :-)  Whereas the
> series does need to do what the patch does one way or another.
>
> Also, it might be hard to do the above case manually anyway (i.e. match
> nested IFN_COND_* ops with an implicitly-conditional top-level op),
> since the match.pd rule wouldn't have easy access to the overall condition.
> And that's by design, or so I'd like to claim.
>
> >> > That said, I'm not sure how much work it is to massage
> >> >
> >> >       if (gimple *def_stmt = get_def (valueize, op2))
> >> >         {
> >> >           if (gassign *def = dyn_cast <gassign *> (def_stmt))
> >> >             switch (gimple_assign_rhs_code (def))
> >> >               {
> >> >               case PLUS_EXPR:
> >> >
> >> > to look like
> >> >
> >> >       if (gimple *def_stmt = get_def (valueize, op2))
> >> >         {
> >> >            code = ERROR_MARK;
> >> >            if (!is_cond_ifn_with_cond (curr_gimple_match_op, &code))
> >> >              if (gassign *def dyn_cast <gassign *> (def_stmt))
> >> >                code = gimple_assign_rhs_code (def);
> >> >            switch (code)
> >> >              {
> >> >              case PLUS_EXPR:
> >> >
> >> > thus transparently treat the IFN_COND_* as their "code" if the condition
> >> > matches that of the context (I'm not sure if we can do anything for
> >> > mismatching contexts).
> >>
> >> Yeah, this was one approach I had in mind for the subnodes, if we do
> >> end up needing it.  But at least for the top-level node, we want to try
> >> both as a native IFN_COND_FOO and as a conditional FOO, which is why the
> >> top-level case is handled directly in gimple-match-head.c.
> >>
> >> Of course, trying both for subnodes would lead to exponential behaviour
> >> in general.  And like you say, in practice most double-IFN_COND cases
> >> should have been folded before we created the IFN_CONDs, so it's hard
> >> to tell which recursive behaviour would be best.
> >
> > ... this it probably makes sense to do it "simple" first.
> >
> > Btw, I'd simply _only_ consider the IFN_ stripped path when looking for
> > defs if it has matching condition (which is a prerequesite anyway).  So
> > the get_at_the_def () would first check for IFN_ with matching condition
> > and then expand to the unconditional operation.  And get_at_the_def ()
> > for UNCOND context would never look into IFN_s.
>
> Yeah, agree we should only consider stripping the conditional part if
> the conditions (and perhaps also the "else" values) are the same.
> But I don't know whether we should *only* consider the unconditional
> part in that case.  (For one thing it would mean we'd still try to the
> match the IFN form whenever the conditions don't match, which might
> might be surprising.)
>
> This is why I'd prefer to wait until we have a motivating case rather
> than try to decide now.
>
> > Even the toplevel handling probably never will need the outermost
> > conditional IFN_ handling - at least I can't think of a pattern that
> > you would be forced to write the outermost conditional IFN_
> > explicitely?
>
> We might want stuff like:
>
>  (simplify
>   (IFN_COND_ADD @0 @1 @2 (plus @1 @3))
>   (plus @1 (vec_cond @0 @2 @3)))
>
> Not sure how useful that would be in practice, but it seems at least
> plausible.

Interesting, yeah, that looks plausible.

So let's go with the patch for now.

Richard.

>
> Thanks,
> Richard


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]