diff options
-rw-r--r-- | llvm/include/llvm/IR/Value.h | 3 | ||||
-rw-r--r-- | llvm/lib/Analysis/Loads.cpp | 31 | ||||
-rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/IR/ConstantFold.cpp | 14 | ||||
-rw-r--r-- | llvm/lib/IR/Value.cpp | 46 | ||||
-rw-r--r-- | llvm/lib/Target/AArch64/AArch64InstrInfo.td | 4 | ||||
-rw-r--r-- | llvm/lib/Transforms/IPO/Attributor.cpp | 3 | ||||
-rw-r--r-- | llvm/unittests/IR/FunctionTest.cpp | 28 |
8 files changed, 69 insertions, 64 deletions
diff --git a/llvm/include/llvm/IR/Value.h b/llvm/include/llvm/IR/Value.h index 58502907f0e..f2c4b3b3f20 100644 --- a/llvm/include/llvm/IR/Value.h +++ b/llvm/include/llvm/IR/Value.h @@ -17,6 +17,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/iterator_range.h" #include "llvm/IR/Use.h" +#include "llvm/Support/Alignment.h" #include "llvm/Support/CBindingWrapping.h" #include "llvm/Support/Casting.h" #include <cassert> @@ -631,7 +632,7 @@ public: /// /// Returns an alignment which is either specified explicitly, e.g. via /// align attribute of a function argument, or guaranteed by DataLayout. - unsigned getPointerAlignment(const DataLayout &DL) const; + MaybeAlign getPointerAlignment(const DataLayout &DL) const; /// Translate PHI node to its predecessor from the given basic block. /// diff --git a/llvm/lib/Analysis/Loads.cpp b/llvm/lib/Analysis/Loads.cpp index f689a17cb28..a4fd49920ad 100644 --- a/llvm/lib/Analysis/Loads.cpp +++ b/llvm/lib/Analysis/Loads.cpp @@ -27,21 +27,24 @@ using namespace llvm; -static bool isAligned(const Value *Base, const APInt &Offset, unsigned Align, - const DataLayout &DL) { - APInt BaseAlign(Offset.getBitWidth(), Base->getPointerAlignment(DL)); +static MaybeAlign getBaseAlign(const Value *Base, const DataLayout &DL) { + if (const MaybeAlign PA = Base->getPointerAlignment(DL)) + return *PA; + Type *const Ty = Base->getType()->getPointerElementType(); + if (!Ty->isSized()) + return None; + return Align(DL.getABITypeAlignment(Ty)); +} - if (!BaseAlign) { - Type *Ty = Base->getType()->getPointerElementType(); - if (!Ty->isSized()) - return false; - BaseAlign = DL.getABITypeAlignment(Ty); +static bool isAligned(const Value *Base, const APInt &Offset, Align Alignment, + const DataLayout &DL) { + if (MaybeAlign BA = getBaseAlign(Base, DL)) { + const APInt APBaseAlign(Offset.getBitWidth(), BA->value()); + const APInt APAlign(Offset.getBitWidth(), Alignment.value()); + assert(APAlign.isPowerOf2() && "must be a power of 2!"); + return APBaseAlign.uge(APAlign) && !(Offset & (APAlign - 1)); } - - APInt Alignment(Offset.getBitWidth(), Align); - - assert(Alignment.isPowerOf2() && "must be a power of 2!"); - return BaseAlign.uge(Alignment) && !(Offset & (Alignment-1)); + return false; } /// Test if V is always a pointer to allocated and suitably aligned memory for @@ -73,7 +76,7 @@ static bool isDereferenceableAndAlignedPointer( Type *Ty = V->getType(); assert(Ty->isSized() && "must be sized"); APInt Offset(DL.getTypeStoreSizeInBits(Ty), 0); - return isAligned(V, Offset, Align, DL); + return isAligned(V, Offset, llvm::Align(Align), DL); } // For GEPs, determine if the indexing lands within the allocated object. diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index aaebba00527..c62ec353b83 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -1721,9 +1721,9 @@ void computeKnownBits(const Value *V, KnownBits &Known, unsigned Depth, // Aligned pointers have trailing zeros - refine Known.Zero set if (V->getType()->isPointerTy()) { - unsigned Align = V->getPointerAlignment(Q.DL); + const MaybeAlign Align = V->getPointerAlignment(Q.DL); if (Align) - Known.Zero.setLowBits(countTrailingZeros(Align)); + Known.Zero.setLowBits(countTrailingZeros(Align->value())); } // computeKnownBitsFromAssume strictly refines Known. diff --git a/llvm/lib/IR/ConstantFold.cpp b/llvm/lib/IR/ConstantFold.cpp index b60b4507a99..71fa795ec29 100644 --- a/llvm/lib/IR/ConstantFold.cpp +++ b/llvm/lib/IR/ConstantFold.cpp @@ -1122,7 +1122,7 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, Constant *C1, isa<GlobalValue>(CE1->getOperand(0))) { GlobalValue *GV = cast<GlobalValue>(CE1->getOperand(0)); - unsigned GVAlign; + MaybeAlign GVAlign; if (Module *TheModule = GV->getParent()) { GVAlign = GV->getPointerAlignment(TheModule->getDataLayout()); @@ -1136,19 +1136,19 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, Constant *C1, // increased code size (see https://reviews.llvm.org/D55115) // FIXME: This code should be deleted once existing targets have // appropriate defaults - if (GVAlign == 0U && isa<Function>(GV)) - GVAlign = 4U; + if (!GVAlign && isa<Function>(GV)) + GVAlign = Align(4); } else if (isa<Function>(GV)) { // Without a datalayout we have to assume the worst case: that the // function pointer isn't aligned at all. - GVAlign = 0U; + GVAlign = llvm::None; } else { - GVAlign = GV->getAlignment(); + GVAlign = MaybeAlign(GV->getAlignment()); } - if (GVAlign > 1) { + if (GVAlign && *GVAlign > 1) { unsigned DstWidth = CI2->getType()->getBitWidth(); - unsigned SrcWidth = std::min(DstWidth, Log2_32(GVAlign)); + unsigned SrcWidth = std::min(DstWidth, Log2(*GVAlign)); APInt BitsNotSet(APInt::getLowBitsSet(DstWidth, SrcWidth)); // If checking bits we know are clear, return zero. diff --git a/llvm/lib/IR/Value.cpp b/llvm/lib/IR/Value.cpp index c44d4b4f2bc..3c8a5b53669 100644 --- a/llvm/lib/IR/Value.cpp +++ b/llvm/lib/IR/Value.cpp @@ -671,22 +671,21 @@ uint64_t Value::getPointerDereferenceableBytes(const DataLayout &DL, return DerefBytes; } -unsigned Value::getPointerAlignment(const DataLayout &DL) const { +MaybeAlign Value::getPointerAlignment(const DataLayout &DL) const { assert(getType()->isPointerTy() && "must be pointer"); if (auto *GO = dyn_cast<GlobalObject>(this)) { if (isa<Function>(GO)) { const MaybeAlign FunctionPtrAlign = DL.getFunctionPtrAlign(); - const unsigned Align = FunctionPtrAlign ? FunctionPtrAlign->value() : 0; switch (DL.getFunctionPtrAlignType()) { case DataLayout::FunctionPtrAlignType::Independent: - return Align; + return FunctionPtrAlign; case DataLayout::FunctionPtrAlignType::MultipleOfFunctionAlign: - return std::max(Align, GO->getAlignment()); + return std::max(FunctionPtrAlign, MaybeAlign(GO->getAlignment())); } llvm_unreachable("Unhandled FunctionPtrAlignType"); } - const unsigned Align = GO->getAlignment(); - if (!Align) { + const MaybeAlign Alignment(GO->getAlignment()); + if (!Alignment) { if (auto *GVar = dyn_cast<GlobalVariable>(GO)) { Type *ObjectType = GVar->getValueType(); if (ObjectType->isSized()) { @@ -694,42 +693,43 @@ unsigned Value::getPointerAlignment(const DataLayout &DL) const { // it the preferred alignment. Otherwise, we have to assume that it // may only have the minimum ABI alignment. if (GVar->isStrongDefinitionForLinker()) - return DL.getPreferredAlignment(GVar); + return MaybeAlign(DL.getPreferredAlignment(GVar)); else - return DL.getABITypeAlignment(ObjectType); + return Align(DL.getABITypeAlignment(ObjectType)); } } } - return Align; + return Alignment; } else if (const Argument *A = dyn_cast<Argument>(this)) { - const unsigned Align = A->getParamAlignment(); - if (!Align && A->hasStructRetAttr()) { + const MaybeAlign Alignment(A->getParamAlignment()); + if (!Alignment && A->hasStructRetAttr()) { // An sret parameter has at least the ABI alignment of the return type. Type *EltTy = cast<PointerType>(A->getType())->getElementType(); if (EltTy->isSized()) - return DL.getABITypeAlignment(EltTy); + return Align(DL.getABITypeAlignment(EltTy)); } - return Align; + return Alignment; } else if (const AllocaInst *AI = dyn_cast<AllocaInst>(this)) { - const unsigned Align = AI->getAlignment(); - if (!Align) { + const MaybeAlign Alignment(AI->getAlignment()); + if (!Alignment) { Type *AllocatedType = AI->getAllocatedType(); if (AllocatedType->isSized()) - return DL.getPrefTypeAlignment(AllocatedType); + return MaybeAlign(DL.getPrefTypeAlignment(AllocatedType)); } - return Align; + return Alignment; } else if (const auto *Call = dyn_cast<CallBase>(this)) { - const unsigned Align = Call->getRetAlignment(); - if (!Align && Call->getCalledFunction()) - return Call->getCalledFunction()->getAttributes().getRetAlignment(); - return Align; + const MaybeAlign Alignment(Call->getRetAlignment()); + if (!Alignment && Call->getCalledFunction()) + return MaybeAlign( + Call->getCalledFunction()->getAttributes().getRetAlignment()); + return Alignment; } else if (const LoadInst *LI = dyn_cast<LoadInst>(this)) { if (MDNode *MD = LI->getMetadata(LLVMContext::MD_align)) { ConstantInt *CI = mdconst::extract<ConstantInt>(MD->getOperand(0)); - return CI->getLimitedValue(); + return MaybeAlign(CI->getLimitedValue()); } } - return 0; + return llvm::None; } const Value *Value::DoPHITranslation(const BasicBlock *CurBB, diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td index 661d089688b..6154528b6d4 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -2203,8 +2203,8 @@ def : InstAlias<"prfm $Rt, [$Rn]", (PRFMui prfop:$Rt, GPR64sp:$Rn, 0)>; def alignedglobal : PatLeaf<(iPTR iPTR:$label), [{ if (auto *G = dyn_cast<GlobalAddressSDNode>(N)) { const DataLayout &DL = MF->getDataLayout(); - unsigned Align = G->getGlobal()->getPointerAlignment(DL); - return Align >= 4 && G->getOffset() % 4 == 0; + MaybeAlign Align = G->getGlobal()->getPointerAlignment(DL); + return Align && *Align >= 4 && G->getOffset() % 4 == 0; } if (auto *C = dyn_cast<ConstantPoolSDNode>(N)) return C->getAlignment() >= 4 && C->getOffset() % 4 == 0; diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp index 73cf5ee4c9c..11a54bdb0a7 100644 --- a/llvm/lib/Transforms/IPO/Attributor.cpp +++ b/llvm/lib/Transforms/IPO/Attributor.cpp @@ -2770,7 +2770,8 @@ struct AAAlignFloating : AAAlignImpl { const auto &AA = A.getAAFor<AAAlign>(*this, IRPosition::value(V)); if (!Stripped && this == &AA) { // Use only IR information if we did not strip anything. - T.takeKnownMaximum(V.getPointerAlignment(DL)); + const MaybeAlign PA = V.getPointerAlignment(DL); + T.takeKnownMaximum(PA ? PA->value() : 0); T.indicatePessimisticFixpoint(); } else { // Use abstract attribute information. diff --git a/llvm/unittests/IR/FunctionTest.cpp b/llvm/unittests/IR/FunctionTest.cpp index 567304cac6b..c0744b08605 100644 --- a/llvm/unittests/IR/FunctionTest.cpp +++ b/llvm/unittests/IR/FunctionTest.cpp @@ -143,23 +143,23 @@ TEST(FunctionTest, GetPointerAlignment) { FunctionType *FuncType(FunctionType::get(VoidType, false)); std::unique_ptr<Function> Func(Function::Create( FuncType, GlobalValue::ExternalLinkage)); - EXPECT_EQ(0U, Func->getPointerAlignment(DataLayout(""))); - EXPECT_EQ(1U, Func->getPointerAlignment(DataLayout("Fi8"))); - EXPECT_EQ(1U, Func->getPointerAlignment(DataLayout("Fn8"))); - EXPECT_EQ(2U, Func->getPointerAlignment(DataLayout("Fi16"))); - EXPECT_EQ(2U, Func->getPointerAlignment(DataLayout("Fn16"))); - EXPECT_EQ(4U, Func->getPointerAlignment(DataLayout("Fi32"))); - EXPECT_EQ(4U, Func->getPointerAlignment(DataLayout("Fn32"))); + EXPECT_EQ(MaybeAlign(), Func->getPointerAlignment(DataLayout(""))); + EXPECT_EQ(Align(1), Func->getPointerAlignment(DataLayout("Fi8"))); + EXPECT_EQ(Align(1), Func->getPointerAlignment(DataLayout("Fn8"))); + EXPECT_EQ(Align(2), Func->getPointerAlignment(DataLayout("Fi16"))); + EXPECT_EQ(Align(2), Func->getPointerAlignment(DataLayout("Fn16"))); + EXPECT_EQ(Align(4), Func->getPointerAlignment(DataLayout("Fi32"))); + EXPECT_EQ(Align(4), Func->getPointerAlignment(DataLayout("Fn32"))); Func->setAlignment(Align(4)); - EXPECT_EQ(0U, Func->getPointerAlignment(DataLayout(""))); - EXPECT_EQ(1U, Func->getPointerAlignment(DataLayout("Fi8"))); - EXPECT_EQ(4U, Func->getPointerAlignment(DataLayout("Fn8"))); - EXPECT_EQ(2U, Func->getPointerAlignment(DataLayout("Fi16"))); - EXPECT_EQ(4U, Func->getPointerAlignment(DataLayout("Fn16"))); - EXPECT_EQ(4U, Func->getPointerAlignment(DataLayout("Fi32"))); - EXPECT_EQ(4U, Func->getPointerAlignment(DataLayout("Fn32"))); + EXPECT_EQ(MaybeAlign(), Func->getPointerAlignment(DataLayout(""))); + EXPECT_EQ(Align(1), Func->getPointerAlignment(DataLayout("Fi8"))); + EXPECT_EQ(Align(4), Func->getPointerAlignment(DataLayout("Fn8"))); + EXPECT_EQ(Align(2), Func->getPointerAlignment(DataLayout("Fi16"))); + EXPECT_EQ(Align(4), Func->getPointerAlignment(DataLayout("Fn16"))); + EXPECT_EQ(Align(4), Func->getPointerAlignment(DataLayout("Fi32"))); + EXPECT_EQ(Align(4), Func->getPointerAlignment(DataLayout("Fn32"))); } } // end namespace |