mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 04:32:44 +01:00
Remove GlobalValue::getAlignment().
This function is deceptive at best: it doesn't return what you'd expect. If you have an arbitrary GlobalValue and you want to determine the alignment of that pointer, Value::getPointerAlignment() returns the correct value. If you want the actual declared alignment of a function or variable, GlobalObject::getAlignment() returns that. This patch switches all the users of GlobalValue::getAlignment to an appropriate alternative. Differential Revision: https://reviews.llvm.org/D80368
This commit is contained in:
parent
8bce4cf299
commit
9d315e1c2b
@ -662,7 +662,7 @@ public:
|
|||||||
virtual void emitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const;
|
virtual void emitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const;
|
||||||
|
|
||||||
/// Return the alignment for the specified \p GV.
|
/// Return the alignment for the specified \p GV.
|
||||||
static Align getGVAlignment(const GlobalValue *GV, const DataLayout &DL,
|
static Align getGVAlignment(const GlobalObject *GV, const DataLayout &DL,
|
||||||
Align InAlign = Align(1));
|
Align InAlign = Align(1));
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -76,6 +76,10 @@ public:
|
|||||||
return Align ? Align->value() : 0;
|
return Align ? Align->value() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the alignment of the given variable or function.
|
||||||
|
///
|
||||||
|
/// Note that for functions this is the alignment of the code, not the
|
||||||
|
/// alignment of a function pointer.
|
||||||
MaybeAlign getAlign() const {
|
MaybeAlign getAlign() const {
|
||||||
unsigned Data = getGlobalValueSubClassData();
|
unsigned Data = getGlobalValueSubClassData();
|
||||||
unsigned AlignmentData = Data & AlignmentMask;
|
unsigned AlignmentData = Data & AlignmentMask;
|
||||||
@ -183,6 +187,13 @@ public:
|
|||||||
void setVCallVisibilityMetadata(VCallVisibility Visibility);
|
void setVCallVisibilityMetadata(VCallVisibility Visibility);
|
||||||
VCallVisibility getVCallVisibility() const;
|
VCallVisibility getVCallVisibility() const;
|
||||||
|
|
||||||
|
/// Returns true if the alignment of the value can be unilaterally
|
||||||
|
/// increased.
|
||||||
|
///
|
||||||
|
/// Note that for functions this is the alignment of the code, not the
|
||||||
|
/// alignment of a function pointer.
|
||||||
|
bool canIncreaseAlignment() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void copyAttributesFrom(const GlobalObject *Src);
|
void copyAttributesFrom(const GlobalObject *Src);
|
||||||
|
|
||||||
|
@ -185,7 +185,6 @@ public:
|
|||||||
|
|
||||||
GlobalValue(const GlobalValue &) = delete;
|
GlobalValue(const GlobalValue &) = delete;
|
||||||
|
|
||||||
unsigned getAlignment() const;
|
|
||||||
unsigned getAddressSpace() const;
|
unsigned getAddressSpace() const;
|
||||||
|
|
||||||
enum class UnnamedAddr {
|
enum class UnnamedAddr {
|
||||||
@ -549,10 +548,6 @@ public:
|
|||||||
return !(isDeclarationForLinker() || isWeakForLinker());
|
return !(isDeclarationForLinker() || isWeakForLinker());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if the alignment of the value can be unilaterally
|
|
||||||
// increased.
|
|
||||||
bool canIncreaseAlignment() const;
|
|
||||||
|
|
||||||
const GlobalObject *getBaseObject() const;
|
const GlobalObject *getBaseObject() const;
|
||||||
GlobalObject *getBaseObject() {
|
GlobalObject *getBaseObject() {
|
||||||
return const_cast<GlobalObject *>(
|
return const_cast<GlobalObject *>(
|
||||||
|
@ -1179,7 +1179,7 @@ void ModuleBitcodeWriter::writeModuleInfo() {
|
|||||||
std::map<std::string, unsigned> GCMap;
|
std::map<std::string, unsigned> GCMap;
|
||||||
unsigned MaxAlignment = 0;
|
unsigned MaxAlignment = 0;
|
||||||
unsigned MaxGlobalType = 0;
|
unsigned MaxGlobalType = 0;
|
||||||
for (const GlobalValue &GV : M.globals()) {
|
for (const GlobalVariable &GV : M.globals()) {
|
||||||
MaxAlignment = std::max(MaxAlignment, GV.getAlignment());
|
MaxAlignment = std::max(MaxAlignment, GV.getAlignment());
|
||||||
MaxGlobalType = std::max(MaxGlobalType, VE.getTypeID(GV.getValueType()));
|
MaxGlobalType = std::max(MaxGlobalType, VE.getTypeID(GV.getValueType()));
|
||||||
if (GV.hasSection()) {
|
if (GV.hasSection()) {
|
||||||
|
@ -157,7 +157,7 @@ static gcp_map_type &getGCMap(void *&P) {
|
|||||||
|
|
||||||
/// getGVAlignment - Return the alignment to use for the specified global
|
/// getGVAlignment - Return the alignment to use for the specified global
|
||||||
/// value. This rounds up to the preferred alignment if possible and legal.
|
/// value. This rounds up to the preferred alignment if possible and legal.
|
||||||
Align AsmPrinter::getGVAlignment(const GlobalValue *GV, const DataLayout &DL,
|
Align AsmPrinter::getGVAlignment(const GlobalObject *GV, const DataLayout &DL,
|
||||||
Align InAlign) {
|
Align InAlign) {
|
||||||
Align Alignment;
|
Align Alignment;
|
||||||
if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV))
|
if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV))
|
||||||
|
@ -1239,8 +1239,8 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, Constant *C1,
|
|||||||
// Without a datalayout we have to assume the worst case: that the
|
// Without a datalayout we have to assume the worst case: that the
|
||||||
// function pointer isn't aligned at all.
|
// function pointer isn't aligned at all.
|
||||||
GVAlign = llvm::None;
|
GVAlign = llvm::None;
|
||||||
} else {
|
} else if (isa<GlobalVariable>(GV)) {
|
||||||
GVAlign = MaybeAlign(GV->getAlignment());
|
GVAlign = cast<GlobalVariable>(GV)->getAlign();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GVAlign && *GVAlign > 1) {
|
if (GVAlign && *GVAlign > 1) {
|
||||||
|
@ -2003,7 +2003,7 @@ LLVMTypeRef LLVMGlobalGetValueType(LLVMValueRef Global) {
|
|||||||
|
|
||||||
unsigned LLVMGetAlignment(LLVMValueRef V) {
|
unsigned LLVMGetAlignment(LLVMValueRef V) {
|
||||||
Value *P = unwrap<Value>(V);
|
Value *P = unwrap<Value>(V);
|
||||||
if (GlobalValue *GV = dyn_cast<GlobalValue>(P))
|
if (GlobalObject *GV = dyn_cast<GlobalObject>(P))
|
||||||
return GV->getAlignment();
|
return GV->getAlignment();
|
||||||
if (AllocaInst *AI = dyn_cast<AllocaInst>(P))
|
if (AllocaInst *AI = dyn_cast<AllocaInst>(P))
|
||||||
return AI->getAlignment();
|
return AI->getAlignment();
|
||||||
@ -2013,7 +2013,7 @@ unsigned LLVMGetAlignment(LLVMValueRef V) {
|
|||||||
return SI->getAlignment();
|
return SI->getAlignment();
|
||||||
|
|
||||||
llvm_unreachable(
|
llvm_unreachable(
|
||||||
"only GlobalValue, AllocaInst, LoadInst and StoreInst have alignment");
|
"only GlobalObject, AllocaInst, LoadInst and StoreInst have alignment");
|
||||||
}
|
}
|
||||||
|
|
||||||
void LLVMSetAlignment(LLVMValueRef V, unsigned Bytes) {
|
void LLVMSetAlignment(LLVMValueRef V, unsigned Bytes) {
|
||||||
|
@ -108,20 +108,6 @@ bool GlobalValue::canBenefitFromLocalAlias() const {
|
|||||||
!isa<GlobalIFunc>(this) && !hasComdat();
|
!isa<GlobalIFunc>(this) && !hasComdat();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned GlobalValue::getAlignment() const {
|
|
||||||
if (auto *GA = dyn_cast<GlobalAlias>(this)) {
|
|
||||||
// In general we cannot compute this at the IR level, but we try.
|
|
||||||
if (const GlobalObject *GO = GA->getBaseObject())
|
|
||||||
return GO->getAlignment();
|
|
||||||
|
|
||||||
// FIXME: we should also be able to handle:
|
|
||||||
// Alias = Global + Offset
|
|
||||||
// Alias = Absolute
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return cast<GlobalObject>(this)->getAlignment();
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned GlobalValue::getAddressSpace() const {
|
unsigned GlobalValue::getAddressSpace() const {
|
||||||
PointerType *PtrTy = getType();
|
PointerType *PtrTy = getType();
|
||||||
return PtrTy->getAddressSpace();
|
return PtrTy->getAddressSpace();
|
||||||
@ -252,7 +238,7 @@ bool GlobalValue::isDeclaration() const {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GlobalValue::canIncreaseAlignment() const {
|
bool GlobalObject::canIncreaseAlignment() const {
|
||||||
// Firstly, can only increase the alignment of a global if it
|
// Firstly, can only increase the alignment of a global if it
|
||||||
// is a strong definition.
|
// is a strong definition.
|
||||||
if (!isStrongDefinitionForLinker())
|
if (!isStrongDefinitionForLinker())
|
||||||
|
@ -570,8 +570,9 @@ void Verifier::visitGlobalValue(const GlobalValue &GV) {
|
|||||||
Assert(!GV.isDeclaration() || GV.hasValidDeclarationLinkage(),
|
Assert(!GV.isDeclaration() || GV.hasValidDeclarationLinkage(),
|
||||||
"Global is external, but doesn't have external or weak linkage!", &GV);
|
"Global is external, but doesn't have external or weak linkage!", &GV);
|
||||||
|
|
||||||
Assert(GV.getAlignment() <= Value::MaximumAlignment,
|
if (const GlobalObject *GO = dyn_cast<GlobalObject>(&GV))
|
||||||
"huge alignment values are unsupported", &GV);
|
Assert(GO->getAlignment() <= Value::MaximumAlignment,
|
||||||
|
"huge alignment values are unsupported", GO);
|
||||||
Assert(!GV.hasAppendingLinkage() || isa<GlobalVariable>(GV),
|
Assert(!GV.hasAppendingLinkage() || isa<GlobalVariable>(GV),
|
||||||
"Only global variables can have appending linkage!", &GV);
|
"Only global variables can have appending linkage!", &GV);
|
||||||
|
|
||||||
|
@ -414,9 +414,8 @@ void LTOModule::addDefinedFunctionSymbol(StringRef Name, const Function *F) {
|
|||||||
|
|
||||||
void LTOModule::addDefinedSymbol(StringRef Name, const GlobalValue *def,
|
void LTOModule::addDefinedSymbol(StringRef Name, const GlobalValue *def,
|
||||||
bool isFunction) {
|
bool isFunction) {
|
||||||
// set alignment part log2() can have rounding errors
|
const GlobalObject *go = dyn_cast<GlobalObject>(def);
|
||||||
uint32_t align = def->getAlignment();
|
uint32_t attr = go ? Log2(go->getAlign().valueOrOne()) : 0;
|
||||||
uint32_t attr = align ? countTrailingZeros(align) : 0;
|
|
||||||
|
|
||||||
// set permissions part
|
// set permissions part
|
||||||
if (isFunction) {
|
if (isFunction) {
|
||||||
|
@ -264,9 +264,13 @@ Error Builder::addSymbol(const ModuleSymbolTable &Msymtab,
|
|||||||
Sym.Flags |= unsigned(GV->getVisibility()) << storage::Symbol::FB_visibility;
|
Sym.Flags |= unsigned(GV->getVisibility()) << storage::Symbol::FB_visibility;
|
||||||
|
|
||||||
if (Flags & object::BasicSymbolRef::SF_Common) {
|
if (Flags & object::BasicSymbolRef::SF_Common) {
|
||||||
|
auto *GVar = dyn_cast<GlobalVariable>(GV);
|
||||||
|
if (!GVar)
|
||||||
|
return make_error<StringError>("Only variables can have common linkage!",
|
||||||
|
inconvertibleErrorCode());
|
||||||
Uncommon().CommonSize = GV->getParent()->getDataLayout().getTypeAllocSize(
|
Uncommon().CommonSize = GV->getParent()->getDataLayout().getTypeAllocSize(
|
||||||
GV->getType()->getElementType());
|
GV->getType()->getElementType());
|
||||||
Uncommon().CommonAlign = GV->getAlignment();
|
Uncommon().CommonAlign = GVar->getAlignment();
|
||||||
}
|
}
|
||||||
|
|
||||||
const GlobalObject *Base = GV->getBaseObject();
|
const GlobalObject *Base = GV->getBaseObject();
|
||||||
|
@ -904,16 +904,9 @@ bool AArch64DAGToDAGISel::SelectAddrModeIndexed(SDValue N, unsigned Size,
|
|||||||
if (!GAN)
|
if (!GAN)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (GAN->getOffset() % Size == 0) {
|
if (GAN->getOffset() % Size == 0 &&
|
||||||
const GlobalValue *GV = GAN->getGlobal();
|
GAN->getGlobal()->getPointerAlignment(DL) >= Size)
|
||||||
unsigned Alignment = GV->getAlignment();
|
return true;
|
||||||
Type *Ty = GV->getValueType();
|
|
||||||
if (Alignment == 0 && Ty->isSized())
|
|
||||||
Alignment = DL.getABITypeAlignment(Ty);
|
|
||||||
|
|
||||||
if (Alignment >= Size)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CurDAG->isBaseWithConstantOffset(N)) {
|
if (CurDAG->isBaseWithConstantOffset(N)) {
|
||||||
|
@ -5161,13 +5161,8 @@ AArch64InstructionSelector::tryFoldAddLowIntoImm(MachineInstr &RootDef,
|
|||||||
if (GV->isThreadLocal())
|
if (GV->isThreadLocal())
|
||||||
return None;
|
return None;
|
||||||
|
|
||||||
unsigned Alignment = GV->getAlignment();
|
|
||||||
Type *Ty = GV->getValueType();
|
|
||||||
auto &MF = *RootDef.getParent()->getParent();
|
auto &MF = *RootDef.getParent()->getParent();
|
||||||
if (Alignment == 0 && Ty->isSized())
|
if (GV->getPointerAlignment(MF.getDataLayout()) < Size)
|
||||||
Alignment = MF.getDataLayout().getABITypeAlignment(Ty);
|
|
||||||
|
|
||||||
if (Alignment < Size)
|
|
||||||
return None;
|
return None;
|
||||||
|
|
||||||
unsigned OpFlags = STI.ClassifyGlobalReference(GV, MF.getTarget());
|
unsigned OpFlags = STI.ClassifyGlobalReference(GV, MF.getTarget());
|
||||||
|
@ -1321,7 +1321,7 @@ SDValue AMDGPUTargetLowering::LowerGlobalAddress(AMDGPUMachineFunction* MFI,
|
|||||||
|
|
||||||
// TODO: We could emit code to handle the initialization somewhere.
|
// TODO: We could emit code to handle the initialization somewhere.
|
||||||
if (!hasDefinedInitializer(GV)) {
|
if (!hasDefinedInitializer(GV)) {
|
||||||
unsigned Offset = MFI->allocateLDSGlobal(DL, *GV);
|
unsigned Offset = MFI->allocateLDSGlobal(DL, *cast<GlobalVariable>(GV));
|
||||||
return DAG.getConstant(Offset, SDLoc(Op), Op.getValueType());
|
return DAG.getConstant(Offset, SDLoc(Op), Op.getValueType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4589,11 +4589,10 @@ void AMDGPUTargetLowering::computeKnownBitsForTargetNode(
|
|||||||
}
|
}
|
||||||
case AMDGPUISD::LDS: {
|
case AMDGPUISD::LDS: {
|
||||||
auto GA = cast<GlobalAddressSDNode>(Op.getOperand(0).getNode());
|
auto GA = cast<GlobalAddressSDNode>(Op.getOperand(0).getNode());
|
||||||
unsigned Align = GA->getGlobal()->getAlignment();
|
Align Alignment = GA->getGlobal()->getPointerAlignment(DAG.getDataLayout());
|
||||||
|
|
||||||
Known.Zero.setHighBits(16);
|
Known.Zero.setHighBits(16);
|
||||||
if (Align)
|
Known.Zero.setLowBits(Log2(Alignment));
|
||||||
Known.Zero.setLowBits(Log2_32(Align));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ISD::INTRINSIC_WO_CHAIN: {
|
case ISD::INTRINSIC_WO_CHAIN: {
|
||||||
|
@ -2099,7 +2099,9 @@ bool AMDGPULegalizerInfo::legalizeGlobalValue(
|
|||||||
return true; // Leave in place;
|
return true; // Leave in place;
|
||||||
}
|
}
|
||||||
|
|
||||||
B.buildConstant(DstReg, MFI->allocateLDSGlobal(B.getDataLayout(), *GV));
|
B.buildConstant(
|
||||||
|
DstReg,
|
||||||
|
MFI->allocateLDSGlobal(B.getDataLayout(), *cast<GlobalVariable>(GV)));
|
||||||
MI.eraseFromParent();
|
MI.eraseFromParent();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ AMDGPUMachineFunction::AMDGPUMachineFunction(const MachineFunction &MF) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsigned AMDGPUMachineFunction::allocateLDSGlobal(const DataLayout &DL,
|
unsigned AMDGPUMachineFunction::allocateLDSGlobal(const DataLayout &DL,
|
||||||
const GlobalValue &GV) {
|
const GlobalVariable &GV) {
|
||||||
auto Entry = LocalMemoryObjects.insert(std::make_pair(&GV, 0));
|
auto Entry = LocalMemoryObjects.insert(std::make_pair(&GV, 0));
|
||||||
if (!Entry.second)
|
if (!Entry.second)
|
||||||
return Entry.first->second;
|
return Entry.first->second;
|
||||||
|
@ -77,7 +77,7 @@ public:
|
|||||||
return WaveLimiter;
|
return WaveLimiter;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned allocateLDSGlobal(const DataLayout &DL, const GlobalValue &GV);
|
unsigned allocateLDSGlobal(const DataLayout &DL, const GlobalVariable &GV);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1143,8 +1143,11 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
|
|||||||
// can be enabled for those subtargets.
|
// can be enabled for those subtargets.
|
||||||
unsigned OpNum = (MI->getOpcode() == PPC::STD) ? 2 : 1;
|
unsigned OpNum = (MI->getOpcode() == PPC::STD) ? 2 : 1;
|
||||||
const MachineOperand &MO = MI->getOperand(OpNum);
|
const MachineOperand &MO = MI->getOperand(OpNum);
|
||||||
if (MO.isGlobal() && MO.getGlobal()->getAlignment() < 4)
|
if (MO.isGlobal()) {
|
||||||
llvm_unreachable("Global must be word-aligned for LD, STD, LWA!");
|
const DataLayout &DL = MO.getGlobal()->getParent()->getDataLayout();
|
||||||
|
if (MO.getGlobal()->getPointerAlignment(DL) < 4)
|
||||||
|
llvm_unreachable("Global must be word-aligned for LD, STD, LWA!");
|
||||||
|
}
|
||||||
// Now process the instruction normally.
|
// Now process the instruction normally.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -6659,7 +6659,8 @@ void PPCDAGToDAGISel::PeepholePPC64() {
|
|||||||
int MaxDisplacement = 7;
|
int MaxDisplacement = 7;
|
||||||
if (GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(ImmOpnd)) {
|
if (GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(ImmOpnd)) {
|
||||||
const GlobalValue *GV = GA->getGlobal();
|
const GlobalValue *GV = GA->getGlobal();
|
||||||
MaxDisplacement = std::min((int) GV->getAlignment() - 1, MaxDisplacement);
|
Align Alignment = GV->getPointerAlignment(CurDAG->getDataLayout());
|
||||||
|
MaxDisplacement = std::min((int)Alignment.value() - 1, MaxDisplacement);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UpdateHBase = false;
|
bool UpdateHBase = false;
|
||||||
@ -6725,10 +6726,10 @@ void PPCDAGToDAGISel::PeepholePPC64() {
|
|||||||
if (GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(ImmOpnd)) {
|
if (GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(ImmOpnd)) {
|
||||||
SDLoc dl(GA);
|
SDLoc dl(GA);
|
||||||
const GlobalValue *GV = GA->getGlobal();
|
const GlobalValue *GV = GA->getGlobal();
|
||||||
|
Align Alignment = GV->getPointerAlignment(CurDAG->getDataLayout());
|
||||||
// We can't perform this optimization for data whose alignment
|
// We can't perform this optimization for data whose alignment
|
||||||
// is insufficient for the instruction encoding.
|
// is insufficient for the instruction encoding.
|
||||||
if (GV->getAlignment() < 4 &&
|
if (Alignment < 4 && (RequiresMod4Offset || (Offset % 4) != 0)) {
|
||||||
(RequiresMod4Offset || (Offset % 4) != 0)) {
|
|
||||||
LLVM_DEBUG(dbgs() << "Rejected this candidate for alignment.\n\n");
|
LLVM_DEBUG(dbgs() << "Rejected this candidate for alignment.\n\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -3591,9 +3591,11 @@ bool PPCInstrInfo::isImmElgibleForForwarding(const MachineOperand &ImmMO,
|
|||||||
// not just an immediate but also a multiple of 4, or 16 depending on the
|
// not just an immediate but also a multiple of 4, or 16 depending on the
|
||||||
// load. A DForm load cannot be represented if it is a multiple of say 2.
|
// load. A DForm load cannot be represented if it is a multiple of say 2.
|
||||||
// XForm loads do not have this restriction.
|
// XForm loads do not have this restriction.
|
||||||
if (ImmMO.isGlobal() &&
|
if (ImmMO.isGlobal()) {
|
||||||
ImmMO.getGlobal()->getAlignment() < III.ImmMustBeMultipleOf)
|
const DataLayout &DL = ImmMO.getGlobal()->getParent()->getDataLayout();
|
||||||
return false;
|
if (ImmMO.getGlobal()->getPointerAlignment(DL) < III.ImmMustBeMultipleOf)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -74,9 +74,12 @@ bool SystemZSubtarget::enableSubRegLiveness() const {
|
|||||||
|
|
||||||
bool SystemZSubtarget::isPC32DBLSymbol(const GlobalValue *GV,
|
bool SystemZSubtarget::isPC32DBLSymbol(const GlobalValue *GV,
|
||||||
CodeModel::Model CM) const {
|
CodeModel::Model CM) const {
|
||||||
// PC32DBL accesses require the low bit to be clear. Note that a zero
|
// PC32DBL accesses require the low bit to be clear.
|
||||||
// value selects the default alignment and is therefore OK.
|
//
|
||||||
if (GV->getAlignment() == 1)
|
// FIXME: Explicitly check for functions: the datalayout is currently
|
||||||
|
// missing information about function pointers.
|
||||||
|
const DataLayout &DL = GV->getParent()->getDataLayout();
|
||||||
|
if (GV->getPointerAlignment(DL) == 1 && !GV->getValueType()->isFunctionTy())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// For the small model, all locally-binding symbols are in range.
|
// For the small model, all locally-binding symbols are in range.
|
||||||
|
@ -435,7 +435,7 @@ SDValue XCoreTargetLowering::LowerLOAD(SDValue Op, SelectionDAG &DAG) const {
|
|||||||
Offset, DAG);
|
Offset, DAG);
|
||||||
}
|
}
|
||||||
if (TLI.isGAPlusOffset(BasePtr.getNode(), GV, Offset) &&
|
if (TLI.isGAPlusOffset(BasePtr.getNode(), GV, Offset) &&
|
||||||
MinAlign(GV->getAlignment(), 4) == 4) {
|
GV->getPointerAlignment(DAG.getDataLayout()) >= 4) {
|
||||||
SDValue NewBasePtr = DAG.getGlobalAddress(GV, DL,
|
SDValue NewBasePtr = DAG.getGlobalAddress(GV, DL,
|
||||||
BasePtr->getValueType(0));
|
BasePtr->getValueType(0));
|
||||||
return lowerLoadWordFromAlignedBasePlusOffset(DL, Chain, NewBasePtr,
|
return lowerLoadWordFromAlignedBasePlusOffset(DL, Chain, NewBasePtr,
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
|
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||||
; RUN: llc < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s
|
; RUN: llc < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s
|
||||||
|
|
||||||
define i8 @test() {
|
define i8 @test() {
|
||||||
; CHECK-LABEL: @test
|
; CHECK-LABEL: test:
|
||||||
; CHECK: adrp {{x[0-9]+}}, foo
|
; CHECK: // %bb.0: // %entry
|
||||||
; CHECK: add {{x[0-9]+}}, {{x[0-9]+}}, :lo12:foo
|
; CHECK-NEXT: adrp x8, foo
|
||||||
; CHECK: ldrb w0, [{{x[0-9]+}}]
|
; CHECK-NEXT: ldrb w0, [x8, :lo12:foo]
|
||||||
|
; CHECK-NEXT: ret
|
||||||
entry:
|
entry:
|
||||||
%0 = load i8, i8* bitcast (void (...)* @foo to i8*), align 1
|
%0 = load i8, i8* bitcast (void (...)* @foo to i8*), align 1
|
||||||
ret i8 %0
|
ret i8 %0
|
||||||
|
@ -51,11 +51,11 @@ define i64 @test_var32_alias() {
|
|||||||
; CHECK-LABEL: test_var32_alias:
|
; CHECK-LABEL: test_var32_alias:
|
||||||
%addr = bitcast [3 x i32]* @alias to i64*
|
%addr = bitcast [3 x i32]* @alias to i64*
|
||||||
|
|
||||||
; Test that we can find the alignment for aliases.
|
; We don't know anything about the alignment of aliases.
|
||||||
%val = load i64, i64* %addr
|
%val = load i64, i64* %addr
|
||||||
; CHECK: adrp x[[HIBITS:[0-9]+]], alias
|
; CHECK: adrp x[[HIBITS:[0-9]+]], alias
|
||||||
; CHECK-NOT: add x[[HIBITS]]
|
; CHECK: add x[[ADDR:[0-9]+]], x[[HIBITS]], {{#?}}:lo12:alias
|
||||||
; CHECK: ldr x0, [x[[HIBITS]], {{#?}}:lo12:alias]
|
; CHECK: ldr x0, [x[[ADDR]]]
|
||||||
|
|
||||||
ret i64 %val
|
ret i64 %val
|
||||||
}
|
}
|
||||||
|
@ -8,11 +8,10 @@ target triple = "powerpc64le-unknown-linux-gnu"
|
|||||||
define i64 @foo() {
|
define i64 @foo() {
|
||||||
; CHECK-LABEL: foo:
|
; CHECK-LABEL: foo:
|
||||||
; CHECK: # %bb.0: # %entry
|
; CHECK: # %bb.0: # %entry
|
||||||
; CHECK-NEXT: addis 3, 2, a@toc@ha
|
|
||||||
; CHECK-NEXT: li 4, 0
|
; CHECK-NEXT: li 4, 0
|
||||||
; CHECK-NEXT: addi 3, 3, a@toc@l
|
; CHECK-NEXT: addis 3, 2, a@toc@ha
|
||||||
|
; CHECK-NEXT: ld 3, a@toc@l(3)
|
||||||
; CHECK-NEXT: cmpd 7, 4, 4
|
; CHECK-NEXT: cmpd 7, 4, 4
|
||||||
; CHECK-NEXT: ld 3, 0(3)
|
|
||||||
; CHECK-NEXT: li 3, 0
|
; CHECK-NEXT: li 3, 0
|
||||||
; CHECK-NEXT: bne- 7, .+4
|
; CHECK-NEXT: bne- 7, .+4
|
||||||
; CHECK-NEXT: isync
|
; CHECK-NEXT: isync
|
||||||
|
Loading…
Reference in New Issue
Block a user