Re: [RFC] rtl: Introduce vec_predicate.
Richard Sandiford <[email protected]>
| Newsgroups | gmane.comp.gcc.patches |
|---|---|
| Message-ID | <[email protected]> |
"Robin Dapp" <[email protected]> writes: >>> > (define_insn "pred_add" >>> > [(set (match_operand:V 0 "register_operand" "=vd") >>> > (vec_predicate:V plus >>> > [(match_operand:V 3 "register_operand" " v") >>> > (match_operand:V 4 "register_operand" " v")] >> >> So there's not actually the predicated RTL operation, but just >> the code and a vector of ... operands? I'd have expected either > > Yeah I don't particularly like it either, in particular that we need > to replicate canonicalization for these "unstructured" operands in > simplify-rtx. It's not a big deal but feels redundant. > >> (vec_predicate >> (plus:<mode> (...) (...)) > > This would still be my preferred way just by the way it reads and re-uses > existing code. Richard's objection here was, though: > >> This again avoids contextual interpretation. A predicated plus is not >> equivalent to taking an existing unpredicated plus and predicating it, >> and vice versa. > > I didn't realize cond_exec is similar and that we need to avoid the "hoisting" > situation already. So maybe the above wouldn't be too bad? cond_exec is a top-level code though. It wraps sets, rather than occurring within sets. Contextual interpretation is a given there, since e.g. XEXP (..., 0) on a SET or a CLOBBER needs to be interpreted as an lvalue rather than an rvalue. That is, you can't interpret a top-level RTX code by evaluating its operands first and then applying the operator to them. But you can do that for all existing rvalue codes that I'm aware of. So it depends on what kind of code we want. Do we want a top-level code or an rvalue code? A "vector predicate version of cond_exec" could indeed... > Introducing a vec_pred_set would avoid a vec_copy... RTX code. I'm not > looking forward to adding combine/etc. handling for vec_predicate + > vec_pred_set combinations, though :) ...be like this, although perhaps keeping the set and the vec_predicate separate (the former within the latter). But the thing about cond_exec is that it's all or nothing. The action that it wraps either happens or doesn't happen. The natural way of extending that to predicates would be to say that the wrapped operation either happens for a lane or does not happen for a lane. In other words, it would be lane-level cond_exec rather than the existing vector-level cond_exec. That would be a natural way of describing merge predication and predicated stores, where the destination is partially modified and partially preserved. Doing that sounds good to me if it's what we want. But I thought we wanted more than that from the new RTL code. I thought we wanted to use it to describe an operation that is performed on some lanes to produce a full vector result, with the values of other lanes being taken from elsewhere. E.g. SVE patterns "need" at least merge with zero, merge with first operand, merge with second operand, and merge with third operand. If we took the cond_exec approach, we'd presumably require the wrapped set operation to have a certain form and use information in the vec_predicate wrapper to "imagine" what the corresponding operation for inactive lanes would be. (In theory, we could avoid the "imagination" by having an explicit rtx that describes the operation for inactive lanes, but that would require duplicating the destination, which sounds worse.) Even with that, the cond_exec approach still seems a bit inflexible. It wouldn't help if we wanted the predicated operation to be nested within another (unconditional) operation. E.g. it's feasible that an instruction could perform zero predication followed by some form of permutation. IIRC SVE LD1RQ would be like that. Having vec_predicate be an rvalue that occurs within the set would avoid that inflexibility. But vec_predicate would then be completely unlike cond_exec. Both the vec_predicate rtx itself and its operands would be subject to combination, cse, forward progatation, etc. Allowing: (vec_predicate predicate (plus op op1) ...) would mean that vec_predicate could not be interpreted by evaluating its operands ("predicate" and "(plus op0 op1)"), then applying the vec_predicate operator to the result. vec_predicate could only be interpreted by treating RTX_CODE and RTX_CODE (XEXP (x, 1)) as a compound operation whose operands are formed from XEXP (x, 0), XEXP (XEXP (x, 1), 0), XEXP (XEXP (x, 1), 1) and whatever is in "...". AFAIK that would make it unique among rtxes that can occur as or within a SET_SRC. I realise that the form above would make the initial implementation easier. But I fear that's only because we'd have to abandon any realistic hope of identifying which pieces of code need to be taught about this new exception and instead wait for users and fuzzers to find them experimentally. That said, I realise that the alternatives aren't particularly appealing either, even if they seem semantically cleaner (to me). Richard