I tried to give a rough overview of our current pseudo structure. I'm mostly focused on the policy handling bits - since that's what I'm in the process of changing - but touched on the other dimensions in the process of framing it.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
llvm/lib/Target/RISCV/RISCVInstrInfo.h | ||
---|---|---|
303 ↗ | (On Diff #531424) | knownledge -> knowledge |
328 ↗ | (On Diff #531424) | How do we represent "undefined" for fma, integer multiple-accumulate where the destination is also an arithmetic source. Also vslideup where the destination is used for elements below offset and for the tail, but only tail follows the tail policy. How do we represent tail "undefined" vs tail "agnostic" for _MASK? |
Generally not sure about the commenting style - I don't think this usage necessitates C-style comments as described here: https://llvm.org/docs/CodingStandards.html#comment-formatting
llvm/lib/Target/RISCV/RISCVInstrInfo.h | ||
---|---|---|
326 ↗ | (On Diff #531424) | existance -> existence |
llvm/lib/Target/RISCV/RISCVInstrInfo.h | ||
---|---|---|
299 ↗ | (On Diff #531424) | Adding upon this, the behavior of "bit pattern -1"" or "preserve" can be different among different lanes. |
321 ↗ | (On Diff #531424) | TA is abbreviation for tail agnostic. I agree that the meaning is ambiguous, as
both share this same state. |
llvm/lib/Target/RISCV/RISCVInstrInfo.h | ||
---|---|---|
300 ↗ | (On Diff #531424) | Is undefined actually a policy, or just a common representation within the backend? Because I don’t think we can mix both tail undefined and mask undisturbed policies, or that there’s no way to represent it at least |
323 ↗ | (On Diff #531424) | Not for this patch, but should we standardise the terminology of passthrough vs. merge throughout the backend and pick one? My weak preference would be for passthrough as it’s less confusing with vmerge etc. |
llvm/lib/Target/RISCV/RISCVInstrInfo.h | ||
---|---|---|
323 ↗ | (On Diff #531424) | Not all TU pseudos have a policy operand (as of today). Should we document that without the policy operand it defaults to TUMU? |
llvm/lib/Target/RISCV/RISCVInstrInfo.h | ||
---|---|---|
323 ↗ | (On Diff #531424) | I think all unmasked Pseudo does not have a policy operand. When the merge operand is undef, the tail policy is agnostic. When the merge operand is not undef, the tail policy is undisturbed. I don't quite understand what are the instructions are affected by the default setting you have mentioned. My understanding is that at Pseudo instruction level the vector instructions all have explicit policy information. May you elaborate more? |
llvm/lib/Target/RISCV/RISCVInstrInfo.h | ||
---|---|---|
323 ↗ | (On Diff #531424) | Thanks for clarifying this, I just did a quick check: with the exception of the VPseudoTiedBinaryNoMask class, unmasked pseudos don't have a policy operand. The bit that I'm getting confused about is the sentence below:
Since TU pseudos are unmasked and don't have a policy operand. By "default" I meant what policy is computed in computeInfoForInstr in RISCVInsertVSETVLI.cpp when there's no policy operand, and this is the piece of logic here: bool TailAgnostic = true; bool MaskAgnostic = true; if (!hasUndefinedMergeOp(MI, *MRI)) { // Start with undisturbed. TailAgnostic = false; MaskAgnostic = false; // If there is a policy operand, use it. if (RISCVII::hasVecPolicyOp(TSFlags)) { const MachineOperand &Op = MI.getOperand(MI.getNumExplicitOperands() - 1); uint64_t Policy = Op.getImm(); assert(Policy <= (RISCVII::TAIL_AGNOSTIC | RISCVII::MASK_AGNOSTIC) && "Invalid Policy Value"); TailAgnostic = Policy & RISCVII::TAIL_AGNOSTIC; MaskAgnostic = Policy & RISCVII::MASK_AGNOSTIC; } // Some pseudo instructions force a tail agnostic policy despite having a // tied def. if (RISCVII::doesForceTailAgnostic(TSFlags)) TailAgnostic = true; if (!RISCVII::usesMaskPolicy(TSFlags)) MaskAgnostic = true; } So as you say, unmasked pseudos don't have a policy operand and so are TUMU "by default", unless the merge operand is undefined in which case it's TAMA. |
llvm/lib/Target/RISCV/RISCVInstrInfo.h | ||
---|---|---|
323 ↗ | (On Diff #531424) | I think having undisturbed as default may not be a good choice, since the vector extension is targeting high performance, and possibly out-of-order cores. The undisturbed policy is likely to ruin the performance. |
llvm/lib/Target/RISCV/RISCVInstrInfo.h | ||
---|---|---|
323 ↗ | (On Diff #531424) | I'm trying to move away from a model where the default is meaningful. Always having an explicit policy operand means the instruction carries the flags, and we can simply setup an agnostic flag if useful. |
328 ↗ | (On Diff #531424) | Right now, we don't represent undefined for either of these cases. We could extend the policy operand with additional bits if desired, but for the moment, but I'm not sure this is warranted at this time. |
Left a tiny nit comment, but looks good (and indeed, very helpful!) to me.
llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td | ||
---|---|---|
47 | Nit, should either change the item above to *, or change this one to 2) for consistency. |
Nit, should either change the item above to *, or change this one to 2) for consistency.