diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp --- a/llvm/lib/IR/Function.cpp +++ b/llvm/lib/IR/Function.cpp @@ -775,10 +775,16 @@ /// indicating that extra care must be taken to ensure a unique name. static std::string getMangledTypeStr(Type *Ty, bool &HasUnnamedType) { std::string Result; - if (PointerType* PTyp = dyn_cast(Ty)) { - Result += "p" + utostr(PTyp->getAddressSpace()) + - getMangledTypeStr(PTyp->getElementType(), HasUnnamedType); - } else if (ArrayType* ATyp = dyn_cast(Ty)) { + if (PointerType *PTyp = dyn_cast(Ty)) { + // Opaque pointer doesn't have pointee type information, so we just mangle + // address space for opaque pointer. + if (PTyp->isOpaque()) { + Result += "op" + utostr(PTyp->getAddressSpace()); + } else { + Result += "p" + utostr(PTyp->getAddressSpace()) + + getMangledTypeStr(PTyp->getElementType(), HasUnnamedType); + } + } else if (ArrayType *ATyp = dyn_cast(Ty)) { Result += "a" + utostr(ATyp->getNumElements()) + getMangledTypeStr(ATyp->getElementType(), HasUnnamedType); } else if (StructType *STyp = dyn_cast(Ty)) { @@ -803,7 +809,7 @@ Result += "vararg"; // Ensure nested function types are distinguishable. Result += "f"; - } else if (VectorType* VTy = dyn_cast(Ty)) { + } else if (VectorType *VTy = dyn_cast(Ty)) { ElementCount EC = VTy->getElementCount(); if (EC.isScalable()) Result += "nx"; diff --git a/llvm/test/Verifier/opaque-ptr.ll b/llvm/test/Verifier/opaque-ptr.ll --- a/llvm/test/Verifier/opaque-ptr.ll +++ b/llvm/test/Verifier/opaque-ptr.ll @@ -23,3 +23,13 @@ %b = atomicrmw add ptr %a, i32 %i acquire ret void } + +; CHECK: @opaque_mangle +define void @opaque_mangle(ptr %a) { + call void @llvm.lifetime.start.op(i64 8, ptr %a) + call void @llvm.lifetime.end.op(i64 8, ptr %a) + ret void +} + +declare void @llvm.lifetime.start.op(i64, ptr nocapture) +declare void @llvm.lifetime.end.op(i64, ptr nocapture)