diff --git a/llvm/include/llvm/IR/IRBuilder.h b/llvm/include/llvm/IR/IRBuilder.h --- a/llvm/include/llvm/IR/IRBuilder.h +++ b/llvm/include/llvm/IR/IRBuilder.h @@ -569,20 +569,40 @@ /// specified, it will be added to the instruction. Likewise with alias.scope /// and noalias tags. CallInst *CreateElementUnorderedAtomicMemCpy( - Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, - uint64_t Size, uint32_t ElementSize, MDNode *TBAATag = nullptr, + Value *Dst, Align DstAlign, Value *Src, Align SrcAlign, Value *Size, + uint32_t ElementSize, MDNode *TBAATag = nullptr, MDNode *TBAAStructTag = nullptr, MDNode *ScopeTag = nullptr, - MDNode *NoAliasTag = nullptr) { + MDNode *NoAliasTag = nullptr); + + /// FIXME: Remove this function once transition to Align is over. + /// Use the version that takes Align instead of this one. + LLVM_ATTRIBUTE_DEPRECATED(CallInst *CreateElementUnorderedAtomicMemCpy( + 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), + "Use the version that takes Align instead") { return CreateElementUnorderedAtomicMemCpy( - Dst, DstAlign, Src, SrcAlign, getInt64(Size), ElementSize, TBAATag, - TBAAStructTag, ScopeTag, NoAliasTag); + Dst, Align(DstAlign), Src, Align(SrcAlign), getInt64(Size), ElementSize, + TBAATag, TBAAStructTag, ScopeTag, NoAliasTag); } - CallInst *CreateElementUnorderedAtomicMemCpy( - 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); + /// FIXME: Remove this function once transition to Align is over. + /// Use the version that takes Align instead of this one. + LLVM_ATTRIBUTE_DEPRECATED(CallInst *CreateElementUnorderedAtomicMemCpy( + 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), + "Use the version that takes Align instead") { + return CreateElementUnorderedAtomicMemCpy( + Dst, Align(DstAlign), Src, Align(SrcAlign), Size, ElementSize, TBAATag, + TBAAStructTag, ScopeTag, NoAliasTag); + } /// Create and insert a memmove between the specified /// pointers. diff --git a/llvm/lib/IR/IRBuilder.cpp b/llvm/lib/IR/IRBuilder.cpp --- a/llvm/lib/IR/IRBuilder.cpp +++ b/llvm/lib/IR/IRBuilder.cpp @@ -201,7 +201,7 @@ } CallInst *IRBuilderBase::CreateElementUnorderedAtomicMemCpy( - Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, Value *Size, + Value *Dst, Align DstAlign, Value *Src, Align SrcAlign, Value *Size, uint32_t ElementSize, MDNode *TBAATag, MDNode *TBAAStructTag, MDNode *ScopeTag, MDNode *NoAliasTag) { assert(DstAlign >= ElementSize && diff --git a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp --- a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp +++ b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp @@ -1089,8 +1089,11 @@ else { // We cannot allow unaligned ops for unordered load/store, so reject // anything where the alignment isn't at least the element size. - unsigned Align = std::min(SI->getAlignment(), LI->getAlignment()); - if (Align < StoreSize) + const MaybeAlign StoreAlign = SI->getAlign(); + const MaybeAlign LoadAlign = LI->getAlign(); + if (StoreAlign == None || LoadAlign == None) + return false; + if (*StoreAlign < StoreSize || *LoadAlign < StoreSize) return false; // If the element.atomic memcpy is not lowered into explicit @@ -1104,8 +1107,8 @@ // 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, SI->getAlignment(), LoadBasePtr, LI->getAlignment(), - NumBytes, StoreSize); + StoreBasePtr, *StoreAlign, LoadBasePtr, *LoadAlign, NumBytes, + StoreSize); } NewCall->setDebugLoc(SI->getDebugLoc());