Index: include/clang/Basic/LangOptions.def =================================================================== --- include/clang/Basic/LangOptions.def +++ include/clang/Basic/LangOptions.def @@ -258,6 +258,8 @@ "value symbol visibility") ENUM_LANGOPT(TypeVisibilityMode, Visibility, 3, DefaultVisibility, "type symbol visibility") +ENUM_LANGOPT(AMDGPUNonKernelFunctionVisibilityMode, Visibility, 3, + DefaultVisibility, "non-kernel function visibility") ENUM_LANGOPT(StackProtector, StackProtectorMode, 2, SSPOff, "stack protector mode") ENUM_LANGOPT(SignedOverflowBehavior, SignedOverflowBehaviorTy, 2, SOB_Undefined, Index: include/clang/Driver/CC1Options.td =================================================================== --- include/clang/Driver/CC1Options.td +++ include/clang/Driver/CC1Options.td @@ -679,6 +679,8 @@ HelpText<"Lower bound for a buffer to be considered for stack protection">; def fvisibility : Separate<["-"], "fvisibility">, HelpText<"Default type and symbol visibility">; +def fvisibility_amdgpu_non_kernel_functions : Separate<["-"], "fvisibility-amdgpu-non-kernel-functions">, + HelpText<"Default non-kernel function symbol visibility">; def ftype_visibility : Separate<["-"], "ftype-visibility">, HelpText<"Default type visibility">; def ftemplate_depth : Separate<["-"], "ftemplate-depth">, Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -1711,6 +1711,8 @@ def fverbose_asm : Flag<["-"], "fverbose-asm">, Group; def fvisibility_EQ : Joined<["-"], "fvisibility=">, Group, HelpText<"Set the default symbol visibility for all global declarations">, Values<"hidden,default">; +def fvisibility_amdgpu_non_kernel_functions_EQ : Joined<["-"], "fvisibility-amdgpu-non-kernel-functions=">, Group, + HelpText<"Set the default symbol visibility for non-kernel function declarations">, Values<"hidden,default">; def fvisibility_inlines_hidden : Flag<["-"], "fvisibility-inlines-hidden">, Group, HelpText<"Give inline C++ member functions hidden visibility by default">, Flags<[CC1Option]>; Index: lib/CodeGen/TargetInfo.cpp =================================================================== --- lib/CodeGen/TargetInfo.cpp +++ lib/CodeGen/TargetInfo.cpp @@ -7734,6 +7734,13 @@ llvm::Function *F = cast(GV); + if (!FD->getExplicitVisibility(FunctionDecl::VisibilityForValue) && + F->getCallingConv() != llvm::CallingConv::AMDGPU_KERNEL) { + GV->setVisibility(M.GetLLVMVisibility( + M.getLangOpts().getAMDGPUNonKernelFunctionVisibilityMode())); + M.setDSOLocal(GV); + } + const auto *ReqdWGS = M.getLangOpts().OpenCL ? FD->getAttr() : nullptr; Index: lib/Driver/ToolChains/AMDGPU.cpp =================================================================== --- lib/Driver/ToolChains/AMDGPU.cpp +++ lib/Driver/ToolChains/AMDGPU.cpp @@ -105,9 +105,8 @@ Action::OffloadKind DeviceOffloadingKind) const { // Default to "hidden" visibility, as object level linking will not be // supported for the forseeable future. - if (!DriverArgs.hasArg(options::OPT_fvisibility_EQ, - options::OPT_fvisibility_ms_compat)) { - CC1Args.push_back("-fvisibility"); - CC1Args.push_back("hidden"); + if (!DriverArgs.hasArg(options::OPT_fvisibility_amdgpu_non_kernel_functions_EQ, + options::OPT_fvisibility_amdgpu_non_kernel_functions)) { + CC1Args.append({"-fvisibility-amdgpu-non-kernel-functions", "hidden"}); } } Index: lib/Driver/ToolChains/Clang.cpp =================================================================== --- lib/Driver/ToolChains/Clang.cpp +++ lib/Driver/ToolChains/Clang.cpp @@ -4167,6 +4167,12 @@ } } + if (const Arg *A = Args.getLastArg( + options::OPT_fvisibility_amdgpu_non_kernel_functions_EQ)) { + CmdArgs.push_back("-fvisibility-amdgpu-non-kernel-functions"); + CmdArgs.push_back(A->getValue()); + } + Args.AddLastArg(CmdArgs, options::OPT_fvisibility_inlines_hidden); Args.AddLastArg(CmdArgs, options::OPT_ftlsmodel_EQ); Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -2310,6 +2310,17 @@ Opts.setTypeVisibilityMode(Opts.getValueVisibilityMode()); } + // The amdgpu-non-kernel-function-visibility mode defaults to the + // value-visibility mode. + if (Arg *amdgpuVisOpt = + Args.getLastArg(OPT_fvisibility_amdgpu_non_kernel_functions)) { + Opts.setAMDGPUNonKernelFunctionVisibilityMode( + parseVisibility(amdgpuVisOpt, Args, Diags)); + } else { + Opts.setAMDGPUNonKernelFunctionVisibilityMode( + Opts.getValueVisibilityMode()); + } + if (Args.hasArg(OPT_fvisibility_inlines_hidden)) Opts.InlineVisibilityHidden = 1; Index: test/CodeGen/visibility-amdgpu-non-kernel-functions.cl =================================================================== --- /dev/null +++ test/CodeGen/visibility-amdgpu-non-kernel-functions.cl @@ -0,0 +1,46 @@ +// RUN: %clang_cc1 -fvisibility hidden -triple amdgcn-unknown-unknown -S -emit-llvm -o - %s | FileCheck --check-prefix=FVIS_HIDDEN %s +// RUN: %clang_cc1 -fvisibility-amdgpu-non-kernel-functions hidden -triple amdgcn-unknown-unknown -S -emit-llvm -o - %s | FileCheck --check-prefix=FVIS_AMDGPU_HIDDEN %s +// RUN: %clang_cc1 -fvisibility-amdgpu-non-kernel-functions default -triple amdgcn-unknown-unknown -S -emit-llvm -o - %s | FileCheck --check-prefix=FVIS_AMDGPU_DEFAULT %s +// RUN: %clang_cc1 -fvisibility hidden -fvisibility-amdgpu-non-kernel-functions default -triple amdgcn-unknown-unknown -S -emit-llvm -o - %s | FileCheck --check-prefix=FVIS_AMDGPU_OVERRIDE %s + +// FVIS_HIDDEN: define hidden amdgpu_kernel void @kern() +// FVIS_AMDGPU_HIDDEN: define amdgpu_kernel void @kern() +// FVIS_AMDGPU_DEFAULT: define amdgpu_kernel void @kern() +// FVIS_AMDGPU_OVERRIDE: define hidden amdgpu_kernel void @kern() +kernel void kern() {} +// FVIS_HIDDEN: define amdgpu_kernel void @default_kern() +// FVIS_AMDGPU_HIDDEN: define amdgpu_kernel void @default_kern() +// FVIS_AMDGPU_DEFAULT: define amdgpu_kernel void @default_kern() +// FVIS_AMDGPU_OVERRIDE: define amdgpu_kernel void @default_kern() +__attribute__((visibility("default"))) kernel void default_kern() {} +// FVIS_HIDDEN: define hidden amdgpu_kernel void @hidden_kern() +// FVIS_AMDGPU_HIDDEN: define hidden amdgpu_kernel void @hidden_kern() +// FVIS_AMDGPU_DEFAULT: define hidden amdgpu_kernel void @hidden_kern() +// FVIS_AMDGPU_OVERRIDE: define hidden amdgpu_kernel void @hidden_kern() +__attribute__((visibility("hidden"))) kernel void hidden_kern() {} +// FVIS_HIDDEN: define protected amdgpu_kernel void @protected_kern() +// FVIS_AMDGPU_HIDDEN: define protected amdgpu_kernel void @protected_kern() +// FVIS_AMDGPU_DEFAULT: define protected amdgpu_kernel void @protected_kern() +// FVIS_AMDGPU_OVERRIDE: define protected amdgpu_kernel void @protected_kern() +__attribute__((visibility("protected"))) kernel void protected_kern() {} + +// FVIS_HIDDEN: define hidden void @func() +// FVIS_AMDGPU_HIDDEN: define hidden void @func() +// FVIS_AMDGPU_DEFAULT: define void @func() +// FVIS_AMDGPU_OVERRIDE: define void @func() +void func() {} +// FVIS_HIDDEN: define void @default_func() +// FVIS_AMDGPU_HIDDEN: define void @default_func() +// FVIS_AMDGPU_DEFAULT: define void @default_func() +// FVIS_AMDGPU_OVERRIDE: define void @default_func() +__attribute__((visibility("default"))) void default_func() {} +// FVIS_HIDDEN: define hidden void @hidden_func() +// FVIS_AMDGPU_HIDDEN: define hidden void @hidden_func() +// FVIS_AMDGPU_DEFAULT: define hidden void @hidden_func() +// FVIS_AMDGPU_OVERRIDE: define hidden void @hidden_func() +__attribute__((visibility("hidden"))) void hidden_func() {} +// FVIS_HIDDEN: define protected void @protected_func() +// FVIS_AMDGPU_HIDDEN: define protected void @protected_func() +// FVIS_AMDGPU_DEFAULT: define protected void @protected_func() +// FVIS_AMDGPU_OVERRIDE: define protected void @protected_func() +__attribute__((visibility("protected"))) void protected_func() {} Index: test/Driver/amdgpu-visibility.cl =================================================================== --- test/Driver/amdgpu-visibility.cl +++ test/Driver/amdgpu-visibility.cl @@ -1,7 +1,11 @@ // RUN: %clang -### -target amdgcn-amd-amdhsa -x cl -c -emit-llvm %s 2>&1 | FileCheck -check-prefix=DEFAULT %s -// RUN: %clang -### -target amdgcn-amd-amdhsa -x cl -c -emit-llvm -fvisibility=protected %s 2>&1 | FileCheck -check-prefix=OVERRIDE-PROTECTED %s -// RUN: %clang -### -target amdgcn-amd-amdhsa -x cl -c -emit-llvm -fvisibility-ms-compat %s 2>&1 | FileCheck -check-prefix=OVERRIDE-MS %s +// RUN: %clang -### -target amdgcn-amd-amdhsa -x cl -c -emit-llvm -fvisibility=hidden %s 2>&1 | FileCheck -check-prefix=VISIBILITY-HIDDEN %s +// RUN: %clang -### -target amdgcn-amd-amdhsa -x cl -c -emit-llvm -fvisibility-amdgpu-non-kernel-functions=hidden %s 2>&1 | FileCheck -check-prefix=AMDGPU-HIDDEN %s +// RUN: %clang -### -target amdgcn-amd-amdhsa -x cl -c -emit-llvm -fvisibility-amdgpu-non-kernel-functions=default %s 2>&1 | FileCheck -check-prefix=AMDGPU-DEFAULT %s +// RUN: %clang -### -target amdgcn-amd-amdhsa -x cl -c -emit-llvm -fvisibility=hidden -fvisibility-amdgpu-non-kernel-functions=default %s 2>&1 | FileCheck -check-prefix=VISIBILITY-HIDDEN-AMDGPU-DEFAULT %s -// DEFAULT: "-fvisibility" "hidden" -// OVERRIDE-PROTECTED: "-fvisibility" "protected" -// OVERRIDE-MS: "-fvisibility" "hidden" "-ftype-visibility" "default" +// DEFAULT: "-fvisibility-amdgpu-non-kernel-functions" "hidden" +// VISIBILITY-HIDDEN: "-fvisibility-amdgpu-non-kernel-functions" "hidden" +// AMDGPU-HIDDEN: "-fvisibility-amdgpu-non-kernel-functions" "hidden" +// AMDGPU-DEFAULT: "-fvisibility-amdgpu-non-kernel-functions" "default" +// VISIBILITY-HIDDEN-AMDGPU-DEFAULT: "-fvisibility-amdgpu-non-kernel-functions" "default"