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,8 @@ /// 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. 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 @@ -335,10 +335,16 @@ 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); + ; + } + for (unsigned i = 0; i < V->arg_size(); ++i) { + if (V->paramHasAttr(i, Attribute::AllocAlign)) { + return V->getOperand(i); + } } - return V->getOperand(FnData->AlignParam); + return nullptr; } /// When we're compiling N-bit code, and the user uses parameters that are