diff --git a/llvm/include/llvm/Analysis/MemoryBuiltins.h b/llvm/include/llvm/Analysis/MemoryBuiltins.h --- a/llvm/include/llvm/Analysis/MemoryBuiltins.h +++ b/llvm/include/llvm/Analysis/MemoryBuiltins.h @@ -100,7 +100,10 @@ /// insertion or speculative execution of allocation routines. bool isAllocRemovable(const CallBase *V, const TargetLibraryInfo *TLI); -/// Gets the alignment argument for an aligned_alloc-like function +/// Gets the alignment argument for an aligned_alloc-like function, using either +/// built-in knowledge based on fuction names/signatures or allocalign +/// attributes. Note: the Value returned may not indicate a valid alignment, per +/// the definition of the allocalign attribute. Value *getAllocAlignment(const CallBase *V, const TargetLibraryInfo *TLI); /// Return the size of the requested allocation. With a trivial mapper, this is diff --git a/llvm/lib/Analysis/MemoryBuiltins.cpp b/llvm/lib/Analysis/MemoryBuiltins.cpp --- a/llvm/lib/Analysis/MemoryBuiltins.cpp +++ b/llvm/lib/Analysis/MemoryBuiltins.cpp @@ -334,10 +334,15 @@ assert(isAllocationFn(V, TLI)); const Optional FnData = getAllocationData(V, AnyAlloc, TLI); - if (!FnData.hasValue() || FnData->AlignParam < 0) { - return nullptr; + if (FnData.hasValue() && FnData->AlignParam >= 0) { + return V->getOperand(FnData->AlignParam); + } + unsigned AllocAlignParam; + if (V->getAttributes().hasAttrSomewhere(Attribute::AllocAlign, + &AllocAlignParam)) { + return V->getOperand(AllocAlignParam-1); } - return V->getOperand(FnData->AlignParam); + return nullptr; } /// When we're compiling N-bit code, and the user uses parameters that are