From 9f82ac5738fced23716ac6f9c5744f99d6b6ba92 Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Mon, 9 Jun 2025 13:51:03 -0700 Subject: [PATCH] Remove GlobalObject::getAlign/setAlignment (#143188) Currently, GlobalObject has an "alignment" property... but it's basically nonsense: alignment doesn't mean the same thing for variables and functions, and it's completely meaningless for ifuncs. This "removes" (actually marking protected) the methods from GlobalObject, adds the relevant methods to Function and GlobalVariable, and adjusts the code appropriately. This should make future alignment-related cleanups easier. --- llvm/include/llvm/IR/Function.h | 15 +++++++ llvm/include/llvm/IR/GlobalObject.h | 8 +--- llvm/include/llvm/IR/GlobalVariable.h | 17 +++++++ llvm/include/llvm/SandboxIR/Constant.h | 38 +++++----------- llvm/include/llvm/SandboxIR/Function.h | 10 +++++ llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 6 ++- llvm/lib/IR/Core.cpp | 8 +++- llvm/lib/IR/IRBuilder.cpp | 6 +-- llvm/lib/IR/Value.cpp | 41 ++++++++--------- llvm/lib/IR/Verifier.cpp | 16 ++++--- llvm/lib/LTO/LTOModule.cpp | 7 ++- llvm/lib/SandboxIR/Constant.cpp | 17 ++----- llvm/lib/SandboxIR/Function.cpp | 7 +++ llvm/lib/Target/PowerPC/PPCMIPeephole.cpp | 7 +-- llvm/lib/Target/SystemZ/SystemZSubtarget.cpp | 8 ++-- llvm/lib/Transforms/Utils/Local.cpp | 12 ++--- .../deltas/ReduceGlobalObjects.cpp | 16 +++++-- llvm/unittests/SandboxIR/SandboxIRTest.cpp | 44 +++++++++---------- 18 files changed, 162 insertions(+), 121 deletions(-) diff --git a/llvm/include/llvm/IR/Function.h b/llvm/include/llvm/IR/Function.h index b37c6c6f94a0..c2510ea75544 100644 --- a/llvm/include/llvm/IR/Function.h +++ b/llvm/include/llvm/IR/Function.h @@ -1038,6 +1038,21 @@ public: /// Return value: true => null pointer dereference is not undefined. bool nullPointerIsDefined() const; + /// Returns the alignment of the given function. + /// + /// Note that this is the alignment of the code, not the alignment of a + /// function pointer. + MaybeAlign getAlign() const { return GlobalObject::getAlign(); } + + /// Sets the alignment attribute of the Function. + void setAlignment(Align Align) { GlobalObject::setAlignment(Align); } + + /// Sets the alignment attribute of the Function. + /// + /// This method will be deprecated as the alignment property should always be + /// defined. + void setAlignment(MaybeAlign Align) { GlobalObject::setAlignment(Align); } + private: void allocHungoffUselist(); template void setHungoffOperand(Constant *C); diff --git a/llvm/include/llvm/IR/GlobalObject.h b/llvm/include/llvm/IR/GlobalObject.h index 557add940f45..08a02b42bdc1 100644 --- a/llvm/include/llvm/IR/GlobalObject.h +++ b/llvm/include/llvm/IR/GlobalObject.h @@ -67,12 +67,7 @@ private: public: GlobalObject(const GlobalObject &) = delete; - /// FIXME: Remove this function once transition to Align is over. - uint64_t getAlignment() const { - MaybeAlign Align = getAlign(); - return Align ? Align->value() : 0; - } - +protected: /// Returns the alignment of the given variable or function. /// /// Note that for functions this is the alignment of the code, not the @@ -103,6 +98,7 @@ public: assert(getGlobalObjectSubClassData() == Val && "representation error"); } +public: /// Check if this global has a custom object file section. /// /// This is more efficient than calling getSection() and checking for an empty diff --git a/llvm/include/llvm/IR/GlobalVariable.h b/llvm/include/llvm/IR/GlobalVariable.h index a411897f5490..388e1d7cfa80 100644 --- a/llvm/include/llvm/IR/GlobalVariable.h +++ b/llvm/include/llvm/IR/GlobalVariable.h @@ -298,6 +298,23 @@ public: /// LLVM_ABI void clearCodeModel(); + /// FIXME: Remove this function once transition to Align is over. + uint64_t getAlignment() const { + MaybeAlign Align = getAlign(); + return Align ? Align->value() : 0; + } + + /// Returns the alignment of the given variable. + MaybeAlign getAlign() const { return GlobalObject::getAlign(); } + + /// Sets the alignment attribute of the GlobalVariable. + void setAlignment(Align Align) { GlobalObject::setAlignment(Align); } + + /// Sets the alignment attribute of the GlobalVariable. + /// This method will be deprecated as the alignment property should always be + /// defined. + void setAlignment(MaybeAlign Align) { GlobalObject::setAlignment(Align); } + // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Value *V) { return V->getValueID() == Value::GlobalVariableVal; diff --git a/llvm/include/llvm/SandboxIR/Constant.h b/llvm/include/llvm/SandboxIR/Constant.h index 2012cf8a8ed3..e7b18a442d33 100644 --- a/llvm/include/llvm/SandboxIR/Constant.h +++ b/llvm/include/llvm/SandboxIR/Constant.h @@ -976,32 +976,6 @@ public: } } - /// FIXME: Remove this function once transition to Align is over. - uint64_t getAlignment() const { - return cast(Val)->getAlignment(); - } - - /// 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 { - return cast(Val)->getAlign(); - } - - // TODO: Add missing: setAlignment(Align) - - /// Sets the alignment attribute of the GlobalObject. - /// This method will be deprecated as the alignment property should always be - /// defined. - void setAlignment(MaybeAlign Align); - - unsigned getGlobalObjectSubClassData() const { - return cast(Val)->getGlobalObjectSubClassData(); - } - - void setGlobalObjectSubClassData(unsigned V); - /// Check if this global has a custom object file section. /// /// This is more efficient than calling getSection() and checking for an empty @@ -1294,6 +1268,18 @@ public: return cast(Val)->getCodeModel(); } + /// Returns the alignment of the given variable. + MaybeAlign getAlign() const { + return cast(Val)->getAlign(); + } + + // TODO: Add missing: setAligment(Align) + + /// Sets the alignment attribute of the GlobalVariable. + /// This method will be deprecated as the alignment property should always be + /// defined. + void setAlignment(MaybeAlign Align); + // TODO: Missing setCodeModel(). Requires custom tracker. #ifndef NDEBUG diff --git a/llvm/include/llvm/SandboxIR/Function.h b/llvm/include/llvm/SandboxIR/Function.h index a810533f769f..2c4b53ef6c1e 100644 --- a/llvm/include/llvm/SandboxIR/Function.h +++ b/llvm/include/llvm/SandboxIR/Function.h @@ -58,6 +58,16 @@ public: } FunctionType *getFunctionType() const; + /// Returns the alignment of the given function. + MaybeAlign getAlign() const { return cast(Val)->getAlign(); } + + // TODO: Add missing: setAligment(Align) + + /// Sets the alignment attribute of the Function. + /// This method will be deprecated as the alignment property should always be + /// defined. + void setAlignment(MaybeAlign Align); + #ifndef NDEBUG void verify() const final { assert(isa(Val) && "Expected Function!"); diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index bcfc64c6f36b..e13e92378d4a 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -369,7 +369,11 @@ Align AsmPrinter::getGVAlignment(const GlobalObject *GV, const DataLayout &DL, Alignment = InAlign; // If the GV has a specified alignment, take it into account. - const MaybeAlign GVAlign(GV->getAlign()); + MaybeAlign GVAlign; + if (auto *GVar = dyn_cast(GV)) + GVAlign = GVar->getAlign(); + else if (auto *F = dyn_cast(GV)) + GVAlign = F->getAlign(); if (!GVAlign) return Alignment; diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp index 1954b44af22a..a7c3a56dcc22 100644 --- a/llvm/lib/IR/Core.cpp +++ b/llvm/lib/IR/Core.cpp @@ -2108,8 +2108,10 @@ LLVMTypeRef LLVMGlobalGetValueType(LLVMValueRef Global) { unsigned LLVMGetAlignment(LLVMValueRef V) { Value *P = unwrap(V); - if (GlobalObject *GV = dyn_cast(P)) + if (GlobalVariable *GV = dyn_cast(P)) return GV->getAlign() ? GV->getAlign()->value() : 0; + if (Function *F = dyn_cast(P)) + return F->getAlign() ? F->getAlign()->value() : 0; if (AllocaInst *AI = dyn_cast(P)) return AI->getAlign().value(); if (LoadInst *LI = dyn_cast(P)) @@ -2128,8 +2130,10 @@ unsigned LLVMGetAlignment(LLVMValueRef V) { void LLVMSetAlignment(LLVMValueRef V, unsigned Bytes) { Value *P = unwrap(V); - if (GlobalObject *GV = dyn_cast(P)) + if (GlobalVariable *GV = dyn_cast(P)) GV->setAlignment(MaybeAlign(Bytes)); + else if (Function *F = dyn_cast(P)) + F->setAlignment(MaybeAlign(Bytes)); else if (AllocaInst *AI = dyn_cast(P)) AI->setAlignment(Align(Bytes)); else if (LoadInst *LI = dyn_cast(P)) diff --git a/llvm/lib/IR/IRBuilder.cpp b/llvm/lib/IR/IRBuilder.cpp index 580b0af70933..90ec6626b3a7 100644 --- a/llvm/lib/IR/IRBuilder.cpp +++ b/llvm/lib/IR/IRBuilder.cpp @@ -457,10 +457,10 @@ CallInst *IRBuilderBase::CreateInvariantStart(Value *Ptr, ConstantInt *Size) { } static MaybeAlign getAlign(Value *Ptr) { - if (auto *O = dyn_cast(Ptr)) - return O->getAlign(); + if (auto *V = dyn_cast(Ptr)) + return V->getAlign(); if (auto *A = dyn_cast(Ptr)) - return A->getAliaseeObject()->getAlign(); + return getAlign(A->getAliaseeObject()); return {}; } diff --git a/llvm/lib/IR/Value.cpp b/llvm/lib/IR/Value.cpp index d6cb65d94a11..02c16e201abe 100644 --- a/llvm/lib/IR/Value.cpp +++ b/llvm/lib/IR/Value.cpp @@ -957,30 +957,27 @@ uint64_t Value::getPointerDereferenceableBytes(const DataLayout &DL, Align Value::getPointerAlignment(const DataLayout &DL) const { assert(getType()->isPointerTy() && "must be pointer"); - if (auto *GO = dyn_cast(this)) { - if (isa(GO)) { - Align FunctionPtrAlign = DL.getFunctionPtrAlign().valueOrOne(); - switch (DL.getFunctionPtrAlignType()) { - case DataLayout::FunctionPtrAlignType::Independent: - return FunctionPtrAlign; - case DataLayout::FunctionPtrAlignType::MultipleOfFunctionAlign: - return std::max(FunctionPtrAlign, GO->getAlign().valueOrOne()); - } - llvm_unreachable("Unhandled FunctionPtrAlignType"); + if (const Function *F = dyn_cast(this)) { + Align FunctionPtrAlign = DL.getFunctionPtrAlign().valueOrOne(); + switch (DL.getFunctionPtrAlignType()) { + case DataLayout::FunctionPtrAlignType::Independent: + return FunctionPtrAlign; + case DataLayout::FunctionPtrAlignType::MultipleOfFunctionAlign: + return std::max(FunctionPtrAlign, F->getAlign().valueOrOne()); } - const MaybeAlign Alignment(GO->getAlign()); + llvm_unreachable("Unhandled FunctionPtrAlignType"); + } else if (auto *GVar = dyn_cast(this)) { + const MaybeAlign Alignment(GVar->getAlign()); if (!Alignment) { - if (auto *GVar = dyn_cast(GO)) { - Type *ObjectType = GVar->getValueType(); - if (ObjectType->isSized()) { - // If the object is defined in the current Module, we'll be giving - // it the preferred alignment. Otherwise, we have to assume that it - // may only have the minimum ABI alignment. - if (GVar->isStrongDefinitionForLinker()) - return DL.getPreferredAlign(GVar); - else - return DL.getABITypeAlign(ObjectType); - } + Type *ObjectType = GVar->getValueType(); + if (ObjectType->isSized()) { + // If the object is defined in the current Module, we'll be giving + // it the preferred alignment. Otherwise, we have to assume that it + // may only have the minimum ABI alignment. + if (GVar->isStrongDefinitionForLinker()) + return DL.getPreferredAlign(GVar); + else + return DL.getABITypeAlign(ObjectType); } } return Alignment.valueOrOne(); diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 2d03a7a261b5..592bb6aa9061 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -735,12 +735,6 @@ void Verifier::visitGlobalValue(const GlobalValue &GV) { "Global is external, but doesn't have external or weak linkage!", &GV); if (const GlobalObject *GO = dyn_cast(&GV)) { - - if (MaybeAlign A = GO->getAlign()) { - Check(A->value() <= Value::MaximumAlignment, - "huge alignment values are unsupported", GO); - } - if (const MDNode *Associated = GO->getMetadata(LLVMContext::MD_associated)) { Check(Associated->getNumOperands() == 1, @@ -830,6 +824,11 @@ void Verifier::visitGlobalValue(const GlobalValue &GV) { void Verifier::visitGlobalVariable(const GlobalVariable &GV) { Type *GVType = GV.getValueType(); + if (MaybeAlign A = GV.getAlign()) { + Check(A->value() <= Value::MaximumAlignment, + "huge alignment values are unsupported", &GV); + } + if (GV.hasInitializer()) { Check(GV.getInitializer()->getType() == GVType, "Global variable initializer type does not match global " @@ -2869,6 +2868,11 @@ void Verifier::visitFunction(const Function &F) { Check(!F.hasStructRetAttr() || F.getReturnType()->isVoidTy(), "Invalid struct return type!", &F); + if (MaybeAlign A = F.getAlign()) { + Check(A->value() <= Value::MaximumAlignment, + "huge alignment values are unsupported", &F); + } + AttributeList Attrs = F.getAttributes(); Check(verifyAttributeCount(Attrs, FT->getNumParams()), diff --git a/llvm/lib/LTO/LTOModule.cpp b/llvm/lib/LTO/LTOModule.cpp index 749ae635e610..e0a975806a31 100644 --- a/llvm/lib/LTO/LTOModule.cpp +++ b/llvm/lib/LTO/LTOModule.cpp @@ -414,8 +414,11 @@ void LTOModule::addDefinedFunctionSymbol(StringRef Name, const GlobalValue *F) { void LTOModule::addDefinedSymbol(StringRef Name, const GlobalValue *def, bool isFunction) { - const GlobalObject *go = dyn_cast(def); - uint32_t attr = go ? Log2(go->getAlign().valueOrOne()) : 0; + uint32_t attr = 0; + if (auto *gv = dyn_cast(def)) + attr = Log2(gv->getAlign().valueOrOne()); + else if (auto *f = dyn_cast(def)) + attr = Log2(f->getAlign().valueOrOne()); // set permissions part if (isFunction) { diff --git a/llvm/lib/SandboxIR/Constant.cpp b/llvm/lib/SandboxIR/Constant.cpp index fa79a01c7f34..82cf0876d580 100644 --- a/llvm/lib/SandboxIR/Constant.cpp +++ b/llvm/lib/SandboxIR/Constant.cpp @@ -282,20 +282,11 @@ PoisonValue *PoisonValue::getElementValue(unsigned Idx) const { cast(Val)->getElementValue(Idx))); } -void GlobalObject::setAlignment(MaybeAlign Align) { +void GlobalVariable::setAlignment(MaybeAlign Align) { Ctx.getTracker() - .emplaceIfTracking< - GenericSetter<&GlobalObject::getAlign, &GlobalObject::setAlignment>>( - this); - cast(Val)->setAlignment(Align); -} - -void GlobalObject::setGlobalObjectSubClassData(unsigned V) { - Ctx.getTracker() - .emplaceIfTracking< - GenericSetter<&GlobalObject::getGlobalObjectSubClassData, - &GlobalObject::setGlobalObjectSubClassData>>(this); - cast(Val)->setGlobalObjectSubClassData(V); + .emplaceIfTracking>(this); + cast(Val)->setAlignment(Align); } void GlobalObject::setSection(StringRef S) { diff --git a/llvm/lib/SandboxIR/Function.cpp b/llvm/lib/SandboxIR/Function.cpp index f7a1d35b0046..f400389ed760 100644 --- a/llvm/lib/SandboxIR/Function.cpp +++ b/llvm/lib/SandboxIR/Function.cpp @@ -17,6 +17,13 @@ FunctionType *Function::getFunctionType() const { Ctx.getType(cast(Val)->getFunctionType())); } +void Function::setAlignment(MaybeAlign Align) { + Ctx.getTracker() + .emplaceIfTracking< + GenericSetter<&Function::getAlign, &Function::setAlignment>>(this); + cast(Val)->setAlignment(Align); +} + #ifndef NDEBUG void Function::dumpNameAndArgs(raw_ostream &OS) const { auto *F = cast(Val); diff --git a/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp b/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp index 1c53b740b3f8..18350650bfe2 100644 --- a/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp +++ b/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp @@ -42,6 +42,7 @@ #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachinePostDominators.h" #include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/IR/GlobalVariable.h" #include "llvm/Support/Debug.h" #include "llvm/Support/DebugCounter.h" @@ -997,9 +998,9 @@ bool PPCMIPeephole::simplifyCode() { // the transformation. bool IsWordAligned = false; if (SrcMI->getOperand(1).isGlobal()) { - const GlobalObject *GO = - dyn_cast(SrcMI->getOperand(1).getGlobal()); - if (GO && GO->getAlign() && *GO->getAlign() >= 4 && + const GlobalVariable *GV = + dyn_cast(SrcMI->getOperand(1).getGlobal()); + if (GV && GV->getAlign() && *GV->getAlign() >= 4 && (SrcMI->getOperand(1).getOffset() % 4 == 0)) IsWordAligned = true; } else if (SrcMI->getOperand(1).isImm()) { diff --git a/llvm/lib/Target/SystemZ/SystemZSubtarget.cpp b/llvm/lib/Target/SystemZ/SystemZSubtarget.cpp index 6c376e4bf622..942ef8838562 100644 --- a/llvm/lib/Target/SystemZ/SystemZSubtarget.cpp +++ b/llvm/lib/Target/SystemZ/SystemZSubtarget.cpp @@ -8,7 +8,7 @@ #include "SystemZSubtarget.h" #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" -#include "llvm/IR/GlobalValue.h" +#include "llvm/IR/GlobalVariable.h" #include "llvm/Target/TargetMachine.h" using namespace llvm; @@ -83,9 +83,9 @@ bool SystemZSubtarget::isAddressedViaADA(const GlobalValue *GV) const { // least two byte alignment, then generated code can use relative // instructions to address the variable. Otherwise, use the ADA to address // the variable. - if (GO->getAlignment() & 0x1) { - return true; - } + if (auto *GV = dyn_cast(GO)) + if (GV->getAlign() && (*GV->getAlign()).value() & 0x1) + return true; // getKindForGlobal only works with definitions if (GO->isDeclaration()) { diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp index c8ad01a592ff..0184a1ee72da 100644 --- a/llvm/lib/Transforms/Utils/Local.cpp +++ b/llvm/lib/Transforms/Utils/Local.cpp @@ -1546,9 +1546,9 @@ Align llvm::tryEnforceAlignment(Value *V, Align PrefAlign, return PrefAlign; } - if (auto *GO = dyn_cast(V)) { + if (auto *GV = dyn_cast(V)) { // TODO: as above, this shouldn't be necessary. - Align CurrentAlign = GO->getPointerAlignment(DL); + Align CurrentAlign = GV->getPointerAlignment(DL); if (PrefAlign <= CurrentAlign) return CurrentAlign; @@ -1556,16 +1556,16 @@ Align llvm::tryEnforceAlignment(Value *V, Align PrefAlign, // of the global. If the memory we set aside for the global may not be the // memory used by the final program then it is impossible for us to reliably // enforce the preferred alignment. - if (!GO->canIncreaseAlignment()) + if (!GV->canIncreaseAlignment()) return CurrentAlign; - if (GO->isThreadLocal()) { - unsigned MaxTLSAlign = GO->getParent()->getMaxTLSAlignment() / CHAR_BIT; + if (GV->isThreadLocal()) { + unsigned MaxTLSAlign = GV->getParent()->getMaxTLSAlignment() / CHAR_BIT; if (MaxTLSAlign && PrefAlign > Align(MaxTLSAlign)) PrefAlign = Align(MaxTLSAlign); } - GO->setAlignment(PrefAlign); + GV->setAlignment(PrefAlign); return PrefAlign; } diff --git a/llvm/tools/llvm-reduce/deltas/ReduceGlobalObjects.cpp b/llvm/tools/llvm-reduce/deltas/ReduceGlobalObjects.cpp index 64bf711f23d5..5d958dd2d82a 100644 --- a/llvm/tools/llvm-reduce/deltas/ReduceGlobalObjects.cpp +++ b/llvm/tools/llvm-reduce/deltas/ReduceGlobalObjects.cpp @@ -13,18 +13,26 @@ using namespace llvm; static bool shouldReduceSection(GlobalObject &GO) { return GO.hasSection(); } -static bool shouldReduceAlign(GlobalObject &GO) { - return GO.getAlign().has_value(); +static bool shouldReduceAlign(GlobalVariable *GV) { + return GV->getAlign().has_value(); } +static bool shouldReduceAlign(Function *F) { return F->getAlign().has_value(); } + static bool shouldReduceComdat(GlobalObject &GO) { return GO.hasComdat(); } void llvm::reduceGlobalObjectsDeltaPass(Oracle &O, ReducerWorkItem &Program) { for (auto &GO : Program.getModule().global_objects()) { if (shouldReduceSection(GO) && !O.shouldKeep()) GO.setSection(""); - if (shouldReduceAlign(GO) && !O.shouldKeep()) - GO.setAlignment(MaybeAlign()); + if (auto *GV = dyn_cast(&GO)) { + if (shouldReduceAlign(GV) && !O.shouldKeep()) + GV->setAlignment(MaybeAlign()); + } + if (auto *F = dyn_cast(&GO)) { + if (shouldReduceAlign(F) && !O.shouldKeep()) + F->setAlignment(MaybeAlign()); + } if (shouldReduceComdat(GO) && !O.shouldKeep()) GO.setComdat(nullptr); } diff --git a/llvm/unittests/SandboxIR/SandboxIRTest.cpp b/llvm/unittests/SandboxIR/SandboxIRTest.cpp index 18882add5994..33928ac118e0 100644 --- a/llvm/unittests/SandboxIR/SandboxIRTest.cpp +++ b/llvm/unittests/SandboxIR/SandboxIRTest.cpp @@ -1051,29 +1051,6 @@ define void @foo() { auto *Call = cast(&*It++); // Check classof(), creation. auto *GO = cast(Call->getCalledOperand()); - // Check getAlignment(). - EXPECT_EQ(GO->getAlignment(), LLVMGO->getAlignment()); - // Check getAlign(). - EXPECT_EQ(GO->getAlign(), LLVMGO->getAlign()); - // Check setAlignment(). - auto OrigMaybeAlign = GO->getAlign(); - auto NewMaybeAlign = MaybeAlign(128); - EXPECT_NE(NewMaybeAlign, OrigMaybeAlign); - GO->setAlignment(NewMaybeAlign); - EXPECT_EQ(GO->getAlign(), NewMaybeAlign); - GO->setAlignment(OrigMaybeAlign); - EXPECT_EQ(GO->getAlign(), OrigMaybeAlign); - // Check getGlobalObjectSubClassData(). - EXPECT_EQ(GO->getGlobalObjectSubClassData(), - LLVMGO->getGlobalObjectSubClassData()); - // Check setGlobalObjectSubClassData(). - auto OrigGOSCD = GO->getGlobalObjectSubClassData(); - auto NewGOSCD = 1u; - EXPECT_NE(NewGOSCD, OrigGOSCD); - GO->setGlobalObjectSubClassData(NewGOSCD); - EXPECT_EQ(GO->getGlobalObjectSubClassData(), NewGOSCD); - GO->setGlobalObjectSubClassData(OrigGOSCD); - EXPECT_EQ(GO->getGlobalObjectSubClassData(), OrigGOSCD); // Check hasSection(). EXPECT_EQ(GO->hasSection(), LLVMGO->hasSection()); // Check getSection(). @@ -1284,6 +1261,16 @@ define void @foo() { EXPECT_EQ(GV0->getCodeModelRaw(), LLVMGV0->getCodeModelRaw()); // Check getCodeModel(). EXPECT_EQ(GV0->getCodeModel(), LLVMGV0->getCodeModel()); + // Check getAlign(). + EXPECT_EQ(GV0->getAlign(), LLVMGV0->getAlign()); + // Check setAlignment(). + auto OrigMaybeAlign = GV0->getAlign(); + auto NewMaybeAlign = MaybeAlign(128); + EXPECT_NE(NewMaybeAlign, OrigMaybeAlign); + GV0->setAlignment(NewMaybeAlign); + EXPECT_EQ(GV0->getAlign(), NewMaybeAlign); + GV0->setAlignment(OrigMaybeAlign); + EXPECT_EQ(GV0->getAlign(), OrigMaybeAlign); } TEST_F(SandboxIRTest, GlobalAlias) { @@ -1855,6 +1842,17 @@ bb1: )IR"); } #endif // NDEBUG + + // Check getAlign(). + EXPECT_EQ(F0->getAlign(), F0->getAlign()); + // Check setAlignment(). + auto OrigMaybeAlign = F0->getAlign(); + auto NewMaybeAlign = MaybeAlign(128); + EXPECT_NE(NewMaybeAlign, OrigMaybeAlign); + F0->setAlignment(NewMaybeAlign); + EXPECT_EQ(F0->getAlign(), NewMaybeAlign); + F0->setAlignment(OrigMaybeAlign); + EXPECT_EQ(F0->getAlign(), OrigMaybeAlign); } TEST_F(SandboxIRTest, Module) {