20#define DEBUG_TYPE "ve-lower"
26 CDAG.
getConstant(
Op.getValueType().getVectorNumElements(), MVT::i32);
33 unsigned Opc =
Op.getOpcode();
34 auto LoRes = CDAG.
getNode(
Opc, MVT::v256i1, {LoA, LoB});
35 auto HiRes = CDAG.
getNode(
Opc, MVT::v256i1, {HiA, HiB});
36 return CDAG.
getPack(MVT::v512i1, LoRes, HiRes, AVL);
41 const unsigned Opcode =
Op->getOpcode();
45 unsigned VVPOpcode = *VVPOpcodeOpt;
53 case VEISD::VVP_STORE:
55 case VEISD::VVP_GATHER:
56 case VEISD::VVP_SCATTER:
72 Mask =
Op->getOperand(*MaskIdx);
74 AVL =
Op->getOperand(*AVLIdx);
85 return CDAG.
getNode(VVPOpcode, LegalVecVT, {
Op->getOperand(0), Mask, AVL});
87 return CDAG.
getNode(VVPOpcode, LegalVecVT,
88 {
Op->getOperand(0),
Op->getOperand(1), Mask, AVL});
92 SDValue VectorV =
Op->getOperand(SrcHasStart ? 1 : 0);
94 VectorV, Mask, AVL,
Op->getFlags());
100 case VEISD::VVP_FFMA: {
103 auto X =
Op->getOperand(2);
104 auto Y =
Op->getOperand(0);
105 auto Z =
Op->getOperand(1);
106 return CDAG.
getNode(VVPOpcode, LegalVecVT, {
X,
Y, Z, Mask, AVL});
108 case VEISD::VVP_SELECT: {
109 auto Mask =
Op->getOperand(0);
110 auto OnTrue =
Op->getOperand(1);
111 auto OnFalse =
Op->getOperand(2);
112 return CDAG.
getNode(VVPOpcode, LegalVecVT, {OnTrue, OnFalse, Mask, AVL});
114 case VEISD::VVP_SETCC: {
116 auto LHS =
Op->getOperand(0);
117 auto RHS =
Op->getOperand(1);
118 auto Pred =
Op->getOperand(2);
119 return CDAG.
getNode(VVPOpcode, LegalResVT, {LHS, RHS, Pred, Mask, AVL});
127 const bool IsLoad = (VVPOpc == VEISD::VVP_LOAD);
146 AVL = CDAG.
getConstant(DataVT.getVectorNumElements(), MVT::i32);
154 Packing, DataVT.getVectorElementType().getSimpleVT());
156 auto NewLoadV = CDAG.
getNode(VEISD::VVP_LOAD, {LegalDataVT, MVT::Other},
157 {Chain, BasePtr, StrideV, Mask, AVL});
159 if (!PassThru || PassThru->
isUndef())
164 {NewLoadV, PassThru, Mask, AVL});
172 assert(VVPOpc == VEISD::VVP_STORE);
179 return CDAG.
getNode(VEISD::VVP_STORE,
Op.getNode()->getVTList(),
180 {Chain, Data, BasePtr, StrideV, Mask, AVL});
186 assert((VVPOC == VEISD::VVP_LOAD) || (VVPOC == VEISD::VVP_STORE));
190 "Can only split packed load/store");
194 "Should have been folded in lowering to VVP layer");
203 unsigned ChainResIdx = PackData ? 0 : 1;
215 UpperPartAVL = SplitTM.AVL;
226 CDAG.
getUnpack(SplitDataVT, PackData, Part, SplitTM.AVL);
243 PartOps[(int)Part] = CDAG.
getNode(VVPOC, MVT::Other, OpVec);
247 CDAG.
getNode(VVPOC, {SplitDataVT, MVT::Other}, OpVec);
285 if (PassThru && PassThru->
isUndef())
288 bool IsScatter = (
bool)StoredValue;
301 return CDAG.
getNode(VEISD::VVP_SCATTER, MVT::Other,
302 {Chain, StoredValue, AddressVec, Mask, AVL});
305 SDValue NewLoadV = CDAG.
getNode(VEISD::VVP_GATHER, {LegalDataVT, MVT::Other},
306 {Chain, AddressVec, Mask, AVL});
313 {NewLoadV, PassThru, Mask, AVL});
336 switch (
Op->getOpcode()) {
337 case VEISD::VVP_LOAD:
338 case VEISD::VVP_STORE:
342 EVT IdiomVT =
Op.getValueType();
359 SDValue PackedAVL = AVLPair.first;
360 assert(!AVLPair.second &&
"Expecting non pack-legalized oepration");
372 UpperPartAVL = SplitTM.AVL;
376 for (
unsigned i = 0; i <
Op.getNumOperands(); ++i) {
377 if (AVLPos && ((
int)i) == *AVLPos)
379 if (MaskPos && ((
int)i) == *MaskPos)
383 auto PackedOperand =
Op.getOperand(i);
384 auto UnpackedOpVT =
splitVectorType(PackedOperand.getSimpleValueType());
386 CDAG.
getUnpack(UnpackedOpVT, PackedOperand, Part, SplitTM.AVL);
395 CDAG.
getNode(
Op.getOpcode(), ResVT, OpVec,
Op->getFlags());
420 "TODO Shift predication from EVL into Mask");
423 LegalAVL = CDAG.
getConstant((ConstAVL->getZExtValue() + 1) / 2, MVT::i32);
434 int NumOp =
Op->getNumOperands();
436 std::vector<SDValue> FixedOperands;
437 for (
int i = 0; i < NumOp; ++i) {
438 if (AVLPos && (i == *AVLPos)) {
439 FixedOperands.push_back(AnnotatedLegalAVL);
442 FixedOperands.push_back(
Op->getOperand(i));
446 auto Flags =
Op->getFlags();
448 CDAG.
getNode(
Op->getOpcode(),
Op->getVTList(), FixedOperands, Flags);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
MVT getVectorElementType() const
bool isUndef() const
Returns true if the node type is UNDEF or POISON.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
LLVMContext * getContext() const
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
virtual EVT getTypeToTransformTo(LLVMContext &Context, EVT VT) const
For types supported by the target, this is an identity function.
LegalizeTypeAction getTypeAction(LLVMContext &Context, EVT VT) const
Return how we should legalize values of this type, either it is already legal (return 'Legal') or we ...
SDValue getSplitPtrOffset(SDValue Ptr, SDValue ByteStride, PackElem Part) const
SDValue getMergeValues(ArrayRef< SDValue > Values) const
} Packing
SDValue getConstantMask(Packing Packing, bool AllTrue) const
SDValue getGatherScatterAddress(SDValue BasePtr, SDValue Scale, SDValue Index, SDValue Mask, SDValue AVL) const
SDValue getLegalReductionOpVVP(unsigned VVPOpcode, EVT ResVT, SDValue StartV, SDValue VectorV, SDValue Mask, SDValue AVL, SDNodeFlags Flags) const
} getNode
SDValue getNode(unsigned OC, SDVTList VTL, ArrayRef< SDValue > OpV, std::optional< SDNodeFlags > Flags=std::nullopt) const
getNode {
SDValue annotateLegalAVL(SDValue AVL) const
SDValue getUnpack(EVT DestVT, SDValue Vec, PackElem Part, SDValue AVL) const
} Legalizing getNode
SelectionDAG * getDAG() const
SDValue getPack(EVT DestVT, SDValue LoVec, SDValue HiVec, SDValue AVL) const
SDValue getConstant(uint64_t Val, EVT VT, bool IsTarget=false, bool IsOpaque=false) const
SDValue getSplitPtrStride(SDValue PackStride) const
VETargetMasks getTargetSplitMask(SDValue RawMask, SDValue RawAVL, PackElem Part) const
SDValue splitMaskArithmetic(SDValue Op, SelectionDAG &DAG) const
SDValue lowerVVP_GATHER_SCATTER(SDValue Op, VECustomDAG &) const
SDValue lowerToVVP(SDValue Op, SelectionDAG &DAG) const
} Custom Inserter
SDValue lowerVVP_LOAD_STORE(SDValue Op, VECustomDAG &) const
SDValue legalizePackedAVL(SDValue Op, VECustomDAG &CDAG) const
SDValue splitPackedLoadStore(SDValue Op, VECustomDAG &CDAG) const
SDValue legalizeInternalVectorOp(SDValue Op, SelectionDAG &DAG) const
SDValue splitVectorOp(SDValue Op, VECustomDAG &CDAG) const
SDValue legalizeInternalLoadStoreOp(SDValue Op, VECustomDAG &CDAG) const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ ADD
Simple integer binary arithmetic operators.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
LLVM_ABI std::optional< unsigned > getVPMaskIdx(unsigned Opcode)
The operand position of the vector mask.
LLVM_ABI std::optional< unsigned > getVPExplicitVectorLengthIdx(unsigned Opcode)
The operand position of the explicit vector length parameter.
LLVM_ABI bool isVPOpcode(unsigned Opcode)
Whether this is a vector-predicated Opcode.
This is an optimization pass for GlobalISel generic memory operations.
bool isVVPReductionOp(unsigned Opcode)
bool isPackedVectorType(EVT SomeVT)
bool supportsPackedMode(unsigned Opcode, EVT IdiomVT)
std::optional< int > getAVLPos(unsigned Opc)
The VE backend uses a two-staged process to lower and legalize vector instructions:
SDValue getGatherScatterScale(SDValue Op)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
SDValue getStoredValue(SDValue Op)
bool isVVPBinaryOp(unsigned VVPOpcode)
std::optional< EVT > getIdiomaticVectorType(SDNode *Op)
} AVL Functions
SDValue getNodeChain(SDValue Op)
Node Properties {.
SDValue getNodeAVL(SDValue Op)
} Node Properties
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool isLegalAVL(SDValue AVL)
MVT splitVectorType(MVT VT)
SDValue getNodePassthru(SDValue Op)
FunctionAddr VTableAddr uintptr_t uintptr_t Data
bool maySafelyIgnoreMask(SDValue Op)
bool isVVPOrVEC(unsigned Opcode)
MVT getLegalVectorType(Packing P, MVT ElemVT)
SDValue getMemoryPtr(SDValue Op)
std::optional< int > getMaskPos(unsigned Opc)
std::pair< SDValue, bool > getAnnotatedNodeAVL(SDValue Op)
DWARFExpression::Operation Op
bool hasReductionStartParam(unsigned OPC)
SDValue getGatherScatterIndex(SDValue Op)
Packing getTypePacking(EVT VT)
std::optional< unsigned > getVVPOpcode(unsigned Opcode)
bool isVVPUnaryOp(unsigned VVPOpcode)
SDValue getNodeMask(SDValue Op)
SDValue getLoadStoreStride(SDValue Op, VECustomDAG &CDAG)
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.