[llvm] r374889 - [Alignment][NFC] Value::getPointerAlignment returns MaybeAlign

Guillaume Chatelet via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 15 06:58:22 PDT 2019


Author: gchatelet
Date: Tue Oct 15 06:58:22 2019
New Revision: 374889

URL: http://llvm.org/viewvc/llvm-project?rev=374889&view=rev
Log:
[Alignment][NFC] Value::getPointerAlignment returns MaybeAlign

Summary:
This is patch is part of a series to introduce an Alignment type.
See this thread for context: http://lists.llvm.org/pipermail/llvm-dev/2019-July/133851.html
See this patch for the introduction of the type: https://reviews.llvm.org/D64790

Reviewers: courbet, jdoerfert

Subscribers: hiraditya, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D68398

Modified:
    llvm/trunk/include/llvm/IR/Value.h
    llvm/trunk/lib/Analysis/Loads.cpp
    llvm/trunk/lib/Analysis/ValueTracking.cpp
    llvm/trunk/lib/IR/ConstantFold.cpp
    llvm/trunk/lib/IR/Value.cpp
    llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.td
    llvm/trunk/lib/Transforms/IPO/Attributor.cpp
    llvm/trunk/unittests/IR/FunctionTest.cpp

Modified: llvm/trunk/include/llvm/IR/Value.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Value.h?rev=374889&r1=374888&r2=374889&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Value.h (original)
+++ llvm/trunk/include/llvm/IR/Value.h Tue Oct 15 06:58:22 2019
@@ -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.
   ///

Modified: llvm/trunk/lib/Analysis/Loads.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/Loads.cpp?rev=374889&r1=374888&r2=374889&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/Loads.cpp (original)
+++ llvm/trunk/lib/Analysis/Loads.cpp Tue Oct 15 06:58:22 2019
@@ -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 isDereferenceableAndAlignedP
       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.

Modified: llvm/trunk/lib/Analysis/ValueTracking.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ValueTracking.cpp?rev=374889&r1=374888&r2=374889&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ValueTracking.cpp (original)
+++ llvm/trunk/lib/Analysis/ValueTracking.cpp Tue Oct 15 06:58:22 2019
@@ -1721,9 +1721,9 @@ void computeKnownBits(const Value *V, Kn
 
   // 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.

Modified: llvm/trunk/lib/IR/ConstantFold.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/ConstantFold.cpp?rev=374889&r1=374888&r2=374889&view=diff
==============================================================================
--- llvm/trunk/lib/IR/ConstantFold.cpp (original)
+++ llvm/trunk/lib/IR/ConstantFold.cpp Tue Oct 15 06:58:22 2019
@@ -1122,7 +1122,7 @@ Constant *llvm::ConstantFoldBinaryInstru
             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::ConstantFoldBinaryInstru
             // 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.

Modified: llvm/trunk/lib/IR/Value.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Value.cpp?rev=374889&r1=374888&r2=374889&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Value.cpp (original)
+++ llvm/trunk/lib/IR/Value.cpp Tue Oct 15 06:58:22 2019
@@ -671,22 +671,21 @@ uint64_t Value::getPointerDereferenceabl
   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(cons
           // 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,

Modified: llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.td?rev=374889&r1=374888&r2=374889&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.td (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.td Tue Oct 15 06:58:22 2019
@@ -2203,8 +2203,8 @@ def : InstAlias<"prfm $Rt, [$Rn]", (PRFM
 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;

Modified: llvm/trunk/lib/Transforms/IPO/Attributor.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/Attributor.cpp?rev=374889&r1=374888&r2=374889&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/Attributor.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/Attributor.cpp Tue Oct 15 06:58:22 2019
@@ -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.

Modified: llvm/trunk/unittests/IR/FunctionTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/IR/FunctionTest.cpp?rev=374889&r1=374888&r2=374889&view=diff
==============================================================================
--- llvm/trunk/unittests/IR/FunctionTest.cpp (original)
+++ llvm/trunk/unittests/IR/FunctionTest.cpp Tue Oct 15 06:58:22 2019
@@ -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




More information about the llvm-commits mailing list