mirror of
https://github.com/RPCS3/llvm.git
synced 2025-03-04 08:37:45 +00:00
DAG: allow DAG pointer size different from memory representation.
In preparation for supporting ILP32 on AArch64, this modifies the SelectionDAG builder code so that pointers are allowed to have a larger type when "live" in the DAG compared to memory. Pointers get zero-extended whenever they are loaded, and truncated prior to stores. In addition, a few not quite so obvious locations need updating: * A GEP that has not been marked inbounds needs to enforce the IR-documented 2s-complement wrapping at the memory pointer size. Inbounds GEPs are undefined if they overflow the address space, so no additional operations are needed. * Signed comparisons would give incorrect results if performed on the zero-extended values. This shouldn't affect CodeGen for now, but will become active when the AArch64 ILP32 support is committed. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@359676 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
789617d109
commit
32c7e441d6
@ -74,6 +74,13 @@ void ComputeValueVTs(const TargetLowering &TLI, const DataLayout &DL, Type *Ty,
|
||||
SmallVectorImpl<uint64_t> *Offsets = nullptr,
|
||||
uint64_t StartingOffset = 0);
|
||||
|
||||
/// Variant of ComputeValueVTs that also produces the memory VTs.
|
||||
void ComputeValueVTs(const TargetLowering &TLI, const DataLayout &DL, Type *Ty,
|
||||
SmallVectorImpl<EVT> &ValueVTs,
|
||||
SmallVectorImpl<EVT> *MemVTs,
|
||||
SmallVectorImpl<uint64_t> *Offsets = nullptr,
|
||||
uint64_t StartingOffset = 0);
|
||||
|
||||
/// computeValueLLTs - Given an LLVM IR type, compute a sequence of
|
||||
/// LLTs that represent all the individual underlying
|
||||
/// non-aggregate types that comprise it.
|
||||
|
@ -794,6 +794,16 @@ public:
|
||||
/// value assuming it was the smaller SrcTy value.
|
||||
SDValue getZeroExtendInReg(SDValue Op, const SDLoc &DL, EVT VT);
|
||||
|
||||
/// Convert Op, which must be of integer type, to the integer type VT, by
|
||||
/// either truncating it or performing either zero or sign extension as
|
||||
/// appropriate extension for the pointer's semantics.
|
||||
SDValue getPtrExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT);
|
||||
|
||||
/// Return the expression required to extend the Op as a pointer value
|
||||
/// assuming it was the smaller SrcTy value. This may be either a zero extend
|
||||
/// or a sign extend.
|
||||
SDValue getPtrExtendInReg(SDValue Op, const SDLoc &DL, EVT VT);
|
||||
|
||||
/// Convert Op, which must be of integer type, to the integer type VT,
|
||||
/// by using an extension appropriate for the target's
|
||||
/// BooleanContent for type OpVT or truncating it.
|
||||
|
@ -238,7 +238,14 @@ public:
|
||||
/// Return the pointer type for the given address space, defaults to
|
||||
/// the pointer type from the data layout.
|
||||
/// FIXME: The default needs to be removed once all the code is updated.
|
||||
MVT getPointerTy(const DataLayout &DL, uint32_t AS = 0) const {
|
||||
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS = 0) const {
|
||||
return MVT::getIntegerVT(DL.getPointerSizeInBits(AS));
|
||||
}
|
||||
|
||||
/// Return the in-memory pointer type for the given address space, defaults to
|
||||
/// the pointer type from the data layout. FIXME: The default needs to be
|
||||
/// removed once all the code is updated.
|
||||
MVT getPointerMemTy(const DataLayout &DL, uint32_t AS = 0) const {
|
||||
return MVT::getIntegerVT(DL.getPointerSizeInBits(AS));
|
||||
}
|
||||
|
||||
@ -1180,6 +1187,25 @@ public:
|
||||
return EVT::getEVT(Ty, AllowUnknown);
|
||||
}
|
||||
|
||||
EVT getMemValueType(const DataLayout &DL, Type *Ty,
|
||||
bool AllowUnknown = false) const {
|
||||
// Lower scalar pointers to native pointer types.
|
||||
if (PointerType *PTy = dyn_cast<PointerType>(Ty))
|
||||
return getPointerMemTy(DL, PTy->getAddressSpace());
|
||||
else if (VectorType *VTy = dyn_cast<VectorType>(Ty)) {
|
||||
Type *Elm = VTy->getElementType();
|
||||
if (PointerType *PT = dyn_cast<PointerType>(Elm)) {
|
||||
EVT PointerTy(getPointerMemTy(DL, PT->getAddressSpace()));
|
||||
Elm = PointerTy.getTypeForEVT(Ty->getContext());
|
||||
}
|
||||
return EVT::getVectorVT(Ty->getContext(), EVT::getEVT(Elm, false),
|
||||
VTy->getNumElements());
|
||||
}
|
||||
|
||||
return getValueType(DL, Ty, AllowUnknown);
|
||||
}
|
||||
|
||||
|
||||
/// Return the MVT corresponding to this LLVM type. See getValueType.
|
||||
MVT getSimpleValueType(const DataLayout &DL, Type *Ty,
|
||||
bool AllowUnknown = false) const {
|
||||
|
@ -82,6 +82,7 @@ unsigned llvm::ComputeLinearIndex(Type *Ty,
|
||||
///
|
||||
void llvm::ComputeValueVTs(const TargetLowering &TLI, const DataLayout &DL,
|
||||
Type *Ty, SmallVectorImpl<EVT> &ValueVTs,
|
||||
SmallVectorImpl<EVT> *MemVTs,
|
||||
SmallVectorImpl<uint64_t> *Offsets,
|
||||
uint64_t StartingOffset) {
|
||||
// Given a struct type, recursively traverse the elements.
|
||||
@ -91,7 +92,7 @@ void llvm::ComputeValueVTs(const TargetLowering &TLI, const DataLayout &DL,
|
||||
EI = EB,
|
||||
EE = STy->element_end();
|
||||
EI != EE; ++EI)
|
||||
ComputeValueVTs(TLI, DL, *EI, ValueVTs, Offsets,
|
||||
ComputeValueVTs(TLI, DL, *EI, ValueVTs, MemVTs, Offsets,
|
||||
StartingOffset + SL->getElementOffset(EI - EB));
|
||||
return;
|
||||
}
|
||||
@ -100,7 +101,7 @@ void llvm::ComputeValueVTs(const TargetLowering &TLI, const DataLayout &DL,
|
||||
Type *EltTy = ATy->getElementType();
|
||||
uint64_t EltSize = DL.getTypeAllocSize(EltTy);
|
||||
for (unsigned i = 0, e = ATy->getNumElements(); i != e; ++i)
|
||||
ComputeValueVTs(TLI, DL, EltTy, ValueVTs, Offsets,
|
||||
ComputeValueVTs(TLI, DL, EltTy, ValueVTs, MemVTs, Offsets,
|
||||
StartingOffset + i * EltSize);
|
||||
return;
|
||||
}
|
||||
@ -109,10 +110,20 @@ void llvm::ComputeValueVTs(const TargetLowering &TLI, const DataLayout &DL,
|
||||
return;
|
||||
// Base case: we can get an EVT for this LLVM IR type.
|
||||
ValueVTs.push_back(TLI.getValueType(DL, Ty));
|
||||
if (MemVTs)
|
||||
MemVTs->push_back(TLI.getMemValueType(DL, Ty));
|
||||
if (Offsets)
|
||||
Offsets->push_back(StartingOffset);
|
||||
}
|
||||
|
||||
void llvm::ComputeValueVTs(const TargetLowering &TLI, const DataLayout &DL,
|
||||
Type *Ty, SmallVectorImpl<EVT> &ValueVTs,
|
||||
SmallVectorImpl<uint64_t> *Offsets,
|
||||
uint64_t StartingOffset) {
|
||||
return ComputeValueVTs(TLI, DL, Ty, ValueVTs, /*MemVTs=*/nullptr, Offsets,
|
||||
StartingOffset);
|
||||
}
|
||||
|
||||
void llvm::computeValueLLTs(const DataLayout &DL, Type &Ty,
|
||||
SmallVectorImpl<LLT> &ValueTys,
|
||||
SmallVectorImpl<uint64_t> *Offsets,
|
||||
|
@ -360,7 +360,7 @@ bool AtomicExpand::bracketInstWithFences(Instruction *I, AtomicOrdering Order) {
|
||||
/// Get the iX type with the same bitwidth as T.
|
||||
IntegerType *AtomicExpand::getCorrespondingIntegerType(Type *T,
|
||||
const DataLayout &DL) {
|
||||
EVT VT = TLI->getValueType(DL, T);
|
||||
EVT VT = TLI->getMemValueType(DL, T);
|
||||
unsigned BitWidth = VT.getStoreSizeInBits();
|
||||
assert(BitWidth == VT.getSizeInBits() && "must be a power of two");
|
||||
return IntegerType::get(T->getContext(), BitWidth);
|
||||
|
@ -1145,6 +1145,18 @@ SDValue SelectionDAG::getZeroExtendInReg(SDValue Op, const SDLoc &DL, EVT VT) {
|
||||
getConstant(Imm, DL, Op.getValueType()));
|
||||
}
|
||||
|
||||
SDValue SelectionDAG::getPtrExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT) {
|
||||
// Only unsigned pointer semantics are supported right now. In the future this
|
||||
// might delegate to TLI to check pointer signedness.
|
||||
return getZExtOrTrunc(Op, DL, VT);
|
||||
}
|
||||
|
||||
SDValue SelectionDAG::getPtrExtendInReg(SDValue Op, const SDLoc &DL, EVT VT) {
|
||||
// Only unsigned pointer semantics are supported right now. In the future this
|
||||
// might delegate to TLI to check pointer signedness.
|
||||
return getZeroExtendInReg(Op, DL, VT);
|
||||
}
|
||||
|
||||
/// getNOT - Create a bitwise NOT operation as (XOR Val, -1).
|
||||
SDValue SelectionDAG::getNOT(const SDLoc &DL, SDValue Val, EVT VT) {
|
||||
EVT EltVT = VT.getScalarType();
|
||||
|
@ -1787,9 +1787,10 @@ void SelectionDAGBuilder::visitRet(const ReturnInst &I) {
|
||||
DemoteReg, PtrValueVTs[0]);
|
||||
SDValue RetOp = getValue(I.getOperand(0));
|
||||
|
||||
SmallVector<EVT, 4> ValueVTs;
|
||||
SmallVector<EVT, 4> ValueVTs, MemVTs;
|
||||
SmallVector<uint64_t, 4> Offsets;
|
||||
ComputeValueVTs(TLI, DL, I.getOperand(0)->getType(), ValueVTs, &Offsets);
|
||||
ComputeValueVTs(TLI, DL, I.getOperand(0)->getType(), ValueVTs, &MemVTs,
|
||||
&Offsets);
|
||||
unsigned NumValues = ValueVTs.size();
|
||||
|
||||
SmallVector<SDValue, 4> Chains(NumValues);
|
||||
@ -1797,8 +1798,11 @@ void SelectionDAGBuilder::visitRet(const ReturnInst &I) {
|
||||
// An aggregate return value cannot wrap around the address space, so
|
||||
// offsets to its parts don't wrap either.
|
||||
SDValue Ptr = DAG.getObjectPtrOffset(getCurSDLoc(), RetPtr, Offsets[i]);
|
||||
Chains[i] = DAG.getStore(
|
||||
Chain, getCurSDLoc(), SDValue(RetOp.getNode(), RetOp.getResNo() + i),
|
||||
|
||||
SDValue Val = RetOp.getValue(i);
|
||||
if (MemVTs[i] != ValueVTs[i])
|
||||
Val = DAG.getPtrExtOrTrunc(Val, getCurSDLoc(), MemVTs[i]);
|
||||
Chains[i] = DAG.getStore(Chain, getCurSDLoc(), Val,
|
||||
// FIXME: better loc info would be nice.
|
||||
Ptr, MachinePointerInfo::getUnknownStack(DAG.getMachineFunction()));
|
||||
}
|
||||
@ -2310,6 +2314,9 @@ void SelectionDAGBuilder::visitSwitchCase(CaseBlock &CB,
|
||||
return;
|
||||
}
|
||||
|
||||
auto &TLI = DAG.getTargetLoweringInfo();
|
||||
EVT MemVT = TLI.getMemValueType(DAG.getDataLayout(), CB.CmpLHS->getType());
|
||||
|
||||
// Build the setcc now.
|
||||
if (!CB.CmpMHS) {
|
||||
// Fold "(X == true)" to X and "(X == false)" to !X to
|
||||
@ -2321,8 +2328,18 @@ void SelectionDAGBuilder::visitSwitchCase(CaseBlock &CB,
|
||||
CB.CC == ISD::SETEQ) {
|
||||
SDValue True = DAG.getConstant(1, dl, CondLHS.getValueType());
|
||||
Cond = DAG.getNode(ISD::XOR, dl, CondLHS.getValueType(), CondLHS, True);
|
||||
} else
|
||||
Cond = DAG.getSetCC(dl, MVT::i1, CondLHS, getValue(CB.CmpRHS), CB.CC);
|
||||
} else {
|
||||
SDValue CondRHS = getValue(CB.CmpRHS);
|
||||
|
||||
// If a pointer's DAG type is larger than its memory type then the DAG
|
||||
// values are zero-extended. This breaks signed comparisons so truncate
|
||||
// back to the underlying type before doing the compare.
|
||||
if (CondLHS.getValueType() != MemVT) {
|
||||
CondLHS = DAG.getPtrExtOrTrunc(CondLHS, getCurSDLoc(), MemVT);
|
||||
CondRHS = DAG.getPtrExtOrTrunc(CondRHS, getCurSDLoc(), MemVT);
|
||||
}
|
||||
Cond = DAG.getSetCC(dl, MVT::i1, CondLHS, CondRHS, CB.CC);
|
||||
}
|
||||
} else {
|
||||
assert(CB.CC == ISD::SETLE && "Can handle only LE ranges now");
|
||||
|
||||
@ -2448,6 +2465,7 @@ static SDValue getLoadStackGuard(SelectionDAG &DAG, const SDLoc &DL,
|
||||
SDValue &Chain) {
|
||||
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
|
||||
EVT PtrTy = TLI.getPointerTy(DAG.getDataLayout());
|
||||
EVT PtrMemTy = TLI.getPointerMemTy(DAG.getDataLayout());
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
Value *Global = TLI.getSDagStackGuard(*MF.getFunction().getParent());
|
||||
MachineSDNode *Node =
|
||||
@ -2460,6 +2478,8 @@ static SDValue getLoadStackGuard(SelectionDAG &DAG, const SDLoc &DL,
|
||||
MPInfo, Flags, PtrTy.getSizeInBits() / 8, DAG.getEVTAlignment(PtrTy));
|
||||
DAG.setNodeMemRefs(Node, {MemRef});
|
||||
}
|
||||
if (PtrTy != PtrMemTy)
|
||||
return DAG.getPtrExtOrTrunc(SDValue(Node, 0), DL, PtrMemTy);
|
||||
return SDValue(Node, 0);
|
||||
}
|
||||
|
||||
@ -2475,6 +2495,7 @@ void SelectionDAGBuilder::visitSPDescriptorParent(StackProtectorDescriptor &SPD,
|
||||
// First create the loads to the guard/stack slot for the comparison.
|
||||
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
|
||||
EVT PtrTy = TLI.getPointerTy(DAG.getDataLayout());
|
||||
EVT PtrMemTy = TLI.getPointerMemTy(DAG.getDataLayout());
|
||||
|
||||
MachineFrameInfo &MFI = ParentBB->getParent()->getFrameInfo();
|
||||
int FI = MFI.getStackProtectorIndex();
|
||||
@ -2487,7 +2508,7 @@ void SelectionDAGBuilder::visitSPDescriptorParent(StackProtectorDescriptor &SPD,
|
||||
|
||||
// Generate code to load the content of the guard slot.
|
||||
SDValue GuardVal = DAG.getLoad(
|
||||
PtrTy, dl, DAG.getEntryNode(), StackSlotPtr,
|
||||
PtrMemTy, dl, DAG.getEntryNode(), StackSlotPtr,
|
||||
MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FI), Align,
|
||||
MachineMemOperand::MOVolatile);
|
||||
|
||||
@ -2530,9 +2551,9 @@ void SelectionDAGBuilder::visitSPDescriptorParent(StackProtectorDescriptor &SPD,
|
||||
const Value *IRGuard = TLI.getSDagStackGuard(M);
|
||||
SDValue GuardPtr = getValue(IRGuard);
|
||||
|
||||
Guard =
|
||||
DAG.getLoad(PtrTy, dl, Chain, GuardPtr, MachinePointerInfo(IRGuard, 0),
|
||||
Align, MachineMemOperand::MOVolatile);
|
||||
Guard = DAG.getLoad(PtrMemTy, dl, Chain, GuardPtr,
|
||||
MachinePointerInfo(IRGuard, 0), Align,
|
||||
MachineMemOperand::MOVolatile);
|
||||
}
|
||||
|
||||
// Perform the comparison via a subtract/getsetcc.
|
||||
@ -3197,6 +3218,18 @@ void SelectionDAGBuilder::visitICmp(const User &I) {
|
||||
SDValue Op2 = getValue(I.getOperand(1));
|
||||
ISD::CondCode Opcode = getICmpCondCode(predicate);
|
||||
|
||||
auto &TLI = DAG.getTargetLoweringInfo();
|
||||
EVT MemVT =
|
||||
TLI.getMemValueType(DAG.getDataLayout(), I.getOperand(0)->getType());
|
||||
|
||||
// If a pointer's DAG type is larger than its memory type then the DAG values
|
||||
// are zero-extended. This breaks signed comparisons so truncate back to the
|
||||
// underlying type before doing the compare.
|
||||
if (Op1.getValueType() != MemVT) {
|
||||
Op1 = DAG.getPtrExtOrTrunc(Op1, getCurSDLoc(), MemVT);
|
||||
Op2 = DAG.getPtrExtOrTrunc(Op2, getCurSDLoc(), MemVT);
|
||||
}
|
||||
|
||||
EVT DestVT = DAG.getTargetLoweringInfo().getValueType(DAG.getDataLayout(),
|
||||
I.getType());
|
||||
setValue(&I, DAG.getSetCC(getCurSDLoc(), DestVT, Op1, Op2, Opcode));
|
||||
@ -3439,18 +3472,26 @@ void SelectionDAGBuilder::visitPtrToInt(const User &I) {
|
||||
// What to do depends on the size of the integer and the size of the pointer.
|
||||
// We can either truncate, zero extend, or no-op, accordingly.
|
||||
SDValue N = getValue(I.getOperand(0));
|
||||
auto &TLI = DAG.getTargetLoweringInfo();
|
||||
EVT DestVT = DAG.getTargetLoweringInfo().getValueType(DAG.getDataLayout(),
|
||||
I.getType());
|
||||
setValue(&I, DAG.getZExtOrTrunc(N, getCurSDLoc(), DestVT));
|
||||
EVT PtrMemVT =
|
||||
TLI.getMemValueType(DAG.getDataLayout(), I.getOperand(0)->getType());
|
||||
N = DAG.getPtrExtOrTrunc(N, getCurSDLoc(), PtrMemVT);
|
||||
N = DAG.getZExtOrTrunc(N, getCurSDLoc(), DestVT);
|
||||
setValue(&I, N);
|
||||
}
|
||||
|
||||
void SelectionDAGBuilder::visitIntToPtr(const User &I) {
|
||||
// What to do depends on the size of the integer and the size of the pointer.
|
||||
// We can either truncate, zero extend, or no-op, accordingly.
|
||||
SDValue N = getValue(I.getOperand(0));
|
||||
EVT DestVT = DAG.getTargetLoweringInfo().getValueType(DAG.getDataLayout(),
|
||||
I.getType());
|
||||
setValue(&I, DAG.getZExtOrTrunc(N, getCurSDLoc(), DestVT));
|
||||
auto &TLI = DAG.getTargetLoweringInfo();
|
||||
EVT DestVT = TLI.getValueType(DAG.getDataLayout(), I.getType());
|
||||
EVT PtrMemVT = TLI.getMemValueType(DAG.getDataLayout(), I.getType());
|
||||
N = DAG.getZExtOrTrunc(N, getCurSDLoc(), PtrMemVT);
|
||||
N = DAG.getPtrExtOrTrunc(N, getCurSDLoc(), DestVT);
|
||||
setValue(&I, N);
|
||||
}
|
||||
|
||||
void SelectionDAGBuilder::visitBitCast(const User &I) {
|
||||
@ -3802,6 +3843,9 @@ void SelectionDAGBuilder::visitGetElementPtr(const User &I) {
|
||||
unsigned AS = Op0->getType()->getScalarType()->getPointerAddressSpace();
|
||||
SDValue N = getValue(Op0);
|
||||
SDLoc dl = getCurSDLoc();
|
||||
auto &TLI = DAG.getTargetLoweringInfo();
|
||||
MVT PtrTy = TLI.getPointerTy(DAG.getDataLayout(), AS);
|
||||
MVT PtrMemTy = TLI.getPointerMemTy(DAG.getDataLayout(), AS);
|
||||
|
||||
// Normalize Vector GEP - all scalar operands should be converted to the
|
||||
// splat vector.
|
||||
@ -3859,6 +3903,8 @@ void SelectionDAGBuilder::visitGetElementPtr(const User &I) {
|
||||
if (Offs.isNonNegative() && cast<GEPOperator>(I).isInBounds())
|
||||
Flags.setNoUnsignedWrap(true);
|
||||
|
||||
OffsVal = DAG.getSExtOrTrunc(OffsVal, dl, N.getValueType());
|
||||
|
||||
N = DAG.getNode(ISD::ADD, dl, N.getValueType(), N, OffsVal, Flags);
|
||||
continue;
|
||||
}
|
||||
@ -3884,7 +3930,8 @@ void SelectionDAGBuilder::visitGetElementPtr(const User &I) {
|
||||
N.getValueType(), IdxN,
|
||||
DAG.getConstant(Amt, dl, IdxN.getValueType()));
|
||||
} else {
|
||||
SDValue Scale = DAG.getConstant(ElementSize, dl, IdxN.getValueType());
|
||||
SDValue Scale = DAG.getConstant(ElementSize.getZExtValue(), dl,
|
||||
IdxN.getValueType());
|
||||
IdxN = DAG.getNode(ISD::MUL, dl,
|
||||
N.getValueType(), IdxN, Scale);
|
||||
}
|
||||
@ -3895,6 +3942,9 @@ void SelectionDAGBuilder::visitGetElementPtr(const User &I) {
|
||||
}
|
||||
}
|
||||
|
||||
if (PtrMemTy != PtrTy && !cast<GEPOperator>(I).isInBounds())
|
||||
N = DAG.getPtrExtendInReg(N, dl, PtrMemTy);
|
||||
|
||||
setValue(&I, N);
|
||||
}
|
||||
|
||||
@ -3986,9 +4036,9 @@ void SelectionDAGBuilder::visitLoad(const LoadInst &I) {
|
||||
I.getAAMetadata(AAInfo);
|
||||
const MDNode *Ranges = I.getMetadata(LLVMContext::MD_range);
|
||||
|
||||
SmallVector<EVT, 4> ValueVTs;
|
||||
SmallVector<EVT, 4> ValueVTs, MemVTs;
|
||||
SmallVector<uint64_t, 4> Offsets;
|
||||
ComputeValueVTs(TLI, DAG.getDataLayout(), Ty, ValueVTs, &Offsets);
|
||||
ComputeValueVTs(TLI, DAG.getDataLayout(), Ty, ValueVTs, &MemVTs, &Offsets);
|
||||
unsigned NumValues = ValueVTs.size();
|
||||
if (NumValues == 0)
|
||||
return;
|
||||
@ -4054,12 +4104,15 @@ void SelectionDAGBuilder::visitLoad(const LoadInst &I) {
|
||||
MMOFlags |= MachineMemOperand::MODereferenceable;
|
||||
MMOFlags |= TLI.getMMOFlags(I);
|
||||
|
||||
SDValue L = DAG.getLoad(ValueVTs[i], dl, Root, A,
|
||||
SDValue L = DAG.getLoad(MemVTs[i], dl, Root, A,
|
||||
MachinePointerInfo(SV, Offsets[i]), Alignment,
|
||||
MMOFlags, AAInfo, Ranges);
|
||||
Chains[ChainI] = L.getValue(1);
|
||||
|
||||
if (MemVTs[i] != ValueVTs[i])
|
||||
L = DAG.getZExtOrTrunc(L, dl, ValueVTs[i]);
|
||||
|
||||
Values[i] = L;
|
||||
Chains[ChainI] = L.getValue(1);
|
||||
}
|
||||
|
||||
if (!ConstantMemory) {
|
||||
@ -4158,10 +4211,10 @@ void SelectionDAGBuilder::visitStore(const StoreInst &I) {
|
||||
}
|
||||
}
|
||||
|
||||
SmallVector<EVT, 4> ValueVTs;
|
||||
SmallVector<EVT, 4> ValueVTs, MemVTs;
|
||||
SmallVector<uint64_t, 4> Offsets;
|
||||
ComputeValueVTs(DAG.getTargetLoweringInfo(), DAG.getDataLayout(),
|
||||
SrcV->getType(), ValueVTs, &Offsets);
|
||||
SrcV->getType(), ValueVTs, &MemVTs, &Offsets);
|
||||
unsigned NumValues = ValueVTs.size();
|
||||
if (NumValues == 0)
|
||||
return;
|
||||
@ -4203,9 +4256,12 @@ void SelectionDAGBuilder::visitStore(const StoreInst &I) {
|
||||
}
|
||||
SDValue Add = DAG.getNode(ISD::ADD, dl, PtrVT, Ptr,
|
||||
DAG.getConstant(Offsets[i], dl, PtrVT), Flags);
|
||||
SDValue St = DAG.getStore(
|
||||
Root, dl, SDValue(Src.getNode(), Src.getResNo() + i), Add,
|
||||
MachinePointerInfo(PtrV, Offsets[i]), Alignment, MMOFlags, AAInfo);
|
||||
SDValue Val = SDValue(Src.getNode(), Src.getResNo() + i);
|
||||
if (MemVTs[i] != ValueVTs[i])
|
||||
Val = DAG.getPtrExtOrTrunc(Val, dl, MemVTs[i]);
|
||||
SDValue St =
|
||||
DAG.getStore(Root, dl, Val, Add, MachinePointerInfo(PtrV, Offsets[i]),
|
||||
Alignment, MMOFlags, AAInfo);
|
||||
Chains[ChainI] = St;
|
||||
}
|
||||
|
||||
@ -4590,9 +4646,10 @@ void SelectionDAGBuilder::visitAtomicLoad(const LoadInst &I) {
|
||||
|
||||
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
|
||||
EVT VT = TLI.getValueType(DAG.getDataLayout(), I.getType());
|
||||
EVT MemVT = TLI.getMemValueType(DAG.getDataLayout(), I.getType());
|
||||
|
||||
if (!TLI.supportsUnalignedAtomics() &&
|
||||
I.getAlignment() < VT.getStoreSize())
|
||||
I.getAlignment() < MemVT.getSizeInBits() / 8)
|
||||
report_fatal_error("Cannot generate unaligned atomic load");
|
||||
|
||||
auto Flags = MachineMemOperand::MOLoad;
|
||||
@ -4608,17 +4665,19 @@ void SelectionDAGBuilder::visitAtomicLoad(const LoadInst &I) {
|
||||
MachineMemOperand *MMO =
|
||||
DAG.getMachineFunction().
|
||||
getMachineMemOperand(MachinePointerInfo(I.getPointerOperand()),
|
||||
Flags, VT.getStoreSize(),
|
||||
Flags, MemVT.getStoreSize(),
|
||||
I.getAlignment() ? I.getAlignment() :
|
||||
DAG.getEVTAlignment(VT),
|
||||
DAG.getEVTAlignment(MemVT),
|
||||
AAMDNodes(), nullptr, SSID, Order);
|
||||
|
||||
InChain = TLI.prepareVolatileOrAtomicLoad(InChain, dl, DAG);
|
||||
SDValue L =
|
||||
DAG.getAtomic(ISD::ATOMIC_LOAD, dl, VT, VT, InChain,
|
||||
DAG.getAtomic(ISD::ATOMIC_LOAD, dl, MemVT, MemVT, InChain,
|
||||
getValue(I.getPointerOperand()), MMO);
|
||||
|
||||
SDValue OutChain = L.getValue(1);
|
||||
if (MemVT != VT)
|
||||
L = DAG.getPtrExtOrTrunc(L, dl, VT);
|
||||
|
||||
setValue(&I, L);
|
||||
DAG.setRoot(OutChain);
|
||||
@ -4633,10 +4692,10 @@ void SelectionDAGBuilder::visitAtomicStore(const StoreInst &I) {
|
||||
SDValue InChain = getRoot();
|
||||
|
||||
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
|
||||
EVT VT =
|
||||
TLI.getValueType(DAG.getDataLayout(), I.getValueOperand()->getType());
|
||||
EVT MemVT =
|
||||
TLI.getMemValueType(DAG.getDataLayout(), I.getValueOperand()->getType());
|
||||
|
||||
if (I.getAlignment() < VT.getStoreSize())
|
||||
if (I.getAlignment() < MemVT.getSizeInBits() / 8)
|
||||
report_fatal_error("Cannot generate unaligned atomic store");
|
||||
|
||||
auto Flags = MachineMemOperand::MOStore;
|
||||
@ -4647,12 +4706,12 @@ void SelectionDAGBuilder::visitAtomicStore(const StoreInst &I) {
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
MachineMemOperand *MMO =
|
||||
MF.getMachineMemOperand(MachinePointerInfo(I.getPointerOperand()), Flags,
|
||||
VT.getStoreSize(), I.getAlignment(), AAMDNodes(),
|
||||
MemVT.getStoreSize(), I.getAlignment(), AAMDNodes(),
|
||||
nullptr, SSID, Ordering);
|
||||
SDValue OutChain =
|
||||
DAG.getAtomic(ISD::ATOMIC_STORE, dl, VT, InChain,
|
||||
getValue(I.getPointerOperand()), getValue(I.getValueOperand()),
|
||||
MMO);
|
||||
|
||||
SDValue Val = DAG.getPtrExtOrTrunc(getValue(I.getValueOperand()), dl, MemVT);
|
||||
SDValue OutChain = DAG.getAtomic(ISD::ATOMIC_STORE, dl, MemVT, InChain,
|
||||
getValue(I.getPointerOperand()), Val, MMO);
|
||||
|
||||
|
||||
DAG.setRoot(OutChain);
|
||||
@ -6226,7 +6285,7 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
|
||||
EVT ResTy = TLI.getValueType(DAG.getDataLayout(), I.getType());
|
||||
// Result type for @llvm.get.dynamic.area.offset should match PtrTy for
|
||||
// target.
|
||||
if (PtrTy != ResTy)
|
||||
if (PtrTy.getSizeInBits() < ResTy.getSizeInBits())
|
||||
report_fatal_error("Wrong result type for @llvm.get.dynamic.area.offset"
|
||||
" intrinsic!");
|
||||
Res = DAG.getNode(ISD::GET_DYNAMIC_AREA_OFFSET, sdl, DAG.getVTList(ResTy),
|
||||
@ -7689,8 +7748,9 @@ static SDValue getAddressForMemoryInput(SDValue Chain, const SDLoc &Location,
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
int SSFI = MF.getFrameInfo().CreateStackObject(TySize, Align, false);
|
||||
SDValue StackSlot = DAG.getFrameIndex(SSFI, TLI.getFrameIndexTy(DL));
|
||||
Chain = DAG.getStore(Chain, Location, OpInfo.CallOperand, StackSlot,
|
||||
MachinePointerInfo::getFixedStack(MF, SSFI));
|
||||
Chain = DAG.getTruncStore(Chain, Location, OpInfo.CallOperand, StackSlot,
|
||||
MachinePointerInfo::getFixedStack(MF, SSFI),
|
||||
TLI.getMemValueType(DL, Ty));
|
||||
OpInfo.CallOperand = StackSlot;
|
||||
|
||||
return Chain;
|
||||
@ -8342,12 +8402,16 @@ void SelectionDAGBuilder::visitVAStart(const CallInst &I) {
|
||||
void SelectionDAGBuilder::visitVAArg(const VAArgInst &I) {
|
||||
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
|
||||
const DataLayout &DL = DAG.getDataLayout();
|
||||
SDValue V = DAG.getVAArg(TLI.getValueType(DAG.getDataLayout(), I.getType()),
|
||||
getCurSDLoc(), getRoot(), getValue(I.getOperand(0)),
|
||||
DAG.getSrcValue(I.getOperand(0)),
|
||||
DL.getABITypeAlignment(I.getType()));
|
||||
setValue(&I, V);
|
||||
SDValue V = DAG.getVAArg(
|
||||
TLI.getMemValueType(DAG.getDataLayout(), I.getType()), getCurSDLoc(),
|
||||
getRoot(), getValue(I.getOperand(0)), DAG.getSrcValue(I.getOperand(0)),
|
||||
DL.getABITypeAlignment(I.getType()));
|
||||
DAG.setRoot(V.getValue(1));
|
||||
|
||||
if (I.getType()->isPointerTy())
|
||||
V = DAG.getPtrExtOrTrunc(
|
||||
V, getCurSDLoc(), TLI.getValueType(DAG.getDataLayout(), I.getType()));
|
||||
setValue(&I, V);
|
||||
}
|
||||
|
||||
void SelectionDAGBuilder::visitVAEnd(const CallInst &I) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user