diff --git a/llvm/include/llvm/IR/IntrinsicInst.h b/llvm/include/llvm/IR/IntrinsicInst.h --- a/llvm/include/llvm/IR/IntrinsicInst.h +++ b/llvm/include/llvm/IR/IntrinsicInst.h @@ -838,6 +838,7 @@ /// FIXME: Remove this function once transition to Align is over. /// Use getDestAlign() instead. + LLVM_DEPRECATED("Use getDestAlign() instead", "getDestAlign") unsigned getDestAlignment() const { if (auto MA = getParamAlign(ARG_DEST)) return MA->value(); @@ -898,6 +899,7 @@ /// FIXME: Remove this function once transition to Align is over. /// Use getSourceAlign() instead. + LLVM_DEPRECATED("Use getSourceAlign() instead", "getSourceAlign") unsigned getSourceAlignment() const { if (auto MA = BaseCL::getParamAlign(ARG_SOURCE)) return MA->value(); diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -5091,19 +5091,6 @@ case Intrinsic::memmove: case Intrinsic::memset: case Intrinsic::memset_inline: { - const auto *MI = cast(&Call); - auto IsValidAlignment = [&](unsigned Alignment) -> bool { - return Alignment == 0 || isPowerOf2_32(Alignment); - }; - Check(IsValidAlignment(MI->getDestAlignment()), - "alignment of arg 0 of memory intrinsic must be 0 or a power of 2", - Call); - if (const auto *MTI = dyn_cast(MI)) { - Check(IsValidAlignment(MTI->getSourceAlignment()), - "alignment of arg 1 of memory intrinsic must be 0 or a power of 2", - Call); - } - break; } case Intrinsic::memcpy_element_unordered_atomic: @@ -5119,15 +5106,13 @@ "must be a power of 2", Call); - auto IsValidAlignment = [&](uint64_t Alignment) { - return isPowerOf2_64(Alignment) && ElementSizeVal.ule(Alignment); + auto IsValidAlignment = [&](MaybeAlign Alignment) { + return Alignment && ElementSizeVal.ule(Alignment->value()); }; - uint64_t DstAlignment = AMI->getDestAlignment(); - Check(IsValidAlignment(DstAlignment), + Check(IsValidAlignment(AMI->getDestAlign()), "incorrect alignment of the destination argument", Call); if (const auto *AMT = dyn_cast(AMI)) { - uint64_t SrcAlignment = AMT->getSourceAlignment(); - Check(IsValidAlignment(SrcAlignment), + Check(IsValidAlignment(AMT->getSourceAlign()), "incorrect alignment of the source argument", Call); } break; diff --git a/llvm/lib/Target/AArch64/AArch64FastISel.cpp b/llvm/lib/Target/AArch64/AArch64FastISel.cpp --- a/llvm/lib/Target/AArch64/AArch64FastISel.cpp +++ b/llvm/lib/Target/AArch64/AArch64FastISel.cpp @@ -189,9 +189,9 @@ void addLoadStoreOperands(Address &Addr, const MachineInstrBuilder &MIB, MachineMemOperand::Flags Flags, unsigned ScaleFactor, MachineMemOperand *MMO); - bool isMemCpySmall(uint64_t Len, unsigned Alignment); + bool isMemCpySmall(uint64_t Len, MaybeAlign Alignment); bool tryEmitSmallMemCpy(Address Dest, Address Src, uint64_t Len, - unsigned Alignment); + MaybeAlign Alignment); bool foldXALUIntrinsic(AArch64CC::CondCode &CC, const Instruction *I, const Value *Cond); bool optimizeIntExtLoad(const Instruction *I, MVT RetVT, MVT SrcVT); @@ -3290,15 +3290,15 @@ return finishCall(CLI, RetVT, NumBytes); } -bool AArch64FastISel::isMemCpySmall(uint64_t Len, unsigned Alignment) { +bool AArch64FastISel::isMemCpySmall(uint64_t Len, MaybeAlign Alignment) { if (Alignment) - return Len / Alignment <= 4; + return Len / Alignment->value() <= 4; else return Len < 32; } bool AArch64FastISel::tryEmitSmallMemCpy(Address Dest, Address Src, - uint64_t Len, unsigned Alignment) { + uint64_t Len, MaybeAlign Alignment) { // Make sure we don't bloat code by inlining very large memcpy's. if (!isMemCpySmall(Len, Alignment)) return false; @@ -3309,7 +3309,7 @@ while (Len) { MVT VT; - if (!Alignment || Alignment >= 8) { + if (!Alignment || *Alignment >= 8) { if (Len >= 8) VT = MVT::i64; else if (Len >= 4) @@ -3320,10 +3320,11 @@ VT = MVT::i8; } } else { + assert(Alignment && "Alignment is set in this branch"); // Bound based on alignment. - if (Len >= 4 && Alignment == 4) + if (Len >= 4 && *Alignment == 4) VT = MVT::i32; - else if (Len >= 2 && Alignment == 2) + else if (Len >= 2 && *Alignment == 2) VT = MVT::i16; else { VT = MVT::i8; @@ -3498,8 +3499,10 @@ // Small memcpy's are common enough that we want to do them without a call // if possible. uint64_t Len = cast(MTI->getLength())->getZExtValue(); - unsigned Alignment = MinAlign(MTI->getDestAlignment(), - MTI->getSourceAlignment()); + MaybeAlign Alignment; + if (MTI->getDestAlign() || MTI->getSourceAlign()) + Alignment = std::min(MTI->getDestAlign().valueOrOne(), + MTI->getSourceAlign().valueOrOne()); if (isMemCpySmall(Len, Alignment)) { Address Dest, Src; if (!computeAddress(MTI->getRawDest(), Dest) || diff --git a/llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp b/llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp --- a/llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp @@ -1096,9 +1096,9 @@ continue; case Intrinsic::memset: { MemSetInst *MemSet = cast(Intr); - Builder.CreateMemSet( - MemSet->getRawDest(), MemSet->getValue(), MemSet->getLength(), - MaybeAlign(MemSet->getDestAlignment()), MemSet->isVolatile()); + Builder.CreateMemSet(MemSet->getRawDest(), MemSet->getValue(), + MemSet->getLength(), MemSet->getDestAlign(), + MemSet->isVolatile()); Intr->eraseFromParent(); continue; } diff --git a/llvm/lib/Target/ARM/ARMFastISel.cpp b/llvm/lib/Target/ARM/ARMFastISel.cpp --- a/llvm/lib/Target/ARM/ARMFastISel.cpp +++ b/llvm/lib/Target/ARM/ARMFastISel.cpp @@ -196,7 +196,7 @@ void ARMSimplifyAddress(Address &Addr, MVT VT, bool useAM3); bool ARMIsMemCpySmall(uint64_t Len); bool ARMTryEmitSmallMemCpy(Address Dest, Address Src, uint64_t Len, - unsigned Alignment); + MaybeAlign Alignment); unsigned ARMEmitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, bool isZExt); unsigned ARMMaterializeFP(const ConstantFP *CFP, MVT VT); unsigned ARMMaterializeInt(const Constant *C, MVT VT); @@ -2439,15 +2439,15 @@ return Len <= 16; } -bool ARMFastISel::ARMTryEmitSmallMemCpy(Address Dest, Address Src, - uint64_t Len, unsigned Alignment) { +bool ARMFastISel::ARMTryEmitSmallMemCpy(Address Dest, Address Src, uint64_t Len, + MaybeAlign Alignment) { // Make sure we don't bloat code by inlining very large memcpy's. if (!ARMIsMemCpySmall(Len)) return false; while (Len) { MVT VT; - if (!Alignment || Alignment >= 4) { + if (!Alignment || *Alignment >= 4) { if (Len >= 4) VT = MVT::i32; else if (Len >= 2) @@ -2457,8 +2457,9 @@ VT = MVT::i8; } } else { + assert(Alignment && "Alignment is set in this branch"); // Bound based on alignment. - if (Len >= 2 && Alignment == 2) + if (Len >= 2 && *Alignment == 2) VT = MVT::i16; else { VT = MVT::i8; @@ -2535,8 +2536,10 @@ if (!ARMComputeAddress(MTI.getRawDest(), Dest) || !ARMComputeAddress(MTI.getRawSource(), Src)) return false; - unsigned Alignment = MinAlign(MTI.getDestAlignment(), - MTI.getSourceAlignment()); + MaybeAlign Alignment; + if (MTI.getDestAlign() || MTI.getSourceAlign()) + Alignment = std::min(MTI.getDestAlign().valueOrOne(), + MTI.getSourceAlign().valueOrOne()); if (ARMTryEmitSmallMemCpy(Dest, Src, Len, Alignment)) return true; } diff --git a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp --- a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp +++ b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp @@ -1431,7 +1431,7 @@ IRBuilder<> Builder(MemCpy); Instruction *NewM = Builder.CreateMemSet(MemCpy->getRawDest(), MemSet->getOperand(1), - CopySize, MaybeAlign(MemCpy->getDestAlignment())); + CopySize, MemCpy->getDestAlign()); auto *LastDef = cast(MSSAU->getMemorySSA()->getMemoryAccess(MemCpy)); auto *NewAccess = MSSAU->createMemoryAccessAfter(NewM, LastDef, LastDef); @@ -1462,9 +1462,8 @@ if (Value *ByteVal = isBytewiseValue(GV->getInitializer(), M->getModule()->getDataLayout())) { IRBuilder<> Builder(M); - Instruction *NewM = - Builder.CreateMemSet(M->getRawDest(), ByteVal, M->getLength(), - MaybeAlign(M->getDestAlignment()), false); + Instruction *NewM = Builder.CreateMemSet( + M->getRawDest(), ByteVal, M->getLength(), M->getDestAlign(), false); auto *LastDef = cast(MSSAU->getMemorySSA()->getMemoryAccess(M)); auto *NewAccess =