From 412f882ee0609da404126a768ece6e58d276898a Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Mon, 9 Feb 2015 03:35:35 +0000 Subject: [PATCH] Merging r228525: ------------------------------------------------------------------------ r228525 | bsteinbr | 2015-02-08 09:07:14 -0800 (Sun, 08 Feb 2015) | 14 lines Correctly combine alias.scope metadata by a union instead of intersecting Summary: The alias.scope metadata represents sets of things an instruction might alias with. When generically combining the metadata from two instructions the result must be the union of the original sets, because the new instruction might alias with anything any of the original instructions aliased with. Reviewers: hfinkel Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D7490 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_36@228561 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/IR/Metadata.h | 1 + lib/Analysis/TypeBasedAliasAnalysis.cpp | 4 ++-- lib/IR/Metadata.cpp | 22 +++++++++++++++++ lib/Transforms/Utils/Local.cpp | 2 ++ lib/Transforms/Vectorize/SLPVectorizer.cpp | 2 ++ .../Util/combine-alias-scope-metadata.ll | 24 +++++++++++++++++++ 6 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 test/Transforms/Util/combine-alias-scope-metadata.ll diff --git a/include/llvm/IR/Metadata.h b/include/llvm/IR/Metadata.h index 3bf6d38d311..27a5d6f8004 100644 --- a/include/llvm/IR/Metadata.h +++ b/include/llvm/IR/Metadata.h @@ -693,6 +693,7 @@ public: static AAMDNodes getMostGenericAA(const AAMDNodes &A, const AAMDNodes &B); static MDNode *getMostGenericFPMath(MDNode *A, MDNode *B); static MDNode *getMostGenericRange(MDNode *A, MDNode *B); + static MDNode *getMostGenericAliasScope(MDNode *A, MDNode *B); }; /// \brief Uniquable metadata node. diff --git a/lib/Analysis/TypeBasedAliasAnalysis.cpp b/lib/Analysis/TypeBasedAliasAnalysis.cpp index 085ce920139..ff8955870cb 100644 --- a/lib/Analysis/TypeBasedAliasAnalysis.cpp +++ b/lib/Analysis/TypeBasedAliasAnalysis.cpp @@ -623,8 +623,8 @@ void Instruction::getAAMetadata(AAMDNodes &N, bool Merge) const { N.TBAA = getMetadata(LLVMContext::MD_tbaa); if (Merge) - N.Scope = - MDNode::intersect(N.Scope, getMetadata(LLVMContext::MD_alias_scope)); + N.Scope = MDNode::getMostGenericAliasScope( + N.Scope, getMetadata(LLVMContext::MD_alias_scope)); else N.Scope = getMetadata(LLVMContext::MD_alias_scope); diff --git a/lib/IR/Metadata.cpp b/lib/IR/Metadata.cpp index 2c6b332dc8e..63e5730f954 100644 --- a/lib/IR/Metadata.cpp +++ b/lib/IR/Metadata.cpp @@ -826,6 +826,28 @@ MDNode *MDNode::intersect(MDNode *A, MDNode *B) { return getOrSelfReference(A->getContext(), MDs); } +MDNode *MDNode::getMostGenericAliasScope(MDNode *A, MDNode *B) { + if (!A || !B) + return nullptr; + + SmallVector MDs(B->op_begin(), B->op_end()); + for (unsigned i = 0, ie = A->getNumOperands(); i != ie; ++i) { + Metadata *MD = A->getOperand(i); + bool insert = true; + for (unsigned j = 0, je = B->getNumOperands(); j != je; ++j) + if (MD == B->getOperand(j)) { + insert = false; + break; + } + if (insert) + MDs.push_back(MD); + } + + // FIXME: This preserves long-standing behaviour, but is it really the right + // behaviour? Or was that an unintended side-effect of node uniquing? + return getOrSelfReference(A->getContext(), MDs); +} + MDNode *MDNode::getMostGenericFPMath(MDNode *A, MDNode *B) { if (!A || !B) return nullptr; diff --git a/lib/Transforms/Utils/Local.cpp b/lib/Transforms/Utils/Local.cpp index 08a4b3f3b73..2a84d7e0c48 100644 --- a/lib/Transforms/Utils/Local.cpp +++ b/lib/Transforms/Utils/Local.cpp @@ -1328,6 +1328,8 @@ void llvm::combineMetadata(Instruction *K, const Instruction *J, ArrayRefsetMetadata(Kind, MDNode::getMostGenericTBAA(JMD, KMD)); break; case LLVMContext::MD_alias_scope: + K->setMetadata(Kind, MDNode::getMostGenericAliasScope(JMD, KMD)); + break; case LLVMContext::MD_noalias: K->setMetadata(Kind, MDNode::intersect(JMD, KMD)); break; diff --git a/lib/Transforms/Vectorize/SLPVectorizer.cpp b/lib/Transforms/Vectorize/SLPVectorizer.cpp index 4834782ecc1..2213031ecdb 100644 --- a/lib/Transforms/Vectorize/SLPVectorizer.cpp +++ b/lib/Transforms/Vectorize/SLPVectorizer.cpp @@ -208,6 +208,8 @@ static Instruction *propagateMetadata(Instruction *I, ArrayRef VL) { MD = MDNode::getMostGenericTBAA(MD, IMD); break; case LLVMContext::MD_alias_scope: + MD = MDNode::getMostGenericAliasScope(MD, IMD); + break; case LLVMContext::MD_noalias: MD = MDNode::intersect(MD, IMD); break; diff --git a/test/Transforms/Util/combine-alias-scope-metadata.ll b/test/Transforms/Util/combine-alias-scope-metadata.ll new file mode 100644 index 00000000000..fd0a3d5c5b9 --- /dev/null +++ b/test/Transforms/Util/combine-alias-scope-metadata.ll @@ -0,0 +1,24 @@ +; RUN: opt < %s -S -basicaa -memcpyopt | FileCheck %s +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +define void @test(i8* noalias dereferenceable(1) %in, i8* noalias dereferenceable(1) %out) { + %tmp = alloca i8 + %tmp2 = alloca i8 +; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %out, i8* %in, i64 1, i32 8, i1 false) + call void @llvm.memcpy.p0i8.p0i8.i64(i8* %tmp, i8* %in, i64 1, i32 8, i1 false), !alias.scope !4 + call void @llvm.memcpy.p0i8.p0i8.i64(i8* %tmp2, i8* %tmp, i64 1, i32 8, i1 false), !alias.scope !5 + + call void @llvm.memcpy.p0i8.p0i8.i64(i8* %out, i8* %tmp2, i64 1, i32 8, i1 false), !noalias !6 + + ret void +} + +declare void @llvm.memcpy.p0i8.p0i8.i64(i8*, i8*, i64, i32, i1) + +!0 = !{!0} +!1 = distinct !{!1, !0, !"in"} +!2 = distinct !{!2, !0, !"tmp"} +!3 = distinct !{!3, !0, !"tmp2"} +!4 = distinct !{!1, !2} +!5 = distinct !{!2, !3} +!6 = distinct !{!1, !2} -- 2.50.1