diff options
author | Daniel Neilson <dneilson@azul.com> | 2017-11-10 19:38:12 +0000 |
---|---|---|
committer | Daniel Neilson <dneilson@azul.com> | 2017-11-10 19:38:12 +0000 |
commit | 6e4aa1e48138182685431c76184dfc36e620aea2 (patch) | |
tree | 613f8dbbdb29e69bfaa89e665a87397d95809ee2 | |
parent | bfd6c1c016c0fcb49144b0c16e6dd0a4387d52b9 (diff) | |
download | bcm5719-llvm-6e4aa1e48138182685431c76184dfc36e620aea2.tar.gz bcm5719-llvm-6e4aa1e48138182685431c76184dfc36e620aea2.zip |
Expand IRBuilder interface for atomic memcpy to require pointer alignments. (NFC)
Summary:
The specification of the @llvm.memcpy.element.unordered.atomic intrinsic requires
that the pointer arguments have alignments of at least the element size. The existing
IRBuilder interface to create a call to this intrinsic does not allow for providing
the alignment of these pointer args. Having an interface that makes it easy to
construct invalid intrinsic calls doesn't seem sensible, so this patch simply
adds the requirement that one provide the argument alignments when using IRBuilder
to create atomic memcpy calls.
llvm-svn: 317918
-rw-r--r-- | llvm/include/llvm/IR/IRBuilder.h | 20 | ||||
-rw-r--r-- | llvm/lib/IR/IRBuilder.cpp | 13 | ||||
-rw-r--r-- | llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp | 14 |
3 files changed, 28 insertions, 19 deletions
diff --git a/llvm/include/llvm/IR/IRBuilder.h b/llvm/include/llvm/IR/IRBuilder.h index 5344a93efb3..fed2cbfa864 100644 --- a/llvm/include/llvm/IR/IRBuilder.h +++ b/llvm/include/llvm/IR/IRBuilder.h @@ -438,22 +438,26 @@ public: /// \brief Create and insert an element unordered-atomic memcpy between the /// specified pointers. /// + /// DstAlign/SrcAlign are the alignments of the Dst/Src pointers, respectively. + /// /// If the pointers aren't i8*, they will be converted. If a TBAA tag is /// specified, it will be added to the instruction. Likewise with alias.scope /// and noalias tags. CallInst *CreateElementUnorderedAtomicMemCpy( - Value *Dst, Value *Src, uint64_t Size, uint32_t ElementSize, - MDNode *TBAATag = nullptr, MDNode *TBAAStructTag = nullptr, - MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) { + Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, + uint64_t Size, uint32_t ElementSize, MDNode *TBAATag = nullptr, + MDNode *TBAAStructTag = nullptr, MDNode *ScopeTag = nullptr, + MDNode *NoAliasTag = nullptr) { return CreateElementUnorderedAtomicMemCpy( - Dst, Src, getInt64(Size), ElementSize, TBAATag, TBAAStructTag, ScopeTag, - NoAliasTag); + Dst, DstAlign, Src, SrcAlign, getInt64(Size), ElementSize, TBAATag, + TBAAStructTag, ScopeTag, NoAliasTag); } CallInst *CreateElementUnorderedAtomicMemCpy( - Value *Dst, Value *Src, Value *Size, uint32_t ElementSize, - MDNode *TBAATag = nullptr, MDNode *TBAAStructTag = nullptr, - MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr); + Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, Value *Size, + uint32_t ElementSize, MDNode *TBAATag = nullptr, + MDNode *TBAAStructTag = nullptr, MDNode *ScopeTag = nullptr, + MDNode *NoAliasTag = nullptr); /// \brief Create and insert a memmove between the specified /// pointers. diff --git a/llvm/lib/IR/IRBuilder.cpp b/llvm/lib/IR/IRBuilder.cpp index 89338c8b849..027c0255bce 100644 --- a/llvm/lib/IR/IRBuilder.cpp +++ b/llvm/lib/IR/IRBuilder.cpp @@ -135,8 +135,13 @@ CreateMemCpy(Value *Dst, Value *Src, Value *Size, unsigned Align, } CallInst *IRBuilderBase::CreateElementUnorderedAtomicMemCpy( - Value *Dst, Value *Src, Value *Size, uint32_t ElementSize, MDNode *TBAATag, - MDNode *TBAAStructTag, MDNode *ScopeTag, MDNode *NoAliasTag) { + Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, Value *Size, + uint32_t ElementSize, MDNode *TBAATag, MDNode *TBAAStructTag, + MDNode *ScopeTag, MDNode *NoAliasTag) { + assert(DstAlign >= ElementSize && + "Pointer alignment must be at least element size"); + assert(SrcAlign >= ElementSize && + "Pointer alignment must be at least element size"); Dst = getCastedInt8PtrValue(Dst); Src = getCastedInt8PtrValue(Src); @@ -148,6 +153,10 @@ CallInst *IRBuilderBase::CreateElementUnorderedAtomicMemCpy( CallInst *CI = createCallHelper(TheFn, Ops, this); + // Set the alignment of the pointer args. + CI->addParamAttr(0, Attribute::getWithAlignment(CI->getContext(), DstAlign)); + CI->addParamAttr(1, Attribute::getWithAlignment(CI->getContext(), SrcAlign)); + // Set the TBAA info if present. if (TBAATag) CI->setMetadata(LLVMContext::MD_tbaa, TBAATag); diff --git a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp index eb5f3cc47ce..7234b97f64d 100644 --- a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp +++ b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp @@ -1063,16 +1063,12 @@ bool LoopIdiomRecognize::processLoopStoreOfLoopLoad(StoreInst *SI, if (StoreSize > TTI->getAtomicMemIntrinsicMaxElementSize()) return false; + // Create the call. + // Note that unordered atomic loads/stores are *required* by the spec to + // have an alignment but non-atomic loads/stores may not. NewCall = Builder.CreateElementUnorderedAtomicMemCpy( - StoreBasePtr, LoadBasePtr, NumBytes, StoreSize); - - // Propagate alignment info onto the pointer args. Note that unordered - // atomic loads/stores are *required* by the spec to have an alignment - // but non-atomic loads/stores may not. - NewCall->addParamAttr(0, Attribute::getWithAlignment(NewCall->getContext(), - SI->getAlignment())); - NewCall->addParamAttr(1, Attribute::getWithAlignment(NewCall->getContext(), - LI->getAlignment())); + StoreBasePtr, SI->getAlignment(), LoadBasePtr, LI->getAlignment(), + NumBytes, StoreSize); } NewCall->setDebugLoc(SI->getDebugLoc()); |