diff options
author | Artur Pilipenko <apilipenko@azulsystems.com> | 2016-06-24 15:10:29 +0000 |
---|---|---|
committer | Artur Pilipenko <apilipenko@azulsystems.com> | 2016-06-24 15:10:29 +0000 |
commit | 140d9e6906892dc07774e1598a17c8836f2b9381 (patch) | |
tree | f4d0e487058bf8ee0dbef8fee16428a8236da99d /unittests | |
parent | 2630656dc9b27283cfb72b89d9f25e4768d6bd74 (diff) |
Remangle intrinsics names when types are renamed
This is a resubmittion of previously reverted rL273568.
This is a fix for the problem mentioned in "LTO and intrinsics mangling" llvm-dev mail thread:
http://lists.llvm.org/pipermail/llvm-dev/2016-April/098387.html
Reviewers: mehdi_amini, reames
Differential Revision: http://reviews.llvm.org/D19373
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@273686 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'unittests')
-rw-r--r-- | unittests/Linker/LinkModulesTest.cpp | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/unittests/Linker/LinkModulesTest.cpp b/unittests/Linker/LinkModulesTest.cpp index 10a89f39869..92c483278be 100644 --- a/unittests/Linker/LinkModulesTest.cpp +++ b/unittests/Linker/LinkModulesTest.cpp @@ -306,4 +306,58 @@ TEST_F(LinkModuleTest, MoveDistinctMDs) { EXPECT_EQ(M3, M4->getOperand(0)); } +TEST_F(LinkModuleTest, RemangleIntrinsics) { + LLVMContext C; + SMDiagnostic Err; + + // We load two modules inside the same context C. In both modules there is a + // "struct.rtx_def" type. In the module loaded the second (Bar) this type will + // be renamed to "struct.rtx_def.0". Check that the intrinsics which have this + // type in the signature are properly remangled. + const char *FooStr = + "%struct.rtx_def = type { i16 }\n" + "define void @foo(%struct.rtx_def* %a, i8 %b, i32 %c) {\n" + " call void @llvm.memset.p0struct.rtx_def.i32(%struct.rtx_def* %a, i8 %b, i32 %c, i32 4, i1 true)\n" + " ret void\n" + "}\n" + "declare void @llvm.memset.p0struct.rtx_def.i32(%struct.rtx_def*, i8, i32, i32, i1)\n"; + + const char *BarStr = + "%struct.rtx_def = type { i16 }\n" + "define void @bar(%struct.rtx_def* %a, i8 %b, i32 %c) {\n" + " call void @llvm.memset.p0struct.rtx_def.i32(%struct.rtx_def* %a, i8 %b, i32 %c, i32 4, i1 true)\n" + " ret void\n" + "}\n" + "declare void @llvm.memset.p0struct.rtx_def.i32(%struct.rtx_def*, i8, i32, i32, i1)\n"; + + std::unique_ptr<Module> Foo = parseAssemblyString(FooStr, Err, C); + assert(Foo); + ASSERT_TRUE(Foo.get()); + // Foo is loaded first, so the type and the intrinsic have theis original + // names. + ASSERT_TRUE(Foo->getFunction("llvm.memset.p0struct.rtx_def.i32")); + ASSERT_FALSE(Foo->getFunction("llvm.memset.p0struct.rtx_def.0.i32")); + + std::unique_ptr<Module> Bar = parseAssemblyString(BarStr, Err, C); + assert(Bar); + ASSERT_TRUE(Bar.get()); + // Bar is loaded after Foo, so the type is renamed to struct.rtx_def.0. Check + // that the intrinsic is also renamed. + ASSERT_FALSE(Bar->getFunction("llvm.memset.p0struct.rtx_def.i32")); + ASSERT_TRUE(Bar->getFunction("llvm.memset.p0struct.rtx_def.0.i32")); + + // Link two modules together. + auto Dst = llvm::make_unique<Module>("Linked", C); + ASSERT_TRUE(Dst.get()); + Ctx.setDiagnosticHandler(expectNoDiags); + bool Failed = Linker::linkModules(*Foo, std::move(Bar)); + ASSERT_FALSE(Failed); + + // "struct.rtx_def" from Foo and "struct.rtx_def.0" from Bar are isomorphic + // types, so they must be uniquified by linker. Check that they use the same + // intrinsic definition. + Function *F = Foo->getFunction("llvm.memset.p0struct.rtx_def.i32"); + ASSERT_EQ(F->getNumUses(), (unsigned)2); +} + } // end anonymous namespace |