diff --git a/llvm/include/llvm/IR/Metadata.h b/llvm/include/llvm/IR/Metadata.h index db1f44fea3b45..6f23ac44dee96 100644 --- a/llvm/include/llvm/IR/Metadata.h +++ b/llvm/include/llvm/IR/Metadata.h @@ -844,6 +844,11 @@ struct AAMDNodes { /// together. Different from `merge`, where different locations should /// overlap each other, `concat` puts non-overlapping locations together. AAMDNodes concat(const AAMDNodes &Other) const; + + /// Create a new AAMDNode for accessing \p AccessSize bytes of this AAMDNode. + /// If his AAMDNode has !tbaa.struct and \p AccessSize matches the size of the + /// field at offset 0, get the TBAA tag describing the accessed field. + AAMDNodes adjustForAccess(unsigned AccessSize); }; // Specialize DenseMapInfo for AAMDNodes. diff --git a/llvm/lib/Analysis/TypeBasedAliasAnalysis.cpp b/llvm/lib/Analysis/TypeBasedAliasAnalysis.cpp index e4dc1a867f6f0..d05f42552e81d 100644 --- a/llvm/lib/Analysis/TypeBasedAliasAnalysis.cpp +++ b/llvm/lib/Analysis/TypeBasedAliasAnalysis.cpp @@ -817,3 +817,18 @@ MDNode *AAMDNodes::extendToTBAA(MDNode *MD, ssize_t Len) { ConstantAsMetadata::get(ConstantInt::get(PreviousSize->getType(), Len)); return MDNode::get(MD->getContext(), NextNodes); } + +AAMDNodes AAMDNodes::adjustForAccess(unsigned AccessSize) { + AAMDNodes New = *this; + MDNode *M = New.TBAAStruct; + New.TBAAStruct = nullptr; + if (M && M->getNumOperands() == 3 && M->getOperand(0) && + mdconst::hasa(M->getOperand(0)) && + mdconst::extract(M->getOperand(0))->isZero() && + M->getOperand(1) && mdconst::hasa(M->getOperand(1)) && + mdconst::extract(M->getOperand(1))->getValue() == + AccessSize && + M->getOperand(2) && isa(M->getOperand(2))) + New.TBAA = cast(M->getOperand(2)); + return New; +} diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp index ed5d44757fbeb..56d1259e95519 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -172,20 +172,7 @@ Instruction *InstCombinerImpl::SimplifyAnyMemTransfer(AnyMemTransferInst *MI) { // If the memcpy has metadata describing the members, see if we can get the // TBAA tag describing our copy. - AAMDNodes AACopyMD = MI->getAAMetadata(); - - if (MDNode *M = AACopyMD.TBAAStruct) { - AACopyMD.TBAAStruct = nullptr; - if (M->getNumOperands() == 3 && M->getOperand(0) && - mdconst::hasa(M->getOperand(0)) && - mdconst::extract(M->getOperand(0))->isZero() && - M->getOperand(1) && - mdconst::hasa(M->getOperand(1)) && - mdconst::extract(M->getOperand(1))->getValue() == - Size && - M->getOperand(2) && isa(M->getOperand(2))) - AACopyMD.TBAA = cast(M->getOperand(2)); - } + AAMDNodes AACopyMD = MI->getAAMetadata().adjustForAccess(Size); Value *Src = MI->getArgOperand(1); Value *Dest = MI->getArgOperand(0);