mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-04 20:20:54 +00:00
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
This commit is contained in:
parent
bfd6c1c016
commit
6e4aa1e481
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user