Index: lib/IR/Function.cpp =================================================================== --- lib/IR/Function.cpp +++ lib/IR/Function.cpp @@ -462,13 +462,16 @@ /// Returns a stable mangling for the type specified for use in the name /// mangling scheme used by 'any' types in intrinsic signatures. The mangling /// of named types is simply their name. Manglings for unnamed types consist -/// of a prefix ('p' for pointers, 'a' for arrays, 'f_' for functions) -/// combined with the mangling of their component types. A vararg function -/// type will have a suffix of 'vararg'. Since function types can contain -/// other function types, we close a function type mangling with suffix 'f' -/// which can't be confused with it's prefix. This ensures we don't have -/// collisions between two unrelated function types. Otherwise, you might -/// parse ffXX as f(fXX) or f(fX)X. (X is a placeholder for any other type.) +/// of a prefix ('p' for pointers, 'a' for arrays, 's_' or 'ls_' for structs, +/// and 'f_' for functions) combined with the mangling of their component types. +/// A vararg function type will have a suffix of 'vararg'. +/// +/// Since function/struct types can contain other function/struct types, we +/// close a function/struct type mangling with suffix 'f'/'s' which can't be +/// confused with its prefix. This ensures we don't have collisions between two +/// unrelated function/struct types. Otherwise, you might parse ffXX as f(fXX) +/// or f(fX)X. (X is a placeholder for any other type.) +/// /// Manglings of integers, floats, and vectors ('i', 'f', and 'v' prefix in most /// cases) fall back to the MVT codepath, where they could be mangled to /// 'x86mmx', for example; matching on derived types is not sufficient to mangle @@ -482,8 +485,14 @@ 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(); + if (STyp->isLiteral()) { + Result += "ls_"; + for (Type* Ty : STyp->elements()) + Result += getMangledTypeStr(Ty); + } else + Result += "s_" + STyp->getName().str(); + // Ensure nested struct types 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++) Index: test/CodeGen/Generic/overloaded-intrinsic-name.ll =================================================================== --- test/CodeGen/Generic/overloaded-intrinsic-name.ll +++ test/CodeGen/Generic/overloaded-intrinsic-name.ll @@ -44,7 +44,7 @@ ; struct define %struct.test* @test_struct(%struct.test* %v) gc "statepoint-example" { %tok = call i32 (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(i32 %tok, i32 7, i32 7) + %v-new = call %struct.test* @llvm.experimental.gc.relocate.p0struct.tests(i32 %tok, i32 7, i32 7) ret %struct.test* %v-new } @@ -54,4 +54,4 @@ declare float* @llvm.experimental.gc.relocate.p0f32(i32, i32, i32) declare [3 x i32]* @llvm.experimental.gc.relocate.p0a3i32(i32, i32, i32) declare <3 x i32>* @llvm.experimental.gc.relocate.p0v3i32(i32, i32, i32) -declare %struct.test* @llvm.experimental.gc.relocate.p0struct.test(i32, i32, i32) +declare %struct.test* @llvm.experimental.gc.relocate.p0struct.tests(i32, i32, i32)