Skip to content

Commit 1d97cb1

Browse files
committed
[HIP] Emit amdgpu_code_object_version module flag
code object version determines ABI, therefore should not be mixed. This patch emits amdgpu_code_object_version module flag in LLVM IR based on code object version (default 4). The amdgpu_code_object_version value is code object version times 100. LLVM IR with different amdgpu_code_object_version module flag cannot be linked. The -cc1 option -mcode-object-version=none is for ROCm device library use only, which supports multiple ABI. Reviewed by: Artem Belevich Differential Revision: https://reviews.llvm.org/D119026
1 parent cfe7f69 commit 1d97cb1

File tree

8 files changed

+102
-23
lines changed

8 files changed

+102
-23
lines changed

clang/include/clang/Basic/TargetOptions.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,18 @@ class TargetOptions {
7878
/// \brief If enabled, allow AMDGPU unsafe floating point atomics.
7979
bool AllowAMDGPUUnsafeFPAtomics = false;
8080

81+
/// \brief Enumeration value for AMDGPU code object version, which is the
82+
/// code object version times 100.
83+
enum CodeObjectVersionKind {
84+
COV_None,
85+
COV_2 = 200,
86+
COV_3 = 300,
87+
COV_4 = 400,
88+
COV_5 = 500,
89+
};
90+
/// \brief Code object version for AMDGPU.
91+
CodeObjectVersionKind CodeObjectVersion;
92+
8193
// The code model to be used as specified by the user. Corresponds to
8294
// CodeModel::Model enum defined in include/llvm/Support/CodeGen.h, plus
8395
// "default" for the case when the user has not explicitly specified a

clang/include/clang/Driver/Options.td

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3450,8 +3450,12 @@ defm amdgpu_ieee : BoolOption<"m", "amdgpu-ieee",
34503450
NegFlag<SetFalse, [CC1Option]>>, Group<m_Group>;
34513451

34523452
def mcode_object_version_EQ : Joined<["-"], "mcode-object-version=">, Group<m_Group>,
3453-
HelpText<"Specify code object ABI version. Defaults to 4. (AMDGPU only)">,
3454-
MetaVarName<"<version>">, Values<"2,3,4,5">;
3453+
HelpText<"Specify code object ABI version. Allowed values are 2, 3, 4, and 5. Defaults to 4. (AMDGPU only)">,
3454+
Flags<[CC1Option]>,
3455+
Values<"none,2,3,4,5">,
3456+
NormalizedValuesScope<"TargetOptions">,
3457+
NormalizedValues<["COV_None", "COV_2", "COV_3", "COV_4", "COV_5"]>,
3458+
MarshallingInfoEnum<TargetOpts<"CodeObjectVersion">, "COV_4">;
34553459

34563460
defm code_object_v3_legacy : SimpleMFlag<"code-object-v3",
34573461
"Legacy option to specify code object ABI V3",

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -552,21 +552,32 @@ void CodeGenModule::Release() {
552552
EmitMainVoidAlias();
553553
}
554554

555-
// Emit reference of __amdgpu_device_library_preserve_asan_functions to
556-
// preserve ASAN functions in bitcode libraries.
557-
if (LangOpts.Sanitize.has(SanitizerKind::Address) && getTriple().isAMDGPU()) {
558-
auto *FT = llvm::FunctionType::get(VoidTy, {});
559-
auto *F = llvm::Function::Create(
560-
FT, llvm::GlobalValue::ExternalLinkage,
561-
"__amdgpu_device_library_preserve_asan_functions", &getModule());
562-
auto *Var = new llvm::GlobalVariable(
563-
getModule(), FT->getPointerTo(),
564-
/*isConstant=*/true, llvm::GlobalValue::WeakAnyLinkage, F,
565-
"__amdgpu_device_library_preserve_asan_functions_ptr", nullptr,
566-
llvm::GlobalVariable::NotThreadLocal);
567-
addCompilerUsedGlobal(Var);
568-
if (!getModule().getModuleFlag("amdgpu_hostcall")) {
569-
getModule().addModuleFlag(llvm::Module::Override, "amdgpu_hostcall", 1);
555+
if (getTriple().isAMDGPU()) {
556+
// Emit reference of __amdgpu_device_library_preserve_asan_functions to
557+
// preserve ASAN functions in bitcode libraries.
558+
if (LangOpts.Sanitize.has(SanitizerKind::Address)) {
559+
auto *FT = llvm::FunctionType::get(VoidTy, {});
560+
auto *F = llvm::Function::Create(
561+
FT, llvm::GlobalValue::ExternalLinkage,
562+
"__amdgpu_device_library_preserve_asan_functions", &getModule());
563+
auto *Var = new llvm::GlobalVariable(
564+
getModule(), FT->getPointerTo(),
565+
/*isConstant=*/true, llvm::GlobalValue::WeakAnyLinkage, F,
566+
"__amdgpu_device_library_preserve_asan_functions_ptr", nullptr,
567+
llvm::GlobalVariable::NotThreadLocal);
568+
addCompilerUsedGlobal(Var);
569+
if (!getModule().getModuleFlag("amdgpu_hostcall")) {
570+
getModule().addModuleFlag(llvm::Module::Override, "amdgpu_hostcall", 1);
571+
}
572+
}
573+
// Emit amdgpu_code_object_version module flag, which is code object version
574+
// times 100.
575+
// ToDo: Enable module flag for all code object version when ROCm device
576+
// library is ready.
577+
if (getTarget().getTargetOpts().CodeObjectVersion == TargetOptions::COV_5) {
578+
getModule().addModuleFlag(llvm::Module::Error,
579+
"amdgpu_code_object_version",
580+
getTarget().getTargetOpts().CodeObjectVersion);
570581
}
571582
}
572583

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1150,7 +1150,8 @@ static const char *RelocationModelName(llvm::Reloc::Model Model) {
11501150
}
11511151
static void handleAMDGPUCodeObjectVersionOptions(const Driver &D,
11521152
const ArgList &Args,
1153-
ArgStringList &CmdArgs) {
1153+
ArgStringList &CmdArgs,
1154+
bool IsCC1As = false) {
11541155
// If no version was requested by the user, use the default value from the
11551156
// back end. This is consistent with the value returned from
11561157
// getAMDGPUCodeObjectVersion. This lets clang emit IR for amdgpu without
@@ -1162,6 +1163,11 @@ static void handleAMDGPUCodeObjectVersionOptions(const Driver &D,
11621163
Args.MakeArgString(Twine("--amdhsa-code-object-version=") +
11631164
Twine(CodeObjVer)));
11641165
CmdArgs.insert(CmdArgs.begin() + 1, "-mllvm");
1166+
// -cc1as does not accept -mcode-object-version option.
1167+
if (!IsCC1As)
1168+
CmdArgs.insert(CmdArgs.begin() + 1,
1169+
Args.MakeArgString(Twine("-mcode-object-version=") +
1170+
Twine(CodeObjVer)));
11651171
}
11661172
}
11671173

@@ -7901,7 +7907,7 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
79017907
}
79027908

79037909
if (Triple.isAMDGPU())
7904-
handleAMDGPUCodeObjectVersionOptions(D, Args, CmdArgs);
7910+
handleAMDGPUCodeObjectVersionOptions(D, Args, CmdArgs, /*IsCC1As=*/true);
79057911

79067912
assert(Input.isFilename() && "Invalid input.");
79077913
CmdArgs.push_back(Input.getFilename());

clang/test/CodeGenCUDA/amdgpu-asan-printf.cu

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
// RUN: -fcuda-is-device -target-cpu gfx906 -fsanitize=address \
33
// RUN: -O3 -x hip | FileCheck -check-prefixes=MFCHECK %s
44

5-
// MFCHECK: !llvm.module.flags = !{![[FLAG1:[0-9]+]], ![[FLAG2:[0-9]+]]}
6-
// MFCHECK: ![[FLAG1]] = !{i32 4, !"amdgpu_hostcall", i32 1}
5+
// MFCHECK: !{{.*}} = !{i32 4, !"amdgpu_hostcall", i32 1}
76

87
// Test to check hostcall module flag metadata is generated correctly
98
// when a program has printf call and compiled with -fsanitize=address.

clang/test/CodeGenCUDA/amdgpu-asan.cu

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,7 @@
2727
// ASAN-DAG: @llvm.compiler.used = {{.*}}@__amdgpu_device_library_preserve_asan_functions_ptr
2828
// ASAN-DAG: define weak void @__asan_report_load1(i64 %{{.*}})
2929

30-
// MFCHECK: !llvm.module.flags = !{![[FLAG1:[0-9]+]], ![[FLAG2:[0-9]+]]}
31-
// MFCHECK: ![[FLAG1]] = !{i32 4, !"amdgpu_hostcall", i32 1}
30+
// MFCHECK: !{{.*}} = !{i32 4, !"amdgpu_hostcall", i32 1}
3231

3332
// CHECK-NOT: @__amdgpu_device_library_preserve_asan_functions
3433
// CHECK-NOT: @__asan_report_load1
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Create module flag for code object version.
2+
3+
// RUN: %clang_cc1 -fcuda-is-device -triple amdgcn-amd-amdhsa -emit-llvm \
4+
// RUN: -o - %s | FileCheck %s -check-prefix=NONE
5+
6+
// RUN: %clang_cc1 -fcuda-is-device -triple amdgcn-amd-amdhsa -emit-llvm \
7+
// RUN: -mcode-object-version=2 -o - %s | FileCheck -check-prefix=NONE %s
8+
9+
// RUN: %clang_cc1 -fcuda-is-device -triple amdgcn-amd-amdhsa -emit-llvm \
10+
// RUN: -mcode-object-version=3 -o - %s | FileCheck -check-prefix=NONE %s
11+
12+
// RUN: %clang_cc1 -fcuda-is-device -triple amdgcn-amd-amdhsa -emit-llvm \
13+
// RUN: -mcode-object-version=4 -o - %s | FileCheck -check-prefix=NONE %s
14+
15+
// RUN: %clang_cc1 -fcuda-is-device -triple amdgcn-amd-amdhsa -emit-llvm \
16+
// RUN: -mcode-object-version=5 -o - %s | FileCheck -check-prefix=V5 %s
17+
18+
// RUN: %clang_cc1 -fcuda-is-device -triple amdgcn-amd-amdhsa -emit-llvm \
19+
// RUN: -mcode-object-version=none -o - %s | FileCheck %s -check-prefix=NONE
20+
21+
// RUN: not %clang_cc1 -fcuda-is-device -triple amdgcn-amd-amdhsa -emit-llvm \
22+
// RUN: -mcode-object-version=4.1 -o - %s 2>&1| FileCheck %s -check-prefix=INV
23+
24+
// V5: !{{.*}} = !{i32 1, !"amdgpu_code_object_version", i32 500}
25+
// NONE-NOT: !{{.*}} = !{i32 1, !"amdgpu_code_object_version",
26+
// INV: error: invalid value '4.1' in '-mcode-object-version=4.1'

clang/test/Driver/hip-code-object-version.hip

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
// RUN: %s 2>&1 | FileCheck -check-prefix=V3 %s
3535

3636
// V3-WARN: warning: argument '-mcode-object-v3' is deprecated, use '-mcode-object-version=3' instead [-Wdeprecated]
37+
// V3: "-mcode-object-version=3"
3738
// V3: "-mllvm" "--amdhsa-code-object-version=3"
3839
// V3: "-targets=host-x86_64-unknown-linux,hip-amdgcn-amd-amdhsa--gfx906"
3940

@@ -44,6 +45,7 @@
4445
// RUN: --offload-arch=gfx906 -nogpulib \
4546
// RUN: %s 2>&1 | FileCheck -check-prefix=V4 %s
4647

48+
// V4: "-mcode-object-version=4"
4749
// V4: "-mllvm" "--amdhsa-code-object-version=4"
4850
// V4: "-targets=host-x86_64-unknown-linux,hipv4-amdgcn-amd-amdhsa--gfx906"
4951

@@ -54,6 +56,7 @@
5456
// RUN: --offload-arch=gfx906 -nogpulib \
5557
// RUN: %s 2>&1 | FileCheck -check-prefix=V5 %s
5658

59+
// V5: "-mcode-object-version=5"
5760
// V5: "-mllvm" "--amdhsa-code-object-version=5"
5861
// V5: "-targets=host-x86_64-unknown-linux,hipv4-amdgcn-amd-amdhsa--gfx906"
5962

@@ -74,6 +77,25 @@
7477
// INVALID: error: invalid integral value '1' in '-mcode-object-version=1'
7578
// INVALID-NOT: error: invalid integral value
7679

80+
// Check LLVM code object version option --amdhsa-code-object-version
81+
// is passed to -cc1 and -cc1as, and -mcode-object-version is passed
82+
// to -cc1 but not -cc1as.
83+
84+
// RUN: %clang -### -target x86_64-linux-gnu \
85+
// RUN: -mcode-object-version=5 \
86+
// RUN: --offload-arch=gfx906 -nogpulib -save-temps \
87+
// RUN: %s 2>&1 | FileCheck -check-prefix=CC1 %s
88+
89+
// CC1: "-cc1" {{.*}}"-mcode-object-version=5" {{.*}}"-mllvm" "--amdhsa-code-object-version=5"
90+
// CC1: "-cc1as" {{.*}}"-mllvm" "--amdhsa-code-object-version=5"
91+
92+
// RUN: %clang -### -target x86_64-linux-gnu \
93+
// RUN: -mcode-object-version=5 \
94+
// RUN: --offload-arch=gfx906 -nogpulib -save-temps \
95+
// RUN: %s 2>&1 | FileCheck -check-prefix=CC1NEG %s
96+
97+
// CC1NEG-NOT: "-cc1as" {{.*}}"-mcode-object-version=5"
98+
7799
// Check warnings are emitted for legacy options before -mcode-object-version options.
78100
// Check warnings are emitted only once.
79101

0 commit comments

Comments
 (0)