From 6ed814a823258fa357c25bd71e76eb688fbbff79 Mon Sep 17 00:00:00 2001 From: Andrew Savonichev Date: Fri, 24 Oct 2025 09:43:10 +0900 Subject: [IR] Fix Module::setModuleFlag for uniqued metadata (#164580) `Module::setModuleFlag` is supposed to change a single module. However, when an `MDNode` has the same value in more than one module in the same `LLVMContext`, such `MDNode` is shared (uniqued) across all of them. Therefore `MDNode::replaceOperandWith` changes all modules that share the same `MDNode`. This used to cause problems for #86212, where a module is marked as "upgraded" via a module flag. When this flag is shared across multiple modules, all of them are marked, yet some may not have been processed at all. After the patch we now construct a new `MDNode` and replace the old one. --- llvm/lib/IR/Module.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'llvm/lib/IR/Module.cpp') diff --git a/llvm/lib/IR/Module.cpp b/llvm/lib/IR/Module.cpp index 30b5e48..e19336e 100644 --- a/llvm/lib/IR/Module.cpp +++ b/llvm/lib/IR/Module.cpp @@ -403,9 +403,14 @@ void Module::setModuleFlag(ModFlagBehavior Behavior, StringRef Key, Metadata *Val) { NamedMDNode *ModFlags = getOrInsertModuleFlagsMetadata(); // Replace the flag if it already exists. - for (MDNode *Flag : ModFlags->operands()) { + for (unsigned i = 0; i < ModFlags->getNumOperands(); ++i) { + MDNode *Flag = ModFlags->getOperand(i); if (cast(Flag->getOperand(1))->getString() == Key) { - Flag->replaceOperandWith(2, Val); + Type *Int32Ty = Type::getInt32Ty(Context); + Metadata *Ops[3] = { + ConstantAsMetadata::get(ConstantInt::get(Int32Ty, Behavior)), + MDString::get(Context, Key), Val}; + ModFlags->setOperand(i, MDNode::get(Context, Ops)); return; } } -- cgit v1.1