Files
ispc/tests/lit-tests/xe_kernels_spec_addrspace.ispc
T
2025-11-21 17:42:57 -07:00

145 lines
8.5 KiB
Plaintext

// This test checks calls of export and extern "C" functions on CPU and GPU based on close to real-life example.
// RUN: %{ispc} %s --target=xehpg-x8 --emit-llvm-text --nowrap --no-discard-value-names -O0 -o %t.ll
// RUN: FileCheck --input-file=%t.ll -check-prefix=CHECK-XE %s
// RUN: %{ispc} %s --target=avx2 --emit-llvm-text --nowrap --no-discard-value-names -O0 -o %t.ll
// RUN: FileCheck --input-file=%t.ll -check-prefix=CHECK-CPU %s
// REQUIRES: XE_ENABLED
struct ISPCParams {
int *img_buf;
int img_size;
};
struct Context {
float *t1;
int x;
int y;
};
struct RayHit {
int ray;
int hit;
int geomID;
int *data;
};
struct vec3f {
float x;
float y;
float z;
};
inline void contextInit(uniform Context *uniform context) {
context->x = 0;
context->y = 1;
}
// CHECK-XE: define spir_func void @swap___{{.*}}
// CHECK-XE: define spir_func void @intersectISPC___{{.*}}(i1 %{{.*}}, {{(%v8_uniform_Context\*)|ptr}} noalias %{{.*}}, {{(%v8_uniform_RayHit\*)|ptr}} noalias %{{.*}}, {{(float\*)|ptr}} noalias %{{.*}}, {{(i8\*)|ptr}} noalias %{{.*}}, <8 x i1> %__mask)
// CHECK-XE-NOT: addrspacecast {{(%v8_uniform_Context addrspace\(4\)\*)|(ptr addrspace\(4\))}} %{{.*}} to {{(%v8_uniform_Context\*)|ptr}}
// CHECK-XE-NOT: addrspacecast {{(%v8_uniform_RayHit addrspace\(4\)\*)|(ptr addrspace\(4\))}} %{{.*}} to {{(%v8_uniform_RayHit\*)|ptr}}
// CHECK-XE-NOT: addrspacecast {{(i8 addrspace\(4\)\*|ptr addrspace\(4\))}} %{{.*}} to {{(i8\*)|ptr}}
// CHECK-XE: call spir_func void @swap___{{.*}}
// CHECK-XE: declare spir_func void @intersectExternal({{(%v8_uniform_Context addrspace\(4\)\*)|(ptr addrspace\(4\))}} noalias, {{(%v8_uniform_RayHit addrspace\(4\)\*)|(ptr addrspace\(4\))}} noalias, {{(float addrspace\(4\)\*)|(ptr addrspace\(4\))}} noalias, {{(i8 addrspace\(4\)\*|ptr addrspace\(4\))}} noalias)
// CHECK-XE: define spir_func void @ispc_test___{{.*}}({{(<8 x float>\*)|ptr}} noalias %out, <8 x i1> %__mask)
// CHECK-XE: define spir_func void @intersectISPC(i1 %{{.*}}, {{(%v8_uniform_Context addrspace\(4\)\*)|(ptr addrspace\(4\))}} noalias %{{.*}}, {{(%v8_uniform_RayHit addrspace\(4\)\*)|(ptr addrspace\(4\))}} noalias %{{.*}}, {{(float addrspace\(4\)\*)|(ptr addrspace\(4\))}} noalias %{{.*}}, {{(i8 addrspace\(4\)\*|ptr addrspace\(4\))}} noalias %{{.*}})
// CHECK-XE: addrspacecast {{(%v8_uniform_Context addrspace\(4\)\*)|(ptr addrspace\(4\))}} %{{.*}} to {{(%v8_uniform_Context\*)|ptr}}
// CHECK-XE: addrspacecast {{(%v8_uniform_RayHit addrspace\(4\)\*)|(ptr addrspace\(4\))}} %{{.*}} to {{(%v8_uniform_RayHit\*)|ptr}}
// CHECK-XE: addrspacecast {{(i8 addrspace\(4\)\*|ptr addrspace\(4\))}} %{{.*}} to {{(i8\*)|ptr}}
// CHECK-XE: call spir_func void @swap___{{.*}}
// CHECK-XE: define dllexport spir_kernel void @kernel({{(i8 addrspace\(1\)\*|ptr addrspace\(1\))}}
// CHECK-XE: addrspacecast {{(%v8_uniform_Context\*)|ptr}} %{{.*}} to {{(%v8_uniform_Context addrspace\(4\)\*)|(ptr addrspace\(4\))}}
// CHECK-XE: addrspacecast {{(%v8_uniform_RayHit\*)|ptr}} %{{.*}} to {{(%v8_uniform_RayHit addrspace\(4\)\*)|(ptr addrspace\(4\))}}
// CHECK-XE: addrspacecast {{(float\*)|ptr}} %{{.*}} to {{(float addrspace\(4\)\*)|(ptr addrspace\(4\))}}
// CHECK-XE: addrspacecast {{(i8\*)|ptr}} %{{.*}} to {{(i8 addrspace\(4\)\*|ptr addrspace\(4\))}}
// CHECK-XE: call spir_func void @intersectExternal({{(%v8_uniform_Context addrspace\(4\)\*)|(ptr addrspace\(4\))}} %{{.*}}, {{(%v8_uniform_RayHit addrspace\(4\)\*)|(ptr addrspace\(4\))}} %{{.*}}, {{(float addrspace\(4\)\*)|(ptr addrspace\(4\))}} %{{.*}}, {{(i8 addrspace\(4\)\*|ptr addrspace\(4\))}} %{{.*}})
// CHECK-XE: call spir_func void @intersectISPC___{{.*}}(i1 {{.*}}, {{(%v8_uniform_Context\*)|ptr}} {{.*}}, {{(%v8_uniform_RayHit\*)|ptr}} {{.*}}, {{(float\*)|ptr}} {{.*}}, {{(i8\*)|ptr}} {{.*}}, <8 x i1> {{.*}}
// CHECK-XE: define spir_func void @ispc_test({{(<8 x float> addrspace\(4\)\*)|(ptr addrspace\(4\))}} noalias %out)
// CHECK-XE: define dllexport spir_kernel void @ispc_kernel({{(i8 addrspace\(1\)\*|ptr addrspace\(1\))}}
// CHECK-XE: call spir_func void @ispc_test___{{.*}}({{(<8 x float>\*)|ptr}} {{.*}})
// CHECK-CPU: define void @swap___{{.*}}
// CHECK-CPU: define void @intersectISPC___{{.*}}(i1 %{{.*}}, {{(%v8_uniform_Context\*)|ptr}} noalias %{{.*}}, {{(%v8_uniform_RayHit\*)|ptr}} noalias %{{.*}}, {{(float\*)|ptr}} noalias %{{.*}}, {{(i8\*)|ptr}} noalias %{{.*}}, <8 x i32> %__mask)
// CHECK-CPU-NOT: addrspacecast {{(%v8_uniform_Context\*)|ptr}} %{{.*}} to {{(%v8_uniform_Context addrspace\(4\)\*)|(ptr addrspace\(4\))}}
// CHECK-CPU-NOT: addrspacecast {{(%v8_uniform_RayHit\*)|ptr}} %{{.*}} to {{(%v8_uniform_RayHit addrspace\(4\)\*)|(ptr addrspace\(4\))}}
// CHECK-CPU-NOT: addrspacecast {{(i8 addrspace\(4\)\*|ptr addrspace\(4\))}} %{{.*}} to {{(i8\*)|ptr}}
// CHECK-CPU: call void @swap___{{.*}}
// CHECK-CPU: declare void @intersectExternal({{(%v8_uniform_Context\*)|ptr}} noalias, {{(%v8_uniform_RayHit\*)|ptr}} noalias, {{(float\*)|ptr}} noalias, {{(i8\*)|ptr}} noalias)
// CHECK-CPU: define void @kernel___{{.*}}
// CHECK-CPU-NOT: addrspacecast {{(%v8_uniform_Context\*)|ptr}} %{{.*}} to {{(%v8_uniform_Context addrspace\(4\)\*)|(ptr addrspace\(4\))}}
// CHECK-CPU-NOT: addrspacecast {{(%v8_uniform_RayHit\*)|ptr}} %{{.*}} to {{(%v8_uniform_RayHit addrspace\(4\)\*)|(ptr addrspace\(4\))}}
// CHECK-CPU-NOT: addrspacecast {{(i8\*)|ptr}} %{{.*}} to {{(i8 addrspace\(4\)\*|ptr addrspace\(4\))}}
// CHECK-CPU: call void @intersectExternal({{(%v8_uniform_Context\*)|ptr}} %{{.*}}, {{(%v8_uniform_RayHit\*)|ptr}} %{{.*}}, {{(float\*)|ptr}} %{{.*}}, {{(i8\*)|ptr}} %{{.*}})
// CHECK-CPU: call void @intersectISPC___{{.*}}(i1 {{.*}}, {{(%v8_uniform_Context\*)|ptr}} {{.*}}, {{(%v8_uniform_RayHit\*)|ptr}} {{.*}}, {{(float\*)|ptr}} {{.*}}, {{(i8\*)|ptr}} {{.*}}, <8 x i32> {{.*}}
// CHECK-CPU: define void @ispc_test___{{.*}}({{(<8 x float>\*)|ptr}} noalias %out, <8 x i32> %__mask)
// CHECK-CPU: define void @ispc_kernel___{{.*}}
// CHECK-CPU: call void @ispc_test___{{.*}}({{(<8 x float>\*)|ptr}} {{.*}})
// CHECK-CPU: define void @intersectISPC(i1 %{{.*}}, {{(%v8_uniform_Context\*)|ptr}} noalias %{{.*}}, {{(%v8_uniform_RayHit\*)|ptr}} noalias %{{.*}}, {{(float\*)|ptr}} noalias %{{.*}}, {{(i8\*)|ptr}} noalias %{{.*}})
// CHECK-CPU-NOT: addrspacecast {{(%v8_uniform_Context addrspace\(4\)\*)|(ptr addrspace\(4\))}} %{{.*}} to {{(%v8_uniform_Context\*)|ptr}}
// CHECK-CPU-NOT: addrspacecast {{(%v8_uniform_RayHit addrspace\(4\)\*)|(ptr addrspace\(4\))}} %{{.*}} to {{(%v8_uniform_RayHit\*)|ptr}}
// CHECK-CPU-NOT: addrspacecast {{(float addrspace\(4\)\*)|(ptr addrspace\(4\))}} %{{.*}} to {{(float\*)|ptr}}
// CHECK-CPU-NOT: addrspacecast {{(i8 addrspace\(4\)\*|ptr addrspace\(4\))}} %{{.*}} to {{(i8\*)|ptr}}
// CHECK-CPU: call void @swap___{{.*}}
// CHECK-CPU: define void @ispc_test({{(<8 x float>\*)|ptr}} noalias %out)
// CHECK-CPU-NOT: define void @ispc_kernel(
noinline void swap(uniform bool doSwap, float &a_foo, float &b_foo) { a_foo = doSwap ? b_foo : a_foo; }
export noinline void intersectISPC(uniform bool test, uniform Context *uniform context, uniform RayHit *uniform rayhit,
uniform float ret[], void* uniform params) {
if (rayhit->ray != 0)
rayhit->hit = context->t1[rayhit->geomID];
context->y = rayhit->hit;
float a1 = context->t1[programIndex] + ret[programIndex];
float b1 = context->t1[programIndex + programCount];
swap(test, a1, b1);
}
extern "C" void intersectExternal(uniform Context *uniform context, uniform RayHit *uniform rayhit,
uniform float ret[], void* uniform params);
task void kernel(void *uniform _params, uniform float ret[]) {
ISPCParams *uniform params = (ISPCParams * uniform) _params;
const uniform int y = taskIndex1;
const uniform int x = taskIndex0;
uniform Context context;
contextInit(&context);
uniform RayHit rayhit;
intersectExternal(&context, &rayhit, ret, params);
intersectISPC(false, &context, &rayhit, ret, params);
if (rayhit.geomID != 300) {
params->img_buf[x + y * params->img_size] = -1;
}
}
varying float LoadFloat(varying float * uniform InParam, const varying int Offset, const bool bConstant) {
return bConstant == true ? InParam[0] : InParam[Offset];
}
export noinline void ispc_test(varying float * uniform out) {
vec3f coord = {out[0], out[1], out[2]};
int offset = out[programIndex];
out[programIndex] = LoadFloat(out, offset, (out[programIndex] > out[programIndex + programCount]));
}
task void ispc_kernel(uniform float ret[]) {
ret[programIndex] = programCount;
float test = ret[programIndex];
ispc_test(&test);
}