Index: llvm/include/llvm-c/Core.h =================================================================== --- llvm/include/llvm-c/Core.h +++ llvm/include/llvm-c/Core.h @@ -2526,7 +2526,8 @@ const char *LLVMIntrinsicCopyOverloadedName(unsigned ID, LLVMTypeRef *ParamTypes, size_t ParamCount, - size_t *NameLength); + size_t *NameLength, + LLVMModuleRef Mod); /** * Obtain if the intrinsic identified by the given ID is overloaded. Index: llvm/include/llvm/IR/Intrinsics.h =================================================================== --- llvm/include/llvm/IR/Intrinsics.h +++ llvm/include/llvm/IR/Intrinsics.h @@ -55,21 +55,17 @@ /// version of getName if overloads are required. StringRef getName(ID id); - /// Return the LLVM name for an intrinsic, such as "llvm.ppc.altivec.lvx". - /// Note, this version of getName supports overloads, but not unnamed types. - /// It is less efficient than the StringRef version of this function. If no - /// overloads are required, it is safe to use this version, but better to use - /// the StringRef version. - std::string getName(ID Id, ArrayRef Tys); - - /// Return the LLVM name for an intrinsic, such as "llvm.ssa.copy.p0s_s.1". - /// Note, this version of getName supports overloads and unnamed types, but is - /// less efficient than the StringRef version of this function. If no + /// Return the LLVM name for an intrinsic, such as "llvm.ppc.altivec.lvx" or + /// "llvm.ssa.copy.p0s_s.1". Note, this version of getName supports overloads. + /// This is less efficient than the StringRef version of this function. If no /// overloads are required, it is safe to use this version, but better to use - /// the StringRef version. A function type FT can be provided to avoid - /// computing it. It is used (or computed) if one of the types is based on an - /// unnamed type. - std::string getName(ID Id, ArrayRef Tys, Module *M, FunctionType *FT); + /// the StringRef version.It is recommended to always provide M, as it is + /// mandatory to support overloads on unnamed types. If one of the types is + /// based on an unnamed type, a function type will be computed. Providing FT + /// will avoid this computation. Calling this as 'getName(Id, None, nullptr)' + /// returns the base name of the intrinsic. + std::string getName(ID Id, ArrayRef Tys, Module *M, + FunctionType *FT = nullptr); /// Return the function type for an intrinsic. FunctionType *getType(LLVMContext &Context, ID id, Index: llvm/lib/CodeGen/MachineOperand.cpp =================================================================== --- llvm/lib/CodeGen/MachineOperand.cpp +++ llvm/lib/CodeGen/MachineOperand.cpp @@ -927,7 +927,7 @@ case MachineOperand::MO_IntrinsicID: { Intrinsic::ID ID = getIntrinsicID(); if (ID < Intrinsic::num_intrinsics) - OS << "intrinsic(@" << Intrinsic::getName(ID, None) << ')'; + OS << "intrinsic(@" << Intrinsic::getName(ID, None, nullptr) << ')'; else if (IntrinsicInfo) OS << "intrinsic(@" << IntrinsicInfo->getName(ID) << ')'; else Index: llvm/lib/CodeGen/ReplaceWithVeclib.cpp =================================================================== --- llvm/lib/CodeGen/ReplaceWithVeclib.cpp +++ llvm/lib/CodeGen/ReplaceWithVeclib.cpp @@ -142,7 +142,7 @@ // converted to scalar above. std::string ScalarName; if (Intrinsic::isOverloaded(IntrinsicID)) { - ScalarName = Intrinsic::getName(IntrinsicID, ScalarTypes); + ScalarName = Intrinsic::getName(IntrinsicID, ScalarTypes, CI.getModule()); } else { ScalarName = Intrinsic::getName(IntrinsicID).str(); } Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp =================================================================== --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp @@ -145,7 +145,7 @@ unsigned OpNo = getOpcode() == ISD::INTRINSIC_WO_CHAIN ? 0 : 1; unsigned IID = cast(getOperand(OpNo))->getZExtValue(); if (IID < Intrinsic::num_intrinsics) - return Intrinsic::getName((Intrinsic::ID)IID, None); + return Intrinsic::getName((Intrinsic::ID)IID, None, nullptr); else if (!G) return "Unknown intrinsic"; else if (const TargetIntrinsicInfo *TII = G->getTarget().getIntrinsicInfo()) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp =================================================================== --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -3745,7 +3745,8 @@ unsigned iid = cast(N->getOperand(HasInputChain))->getZExtValue(); if (iid < Intrinsic::num_intrinsics) - Msg << "intrinsic %" << Intrinsic::getName((Intrinsic::ID)iid, None); + Msg << "intrinsic %" + << Intrinsic::getName((Intrinsic::ID)iid, None, nullptr); else if (const TargetIntrinsicInfo *TII = TM.getIntrinsicInfo()) Msg << "target intrinsic %" << TII->getName(iid); else Index: llvm/lib/IR/AutoUpgrade.cpp =================================================================== --- llvm/lib/IR/AutoUpgrade.cpp +++ llvm/lib/IR/AutoUpgrade.cpp @@ -773,7 +773,7 @@ Intrinsic::lifetime_start : Intrinsic::invariant_start; auto Args = F->getFunctionType()->params(); Type* ObjectPtr[1] = {Args[1]}; - if (F->getName() != Intrinsic::getName(ID, ObjectPtr)) { + if (F->getName() != Intrinsic::getName(ID, ObjectPtr, F->getParent())) { rename(F); NewFn = Intrinsic::getDeclaration(F->getParent(), ID, ObjectPtr); return true; @@ -787,7 +787,7 @@ auto Args = F->getFunctionType()->params(); Type* ObjectPtr[1] = {Args[IsLifetimeEnd ? 1 : 2]}; - if (F->getName() != Intrinsic::getName(ID, ObjectPtr)) { + if (F->getName() != Intrinsic::getName(ID, ObjectPtr, F->getParent())) { rename(F); NewFn = Intrinsic::getDeclaration(F->getParent(), ID, ObjectPtr); return true; @@ -809,7 +809,8 @@ case 'm': { if (Name.startswith("masked.load.")) { Type *Tys[] = { F->getReturnType(), F->arg_begin()->getType() }; - if (F->getName() != Intrinsic::getName(Intrinsic::masked_load, Tys)) { + if (F->getName() != + Intrinsic::getName(Intrinsic::masked_load, Tys, F->getParent())) { rename(F); NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::masked_load, @@ -820,7 +821,8 @@ if (Name.startswith("masked.store.")) { auto Args = F->getFunctionType()->params(); Type *Tys[] = { Args[0], Args[1] }; - if (F->getName() != Intrinsic::getName(Intrinsic::masked_store, Tys)) { + if (F->getName() != + Intrinsic::getName(Intrinsic::masked_store, Tys, F->getParent())) { rename(F); NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::masked_store, @@ -832,7 +834,8 @@ // to the new overload which includes an address space if (Name.startswith("masked.gather.")) { Type *Tys[] = {F->getReturnType(), F->arg_begin()->getType()}; - if (F->getName() != Intrinsic::getName(Intrinsic::masked_gather, Tys)) { + if (F->getName() != + Intrinsic::getName(Intrinsic::masked_gather, Tys, F->getParent())) { rename(F); NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::masked_gather, Tys); @@ -842,7 +845,8 @@ if (Name.startswith("masked.scatter.")) { auto Args = F->getFunctionType()->params(); Type *Tys[] = {Args[0], Args[1]}; - if (F->getName() != Intrinsic::getName(Intrinsic::masked_scatter, Tys)) { + if (F->getName() != + Intrinsic::getName(Intrinsic::masked_scatter, Tys, F->getParent())) { rename(F); NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::masked_scatter, Tys); @@ -923,7 +927,8 @@ if (Name.startswith("objectsize.")) { Type *Tys[2] = { F->getReturnType(), F->arg_begin()->getType() }; if (F->arg_size() == 2 || F->arg_size() == 3 || - F->getName() != Intrinsic::getName(Intrinsic::objectsize, Tys)) { + F->getName() != + Intrinsic::getName(Intrinsic::objectsize, Tys, F->getParent())) { rename(F); NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::objectsize, Tys); @@ -936,7 +941,8 @@ if (Name == "prefetch") { // Handle address space overloading. Type *Tys[] = {F->arg_begin()->getType()}; - if (F->getName() != Intrinsic::getName(Intrinsic::prefetch, Tys)) { + if (F->getName() != + Intrinsic::getName(Intrinsic::prefetch, Tys, F->getParent())) { rename(F); NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::prefetch, Tys); Index: llvm/lib/IR/Core.cpp =================================================================== --- llvm/lib/IR/Core.cpp +++ llvm/lib/IR/Core.cpp @@ -2413,10 +2413,11 @@ const char *LLVMIntrinsicCopyOverloadedName(unsigned ID, LLVMTypeRef *ParamTypes, size_t ParamCount, - size_t *NameLength) { + size_t *NameLength, + LLVMModuleRef Mod) { auto IID = llvm_map_to_intrinsic_id(ID); ArrayRef Tys(unwrap(ParamTypes), ParamCount); - auto Str = llvm::Intrinsic::getName(IID, Tys); + auto Str = llvm::Intrinsic::getName(IID, Tys, unwrap(Mod)); *NameLength = Str.length(); return strdup(Str.c_str()); } Index: llvm/lib/IR/Function.cpp =================================================================== --- llvm/lib/IR/Function.cpp +++ llvm/lib/IR/Function.cpp @@ -798,6 +798,8 @@ assert(Id < num_intrinsics && "Invalid intrinsic ID!"); assert((Tys.empty() || Intrinsic::isOverloaded(Id)) && "This version of getName is for overloaded intrinsics only"); + assert((M || !any_of(Tys, [](Type *T) { return isa(T); })) && + "Intrinsic overloading on pointer types need to proved a Module"); bool HasUnnamedType = false; std::string Result(IntrinsicNameTable[Id]); for (Type *Ty : Tys) { @@ -815,10 +817,6 @@ return Result; } -std::string Intrinsic::getName(ID Id, ArrayRef Tys) { - return getName(Id, Tys, nullptr, nullptr); -} - /// IIT_Info - These are enumerators that describe the entries returned by the /// getIntrinsicInfoTableEntries function. /// Index: llvm/lib/Transforms/Scalar/LowerMatrixIntrinsics.cpp =================================================================== --- llvm/lib/Transforms/Scalar/LowerMatrixIntrinsics.cpp +++ llvm/lib/Transforms/Scalar/LowerMatrixIntrinsics.cpp @@ -1631,7 +1631,7 @@ return; } IntrinsicInst *II = dyn_cast(CI); - write(StringRef(Intrinsic::getName(II->getIntrinsicID(), {})) + write(StringRef(Intrinsic::getName(II->getIntrinsicID(), None, nullptr)) .drop_front(StringRef("llvm.matrix.").size())); write("."); std::string Tmp; Index: llvm/test/Assembler/auto_upgrade_intrinsics.ll =================================================================== --- llvm/test/Assembler/auto_upgrade_intrinsics.ll +++ llvm/test/Assembler/auto_upgrade_intrinsics.ll @@ -2,15 +2,14 @@ ; RUN: llvm-as < %s | llvm-dis | FileCheck %s ; RUN: verify-uselistorder %s +%0 = type opaque; + declare i8 @llvm.ctlz.i8(i8) declare i16 @llvm.ctlz.i16(i16) declare i32 @llvm.ctlz.i32(i32) declare i42 @llvm.ctlz.i42(i42) ; Not a power-of-2 -declare i32 @llvm.objectsize.i32(i8*, i1) nounwind readonly - - define void @test.ctlz(i8 %a, i16 %b, i32 %c, i42 %d) { ; CHECK: @test.ctlz @@ -51,6 +50,7 @@ @a = private global [60 x i8] zeroinitializer, align 1 +declare i32 @llvm.objectsize.i32(i8*, i1) nounwind readonly define i32 @test.objectsize() { ; CHECK-LABEL: @test.objectsize( ; CHECK: @llvm.objectsize.i32.p0i8(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i1 false, i1 false, i1 false) @@ -66,6 +66,24 @@ ret i64 %s } +@u = private global [60 x %0*] zeroinitializer, align 1 + +declare i32 @llvm.objectsize.i32.unnamed(%0**, i1) nounwind readonly +define i32 @test.objectsize.unnamed() { +; CHECK-LABEL: @test.objectsize.unnamed( +; CHECK: @llvm.objectsize.i32.p0p0s_s.0(%0** getelementptr inbounds ([60 x %0*], [60 x %0*]* @u, i32 0, i32 0), i1 false, i1 false, i1 false) + %s = call i32 @llvm.objectsize.i32.unnamed(%0** getelementptr inbounds ([60 x %0*], [60 x %0*]* @u, i32 0, i32 0), i1 false) + ret i32 %s +} + +declare i64 @llvm.objectsize.i64.p0p0s_s.0(%0**, i1) nounwind readonly +define i64 @test.objectsize.unnamed.2() { +; CHECK-LABEL: @test.objectsize.unnamed.2( +; CHECK: @llvm.objectsize.i64.p0p0s_s.0(%0** getelementptr inbounds ([60 x %0*], [60 x %0*]* @u, i32 0, i32 0), i1 false, i1 false, i1 false) + %s = call i64 @llvm.objectsize.i64.p0p0s_s.0(%0** getelementptr inbounds ([60 x %0*], [60 x %0*]* @u, i32 0, i32 0), i1 false) + ret i64 %s +} + declare <2 x double> @llvm.masked.load.v2f64(<2 x double>* %ptrs, i32, <2 x i1> %mask, <2 x double> %src0) define <2 x double> @tests.masked.load(<2 x double>* %ptr, <2 x i1> %mask, <2 x double> %passthru) { @@ -116,6 +134,20 @@ ret void } +declare {}* @llvm.invariant.start.unnamed(i64, %0** nocapture) nounwind readonly +declare void @llvm.invariant.end.unnamed({}*, i64, %0** nocapture) nounwind + +define void @tests.invariant.start.end.unnamed() { + ; CHECK-LABEL: @tests.invariant.start.end.unnamed( + %a = alloca %0* + %i = call {}* @llvm.invariant.start.unnamed(i64 1, %0** %a) + ; CHECK: call {}* @llvm.invariant.start.p0p0s_s.0 + store %0* null, %0** %a + call void @llvm.invariant.end.unnamed({}* %i, i64 1, %0** %a) + ; CHECK: call void @llvm.invariant.end.p0p0s_s.0 + ret void +} + @__stack_chk_guard = external global i8* declare void @llvm.stackprotectorcheck(i8**) @@ -140,6 +172,20 @@ ret void } +declare void @llvm.lifetime.start.unnamed(i64, %0** nocapture) nounwind readonly +declare void @llvm.lifetime.end.unnamed(i64, %0** nocapture) nounwind + +define void @tests.lifetime.start.end.unnamed() { + ; CHECK-LABEL: @tests.lifetime.start.end.unnamed( + %a = alloca %0* + call void @llvm.lifetime.start.unnamed(i64 1, %0** %a) + ; CHECK: call void @llvm.lifetime.start.p0p0s_s.0(i64 1, %0** %a) + store %0* null, %0** %a + call void @llvm.lifetime.end.unnamed(i64 1, %0** %a) + ; CHECK: call void @llvm.lifetime.end.p0p0s_s.0(i64 1, %0** %a) + ret void +} + declare void @llvm.prefetch(i8*, i32, i32, i32) define void @test.prefetch(i8* %ptr) { ; CHECK-LABEL: @test.prefetch( @@ -156,10 +202,20 @@ ret void } +declare void @llvm.prefetch.unnamed(%0**, i32, i32, i32) +define void @test.prefetch.unnamed(%0** %ptr) { +; CHECK-LABEL: @test.prefetch.unnamed( +; CHECK: @llvm.prefetch.p0p0s_s.0(%0** %ptr, i32 0, i32 3, i32 2) + call void @llvm.prefetch.unnamed(%0** %ptr, i32 0, i32 3, i32 2) + ret void +} + ; This is part of @test.objectsize(), since llvm.objectsize declaration gets ; emitted at the end. ; CHECK: declare i32 @llvm.objectsize.i32.p0i8 - +; CHECK: declare i32 @llvm.objectsize.i32.p0p0s_s.0 ; CHECK: declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) ; CHECK: declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) +; CHECK: declare void @llvm.lifetime.start.p0p0s_s.0(i64 immarg, %0** nocapture) +; CHECK: declare void @llvm.lifetime.end.p0p0s_s.0(i64 immarg, %0** nocapture)