Skip to content

Commit a27574f

Browse files
committed
[clang] Fix inconsistencies with the device_kernel attr on different targets
Signed-off-by: Sarnie, Nick <nick.sarnie@intel.com>
1 parent 3b38314 commit a27574f

File tree

10 files changed

+100
-29
lines changed

10 files changed

+100
-29
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,7 @@ Bug Fixes to Attribute Support
401401
- Using ``[[gnu::cleanup(some_func)]]`` where some_func is annotated with
402402
``[[gnu::error("some error")]]`` now correctly triggers an error. (#GH146520)
403403
- Fix a crash when the function name is empty in the `swift_name` attribute. (#GH157075)
404+
- Fixes crashes or missing diagnostics with the `device_kernel` attribute. (#GH161905)
404405

405406
Bug Fixes to C++ Support
406407
^^^^^^^^^^^^^^^^^^^^^^^^

clang/include/clang/Basic/Attr.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1599,7 +1599,7 @@ def CUDAShared : InheritableAttr {
15991599
}
16001600
def : MutualExclusions<[CUDAConstant, CUDAShared, HIPManaged]>;
16011601

1602-
def DeviceKernel : DeclOrTypeAttr {
1602+
def DeviceKernel : InheritableAttr {
16031603
let Spellings = [Clang<"device_kernel">, Clang<"sycl_kernel">,
16041604
Clang<"nvptx_kernel">, Clang<"amdgpu_kernel">,
16051605
CustomKeyword<"__kernel">, CustomKeyword<"kernel">];

clang/lib/AST/TypePrinter.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2147,9 +2147,6 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
21472147
}
21482148
case attr::AArch64VectorPcs: OS << "aarch64_vector_pcs"; break;
21492149
case attr::AArch64SVEPcs: OS << "aarch64_sve_pcs"; break;
2150-
case attr::DeviceKernel:
2151-
OS << T->getAttr()->getSpelling();
2152-
break;
21532150
case attr::IntelOclBicc:
21542151
OS << "inteloclbicc";
21552152
break;

clang/lib/Basic/Targets/NVPTX.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ class LLVM_LIBRARY_VISIBILITY NVPTXTargetInfo : public TargetInfo {
200200
// a host function.
201201
if (HostTarget)
202202
return HostTarget->checkCallingConvention(CC);
203-
return CCCR_Warning;
203+
return CC == CC_DeviceKernel ? CCCR_OK : CCCR_Warning;
204204
}
205205

206206
bool hasBitIntType() const override { return true; }

clang/lib/CodeGen/Targets/AMDGPU.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -419,9 +419,11 @@ void AMDGPUTargetCodeGenInfo::setTargetAttributes(
419419
return;
420420

421421
const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
422-
if (FD)
422+
if (FD) {
423423
setFunctionDeclAttributes(FD, F, M);
424-
424+
if (FD->hasAttr<DeviceKernelAttr>() && !M.getLangOpts().OpenCL)
425+
F->setCallingConv(llvm::CallingConv::AMDGPU_KERNEL);
426+
}
425427
if (!getABIInfo().getCodeGenOpts().EmitIEEENaNCompliantInsts)
426428
F->addFnAttr("amdgpu-ieee", "false");
427429
}

clang/lib/CodeGen/Targets/SPIR.cpp

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ class CommonSPIRTargetCodeGenInfo : public TargetCodeGenInfo {
6161
QualType SampledType, CodeGenModule &CGM) const;
6262
void
6363
setOCLKernelStubCallingConvention(const FunctionType *&FT) const override;
64+
void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
65+
CodeGen::CodeGenModule &M) const override;
6466
};
6567
class SPIRVTargetCodeGenInfo : public CommonSPIRTargetCodeGenInfo {
6668
public:
@@ -240,6 +242,26 @@ void CommonSPIRTargetCodeGenInfo::setOCLKernelStubCallingConvention(
240242
FT, FT->getExtInfo().withCallingConv(CC_SpirFunction));
241243
}
242244

245+
void CommonSPIRTargetCodeGenInfo::setTargetAttributes(
246+
const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M) const {
247+
if (M.getLangOpts().OpenCL)
248+
return;
249+
250+
if (GV->isDeclaration())
251+
return;
252+
253+
llvm::Function *F = dyn_cast<llvm::Function>(GV);
254+
if (!F)
255+
return;
256+
257+
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
258+
if (!FD)
259+
return;
260+
261+
if (FD->hasAttr<DeviceKernelAttr>())
262+
F->setCallingConv(getDeviceKernelCallingConv());
263+
}
264+
243265
LangAS
244266
SPIRVTargetCodeGenInfo::getGlobalVarAddressSpace(CodeGenModule &CGM,
245267
const VarDecl *D) const {
@@ -264,9 +286,6 @@ SPIRVTargetCodeGenInfo::getGlobalVarAddressSpace(CodeGenModule &CGM,
264286

265287
void SPIRVTargetCodeGenInfo::setTargetAttributes(
266288
const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M) const {
267-
if (!M.getLangOpts().HIP ||
268-
M.getTarget().getTriple().getVendor() != llvm::Triple::AMD)
269-
return;
270289
if (GV->isDeclaration())
271290
return;
272291

@@ -277,6 +296,14 @@ void SPIRVTargetCodeGenInfo::setTargetAttributes(
277296
auto FD = dyn_cast_or_null<FunctionDecl>(D);
278297
if (!FD)
279298
return;
299+
300+
if (FD->hasAttr<DeviceKernelAttr>())
301+
F->setCallingConv(llvm::CallingConv::SPIR_KERNEL);
302+
303+
if (!M.getLangOpts().HIP ||
304+
M.getTarget().getTriple().getVendor() != llvm::Triple::AMD)
305+
return;
306+
280307
if (!FD->hasAttr<CUDAGlobalAttr>())
281308
return;
282309

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5204,25 +5204,55 @@ static void handleCallConvAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
52045204
static void handleDeviceKernelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
52055205
const auto *FD = dyn_cast_or_null<FunctionDecl>(D);
52065206
bool IsFunctionTemplate = FD && FD->getDescribedFunctionTemplate();
5207-
if (S.getLangOpts().SYCLIsDevice) {
5207+
llvm::Triple Triple = S.getASTContext().getTargetInfo().getTriple();
5208+
const LangOptions &LangOpts = S.getLangOpts();
5209+
5210+
if (LangOpts.SYCLIsDevice) {
52085211
if (!IsFunctionTemplate) {
52095212
S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type_str)
52105213
<< AL << AL.isRegularKeywordAttribute() << "function templates";
5214+
AL.setInvalid();
5215+
return;
52115216
} else {
52125217
S.SYCL().handleKernelAttr(D, AL);
52135218
}
52145219
} else if (DeviceKernelAttr::isSYCLSpelling(AL)) {
52155220
S.Diag(AL.getLoc(), diag::warn_attribute_ignored) << AL;
5216-
} else if (S.getASTContext().getTargetInfo().getTriple().isNVPTX()) {
5221+
AL.setInvalid();
5222+
5223+
return;
5224+
} else if (Triple.isNVPTX()) {
52175225
handleGlobalAttr(S, D, AL);
52185226
} else {
52195227
// OpenCL C++ will throw a more specific error.
5220-
if (!S.getLangOpts().OpenCLCPlusPlus && (!FD || IsFunctionTemplate)) {
5228+
if (!LangOpts.OpenCLCPlusPlus && (!FD || IsFunctionTemplate)) {
52215229
S.Diag(AL.getLoc(), diag::err_attribute_wrong_decl_type_str)
52225230
<< AL << AL.isRegularKeywordAttribute() << "functions";
5231+
AL.setInvalid();
5232+
return;
52235233
}
52245234
handleSimpleAttribute<DeviceKernelAttr>(S, D, AL);
52255235
}
5236+
// TODO: isGPU() should probably return true for SPIR.
5237+
bool TargetDeviceEnvironment = Triple.isGPU() || Triple.isSPIR() ||
5238+
LangOpts.isTargetDevice() || LangOpts.OpenCL;
5239+
bool IsAMDGPUMismatch =
5240+
DeviceKernelAttr::isAMDGPUSpelling(AL) && !Triple.isAMDGPU();
5241+
bool IsNVPTXMismatch =
5242+
DeviceKernelAttr::isNVPTXSpelling(AL) && !Triple.isNVPTX();
5243+
if (IsAMDGPUMismatch || IsNVPTXMismatch || !TargetDeviceEnvironment) {
5244+
// While both are just different spellings of the same underlying
5245+
// attribute, it makes more sense to the user if amdgpu_kernel can only
5246+
// be used on AMDGPU and the equivalent for NVPTX, so warn and ignore
5247+
// the attribute if there's a mismatch.
5248+
// Also warn if this is not an environment where a device kernel makes
5249+
// sense.
5250+
S.Diag(AL.getLoc(), diag::warn_cconv_unsupported)
5251+
<< AL << (int)Sema::CallingConventionIgnoredReason::ForThisTarget;
5252+
AL.setInvalid();
5253+
return;
5254+
}
5255+
52265256
// Make sure we validate the CC with the target
52275257
// and warn/error if necessary.
52285258
handleCallConvAttr(S, D, AL);

clang/lib/Sema/SemaType.cpp

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,6 @@ static void diagnoseBadTypeAttribute(Sema &S, const ParsedAttr &attr,
134134
case ParsedAttr::AT_VectorCall: \
135135
case ParsedAttr::AT_AArch64VectorPcs: \
136136
case ParsedAttr::AT_AArch64SVEPcs: \
137-
case ParsedAttr::AT_DeviceKernel: \
138137
case ParsedAttr::AT_MSABI: \
139138
case ParsedAttr::AT_SysVABI: \
140139
case ParsedAttr::AT_Pcs: \
@@ -3781,7 +3780,8 @@ static CallingConv getCCForDeclaratorChunk(
37813780
}
37823781
}
37833782
if (!S.getLangOpts().isSYCL()) {
3784-
for (const ParsedAttr &AL : D.getDeclSpec().getAttributes()) {
3783+
for (const ParsedAttr &AL : llvm::concat<ParsedAttr>(
3784+
D.getDeclSpec().getAttributes(), D.getAttributes())) {
37853785
if (AL.getKind() == ParsedAttr::AT_DeviceKernel) {
37863786
CC = CC_DeviceKernel;
37873787
break;
@@ -7565,8 +7565,6 @@ static Attr *getCCTypeAttr(ASTContext &Ctx, ParsedAttr &Attr) {
75657565
return createSimpleAttr<AArch64SVEPcsAttr>(Ctx, Attr);
75667566
case ParsedAttr::AT_ArmStreaming:
75677567
return createSimpleAttr<ArmStreamingAttr>(Ctx, Attr);
7568-
case ParsedAttr::AT_DeviceKernel:
7569-
return createSimpleAttr<DeviceKernelAttr>(Ctx, Attr);
75707568
case ParsedAttr::AT_Pcs: {
75717569
// The attribute may have had a fixit applied where we treated an
75727570
// identifier as a string literal. The contents of the string are valid,
@@ -8805,16 +8803,6 @@ static void HandleHLSLParamModifierAttr(TypeProcessingState &State,
88058803
}
88068804
}
88078805

8808-
static bool isMultiSubjectAttrAllowedOnType(const ParsedAttr &Attr) {
8809-
// The DeviceKernel attribute is shared for many targets, and
8810-
// it is only allowed to be a type attribute with the AMDGPU
8811-
// spelling, so skip processing the attr as a type attr
8812-
// unless it has that spelling.
8813-
if (Attr.getKind() != ParsedAttr::AT_DeviceKernel)
8814-
return true;
8815-
return DeviceKernelAttr::isAMDGPUSpelling(Attr);
8816-
}
8817-
88188806
static void processTypeAttrs(TypeProcessingState &state, QualType &type,
88198807
TypeAttrLocation TAL,
88208808
const ParsedAttributesView &attrs,
@@ -9068,8 +9056,6 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type,
90689056
break;
90699057
[[fallthrough]];
90709058
FUNCTION_TYPE_ATTRS_CASELIST:
9071-
if (!isMultiSubjectAttrAllowedOnType(attr))
9072-
break;
90739059

90749060
attr.setUsedAsTypeAttr();
90759061

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -emit-llvm %s 2>&1 -o -| FileCheck -check-prefix=CHECK-AMDGPU %s
2+
// RUN: %clang_cc1 -triple nvptx64-nvidia-cuda- -emit-llvm %s 2>&1 -o -| FileCheck -check-prefix=CHECK-NVPTX %s
3+
// RUN: %clang_cc1 -triple spir64 -emit-llvm %s 2>&1 -o - | FileCheck -check-prefix=CHECK-SPIR %s
4+
// RUN: %clang_cc1 -triple spirv64 -emit-llvm %s 2>&1 -o - | FileCheck -check-prefix=CHECK-SPIR %s
5+
6+
// CHECK-AMDGPU-DAG: amdgpu_kernel void @kernel1()
7+
// CHECK-NVPTX-DAG: ptx_kernel void @kernel1()
8+
// CHECK-SPIR-DAG: spir_kernel void @kernel1()
9+
[[clang::device_kernel]] void kernel1() {}
10+
11+
// CHECK-AMDGPU-DAG: amdgpu_kernel void @kernel2()
12+
// CHECK-NVPTX-DAG: 14:3: warning: 'clang::amdgpu_kernel' calling convention is not supported for this target
13+
// CHECK-SPIR-DAG: 14:3: warning: 'clang::amdgpu_kernel' calling convention is not supported for this target
14+
[[clang::amdgpu_kernel]] void kernel2() {}
15+
16+
// CHECK-AMDGPU-DAG: 19:3: warning: 'clang::nvptx_kernel' calling convention is not supported for this target
17+
// CHECK-NVPTX-DAG: ptx_kernel void @kernel3()
18+
// CHECK-SPIR-DAG: 19:3: warning: 'clang::nvptx_kernel' calling convention is not supported for this target
19+
[[clang::nvptx_kernel]] void kernel3() {}
20+
21+
// CHECK-AMDGPU-DAG: 24:3: warning: 'clang::sycl_kernel' attribute ignored
22+
// CHECK-NVPTX-DAG: 24:3: warning: 'clang::sycl_kernel' attribute ignored
23+
// CHECK-SPIR-DAG: 24:3: warning: 'clang::sycl_kernel' attribute ignored
24+
[[clang::sycl_kernel]] void kernel4() {}

clang/test/Sema/callingconv.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ int __attribute__((aarch64_vector_pcs)) aavpcs(void); // expected-warning {{'aar
5555
int __attribute__((aarch64_sve_pcs)) aasvepcs(void); // expected-warning {{'aarch64_sve_pcs' calling convention is not supported for this target}}
5656

5757
int __attribute__((amdgpu_kernel)) amdgpu_kernel(void); // expected-warning {{'amdgpu_kernel' calling convention is not supported for this target}}
58+
int __attribute__((device_kernel)) device_kernel(void) { // expected-warning {{'device_kernel' calling convention is not supported for this target}}
59+
}
60+
int __attribute__((sycl_kernel)) sycl_kernel(void) { // expected-warning {{'sycl_kernel' attribute ignored}}
61+
}
5862

5963
// PR6361
6064
void ctest3();

0 commit comments

Comments
 (0)