summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Neilson <dneilson@azul.com>2017-11-10 19:38:12 +0000
committerDaniel Neilson <dneilson@azul.com>2017-11-10 19:38:12 +0000
commit6e4aa1e48138182685431c76184dfc36e620aea2 (patch)
tree613f8dbbdb29e69bfaa89e665a87397d95809ee2
parentbfd6c1c016c0fcb49144b0c16e6dd0a4387d52b9 (diff)
downloadbcm5719-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.h20
-rw-r--r--llvm/lib/IR/IRBuilder.cpp13
-rw-r--r--llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp14
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());
OpenPOWER on IntegriCloud