25#define DEBUG_TYPE "legalize-types"
34void DAGTypeLegalizer::ExpandRes_MERGE_VALUES(
SDNode *
N,
unsigned ResNo,
36 SDValue Op = DisintegrateMERGE_VALUES(
N, ResNo);
41 EVT OutVT =
N->getValueType(0);
42 EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT);
48 switch (getTypeAction(InVT)) {
56 SplitInteger(GetSoftenedFloat(InOp),
Lo,
Hi);
62 auto &
DL = DAG.getDataLayout();
64 GetExpandedOp(InOp,
Lo,
Hi);
65 if (TLI.hasBigEndianPartOrdering(InVT,
DL) !=
66 TLI.hasBigEndianPartOrdering(OutVT,
DL))
73 GetSplitVector(InOp,
Lo,
Hi);
74 if (TLI.hasBigEndianPartOrdering(OutVT, DAG.getDataLayout()))
81 SplitInteger(BitConvertToInteger(GetScalarizedVector(InOp)),
Lo,
Hi);
89 InOp = GetWidenedVector(InOp);
91 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(InVT);
92 std::tie(
Lo,
Hi) = DAG.SplitVector(InOp, dl, LoVT, HiVT);
93 if (TLI.hasBigEndianPartOrdering(OutVT, DAG.getDataLayout()))
104 unsigned NumElems = 2;
109 while (!isTypeLegal(NVT)) {
112 if (NewSizeInBits < 8)
119 if (isTypeLegal(NVT)) {
123 for (
unsigned i = 0; i < NumElems; ++i)
125 CastInOp, DAG.getVectorIdxConstant(i, dl)));
129 for (
unsigned e = Vals.
size(); e - Slot > 2; Slot += 2, e += 1) {
135 if (DAG.getDataLayout().isBigEndian())
146 if (DAG.getDataLayout().isBigEndian())
161 Align InAlign = DAG.getReducedAlign(InVT,
false);
162 Align NOutAlign = DAG.getReducedAlign(NOutVT,
false);
166 MachinePointerInfo PtrInfo =
170 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, PtrInfo);
173 Lo = DAG.getLoad(NOutVT, dl, Store, StackPtr, PtrInfo, NOutAlign);
181 Hi = DAG.getLoad(NOutVT, dl, Store, StackPtr,
185 if (TLI.hasBigEndianPartOrdering(OutVT, DAG.getDataLayout()))
192 Lo =
N->getOperand(0);
193 Hi =
N->getOperand(1);
198 GetExpandedOp(
N->getOperand(0),
Lo,
Hi);
202 "Type twice as big as expanded type not itself expanded!");
204 GetPairElements(Part,
Lo,
Hi);
216 EVT OldVT =
N->getValueType(0);
217 EVT NewVT = TLI.getTypeToTransformTo(*DAG.getContext(), OldVT);
219 if (OldVT != OldEltVT) {
223 assert(OldEltVT.
bitsLT(OldVT) &&
"Result type smaller then element type!");
242 if (DAG.getDataLayout().isBigEndian())
252 assert(!
LD->isAtomic() &&
"Atomics can not be split");
253 EVT ValueVT =
LD->getValueType(0);
254 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), ValueVT);
257 AAMDNodes AAInfo =
LD->getAAInfo();
261 Lo = DAG.getLoad(NVT, dl, Chain, Ptr,
LD->getPointerInfo(),
262 LD->getBaseAlign(),
LD->getMemOperand()->getFlags(), AAInfo);
267 Hi = DAG.getLoad(NVT, dl, Chain, Ptr,
268 LD->getPointerInfo().getWithOffset(IncrementSize),
269 LD->getBaseAlign(),
LD->getMemOperand()->getFlags(), AAInfo);
277 if (TLI.hasBigEndianPartOrdering(ValueVT, DAG.getDataLayout()))
282 ReplaceValueWith(
SDValue(
N, 1), Chain);
286 EVT OVT =
N->getValueType(0);
287 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
291 const unsigned Align =
N->getConstantOperandVal(3);
293 Lo = DAG.getVAArg(NVT, dl, Chain, Ptr,
N->getOperand(2), Align);
294 Hi = DAG.getVAArg(NVT, dl,
Lo.getValue(1), Ptr,
N->getOperand(2), 0);
298 if (TLI.hasBigEndianPartOrdering(OVT, DAG.getDataLayout()))
303 ReplaceValueWith(
SDValue(
N, 1), Chain);
311void DAGTypeLegalizer::IntegerToVector(
SDValue Op,
unsigned NumElements,
314 assert(
Op.getValueType().isInteger());
318 if (NumElements > 1) {
320 SplitInteger(
Op, Parts[0], Parts[1]);
321 if (DAG.getDataLayout().isBigEndian())
323 IntegerToVector(Parts[0], NumElements,
Ops, EltVT);
324 IntegerToVector(Parts[1], NumElements,
Ops, EltVT);
332 if (
N->getValueType(0).isVector() &&
333 N->getOperand(0).getValueType().isInteger()) {
343 unsigned NumElts = 2;
344 EVT OVT =
N->getOperand(0).getValueType();
346 TLI.getTypeToTransformTo(*DAG.getContext(), OVT),
348 if (!isTypeLegal(NVT)) {
351 NumElts =
N->getValueType(0).getVectorNumElements();
352 NVT =
N->getValueType(0);
359 return DAG.getNode(
ISD::BITCAST, dl,
N->getValueType(0), Vec);
363 return CreateStackStoreLoad(
N->getOperand(0),
N->getValueType(0));
370 EVT OldVT =
N->getOperand(0).getValueType();
371 EVT NewVT = TLI.getTypeToTransformTo(*DAG.getContext(), OldVT);
375 "BUILD_VECTOR operand type doesn't match vector element type!");
381 GetExpandedOp(V,
Lo,
Hi);
391 for (
unsigned i = 0; i < NumElts; ++i) {
393 GetExpandedOp(
N->getOperand(i),
Lo,
Hi);
394 if (DAG.getDataLayout().isBigEndian())
401 SDValue NewVec = DAG.getBuildVector(NewVecVT, dl, NewElts);
409 GetExpandedOp(
N->getOperand(0),
Lo,
Hi);
410 return N->getConstantOperandVal(1) ?
Hi :
Lo;
418 GetExpandedOp(
N->getOperand(1),
Lo,
Hi);
420 DAG.UpdateNodeOperands(
N, LoUse,
Hi);
426 EVT VecVT =
N->getValueType(0);
432 EVT NewEVT = TLI.getTypeToTransformTo(*DAG.getContext(), OldEVT);
435 "Inserted element type doesn't match vector element type!");
441 NewVecVT,
N->getOperand(0));
444 GetExpandedOp(Val,
Lo,
Hi);
445 if (DAG.getDataLayout().isBigEndian())
462 EVT VT =
N->getValueType(0);
464 "SCALAR_TO_VECTOR operand type doesn't match vector element type!");
467 Ops[0] =
N->getOperand(0);
469 for (
unsigned i = 1; i < NumElts; ++i)
471 return DAG.getBuildVector(VT, dl,
Ops);
474SDValue DAGTypeLegalizer::ExpandOp_NormalStore(
SDNode *
N,
unsigned OpNo) {
476 assert(OpNo == 1 &&
"Can only expand the stored value so far");
482 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), ValueVT);
493 if (TLI.hasBigEndianPartOrdering(ValueVT, DAG.getDataLayout()))
518void DAGTypeLegalizer::SplitRes_MERGE_VALUES(
SDNode *
N,
unsigned ResNo,
520 SDValue Op = DisintegrateMERGE_VALUES(
N, ResNo);
527 unsigned Opcode =
N->getOpcode();
528 GetSplitOp(
N->getOperand(1), LL, LH);
529 GetSplitOp(
N->getOperand(2), RL, RH);
533 if (
Cond.getValueType().isVector()) {
534 if (
SDValue Res = WidenVSELECTMask(
N))
535 std::tie(CL,
CH) = DAG.SplitVector(Res, dl);
538 else if (getTypeAction(
Cond.getValueType()) ==
540 GetSplitVector(
Cond, CL,
CH);
547 EVT CondLHSVT =
Cond.getOperand(0).getValueType();
548 if (
Cond.getValueType().getVectorElementType() == MVT::i1 &&
549 isTypeLegal(CondLHSVT) &&
550 getSetCCResultType(CondLHSVT) ==
Cond.getValueType())
551 std::tie(CL,
CH) = DAG.SplitVector(
Cond, dl);
553 SplitVecRes_SETCC(
Cond.getNode(), CL,
CH);
555 std::tie(CL,
CH) = DAG.SplitVector(
Cond, dl);
558 if (Opcode != ISD::VP_SELECT && Opcode != ISD::VP_MERGE) {
565 std::tie(EVLLo, EVLHi) =
566 DAG.SplitEVL(
N->getOperand(3),
N->getValueType(0), dl);
576 GetSplitOp(
N->getOperand(2), LL, LH);
577 GetSplitOp(
N->getOperand(3), RL, RH);
580 N->getOperand(1), LL, RL,
N->getOperand(4));
582 N->getOperand(1), LH, RH,
N->getOperand(4));
587 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(
N->getValueType(0));
588 Lo = DAG.getUNDEF(LoVT);
589 Hi = DAG.getUNDEF(HiVT);
596 GetSplitOp(
N->getOperand(0), L,
H);
606 GetSplitOp(
N->getOperand(0), L,
H);
615 GetSplitOp(
N->getOperand(0), L,
H);
625 GetSplitOp(
N->getOperand(0), L,
H);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
const SmallVectorImpl< MachineOperand > & Cond
static Type * getValueType(Value *V)
Returns the type of the given value/instruction V.
Flags getFlags() const
Return the raw flags of the source value,.
Align getBaseAlign() const
Returns alignment and volatility of the memory access.
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
const MachinePointerInfo & getPointerInfo() const
const SDValue & getChain() const
bool isAtomic() const
Return true if the memory operation ordering is Unordered or higher.
Represents one node in the SelectionDAG.
const SDValue & getOperand(unsigned Num) const
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
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
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void reserve(size_type N)
void push_back(const T &Elt)
const SDValue & getBasePtr() const
const SDValue & getValue() const
@ TypeScalarizeScalableVector
static constexpr TypeSize getFixed(ScalarTy ExactSize)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ ADD
Simple integer binary arithmetic operators.
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ FAKE_USE
FAKE_USE represents a use of the operand but does not do anything.
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
@ SPLAT_VECTOR
SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL duplicated in all lanes.
@ ARITH_FENCE
ARITH_FENCE - This corresponds to a arithmetic fence intrinsic.
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ SPLAT_VECTOR_PARTS
SPLAT_VECTOR_PARTS(SCALAR1, SCALAR2, ...) - Returns a vector with the scalar values joined together a...
@ FREEZE
FREEZE - FREEZE(VAL) returns an arbitrary value if VAL is UNDEF (or is evaluated to UNDEF),...
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
bool isNormalStore(const SDNode *N)
Returns true if the specified node is a non-truncating and unindexed store.
bool isNormalLoad(const SDNode *N)
Returns true if the specified node is a non-extending and unindexed load.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI Value * getSplatValue(const Value *V)
Get splat value if the input is a splat vector or return nullptr.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
bool bitsLT(EVT VT) const
Return true if this has less bits than VT.
ElementCount getVectorElementCount() const
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
bool isByteSized() const
Return true if the bit size is a multiple of 8.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
bool isVector() const
Return true if this is a vector value type.
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.
bool isInteger() const
Return true if this is an integer or a vector integer type.
MachinePointerInfo getWithOffset(int64_t O) const
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.