diff --git a/llvm/lib/IR/Module.cpp b/llvm/lib/IR/Module.cpp index 30b5e48652b28..e19336efd1c8a 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; } } diff --git a/llvm/unittests/IR/ModuleTest.cpp b/llvm/unittests/IR/ModuleTest.cpp index 36c356730d27a..30eda738020d0 100644 --- a/llvm/unittests/IR/ModuleTest.cpp +++ b/llvm/unittests/IR/ModuleTest.cpp @@ -103,6 +103,36 @@ TEST(ModuleTest, setModuleFlagInt) { EXPECT_EQ(Val2, A2->getZExtValue()); } +TEST(ModuleTest, setModuleFlagTwoMod) { + LLVMContext Context; + Module MA("MA", Context); + Module MB("MB", Context); + StringRef Key = "Key"; + uint32_t Val1 = 1; + uint32_t Val2 = 2; + + // Set a flag to MA + EXPECT_EQ(nullptr, MA.getModuleFlag(Key)); + MA.setModuleFlag(Module::ModFlagBehavior::Error, Key, Val1); + auto A1 = mdconst::extract_or_null(MA.getModuleFlag(Key)); + EXPECT_EQ(Val1, A1->getZExtValue()); + + // Set a flag to MB + EXPECT_EQ(nullptr, MB.getModuleFlag(Key)); + MB.setModuleFlag(Module::ModFlagBehavior::Error, Key, Val1); + auto B1 = mdconst::extract_or_null(MB.getModuleFlag(Key)); + EXPECT_EQ(Val1, B1->getZExtValue()); + + // Change the flag of MA + MA.setModuleFlag(Module::ModFlagBehavior::Error, Key, Val2); + auto A2 = mdconst::extract_or_null(MA.getModuleFlag(Key)); + EXPECT_EQ(Val2, A2->getZExtValue()); + + // MB should keep the original flag value + auto B2 = mdconst::extract_or_null(MB.getModuleFlag(Key)); + EXPECT_EQ(Val1, B2->getZExtValue()); +} + const char *IRString = R"IR( !llvm.module.flags = !{!0}