Index: lib/IR/ValueSymbolTable.cpp =================================================================== --- lib/IR/ValueSymbolTable.cpp +++ lib/IR/ValueSymbolTable.cpp @@ -13,7 +13,9 @@ #include "llvm/IR/ValueSymbolTable.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/Triple.h" #include "llvm/IR/GlobalValue.h" +#include "llvm/IR/Module.h" #include "llvm/IR/Type.h" #include "llvm/IR/Value.h" #include "llvm/Support/Casting.h" @@ -45,8 +47,16 @@ // Trim any suffix off and append the next number. UniqueName.resize(BaseSize); raw_svector_ostream S(UniqueName); - if (isa(V)) - S << "."; + if (auto *GV = dyn_cast(V)) { + const Module *M = GV->getParent(); + // On NVPTX we cannot use a dot because PTX only allows [A-Za-z0-9_$] for + // identifiers. Instead we use a dollar sign which wouldn't be legal for + // MSVC name mangling but is fine for PTX. + if (M && Triple(M->getTargetTriple()).isNVPTX()) + S << "$"; + else + S << "."; + } S << ++LastUnique; // Try insert the vmap entry with this suffix. Index: lib/Target/NVPTX/NVPTXAssignValidGlobalNames.cpp =================================================================== --- lib/Target/NVPTX/NVPTXAssignValidGlobalNames.cpp +++ lib/Target/NVPTX/NVPTXAssignValidGlobalNames.cpp @@ -18,6 +18,7 @@ //===----------------------------------------------------------------------===// #include "NVPTX.h" +#include "llvm/IR/Function.h" #include "llvm/IR/GlobalVariable.h" #include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Module.h" @@ -61,6 +62,11 @@ } } + // Do the same for local functions. + for (Function &F : M.functions()) + if (F.hasLocalLinkage()) + F.setName(cleanUpName(F.getName())); + return true; } Index: test/CodeGen/NVPTX/symbol-naming.ll =================================================================== --- test/CodeGen/NVPTX/symbol-naming.ll +++ test/CodeGen/NVPTX/symbol-naming.ll @@ -1,17 +1,17 @@ -; RUN: llc < %s -march=nvptx -mcpu=sm_20 | FileCheck %s --check-prefix=PTX32 -; RUN: llc < %s -march=nvptx64 -mcpu=sm_20 | FileCheck %s --check-prefix=PTX64 +; RUN: llc < %s -march=nvptx -mcpu=sm_20 | FileCheck %s +; RUN: llc < %s -march=nvptx64 -mcpu=sm_20 | FileCheck %s ; Verify that the NVPTX target removes invalid symbol names prior to emitting ; PTX. -; PTX32-NOT: .str -; PTX64-NOT: .str +; CHECK-NOT: .str +; CHECK-NOT: .function. -; PTX32-DAG: _$_str.1 -; PTX32-DAG: _$_str +; CHECK-DAG: _$_str +; CHECK-DAG: _$_str$1 -; PTX64-DAG: _$_str.1 -; PTX64-DAG: _$_str +; CHECK-DAG: _$_function_$_ +; CHECK-DAG: _$_function_$_$2 target datalayout = "e-i64:64-v16:16-v32:32-n16:32:64" target triple = "nvptx64-unknown-unknown" @@ -22,10 +22,25 @@ ; Function Attrs: nounwind -define void @foo(i32 %a, float %b, i8 signext %c, i32 %e) { +define internal void @.function.() { entry: %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str, i32 0, i32 0)) ret void } +; Function Attrs: nounwind +define internal void @_$_function_$_() { +entry: + %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([13 x i8], [13 x i8]* @_$_str, i32 0, i32 0)) + ret void +} + +; Function Attrs: nounwind +define void @global_function() { +entry: + call void @.function.() + call void @_$_function_$_() + ret void +} + declare i32 @printf(i8*, ...)