diff options
author | Chris Lattner <sabre@nondot.org> | 2010-04-28 20:16:12 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2010-04-28 20:16:12 +0000 |
commit | f3f325b82fdeeb055225d98d9076214108d35f39 (patch) | |
tree | cfe498a4e9eecd4aedec2c8b527a5ba1c653bc9d | |
parent | 59b3655564bb6717b296ca9e71f13bf7db45b590 (diff) | |
download | llvm-f3f325b82fdeeb055225d98d9076214108d35f39.tar.gz llvm-f3f325b82fdeeb055225d98d9076214108d35f39.tar.bz2 llvm-f3f325b82fdeeb055225d98d9076214108d35f39.tar.xz |
fix PR6112 - When globalopt (or any other pass) does RAUW(@G, %G),
metadata references in non-function-local MDNodes should drop to
null.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@102519 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/VMCore/Metadata.cpp | 17 | ||||
-rw-r--r-- | test/Transforms/GlobalOpt/metadata.ll | 19 |
2 files changed, 34 insertions, 2 deletions
diff --git a/lib/VMCore/Metadata.cpp b/lib/VMCore/Metadata.cpp index 72de0321c3..092fe00a53 100644 --- a/lib/VMCore/Metadata.cpp +++ b/lib/VMCore/Metadata.cpp @@ -178,6 +178,13 @@ void MDNode::destroy() { free(this); } +/// isFunctionLocalValue - Return true if this is a value that would require a +/// function-local MDNode. +static bool isFunctionLocalValue(Value *V) { + return isa<Instruction>(V) || isa<Argument>(V) || isa<BasicBlock>(V) || + (isa<MDNode>(V) && cast<MDNode>(V)->isFunctionLocal()); +} + MDNode *MDNode::getMDNode(LLVMContext &Context, Value *const *Vals, unsigned NumVals, FunctionLocalness FL, bool Insert) { @@ -188,8 +195,7 @@ MDNode *MDNode::getMDNode(LLVMContext &Context, Value *const *Vals, for (unsigned i = 0; i != NumVals; ++i) { Value *V = Vals[i]; if (!V) continue; - if (isa<Instruction>(V) || isa<Argument>(V) || isa<BasicBlock>(V) || - (isa<MDNode>(V) && cast<MDNode>(V)->isFunctionLocal())) { + if (isFunctionLocalValue(V)) { isFunctionLocal = true; break; } @@ -262,6 +268,13 @@ void MDNode::setIsNotUniqued() { void MDNode::replaceOperand(MDNodeOperand *Op, Value *To) { Value *From = *Op; + // If is possible that someone did GV->RAUW(inst), replacing a global variable + // with an instruction or some other function-local object. If this is a + // non-function-local MDNode, it can't point to a function-local object. + // Handle this case by implicitly dropping the MDNode reference to null. + if (!isFunctionLocal() && To && isFunctionLocalValue(To)) + To = 0; + if (From == To) return; diff --git a/test/Transforms/GlobalOpt/metadata.ll b/test/Transforms/GlobalOpt/metadata.ll new file mode 100644 index 0000000000..55b2ff90ee --- /dev/null +++ b/test/Transforms/GlobalOpt/metadata.ll @@ -0,0 +1,19 @@ +; RUN: opt -S -globalopt metadata.ll | FileCheck %s + +; PR6112 - When globalopt does RAUW(@G, %G), the metadata reference should drop +; to null. +@G = internal global i8** null + +define i32 @main(i32 %argc, i8** %argv) { +; CHECK: @main +; CHECK: %G = alloca + store i8** %argv, i8*** @G + ret i32 0 +} + +!named = !{!0} + +; CHECK: !0 = metadata !{null} +!0 = metadata !{i8*** @G} + + |