Rationale: OpenCL kernels are called via an explicit runtime API with arguments set with clSetKernelArg(), not as normal sub-functions. Return SPIR_KERNEL by default as the kernel calling convention to ensure the fingerprint is fixed such way that each OpenCL argument gets one matching argument in the produced kernel function argument list to enable feasible implementation of clSetKernelArg() with aggregates etc. In case we would use the default C calling conv here, clSetKernelArg() might break depending on the target-specific conventions; different targets might split structs passed as values to multiple function arguments etc. https://reviews.llvm.org/D33639 llvm-svn: 304389
66 lines
1.9 KiB
Common Lisp
66 lines
1.9 KiB
Common Lisp
// RUN: %clang_cc1 %s -cl-std=CL1.2 -emit-llvm -triple x86_64-unknown-unknown -o - | FileCheck %s
|
|
// RUN: %clang_cc1 %s -cl-std=CL1.2 -emit-llvm -triple amdgcn-unknown-unknown -o - | FileCheck -check-prefixes=AMDGCN %s
|
|
// Test that the kernels always use the SPIR calling convention
|
|
// to have unambiguous mapping of arguments to feasibly implement
|
|
// clSetKernelArg().
|
|
|
|
typedef struct int_single {
|
|
int a;
|
|
} int_single;
|
|
|
|
typedef struct int_pair {
|
|
long a;
|
|
long b;
|
|
} int_pair;
|
|
|
|
typedef struct test_struct {
|
|
int elementA;
|
|
int elementB;
|
|
long elementC;
|
|
char elementD;
|
|
long elementE;
|
|
float elementF;
|
|
short elementG;
|
|
double elementH;
|
|
} test_struct;
|
|
|
|
kernel void test_single(int_single input, global int* output) {
|
|
// CHECK: spir_kernel
|
|
// AMDGCN: define amdgpu_kernel void @test_single
|
|
// CHECK: struct.int_single* byval nocapture
|
|
// CHECK: i32* nocapture %output
|
|
output[0] = input.a;
|
|
}
|
|
|
|
kernel void test_pair(int_pair input, global int* output) {
|
|
// CHECK: spir_kernel
|
|
// AMDGCN: define amdgpu_kernel void @test_pair
|
|
// CHECK: struct.int_pair* byval nocapture
|
|
// CHECK: i32* nocapture %output
|
|
output[0] = (int)input.a;
|
|
output[1] = (int)input.b;
|
|
}
|
|
|
|
kernel void test_kernel(test_struct input, global int* output) {
|
|
// CHECK: spir_kernel
|
|
// AMDGCN: define amdgpu_kernel void @test_kernel
|
|
// CHECK: struct.test_struct* byval nocapture
|
|
// CHECK: i32* nocapture %output
|
|
output[0] = input.elementA;
|
|
output[1] = input.elementB;
|
|
output[2] = (int)input.elementC;
|
|
output[3] = (int)input.elementD;
|
|
output[4] = (int)input.elementE;
|
|
output[5] = (int)input.elementF;
|
|
output[6] = (int)input.elementG;
|
|
output[7] = (int)input.elementH;
|
|
};
|
|
|
|
void test_function(int_pair input, global int* output) {
|
|
// CHECK-NOT: spir_kernel
|
|
// AMDGCN-NOT: define amdgpu_kernel void @test_function
|
|
// CHECK: i64 %input.coerce0, i64 %input.coerce1, i32* nocapture %output
|
|
output[0] = (int)input.a;
|
|
output[1] = (int)input.b;
|
|
}
|