143 lines
6.6 KiB
Plaintext
143 lines
6.6 KiB
Plaintext
// This test in conjunction with `xe_gather_coalescing_ptr_alloca.ispc` checks
|
|
// for vectorization of consecitive loads to aggregate structures (`vec3f`).
|
|
// The tests are split to check for vectorization of directly-addressed,
|
|
// alloca-allocated pointers and pointer-indirection to pointers based on
|
|
// non-constant terms (indvars).
|
|
|
|
|
|
// This test checks desired behavior of gather coalescing optimization.
|
|
// Current implementation produces the following code sequence 9 times:
|
|
// %ptr209 = getelementptr float, float* %self_load3_color6_mem31.i184278, i64 %scaled_offset208
|
|
// %self_load = load float, float* %ptr209, align 4
|
|
// %self_load_insert = insertelement <8 x float> undef, float %self_load, i32 X
|
|
// %self_load_insert_shuffle = shufflevector <8 x float> %self_load_insert, <8 x float> undef, <8 x i32> zeroinitializer
|
|
|
|
// The optimization should optimize memory access by combining each 3 loads to one plus EEI:
|
|
// %vectorized_ld = call <3 x float> @llvm.genx.svm.block.ld.unaligned.v8f32.i64(i64 %vectorized_address)
|
|
// %vectorized_extr_elem223 = extractelement <3 x float> %vectorized_ld, i64 1
|
|
// %vectorized_extr_elem222 = extractelement <3 x float> %vectorized_ld, i64 2
|
|
// %vectorized_extr_elem221 = extractelement <3 x float> %vectorized_ld, i64 3
|
|
|
|
// RUN: %{ispc} %s --target=xehpg-x16 --arch=xe64 -h %t.h --emit-llvm-text --debug-phase=321:321 --dump-file=%t -o /dev/null
|
|
// RUN: FileCheck --input-file %t/ir_321_ispcMemoryCoalescing.ll %s --check-prefixes CHECK_ALL,CHECK_LOAD,CHECK_VARYING
|
|
// RUN: %{ispc} %s --target=xehpg-x8 --arch=xe64 -h %t.h --emit-llvm-text --debug-phase=321:321 --dump-file=%t -o /dev/null
|
|
// RUN: FileCheck --input-file %t/ir_321_ispcMemoryCoalescing.ll %s --check-prefixes CHECK_ALL,CHECK_LOAD,CHECK_VARYING
|
|
|
|
// REQUIRES: XE_ENABLED
|
|
// XFAIL: XE_ENABLED
|
|
|
|
|
|
struct vec3f {
|
|
float x;
|
|
float y;
|
|
float z;
|
|
};
|
|
|
|
struct Data {
|
|
uint8 *mem;
|
|
};
|
|
|
|
struct Linear {
|
|
Data *opacity;
|
|
Data *color;
|
|
};
|
|
|
|
static inline vec3f make_vec3f(vec3f a, vec3f b) {
|
|
vec3f res;
|
|
res.x = a.x + b.x;
|
|
res.y = a.y + b.y;
|
|
res.z = a.z + b.z;
|
|
return res;
|
|
}
|
|
|
|
static inline vec3f get_color(const uniform Linear *uniform self, int index) {
|
|
return ((uniform vec3f * uniform) self->color->mem)[index];
|
|
}
|
|
|
|
#define NUM 64
|
|
|
|
|
|
// For test cases with uniform induction variables, we would like the loads to
|
|
// the contiguous fields of the vec3f structure at index i to be coalesced.
|
|
|
|
// CHECK_ALL-LABEL: @gather_coalescing_i
|
|
|
|
// CHECK_LOAD-NOT: %self_load{{[0-9]*}}_color{{[0-9]*}}_mem_{{.*}} = load float, float* %ptr{{[0-9]*}}
|
|
// CHECK_LOAD: %vectorized_ptrtoint = ptrtoint float* %ptr{{[0-9]*}} to i64
|
|
// CHECK_LOAD: %vectorized_address = add i64 %vectorized_ptrtoint, 0
|
|
// CHECK_LOAD: %vectorized_address_ptr = inttoptr i64 %vectorized_address to <4 x float>*
|
|
// CHECK_LOAD: %vectorized_ld_exp = load <4 x float>, <4 x float>* %vectorized_address_ptr
|
|
// CHECK_LOAD: %mem_coal_eei{{[0-9]*}} = extractelement <4 x float> %vectorized_ld_exp, i64 0
|
|
// CHECK_LOAD: %mem_coal_eei{{[0-9]*}} = extractelement <4 x float> %vectorized_ld_exp, i64 1
|
|
// CHECK_LOAD: %mem_coal_eei{{[0-9]*}} = extractelement <4 x float> %vectorized_ld_exp, i64 2
|
|
|
|
task void gather_coalescing_i(uniform float _out[], uniform float _in[], uniform Linear *uniform _self) {
|
|
vec3f v0 = {_in[0], _in[1], _in[2]};
|
|
|
|
for (uniform int i = 0; i < NUM; i++)
|
|
v0 = make_vec3f(v0, get_color(_self, i));
|
|
|
|
_out[programIndex] = v0.x + v0.y + v0.z;
|
|
}
|
|
|
|
// CHECK_ALL-LABEL: @gather_coalescing_inogetter
|
|
|
|
// CHECK_LOAD-NOT: %color{{[0-9]*}}_{{.*}} = load float, float* %ptr{{[0-9]*}}
|
|
// CHECK_LOAD: %vectorized_ptrtoint = ptrtoint float* %_in to i64
|
|
// CHECK_LOAD: %vectorized_address = add i64 %vectorized_ptrtoint, 0
|
|
// CHECK_LOAD: %vectorized_address_ptr = inttoptr i64 %vectorized_address to <4 x float>*
|
|
// CHECK_LOAD: %vectorized_ld_exp = load <4 x float>, <4 x float>* %vectorized_address_ptr
|
|
// CHECK_LOAD: %mem_coal_eei{{[0-9]*}} = extractelement <4 x float> %vectorized_ld_exp, i64 0
|
|
// CHECK_LOAD: %mem_coal_eei{{[0-9]*}} = extractelement <4 x float> %vectorized_ld_exp, i64 1
|
|
// CHECK_LOAD: %mem_coal_eei{{[0-9]*}} = extractelement <4 x float> %vectorized_ld_exp, i64 2
|
|
|
|
task void gather_coalescing_inogetter(uniform float _out[], uniform float _in[], uniform Linear *uniform _self) {
|
|
uniform uint8 color[1024];
|
|
vec3f v0 = {_in[0], _in[1], _in[2]};
|
|
|
|
for (uniform int i = 0; i < NUM; i++)
|
|
v0 = make_vec3f(v0, ((uniform vec3f * uniform)&color)[i]);
|
|
|
|
_out[programIndex] = v0.x + v0.y + v0.z;
|
|
}
|
|
|
|
// The tests cases below produce gather and scatter calls which currently
|
|
// cannot be coalesced.
|
|
|
|
// CHECK_ALL-LABEL: @gather_coalescing_ivarying
|
|
|
|
// CHECK_VARYING: %res{{.*}} = {{(tail )?}}call <{{(8|16)}} x float> @llvm.genx.svm.gather.v{{(8|16)}}f32
|
|
// CHECK_VARYING: %res{{.*}} = {{(tail )?}}call <{{(8|16)}} x float> @llvm.genx.svm.gather.v{{(8|16)}}f32
|
|
// CHECK_VARYING: %res{{.*}} = {{(tail )?}}call <{{(8|16)}} x float> @llvm.genx.svm.gather.v{{(8|16)}}f32
|
|
// CHECK_VARYING: call void @llvm.genx.svm.scatter.v{{(8|16)}}i1.v{{(8|16)}}i64.v{{(8|16)}}f32
|
|
// CHECK_VARYING: call void @llvm.genx.svm.scatter.v{{(8|16)}}i1.v{{(8|16)}}i64.v{{(8|16)}}f32
|
|
// CHECK_VARYING: call void @llvm.genx.svm.scatter.v{{(8|16)}}i1.v{{(8|16)}}i64.v{{(8|16)}}f32
|
|
|
|
task void gather_coalescing_ivarying(uniform float _out[], uniform float _in[], uniform Linear *uniform _self) {
|
|
vec3f v0 = {_in[0], _in[1], _in[2]};
|
|
|
|
for (varying int i = programIndex; i < NUM; i += programCount)
|
|
v0 = make_vec3f(v0, get_color(_self, i));
|
|
|
|
_out[programIndex] = v0.x + v0.y + v0.z;
|
|
}
|
|
|
|
// CHECK_ALL-LABEL: @gather_coalescing_ivaryingnogetter
|
|
|
|
// CHECK_VARYING: %res{{.*}} = {{(tail )?}}call <{{(8|16)}} x float> @llvm.genx.svm.gather.v{{(8|16)}}f32
|
|
// CHECK_VARYING: %res{{.*}} = {{(tail )?}}call <{{(8|16)}} x float> @llvm.genx.svm.gather.v{{(8|16)}}f32
|
|
// CHECK_VARYING: %res{{.*}} = {{(tail )?}}call <{{(8|16)}} x float> @llvm.genx.svm.gather.v{{(8|16)}}f32
|
|
// CHECK_VARYING: call void @llvm.genx.svm.scatter.v{{(8|16)}}i1.v{{(8|16)}}i64.v{{(8|16)}}f32
|
|
// CHECK_VARYING: call void @llvm.genx.svm.scatter.v{{(8|16)}}i1.v{{(8|16)}}i64.v{{(8|16)}}f32
|
|
// CHECK_VARYING: call void @llvm.genx.svm.scatter.v{{(8|16)}}i1.v{{(8|16)}}i64.v{{(8|16)}}f32
|
|
|
|
task void gather_coalescing_ivaryingnogetter(uniform float _out[], uniform float _in[], uniform Linear *uniform _self) {
|
|
uniform uint8 color[1024];
|
|
vec3f v0 = {_in[0], _in[1], _in[2]};
|
|
|
|
for (varying int i = programIndex; i < NUM; i += programCount)
|
|
v0 = make_vec3f(v0, ((uniform vec3f * uniform)&color)[i]);
|
|
|
|
_out[programIndex] = v0.x + v0.y + v0.z;
|
|
}
|