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) {
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;
}
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;
--- /dev/null
+; 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}
+
+