diff options
author | Artur Pilipenko <apilipenko@azulsystems.com> | 2016-06-23 15:25:09 +0000 |
---|---|---|
committer | Artur Pilipenko <apilipenko@azulsystems.com> | 2016-06-23 15:25:09 +0000 |
commit | f0c9f813796cd0cf210ba21833c5cfbaa7d65399 (patch) | |
tree | 53582157dfa1bdee5e81241e84dc0fe3bcb7735a /llvm/unittests/Linker/LinkModulesTest.cpp | |
parent | b1a2b5a708ec9993ec6c7a5eb2068864b109a43c (diff) | |
download | bcm5719-llvm-f0c9f813796cd0cf210ba21833c5cfbaa7d65399.tar.gz bcm5719-llvm-f0c9f813796cd0cf210ba21833c5cfbaa7d65399.zip |
Remangle intrinsics names when types are renamed
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
llvm-svn: 273568
Diffstat (limited to 'llvm/unittests/Linker/LinkModulesTest.cpp')
-rw-r--r-- | llvm/unittests/Linker/LinkModulesTest.cpp | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/llvm/unittests/Linker/LinkModulesTest.cpp b/llvm/unittests/Linker/LinkModulesTest.cpp index 10a89f39869..92c483278be 100644 --- a/llvm/unittests/Linker/LinkModulesTest.cpp +++ b/llvm/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 |