Index: llvm/trunk/lib/IR/AutoUpgrade.cpp =================================================================== --- llvm/trunk/lib/IR/AutoUpgrade.cpp +++ llvm/trunk/lib/IR/AutoUpgrade.cpp @@ -489,6 +489,12 @@ break; } } + // Remangle our intrinsic since we upgrade the mangling + auto Result = llvm::Intrinsic::remangleIntrinsicFunction(F); + if (Result != None) { + NewFn = Result.getValue(); + return true; + } // This may not belong here. This function is effectively being overloaded // to both detect an intrinsic which needs upgrading, and to provide the @@ -1821,8 +1827,17 @@ CI->setName(Name + ".old"); switch (NewFn->getIntrinsicID()) { - default: - llvm_unreachable("Unknown function for CallInst upgrade."); + default: { + // Handle generic mangling change, but nothing else + assert( + (CI->getCalledFunction()->getName() != NewFn->getName()) && + "Unknown function for CallInst upgrade and isn't just a name change"); + SmallVector Args(CI->arg_operands().begin(), + CI->arg_operands().end()); + CI->replaceAllUsesWith(Builder.CreateCall(NewFn, Args)); + CI->eraseFromParent(); + return; + } case Intrinsic::arm_neon_vld1: case Intrinsic::arm_neon_vld2: Index: llvm/trunk/lib/IR/Function.cpp =================================================================== --- llvm/trunk/lib/IR/Function.cpp +++ llvm/trunk/lib/IR/Function.cpp @@ -505,10 +505,18 @@ } else if (ArrayType* ATyp = dyn_cast(Ty)) { Result += "a" + llvm::utostr(ATyp->getNumElements()) + getMangledTypeStr(ATyp->getElementType()); - } else if (StructType* STyp = dyn_cast(Ty)) { - assert(!STyp->isLiteral() && "TODO: implement literal types"); - Result += STyp->getName(); - } else if (FunctionType* FT = dyn_cast(Ty)) { + } else if (StructType *STyp = dyn_cast(Ty)) { + if (!STyp->isLiteral()) { + Result += "s_"; + Result += STyp->getName(); + } else { + Result += "sl_"; + for (auto Elem : STyp->elements()) + Result += getMangledTypeStr(Elem); + } + // Ensure nested structs are distinguishable. + Result += "s"; + } else if (FunctionType *FT = dyn_cast(Ty)) { Result += "f_" + getMangledTypeStr(FT->getReturnType()); for (size_t i = 0; i < FT->getNumParams(); i++) Result += getMangledTypeStr(FT->getParamType(i)); Index: llvm/trunk/test/CodeGen/Generic/overloaded-intrinsic-name.ll =================================================================== --- llvm/trunk/test/CodeGen/Generic/overloaded-intrinsic-name.ll +++ llvm/trunk/test/CodeGen/Generic/overloaded-intrinsic-name.ll @@ -44,14 +44,41 @@ ; struct define %struct.test* @test_struct(%struct.test* %v) gc "statepoint-example" { %tok = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, %struct.test* %v) - %v-new = call %struct.test* @llvm.experimental.gc.relocate.p0struct.test(token %tok, i32 7, i32 7) + %v-new = call %struct.test* @llvm.experimental.gc.relocate.p0s_struct.tests(token %tok, i32 7, i32 7) ret %struct.test* %v-new } +; literal struct with nested literal struct +define {i64, i64, {i64} }* @test_literal_struct({i64, i64, {i64}}* %v) gc "statepoint-example" { + %tok = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, {i64, i64, {i64}} *%v) + %v-new = call {i64, i64, {i64}}* @llvm.experimental.gc.relocate.p0sl_i64i64sl_i64ss.test(token %tok, i32 7, i32 7) + ret {i64, i64, {i64}}* %v-new +} +; struct with a horrible name, broken when structs were unprefixed +%i32 = type { i32 } + +define %i32* @test_i32_struct(%i32* %v) gc "statepoint-example" { +entry: + %tok = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, %i32* %v) + %v-new = call %i32* @llvm.experimental.gc.relocate.p0s_i32s(token %tok, i32 7, i32 7) + ret %i32* %v-new +} +; completely broken intrinsic naming due to needing remangling. Just use random naming to test + +define %i32* @test_broken_names(%i32* %v) gc "statepoint-example" { +entry: + %tok = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.deadbeef(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, %i32* %v) + %v-new = call %i32* @llvm.experimental.gc.relocate.beefdead(token %tok, i32 7, i32 7) + ret %i32* %v-new +} declare zeroext i1 @return_i1() declare token @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...) declare i32* @llvm.experimental.gc.relocate.p0i32(token, i32, i32) declare float* @llvm.experimental.gc.relocate.p0f32(token, i32, i32) declare [3 x i32]* @llvm.experimental.gc.relocate.p0a3i32(token, i32, i32) declare <3 x i32>* @llvm.experimental.gc.relocate.p0v3i32(token, i32, i32) -declare %struct.test* @llvm.experimental.gc.relocate.p0struct.test(token, i32, i32) +declare %struct.test* @llvm.experimental.gc.relocate.p0s_struct.tests(token, i32, i32) +declare {i64, i64, {i64}}* @llvm.experimental.gc.relocate.p0sl_i64i64sl_i64ss.test(token, i32, i32) +declare %i32* @llvm.experimental.gc.relocate.p0s_i32s(token, i32, i32) +declare %i32* @llvm.experimental.gc.relocate.beefdead(token, i32, i32) +declare token @llvm.experimental.gc.statepoint.deadbeef(i64, i32, i1 ()*, i32, i32, ...) Index: llvm/trunk/test/LTO/X86/remangle_intrinsics_tbaa.ll =================================================================== --- llvm/trunk/test/LTO/X86/remangle_intrinsics_tbaa.ll +++ llvm/trunk/test/LTO/X86/remangle_intrinsics_tbaa.ll @@ -3,7 +3,7 @@ ; RUN: llvm-link -disable-lazy-loading %t2.bc %t1.bc -S | FileCheck %s ; Verify that we correctly rename the intrinsic and don't crash -; CHECK: @llvm.masked.store.v4p0some_named_struct.0.p0v4p0some_named_struct.0 +; CHECK: @llvm.masked.store.v4p0s_some_named_struct.0s.p0v4p0s_some_named_struct.0s target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-apple-macosx10.11.0" Index: llvm/trunk/unittests/Linker/LinkModulesTest.cpp =================================================================== --- llvm/trunk/unittests/Linker/LinkModulesTest.cpp +++ llvm/trunk/unittests/Linker/LinkModulesTest.cpp @@ -317,34 +317,34 @@ 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" + " call void @llvm.memset.p0s_struct.rtx_defs.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"; + "declare void @llvm.memset.p0s_struct.rtx_defs.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" + " call void @llvm.memset.p0s_struct.rtx_defs.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"; + "declare void @llvm.memset.p0s_struct.rtx_defs.i32(%struct.rtx_def*, i8, i32, i32, i1)\n"; std::unique_ptr 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")); + ASSERT_TRUE(Foo->getFunction("llvm.memset.p0s_struct.rtx_defs.i32")); + ASSERT_FALSE(Foo->getFunction("llvm.memset.p0s_struct.rtx_defs.0.i32")); std::unique_ptr 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")); + ASSERT_FALSE(Bar->getFunction("llvm.memset.p0s_struct.rtx_defs.i32")); + ASSERT_TRUE(Bar->getFunction("llvm.memset.p0s_struct.rtx_def.0s.i32")); // Link two modules together. auto Dst = llvm::make_unique("Linked", C); @@ -356,7 +356,7 @@ // "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"); + Function *F = Foo->getFunction("llvm.memset.p0s_struct.rtx_defs.i32"); ASSERT_EQ(F->getNumUses(), (unsigned)2); }