diff options
126 files changed, 95 insertions, 25375 deletions
@@ -25,7 +25,3 @@ members = [ ]
default-members = ["zluda_lib", "zluda_ml", "zluda_inject", "zluda_redirect"]
-
-[patch.crates-io]
-rspirv = { git = 'https://github.com/vosen/rspirv', rev = '9826e59a232c4a426482cda12f88d11bfda3ff9c' }
-spirv_headers = { git = 'https://github.com/vosen/rspirv', rev = '9826e59a232c4a426482cda12f88d11bfda3ff9c' }
diff --git a/ptx/Cargo.toml b/ptx/Cargo.toml index e2c4ff8..9f3fa02 100644 --- a/ptx/Cargo.toml +++ b/ptx/Cargo.toml @@ -9,9 +9,6 @@ edition = "2021" [dependencies] ptx_parser = { path = "../ptx_parser" } llvm_zluda = { path = "../llvm_zluda" } -regex = "1" -rspirv = "0.7" -spirv_headers = "1.5" quick-error = "1.2" thiserror = "1.0" bit-vec = "0.6" @@ -21,18 +18,9 @@ rustc-hash = "2.0.0" strum = "0.26" strum_macros = "0.26" -[dependencies.lalrpop-util] -version = "0.19.12" -features = ["lexer"] - -[build-dependencies.lalrpop] -version = "0.19.12" -features = ["lexer"] - [dev-dependencies] hip_runtime-sys = { path = "../ext/hip_runtime-sys" } comgr = { path = "../comgr" } -spirv_tools-sys = { path = "../spirv_tools-sys" } tempfile = "3" paste = "1.0" cuda-driver-sys = "0.3.0" diff --git a/ptx/build.rs b/ptx/build.rs deleted file mode 100644 index 42c5d59..0000000 --- a/ptx/build.rs +++ /dev/null @@ -1,5 +0,0 @@ -extern crate lalrpop; - -fn main() { - lalrpop::process_root().unwrap(); -}
\ No newline at end of file diff --git a/ptx/lib/zluda_ptx_impl.cl b/ptx/lib/zluda_ptx_impl.cl deleted file mode 100644 index 86bb593..0000000 --- a/ptx/lib/zluda_ptx_impl.cl +++ /dev/null @@ -1,344 +0,0 @@ -// Every time this file changes it must te rebuilt:
-// ocloc -file zluda_ptx_impl.cl -64 -options "-cl-std=CL2.0 -Dcl_intel_bit_instructions -DINTEL" -out_dir . -device kbl -output_no_suffix -spv_only
-// /opt/rocm/llvm/bin/clang -Wall -Wextra -Wsign-compare -Wconversion -x cl -Xclang -finclude-default-header zluda_ptx_impl.cl -cl-std=CL2.0 -c -target amdgcn-amd-amdhsa -o zluda_ptx_impl.bc -emit-llvm
-// Additionally you should strip names:
-// spirv-opt --strip-debug zluda_ptx_impl.spv -o zluda_ptx_impl.spv --target-env=spv1.3
-
-#pragma OPENCL EXTENSION cl_khr_int64_base_atomics : enable
-#pragma OPENCL EXTENSION cl_khr_int64_extended_atomics : enable
-
-#define FUNC(NAME) __zluda_ptx_impl__ ## NAME
-
-#define atomic_inc(NAME, SUCCESS, FAILURE, SCOPE, SPACE) \
- uint FUNC(NAME)(SPACE uint* ptr, uint threshold) { \
- uint expected = *ptr; \
- uint desired; \
- do { \
- desired = (expected >= threshold) ? 0 : expected + 1; \
- } while (!atomic_compare_exchange_strong_explicit((volatile SPACE atomic_uint*)ptr, &expected, desired, SUCCESS, FAILURE, SCOPE)); \
- return expected; \
- }
-
-#define atomic_dec(NAME, SUCCESS, FAILURE, SCOPE, SPACE) \
- uint FUNC(NAME)(SPACE uint* ptr, uint threshold) { \
- uint expected = *ptr; \
- uint desired; \
- do { \
- desired = (expected == 0 || expected > threshold) ? threshold : expected - 1; \
- } while (!atomic_compare_exchange_strong_explicit((volatile SPACE atomic_uint*)ptr, &expected, desired, SUCCESS, FAILURE, SCOPE)); \
- return expected; \
- }
-
-#define atomic_add(NAME, SUCCESS, FAILURE, SCOPE, SPACE, TYPE, ATOMIC_TYPE, INT_TYPE) \
- TYPE FUNC(NAME)(SPACE TYPE* ptr, TYPE value) { \
- volatile SPACE ATOMIC_TYPE* atomic_ptr = (volatile SPACE ATOMIC_TYPE*)ptr; \
- union { \
- INT_TYPE int_view; \
- TYPE float_view; \
- } expected, desired; \
- expected.float_view = *ptr; \
- do { \
- desired.float_view = expected.float_view + value; \
- } while (!atomic_compare_exchange_strong_explicit(atomic_ptr, &expected.int_view, desired.int_view, SUCCESS, FAILURE, SCOPE)); \
- return expected.float_view; \
- }
-
-// We are doing all this mess instead of accepting memory_order and memory_scope parameters
-// because ocloc emits broken (failing spirv-dis) SPIR-V when memory_order or memory_scope is a parameter
-
-// atom.inc
-atomic_inc(atom_relaxed_cta_generic_inc, memory_order_relaxed, memory_order_relaxed, memory_scope_work_group, );
-atomic_inc(atom_acquire_cta_generic_inc, memory_order_acquire, memory_order_acquire, memory_scope_work_group, );
-atomic_inc(atom_release_cta_generic_inc, memory_order_release, memory_order_acquire, memory_scope_work_group, );
-atomic_inc(atom_acq_rel_cta_generic_inc, memory_order_acq_rel, memory_order_acquire, memory_scope_work_group, );
-
-atomic_inc(atom_relaxed_gpu_generic_inc, memory_order_relaxed, memory_order_relaxed, memory_scope_device, );
-atomic_inc(atom_acquire_gpu_generic_inc, memory_order_acquire, memory_order_acquire, memory_scope_device, );
-atomic_inc(atom_release_gpu_generic_inc, memory_order_release, memory_order_acquire, memory_scope_device, );
-atomic_inc(atom_acq_rel_gpu_generic_inc, memory_order_acq_rel, memory_order_acquire, memory_scope_device, );
-
-atomic_inc(atom_relaxed_sys_generic_inc, memory_order_relaxed, memory_order_relaxed, memory_scope_device, );
-atomic_inc(atom_acquire_sys_generic_inc, memory_order_acquire, memory_order_acquire, memory_scope_device, );
-atomic_inc(atom_release_sys_generic_inc, memory_order_release, memory_order_acquire, memory_scope_device, );
-atomic_inc(atom_acq_rel_sys_generic_inc, memory_order_acq_rel, memory_order_acquire, memory_scope_device, );
-
-atomic_inc(atom_relaxed_cta_global_inc, memory_order_relaxed, memory_order_relaxed, memory_scope_work_group, __global);
-atomic_inc(atom_acquire_cta_global_inc, memory_order_acquire, memory_order_acquire, memory_scope_work_group, __global);
-atomic_inc(atom_release_cta_global_inc, memory_order_release, memory_order_acquire, memory_scope_work_group, __global);
-atomic_inc(atom_acq_rel_cta_global_inc, memory_order_acq_rel, memory_order_acquire, memory_scope_work_group, __global);
-
-atomic_inc(atom_relaxed_gpu_global_inc, memory_order_relaxed, memory_order_relaxed, memory_scope_device, __global);
-atomic_inc(atom_acquire_gpu_global_inc, memory_order_acquire, memory_order_acquire, memory_scope_device, __global);
-atomic_inc(atom_release_gpu_global_inc, memory_order_release, memory_order_acquire, memory_scope_device, __global);
-atomic_inc(atom_acq_rel_gpu_global_inc, memory_order_acq_rel, memory_order_acquire, memory_scope_device, __global);
-
-atomic_inc(atom_relaxed_sys_global_inc, memory_order_relaxed, memory_order_relaxed, memory_scope_device, __global);
-atomic_inc(atom_acquire_sys_global_inc, memory_order_acquire, memory_order_acquire, memory_scope_device, __global);
-atomic_inc(atom_release_sys_global_inc, memory_order_release, memory_order_acquire, memory_scope_device, __global);
-atomic_inc(atom_acq_rel_sys_global_inc, memory_order_acq_rel, memory_order_acquire, memory_scope_device, __global);
-
-atomic_inc(atom_relaxed_cta_shared_inc, memory_order_relaxed, memory_order_relaxed, memory_scope_work_group, __local);
-atomic_inc(atom_acquire_cta_shared_inc, memory_order_acquire, memory_order_acquire, memory_scope_work_group, __local);
-atomic_inc(atom_release_cta_shared_inc, memory_order_release, memory_order_acquire, memory_scope_work_group, __local);
-atomic_inc(atom_acq_rel_cta_shared_inc, memory_order_acq_rel, memory_order_acquire, memory_scope_work_group, __local);
-
-atomic_inc(atom_relaxed_gpu_shared_inc, memory_order_relaxed, memory_order_relaxed, memory_scope_device, __local);
-atomic_inc(atom_acquire_gpu_shared_inc, memory_order_acquire, memory_order_acquire, memory_scope_device, __local);
-atomic_inc(atom_release_gpu_shared_inc, memory_order_release, memory_order_acquire, memory_scope_device, __local);
-atomic_inc(atom_acq_rel_gpu_shared_inc, memory_order_acq_rel, memory_order_acquire, memory_scope_device, __local);
-
-atomic_inc(atom_relaxed_sys_shared_inc, memory_order_relaxed, memory_order_relaxed, memory_scope_device, __local);
-atomic_inc(atom_acquire_sys_shared_inc, memory_order_acquire, memory_order_acquire, memory_scope_device, __local);
-atomic_inc(atom_release_sys_shared_inc, memory_order_release, memory_order_acquire, memory_scope_device, __local);
-atomic_inc(atom_acq_rel_sys_shared_inc, memory_order_acq_rel, memory_order_acquire, memory_scope_device, __local);
-
-// atom.dec
-atomic_dec(atom_relaxed_cta_generic_dec, memory_order_relaxed, memory_order_relaxed, memory_scope_work_group, );
-atomic_dec(atom_acquire_cta_generic_dec, memory_order_acquire, memory_order_acquire, memory_scope_work_group, );
-atomic_dec(atom_release_cta_generic_dec, memory_order_release, memory_order_acquire, memory_scope_work_group, );
-atomic_dec(atom_acq_rel_cta_generic_dec, memory_order_acq_rel, memory_order_acquire, memory_scope_work_group, );
-
-atomic_dec(atom_relaxed_gpu_generic_dec, memory_order_relaxed, memory_order_relaxed, memory_scope_device, );
-atomic_dec(atom_acquire_gpu_generic_dec, memory_order_acquire, memory_order_acquire, memory_scope_device, );
-atomic_dec(atom_release_gpu_generic_dec, memory_order_release, memory_order_acquire, memory_scope_device, );
-atomic_dec(atom_acq_rel_gpu_generic_dec, memory_order_acq_rel, memory_order_acquire, memory_scope_device, );
-
-atomic_dec(atom_relaxed_sys_generic_dec, memory_order_relaxed, memory_order_relaxed, memory_scope_device, );
-atomic_dec(atom_acquire_sys_generic_dec, memory_order_acquire, memory_order_acquire, memory_scope_device, );
-atomic_dec(atom_release_sys_generic_dec, memory_order_release, memory_order_acquire, memory_scope_device, );
-atomic_dec(atom_acq_rel_sys_generic_dec, memory_order_acq_rel, memory_order_acquire, memory_scope_device, );
-
-atomic_dec(atom_relaxed_cta_global_dec, memory_order_relaxed, memory_order_relaxed, memory_scope_work_group, __global);
-atomic_dec(atom_acquire_cta_global_dec, memory_order_acquire, memory_order_acquire, memory_scope_work_group, __global);
-atomic_dec(atom_release_cta_global_dec, memory_order_release, memory_order_acquire, memory_scope_work_group, __global);
-atomic_dec(atom_acq_rel_cta_global_dec, memory_order_acq_rel, memory_order_acquire, memory_scope_work_group, __global);
-
-atomic_dec(atom_relaxed_gpu_global_dec, memory_order_relaxed, memory_order_relaxed, memory_scope_device, __global);
-atomic_dec(atom_acquire_gpu_global_dec, memory_order_acquire, memory_order_acquire, memory_scope_device, __global);
-atomic_dec(atom_release_gpu_global_dec, memory_order_release, memory_order_acquire, memory_scope_device, __global);
-atomic_dec(atom_acq_rel_gpu_global_dec, memory_order_acq_rel, memory_order_acquire, memory_scope_device, __global);
-
-atomic_dec(atom_relaxed_sys_global_dec, memory_order_relaxed, memory_order_relaxed, memory_scope_device, __global);
-atomic_dec(atom_acquire_sys_global_dec, memory_order_acquire, memory_order_acquire, memory_scope_device, __global);
-atomic_dec(atom_release_sys_global_dec, memory_order_release, memory_order_acquire, memory_scope_device, __global);
-atomic_dec(atom_acq_rel_sys_global_dec, memory_order_acq_rel, memory_order_acquire, memory_scope_device, __global);
-
-atomic_dec(atom_relaxed_cta_shared_dec, memory_order_relaxed, memory_order_relaxed, memory_scope_work_group, __local);
-atomic_dec(atom_acquire_cta_shared_dec, memory_order_acquire, memory_order_acquire, memory_scope_work_group, __local);
-atomic_dec(atom_release_cta_shared_dec, memory_order_release, memory_order_acquire, memory_scope_work_group, __local);
-atomic_dec(atom_acq_rel_cta_shared_dec, memory_order_acq_rel, memory_order_acquire, memory_scope_work_group, __local);
-
-atomic_dec(atom_relaxed_gpu_shared_dec, memory_order_relaxed, memory_order_relaxed, memory_scope_device, __local);
-atomic_dec(atom_acquire_gpu_shared_dec, memory_order_acquire, memory_order_acquire, memory_scope_device, __local);
-atomic_dec(atom_acq_rel_sys_shared_dec, memory_order_acq_rel, memory_order_acquire, memory_scope_device, __local);
-
-// atom.add.f32
-atomic_add(atom_relaxed_cta_generic_add_f32, memory_order_relaxed, memory_order_relaxed, memory_scope_work_group, , float, atomic_uint, uint);
-atomic_add(atom_acquire_cta_generic_add_f32, memory_order_acquire, memory_order_acquire, memory_scope_work_group, , float, atomic_uint, uint);
-atomic_add(atom_release_cta_generic_add_f32, memory_order_release, memory_order_acquire, memory_scope_work_group, , float, atomic_uint, uint);
-atomic_add(atom_acq_rel_cta_generic_add_f32, memory_order_acq_rel, memory_order_acquire, memory_scope_work_group, , float, atomic_uint, uint);
-
-atomic_add(atom_relaxed_gpu_generic_add_f32, memory_order_relaxed, memory_order_relaxed, memory_scope_device, , float, atomic_uint, uint);
-atomic_add(atom_acquire_gpu_generic_add_f32, memory_order_acquire, memory_order_acquire, memory_scope_device, , float, atomic_uint, uint);
-atomic_add(atom_release_gpu_generic_add_f32, memory_order_release, memory_order_acquire, memory_scope_device, , float, atomic_uint, uint);
-atomic_add(atom_acq_rel_gpu_generic_add_f32, memory_order_acq_rel, memory_order_acquire, memory_scope_device, , float, atomic_uint, uint);
-
-atomic_add(atom_relaxed_sys_generic_add_f32, memory_order_relaxed, memory_order_relaxed, memory_scope_device, , float, atomic_uint, uint);
-atomic_add(atom_acquire_sys_generic_add_f32, memory_order_acquire, memory_order_acquire, memory_scope_device, , float, atomic_uint, uint);
-atomic_add(atom_release_sys_generic_add_f32, memory_order_release, memory_order_acquire, memory_scope_device, , float, atomic_uint, uint);
-atomic_add(atom_acq_rel_sys_generic_add_f32, memory_order_acq_rel, memory_order_acquire, memory_scope_device, , float, atomic_uint, uint);
-
-atomic_add(atom_relaxed_cta_global_add_f32, memory_order_relaxed, memory_order_relaxed, memory_scope_work_group, __global, float, atomic_uint, uint);
-atomic_add(atom_acquire_cta_global_add_f32, memory_order_acquire, memory_order_acquire, memory_scope_work_group, __global, float, atomic_uint, uint);
-atomic_add(atom_release_cta_global_add_f32, memory_order_release, memory_order_acquire, memory_scope_work_group, __global, float, atomic_uint, uint);
-atomic_add(atom_acq_rel_cta_global_add_f32, memory_order_acq_rel, memory_order_acquire, memory_scope_work_group, __global, float, atomic_uint, uint);
-
-atomic_add(atom_relaxed_gpu_global_add_f32, memory_order_relaxed, memory_order_relaxed, memory_scope_device, __global, float, atomic_uint, uint);
-atomic_add(atom_acquire_gpu_global_add_f32, memory_order_acquire, memory_order_acquire, memory_scope_device, __global, float, atomic_uint, uint);
-atomic_add(atom_release_gpu_global_add_f32, memory_order_release, memory_order_acquire, memory_scope_device, __global, float, atomic_uint, uint);
-atomic_add(atom_acq_rel_gpu_global_add_f32, memory_order_acq_rel, memory_order_acquire, memory_scope_device, __global, float, atomic_uint, uint);
-
-atomic_add(atom_relaxed_sys_global_add_f32, memory_order_relaxed, memory_order_relaxed, memory_scope_device, __global, float, atomic_uint, uint);
-atomic_add(atom_acquire_sys_global_add_f32, memory_order_acquire, memory_order_acquire, memory_scope_device, __global, float, atomic_uint, uint);
-atomic_add(atom_release_sys_global_add_f32, memory_order_release, memory_order_acquire, memory_scope_device, __global, float, atomic_uint, uint);
-atomic_add(atom_acq_rel_sys_global_add_f32, memory_order_acq_rel, memory_order_acquire, memory_scope_device, __global, float, atomic_uint, uint);
-
-atomic_add(atom_relaxed_cta_shared_add_f32, memory_order_relaxed, memory_order_relaxed, memory_scope_work_group, __local, float, atomic_uint, uint);
-atomic_add(atom_acquire_cta_shared_add_f32, memory_order_acquire, memory_order_acquire, memory_scope_work_group, __local, float, atomic_uint, uint);
-atomic_add(atom_release_cta_shared_add_f32, memory_order_release, memory_order_acquire, memory_scope_work_group, __local, float, atomic_uint, uint);
-atomic_add(atom_acq_rel_cta_shared_add_f32, memory_order_acq_rel, memory_order_acquire, memory_scope_work_group, __local, float, atomic_uint, uint);
-
-atomic_add(atom_relaxed_gpu_shared_add_f32, memory_order_relaxed, memory_order_relaxed, memory_scope_device, __local, float, atomic_uint, uint);
-atomic_add(atom_acquire_gpu_shared_add_f32, memory_order_acquire, memory_order_acquire, memory_scope_device, __local, float, atomic_uint, uint);
-atomic_add(atom_release_gpu_shared_add_f32, memory_order_release, memory_order_acquire, memory_scope_device, __local, float, atomic_uint, uint);
-atomic_add(atom_acq_rel_gpu_shared_add_f32, memory_order_acq_rel, memory_order_acquire, memory_scope_device, __local, float, atomic_uint, uint);
-
-atomic_add(atom_relaxed_sys_shared_add_f32, memory_order_relaxed, memory_order_relaxed, memory_scope_device, __local, float, atomic_uint, uint);
-atomic_add(atom_acquire_sys_shared_add_f32, memory_order_acquire, memory_order_acquire, memory_scope_device, __local, float, atomic_uint, uint);
-atomic_add(atom_release_sys_shared_add_f32, memory_order_release, memory_order_acquire, memory_scope_device, __local, float, atomic_uint, uint);
-atomic_add(atom_acq_rel_sys_shared_add_f32, memory_order_acq_rel, memory_order_acquire, memory_scope_device, __local, float, atomic_uint, uint);
-
-atomic_add(atom_relaxed_cta_generic_add_f64, memory_order_relaxed, memory_order_relaxed, memory_scope_work_group, , double, atomic_ulong, ulong);
-atomic_add(atom_acquire_cta_generic_add_f64, memory_order_acquire, memory_order_acquire, memory_scope_work_group, , double, atomic_ulong, ulong);
-atomic_add(atom_release_cta_generic_add_f64, memory_order_release, memory_order_acquire, memory_scope_work_group, , double, atomic_ulong, ulong);
-atomic_add(atom_acq_rel_cta_generic_add_f64, memory_order_acq_rel, memory_order_acquire, memory_scope_work_group, , double, atomic_ulong, ulong);
-
-atomic_add(atom_relaxed_gpu_generic_add_f64, memory_order_relaxed, memory_order_relaxed, memory_scope_device, , double, atomic_ulong, ulong);
-atomic_add(atom_acquire_gpu_generic_add_f64, memory_order_acquire, memory_order_acquire, memory_scope_device, , double, atomic_ulong, ulong);
-atomic_add(atom_release_gpu_generic_add_f64, memory_order_release, memory_order_acquire, memory_scope_device, , double, atomic_ulong, ulong);
-atomic_add(atom_acq_rel_gpu_generic_add_f64, memory_order_acq_rel, memory_order_acquire, memory_scope_device, , double, atomic_ulong, ulong);
-
-atomic_add(atom_relaxed_sys_generic_add_f64, memory_order_relaxed, memory_order_relaxed, memory_scope_device, , double, atomic_ulong, ulong);
-atomic_add(atom_acquire_sys_generic_add_f64, memory_order_acquire, memory_order_acquire, memory_scope_device, , double, atomic_ulong, ulong);
-atomic_add(atom_release_sys_generic_add_f64, memory_order_release, memory_order_acquire, memory_scope_device, , double, atomic_ulong, ulong);
-atomic_add(atom_acq_rel_sys_generic_add_f64, memory_order_acq_rel, memory_order_acquire, memory_scope_device, , double, atomic_ulong, ulong);
-// atom.add.f64
-atomic_add(atom_relaxed_cta_global_add_f64, memory_order_relaxed, memory_order_relaxed, memory_scope_work_group, __global, double, atomic_ulong, ulong);
-atomic_add(atom_acquire_cta_global_add_f64, memory_order_acquire, memory_order_acquire, memory_scope_work_group, __global, double, atomic_ulong, ulong);
-atomic_add(atom_release_cta_global_add_f64, memory_order_release, memory_order_acquire, memory_scope_work_group, __global, double, atomic_ulong, ulong);
-atomic_add(atom_acq_rel_cta_global_add_f64, memory_order_acq_rel, memory_order_acquire, memory_scope_work_group, __global, double, atomic_ulong, ulong);
-
-atomic_add(atom_relaxed_gpu_global_add_f64, memory_order_relaxed, memory_order_relaxed, memory_scope_device, __global, double, atomic_ulong, ulong);
-atomic_add(atom_acquire_gpu_global_add_f64, memory_order_acquire, memory_order_acquire, memory_scope_device, __global, double, atomic_ulong, ulong);
-atomic_add(atom_release_gpu_global_add_f64, memory_order_release, memory_order_acquire, memory_scope_device, __global, double, atomic_ulong, ulong);
-atomic_add(atom_acq_rel_gpu_global_add_f64, memory_order_acq_rel, memory_order_acquire, memory_scope_device, __global, double, atomic_ulong, ulong);
-
-atomic_add(atom_relaxed_sys_global_add_f64, memory_order_relaxed, memory_order_relaxed, memory_scope_device, __global, double, atomic_ulong, ulong);
-atomic_add(atom_acquire_sys_global_add_f64, memory_order_acquire, memory_order_acquire, memory_scope_device, __global, double, atomic_ulong, ulong);
-atomic_add(atom_release_sys_global_add_f64, memory_order_release, memory_order_acquire, memory_scope_device, __global, double, atomic_ulong, ulong);
-atomic_add(atom_acq_rel_sys_global_add_f64, memory_order_acq_rel, memory_order_acquire, memory_scope_device, __global, double, atomic_ulong, ulong);
-
-atomic_add(atom_relaxed_cta_shared_add_f64, memory_order_relaxed, memory_order_relaxed, memory_scope_work_group, __local, double, atomic_ulong, ulong);
-atomic_add(atom_acquire_cta_shared_add_f64, memory_order_acquire, memory_order_acquire, memory_scope_work_group, __local, double, atomic_ulong, ulong);
-atomic_add(atom_release_cta_shared_add_f64, memory_order_release, memory_order_acquire, memory_scope_work_group, __local, double, atomic_ulong, ulong);
-atomic_add(atom_acq_rel_cta_shared_add_f64, memory_order_acq_rel, memory_order_acquire, memory_scope_work_group, __local, double, atomic_ulong, ulong);
-
-atomic_add(atom_relaxed_gpu_shared_add_f64, memory_order_relaxed, memory_order_relaxed, memory_scope_device, __local, double, atomic_ulong, ulong);
-atomic_add(atom_acquire_gpu_shared_add_f64, memory_order_acquire, memory_order_acquire, memory_scope_device, __local, double, atomic_ulong, ulong);
-atomic_add(atom_release_gpu_shared_add_f64, memory_order_release, memory_order_acquire, memory_scope_device, __local, double, atomic_ulong, ulong);
-atomic_add(atom_acq_rel_gpu_shared_add_f64, memory_order_acq_rel, memory_order_acquire, memory_scope_device, __local, double, atomic_ulong, ulong);
-
-atomic_add(atom_relaxed_sys_shared_add_f64, memory_order_relaxed, memory_order_relaxed, memory_scope_device, __local, double, atomic_ulong, ulong);
-atomic_add(atom_acquire_sys_shared_add_f64, memory_order_acquire, memory_order_acquire, memory_scope_device, __local, double, atomic_ulong, ulong);
-atomic_add(atom_release_sys_shared_add_f64, memory_order_release, memory_order_acquire, memory_scope_device, __local, double, atomic_ulong, ulong);
-atomic_add(atom_acq_rel_sys_shared_add_f64, memory_order_acq_rel, memory_order_acquire, memory_scope_device, __local, double, atomic_ulong, ulong);
-
-#ifdef INTEL
- uint FUNC(bfe_u32)(uint base, uint pos, uint len) {
- return intel_ubfe(base, pos, len);
- }
-
- ulong FUNC(bfe_u64)(ulong base, uint pos, uint len) {
- return intel_ubfe(base, pos, len);
- }
-
- int FUNC(bfe_s32)(int base, uint pos, uint len) {
- return intel_sbfe(base, pos, len);
- }
-
- long FUNC(bfe_s64)(long base, uint pos, uint len) {
- return intel_sbfe(base, pos, len);
- }
-
- uint FUNC(bfi_b32)(uint insert, uint base, uint offset, uint count) {
- return intel_bfi(base, insert, offset, count);
- }
-
- ulong FUNC(bfi_b64)(ulong insert, ulong base, uint offset, uint count) {
- return intel_bfi(base, insert, offset, count);
- }
-
- uint FUNC(brev_b32)(uint base) {
- return intel_bfrev(base);
- }
-
- ulong FUNC(brev_b64)(ulong base) {
- return intel_bfrev(base);
- }
-#else
- uint FUNC(bfe_u32)(uint base, uint pos, uint len) {
- return amd_bfe(base, pos, len);
- }
-
- ulong FUNC(bfe_u64)(ulong base, uint pos, uint len) {
- return (base >> pos) & len;
- }
-
- int FUNC(bfe_s32)(int base, uint pos, uint len) {
- return amd_bfe(base, pos, len);
- }
-
- long FUNC(bfe_s64)(long base, uint pos, uint len) {
- return (base >> pos) & len;
- }
-
- uint FUNC(bfi_b32)(uint insert, uint base, uint offset, uint count) {
- uint mask = amd_bfm(count, offset);
- return (~mask & base) | (mask & insert);
- }
-
- ulong FUNC(bfi_b64)(ulong insert, ulong base, uint offset, uint count) {
- ulong mask = ((1UL << (count & 0x3f)) - 1UL) << (offset & 0x3f);
- return (~mask & base) | (mask & insert);
- }
-
- extern __attribute__((const)) uint __llvm_bitreverse_i32(uint) __asm("llvm.bitreverse.i32");
- uint FUNC(brev_b32)(uint base) {
- return __llvm_bitreverse_i32(base);
- }
-
- extern __attribute__((const)) ulong __llvm_bitreverse_i64(ulong) __asm("llvm.bitreverse.i64");
- ulong FUNC(brev_b64)(ulong base) {
- return __llvm_bitreverse_i64(base);
- }
-
- // Taken from __ballot definition in hipamd/include/hip/amd_detail/amd_device_functions.h
- uint FUNC(activemask)() {
- return (uint)__builtin_amdgcn_uicmp(1, 0, 33);
- }
-
- uint FUNC(sreg_tid)(uchar dim) {
- return (uint)get_local_id(dim);
- }
-
- uint FUNC(sreg_ntid)(uchar dim) {
- return (uint)get_local_size(dim);
- }
-
- uint FUNC(sreg_ctaid)(uchar dim) {
- return (uint)get_group_id(dim);
- }
-
- uint FUNC(sreg_nctaid)(uchar dim) {
- return (uint)get_num_groups(dim);
- }
-
- uint FUNC(sreg_clock)() {
- return (uint)__builtin_amdgcn_s_memtime();
- }
-
- // Taken from __ballot definition in hipamd/include/hip/amd_detail/amd_device_functions.h
- // They return active threads, which I think is incorrect
- extern __attribute__((const)) uint __ockl_lane_u32();
- uint FUNC(sreg_lanemask_lt)() {
- uint lane_idx = __ockl_lane_u32();
- ulong mask = (1UL << lane_idx) - 1UL;
- return (uint)mask;
- }
-#endif
-
-void FUNC(__assertfail)(
- __attribute__((unused)) __private ulong* message,
- __attribute__((unused)) __private ulong* file,
- __attribute__((unused)) __private uint* line,
- __attribute__((unused)) __private ulong* function,
- __attribute__((unused)) __private ulong* charSize
-) {
-}
-
-uint FUNC(vprintf)(
- __attribute__((unused)) __generic void* format,
- __attribute__((unused)) __generic void* valist
-) {
- return 0;
-}
diff --git a/ptx/lib/zluda_ptx_impl.spv b/ptx/lib/zluda_ptx_impl.spv Binary files differdeleted file mode 100644 index e9fc938..0000000 --- a/ptx/lib/zluda_ptx_impl.spv +++ /dev/null diff --git a/ptx/src/ast.rs b/ptx/src/ast.rs deleted file mode 100644 index 358b8ce..0000000 --- a/ptx/src/ast.rs +++ /dev/null @@ -1,1074 +0,0 @@ -use half::f16; -use lalrpop_util::{lexer::Token, ParseError}; -use std::{convert::From, mem, num::ParseFloatError, str::FromStr}; -use std::{marker::PhantomData, num::ParseIntError}; - -#[derive(Debug, thiserror::Error)] -pub enum PtxError { - #[error("{source}")] - ParseInt { - #[from] - source: ParseIntError, - }, - #[error("{source}")] - ParseFloat { - #[from] - source: ParseFloatError, - }, - #[error("")] - Unsupported32Bit, - #[error("")] - SyntaxError, - #[error("")] - NonF32Ftz, - #[error("")] - WrongArrayType, - #[error("")] - WrongVectorElement, - #[error("")] - MultiArrayVariable, - #[error("")] - ZeroDimensionArray, - #[error("")] - ArrayInitalizer, - #[error("")] - NonExternPointer, - #[error("{start}:{end}")] - UnrecognizedStatement { start: usize, end: usize }, - #[error("{start}:{end}")] - UnrecognizedDirective { start: usize, end: usize }, -} - -// For some weird reson this is illegal: -// .param .f16x2 foobar; -// but this is legal: -// .param .f16x2 foobar[1]; -// even more interestingly this is legal, but only in .func (not in .entry): -// .param .b32 foobar[] - -#[derive(Copy, Clone, Eq, PartialEq)] -pub enum BarDetails { - SyncAligned, -} - -pub trait UnwrapWithVec<E, To> { - fn unwrap_with(self, errs: &mut Vec<E>) -> To; -} - -impl<R: Default, EFrom: std::convert::Into<EInto>, EInto> UnwrapWithVec<EInto, R> - for Result<R, EFrom> -{ - fn unwrap_with(self, errs: &mut Vec<EInto>) -> R { - self.unwrap_or_else(|e| { - errs.push(e.into()); - R::default() - }) - } -} - -impl< - R1: Default, - EFrom1: std::convert::Into<EInto>, - R2: Default, - EFrom2: std::convert::Into<EInto>, - EInto, - > UnwrapWithVec<EInto, (R1, R2)> for (Result<R1, EFrom1>, Result<R2, EFrom2>) -{ - fn unwrap_with(self, errs: &mut Vec<EInto>) -> (R1, R2) { - let (x, y) = self; - let r1 = x.unwrap_with(errs); - let r2 = y.unwrap_with(errs); - (r1, r2) - } -} - -pub struct Module<'a> { - pub version: (u8, u8), - pub directives: Vec<Directive<'a, ParsedArgParams<'a>>>, -} - -pub enum Directive<'a, P: ArgParams> { - Variable(LinkingDirective, Variable<P::Id>), - Method(LinkingDirective, Function<'a, &'a str, Statement<P>>), -} - -#[derive(Hash, PartialEq, Eq, Copy, Clone)] -pub enum MethodName<'input, ID> { - Kernel(&'input str), - Func(ID), -} - -pub struct MethodDeclaration<'input, ID> { - pub return_arguments: Vec<Variable<ID>>, - pub name: MethodName<'input, ID>, - pub input_arguments: Vec<Variable<ID>>, - pub shared_mem: Option<ID>, -} - -pub struct Function<'a, ID, S> { - pub func_directive: MethodDeclaration<'a, ID>, - pub tuning: Vec<TuningDirective>, - pub body: Option<Vec<S>>, -} - -pub type ParsedFunction<'a> = Function<'a, &'a str, Statement<ParsedArgParams<'a>>>; - -#[derive(PartialEq, Eq, Clone)] -pub enum Type { - // .param.b32 foo; - // -> OpTypeInt - Scalar(ScalarType), - // .param.v2.b32 foo; - // -> OpTypeVector - Vector(ScalarType, u8), - // .param.b32 foo[4]; - // -> OpTypeArray - Array(ScalarType, Vec<u32>), - /* - Variables of this type almost never exist in the original .ptx and are - usually artificially created. Some examples below: - - extern pointers to the .shared memory in the form: - .extern .shared .b32 shared_mem[]; - which we first parse as - .extern .shared .b32 shared_mem; - and then convert to an additional function parameter: - .param .ptr<.b32.shared> shared_mem; - and do a load at the start of the function (and renames inside fn): - .reg .ptr<.b32.shared> temp; - ld.param.ptr<.b32.shared> temp, [shared_mem]; - note, we don't support non-.shared extern pointers, because there's - zero use for them in the ptxas - - artifical pointers created by stateful conversion, which work - similiarly to the above - - function parameters: - foobar(.param .align 4 .b8 numbers[]) - which get parsed to - foobar(.param .align 4 .b8 numbers) - and then converted to - foobar(.reg .align 4 .ptr<.b8.param> numbers) - - ld/st with offset: - .reg.b32 x; - .param.b64 arg0; - st.param.b32 [arg0+4], x; - Yes, this code is legal and actually emitted by the NV compiler! - We convert the st to: - .reg ptr<.b64.param> temp = ptr_offset(arg0, 4); - st.param.b32 [temp], x; - */ - // .reg ptr<.b64.param> - // -> OpTypePointer Function - Pointer(ScalarType, StateSpace), -} - -#[derive(PartialEq, Eq, Hash, Clone, Copy)] -pub enum ScalarType { - B8, - B16, - B32, - B64, - U8, - U16, - U32, - U64, - S8, - S16, - S32, - S64, - F16, - F32, - F64, - F16x2, - Pred, -} - -impl ScalarType { - pub fn size_of(self) -> u8 { - match self { - ScalarType::U8 => 1, - ScalarType::S8 => 1, - ScalarType::B8 => 1, - ScalarType::U16 => 2, - ScalarType::S16 => 2, - ScalarType::B16 => 2, - ScalarType::F16 => 2, - ScalarType::U32 => 4, - ScalarType::S32 => 4, - ScalarType::B32 => 4, - ScalarType::F32 => 4, - ScalarType::U64 => 8, - ScalarType::S64 => 8, - ScalarType::B64 => 8, - ScalarType::F64 => 8, - ScalarType::F16x2 => 4, - ScalarType::Pred => 1, - } - } -} - -impl Default for ScalarType { - fn default() -> Self { - ScalarType::B8 - } -} - -pub enum Statement<P: ArgParams> { - Label(P::Id), - Variable(MultiVariable<P::Id>), - Instruction(Option<PredAt<P::Id>>, Instruction<P>), - Block(Vec<Statement<P>>), -} - -pub struct MultiVariable<ID> { - pub var: Variable<ID>, - pub count: Option<u32>, -} - -#[derive(Clone)] -pub struct Variable<ID> { - pub align: Option<u32>, - pub v_type: Type, - pub state_space: StateSpace, - pub name: ID, - pub array_init: Vec<u8>, -} - -#[derive(Copy, Clone, PartialEq, Eq)] -pub enum StateSpace { - Reg, - Const, - Global, - Local, - Shared, - Param, - Generic, - Sreg, -} - -pub struct PredAt<ID> { - pub not: bool, - pub label: ID, -} - -pub enum Instruction<P: ArgParams> { - Ld(LdDetails, Arg2Ld<P>), - Mov(MovDetails, Arg2Mov<P>), - Mul(MulDetails, Arg3<P>), - Add(ArithDetails, Arg3<P>), - Setp(SetpData, Arg4Setp<P>), - SetpBool(SetpBoolData, Arg5Setp<P>), - Not(ScalarType, Arg2<P>), - Bra(BraData, Arg1<P>), - Cvt(CvtDetails, Arg2<P>), - Cvta(CvtaDetails, Arg2<P>), - Shl(ScalarType, Arg3<P>), - Shr(ScalarType, Arg3<P>), - St(StData, Arg2St<P>), - Ret(RetData), - Call(CallInst<P>), - Abs(AbsDetails, Arg2<P>), - Mad(MulDetails, Arg4<P>), - Fma(ArithFloat, Arg4<P>), - Or(ScalarType, Arg3<P>), - Sub(ArithDetails, Arg3<P>), - Min(MinMaxDetails, Arg3<P>), - Max(MinMaxDetails, Arg3<P>), - Rcp(RcpDetails, Arg2<P>), - And(ScalarType, Arg3<P>), - Selp(ScalarType, Arg4<P>), - Bar(BarDetails, Arg1Bar<P>), - Atom(AtomDetails, Arg3<P>), - AtomCas(AtomCasDetails, Arg4<P>), - Div(DivDetails, Arg3<P>), - Sqrt(SqrtDetails, Arg2<P>), - Rsqrt(RsqrtDetails, Arg2<P>), - Neg(NegDetails, Arg2<P>), - Sin { flush_to_zero: bool, arg: Arg2<P> }, - Cos { flush_to_zero: bool, arg: Arg2<P> }, - Lg2 { flush_to_zero: bool, arg: Arg2<P> }, - Ex2 { flush_to_zero: bool, arg: Arg2<P> }, - Clz { typ: ScalarType, arg: Arg2<P> }, - Brev { typ: ScalarType, arg: Arg2<P> }, - Popc { typ: ScalarType, arg: Arg2<P> }, - Xor { typ: ScalarType, arg: Arg3<P> }, - Bfe { typ: ScalarType, arg: Arg4<P> }, - Bfi { typ: ScalarType, arg: Arg5<P> }, - Rem { typ: ScalarType, arg: Arg3<P> }, - Prmt { control: u16, arg: Arg3<P> }, - Activemask { arg: Arg1<P> }, - Membar { level: MemScope }, -} - -#[derive(Copy, Clone)] -pub struct MadFloatDesc {} - -#[derive(Copy, Clone)] -pub struct AbsDetails { - pub flush_to_zero: Option<bool>, - pub typ: ScalarType, -} -#[derive(Copy, Clone)] -pub struct RcpDetails { - pub rounding: Option<RoundingMode>, - pub flush_to_zero: Option<bool>, - pub is_f64: bool, -} - -pub struct CallInst<P: ArgParams> { - pub uniform: bool, - pub ret_params: Vec<P::Id>, - pub func: P::Id, - pub param_list: Vec<P::Operand>, -} - -pub trait ArgParams { - type Id; - type Operand; -} - -pub struct ParsedArgParams<'a> { - _marker: PhantomData<&'a ()>, -} - -impl<'a> ArgParams for ParsedArgParams<'a> { - type Id = &'a str; - type Operand = Operand<&'a str>; -} - -pub struct Arg1<P: ArgParams> { - pub src: P::Id, // it is a jump destination, but in terms of operands it is a source operand -} - -pub struct Arg1Bar<P: ArgParams> { - pub src: P::Operand, -} - -pub struct Arg2<P: ArgParams> { - pub dst: P::Operand, - pub src: P::Operand, -} -pub struct Arg2Ld<P: ArgParams> { - pub dst: P::Operand, - pub src: P::Operand, -} - -pub struct Arg2St<P: ArgParams> { - pub src1: P::Operand, - pub src2: P::Operand, -} - -pub struct Arg2Mov<P: ArgParams> { - pub dst: P::Operand, - pub src: P::Operand, -} - -pub struct Arg3<P: ArgParams> { - pub dst: P::Operand, - pub src1: P::Operand, - pub src2: P::Operand, -} - -pub struct Arg4<P: ArgParams> { - pub dst: P::Operand, - pub src1: P::Operand, - pub src2: P::Operand, - pub src3: P::Operand, -} - -pub struct Arg4Setp<P: ArgParams> { - pub dst1: P::Id, - pub dst2: Option<P::Id>, - pub src1: P::Operand, - pub src2: P::Operand, -} - -pub struct Arg5<P: ArgParams> { - pub dst: P::Operand, - pub src1: P::Operand, - pub src2: P::Operand, - pub src3: P::Operand, - pub src4: P::Operand, -} - -pub struct Arg5Setp<P: ArgParams> { - pub dst1: P::Id, - pub dst2: Option<P::Id>, - pub src1: P::Operand, - pub src2: P::Operand, - pub src3: P::Operand, -} - -#[derive(Copy, Clone)] -pub enum ImmediateValue { - U64(u64), - S64(i64), - F32(f32), - F64(f64), -} - -#[derive(Clone)] -pub enum Operand<Id> { - Reg(Id), - RegOffset(Id, i32), - Imm(ImmediateValue), - VecMember(Id, u8), - VecPack(Vec<Id>), -} - -pub enum VectorPrefix { - V2, - V4, -} - -pub struct LdDetails { - pub qualifier: LdStQualifier, - pub state_space: StateSpace, - pub caching: LdCacheOperator, - pub typ: Type, - pub non_coherent: bool, -} - -#[derive(Copy, Clone, PartialEq, Eq)] -pub enum LdStQualifier { - Weak, - Volatile, - Relaxed(MemScope), - Acquire(MemScope), -} - -#[derive(Copy, Clone, PartialEq, Eq)] -pub enum MemScope { - Cta, - Gpu, - Sys, -} - -#[derive(Copy, Clone, PartialEq, Eq)] -pub enum LdCacheOperator { - Cached, - L2Only, - Streaming, - LastUse, - Uncached, -} - -#[derive(Clone)] -pub struct MovDetails { - pub typ: Type, - pub src_is_address: bool, - // two fields below are in use by member moves - pub dst_width: u8, - pub src_width: u8, - // This is in use by auto-generated movs - pub relaxed_src2_conv: bool, -} - -impl MovDetails { - pub fn new(typ: Type) -> Self { - MovDetails { - typ, - src_is_address: false, - dst_width: 0, - src_width: 0, - relaxed_src2_conv: false, - } - } -} - -#[derive(Copy, Clone)] -pub struct MulIntDesc { - pub typ: ScalarType, - pub control: MulIntControl, -} - -#[derive(Copy, Clone, PartialEq, Eq)] -pub enum MulIntControl { - Low, - High, - Wide, -} - -#[derive(PartialEq, Eq, Copy, Clone)] -pub enum RoundingMode { - NearestEven, - Zero, - NegativeInf, - PositiveInf, -} - -pub struct AddIntDesc { - pub typ: ScalarType, - pub saturate: bool, -} - -pub struct SetpData { - pub typ: ScalarType, - pub flush_to_zero: Option<bool>, - pub cmp_op: SetpCompareOp, -} - -#[derive(PartialEq, Eq, Copy, Clone)] -pub enum SetpCompareOp { - Eq, - NotEq, - Less, - LessOrEq, - Greater, - GreaterOrEq, - NanEq, - NanNotEq, - NanLess, - NanLessOrEq, - NanGreater, - NanGreaterOrEq, - IsNotNan, - IsAnyNan, -} - -pub enum SetpBoolPostOp { - And, - Or, - Xor, -} - -pub struct SetpBoolData { - pub typ: ScalarType, - pub flush_to_zero: Option<bool>, - pub cmp_op: SetpCompareOp, - pub bool_op: SetpBoolPostOp, -} - -pub struct BraData { - pub uniform: bool, -} - -pub enum CvtDetails { - IntFromInt(CvtIntToIntDesc), - FloatFromFloat(CvtDesc), - IntFromFloat(CvtDesc), - FloatFromInt(CvtDesc), -} - -pub struct CvtIntToIntDesc { - pub dst: ScalarType, - pub src: ScalarType, - pub saturate: bool, -} - -pub struct CvtDesc { - pub rounding: Option<RoundingMode>, - pub flush_to_zero: Option<bool>, - pub saturate: bool, - pub dst: ScalarType, - pub src: ScalarType, -} - -impl CvtDetails { - pub fn new_int_from_int_checked<'err, 'input>( - saturate: bool, - dst: ScalarType, - src: ScalarType, - err: &'err mut Vec<ParseError<usize, Token<'input>, PtxError>>, - ) -> Self { - if saturate { - if src.kind() == ScalarKind::Signed { - if dst.kind() == ScalarKind::Signed && dst.size_of() >= src.size_of() { - err.push(ParseError::User { - error: PtxError::SyntaxError, - }); - } - } else { - if dst == src || dst.size_of() >= src.size_of() { - err.push(ParseError::User { - error: PtxError::SyntaxError, - }); - } - } - } - CvtDetails::IntFromInt(CvtIntToIntDesc { dst, src, saturate }) - } - - pub fn new_float_from_int_checked<'err, 'input>( - rounding: RoundingMode, - flush_to_zero: bool, - saturate: bool, - dst: ScalarType, - src: ScalarType, - err: &'err mut Vec<ParseError<usize, Token<'input>, PtxError>>, - ) -> Self { - if flush_to_zero && dst != ScalarType::F32 { - err.push(ParseError::from(lalrpop_util::ParseError::User { - error: PtxError::NonF32Ftz, - })); - } - CvtDetails::FloatFromInt(CvtDesc { - dst, - src, - saturate, - flush_to_zero: Some(flush_to_zero), - rounding: Some(rounding), - }) - } - - pub fn new_int_from_float_checked<'err, 'input>( - rounding: RoundingMode, - flush_to_zero: bool, - saturate: bool, - dst: ScalarType, - src: ScalarType, - err: &'err mut Vec<ParseError<usize, Token<'input>, PtxError>>, - ) -> Self { - if flush_to_zero && src != ScalarType::F32 { - err.push(ParseError::from(lalrpop_util::ParseError::User { - error: PtxError::NonF32Ftz, - })); - } - CvtDetails::IntFromFloat(CvtDesc { - dst, - src, - saturate, - flush_to_zero: Some(flush_to_zero), - rounding: Some(rounding), - }) - } -} - -pub struct CvtaDetails { - pub to: StateSpace, - pub from: StateSpace, - pub size: CvtaSize, -} - -pub enum CvtaSize { - U32, - U64, -} - -pub struct StData { - pub qualifier: LdStQualifier, - pub state_space: StateSpace, - pub caching: StCacheOperator, - pub typ: Type, -} - -#[derive(PartialEq, Eq)] -pub enum StCacheOperator { - Writeback, - L2Only, - Streaming, - Writethrough, -} - -pub struct RetData { - pub uniform: bool, -} - -#[derive(Copy, Clone)] -pub enum MulDetails { - Unsigned(MulUInt), - Signed(MulSInt), - Float(ArithFloat), -} - -#[derive(Copy, Clone)] -pub struct MulUInt { - pub typ: ScalarType, - pub control: MulIntControl, -} - -#[derive(Copy, Clone)] -pub struct MulSInt { - pub typ: ScalarType, - pub control: MulIntControl, -} - -#[derive(Copy, Clone)] -pub enum ArithDetails { - Unsigned(ScalarType), - Signed(ArithSInt), - Float(ArithFloat), -} - -#[derive(Copy, Clone)] -pub struct ArithSInt { - pub typ: ScalarType, - pub saturate: bool, -} - -#[derive(Copy, Clone)] -pub struct ArithFloat { - pub typ: ScalarType, - pub rounding: Option<RoundingMode>, - pub flush_to_zero: Option<bool>, - pub saturate: bool, -} - -#[derive(Copy, Clone)] -pub enum MinMaxDetails { - Signed(ScalarType), - Unsigned(ScalarType), - Float(MinMaxFloat), -} - -#[derive(Copy, Clone)] -pub struct MinMaxFloat { - pub flush_to_zero: Option<bool>, - pub nan: bool, - pub typ: ScalarType, -} - -#[derive(Copy, Clone)] -pub struct AtomDetails { - pub semantics: AtomSemantics, - pub scope: MemScope, - pub space: StateSpace, - pub inner: AtomInnerDetails, -} - -#[derive(Copy, Clone)] -pub enum AtomSemantics { - Relaxed, - Acquire, - Release, - AcquireRelease, -} - -#[derive(Copy, Clone)] -pub enum AtomInnerDetails { - Bit { op: AtomBitOp, typ: ScalarType }, - Unsigned { op: AtomUIntOp, typ: ScalarType }, - Signed { op: AtomSIntOp, typ: ScalarType }, - Float { op: AtomFloatOp, typ: ScalarType }, -} - -#[derive(Copy, Clone, Eq, PartialEq)] -pub enum AtomBitOp { - And, - Or, - Xor, - Exchange, -} - -#[derive(Copy, Clone, Eq, PartialEq)] -pub enum AtomUIntOp { - Add, - Inc, - Dec, - Min, - Max, -} - -#[derive(Copy, Clone, Eq, PartialEq)] -pub enum AtomSIntOp { - Add, - Min, - Max, -} - -#[derive(Copy, Clone, Eq, PartialEq)] -pub enum AtomFloatOp { - Add, -} - -#[derive(Copy, Clone)] -pub struct AtomCasDetails { - pub semantics: AtomSemantics, - pub scope: MemScope, - pub space: StateSpace, - pub typ: ScalarType, -} - -#[derive(Copy, Clone)] -pub enum DivDetails { - Unsigned(ScalarType), - Signed(ScalarType), - Float(DivFloatDetails), -} - -#[derive(Copy, Clone)] -pub struct DivFloatDetails { - pub typ: ScalarType, - pub flush_to_zero: Option<bool>, - pub kind: DivFloatKind, -} - -#[derive(Copy, Clone, Eq, PartialEq)] -pub enum DivFloatKind { - Approx, - Full, - Rounding(RoundingMode), -} - -pub enum NumsOrArrays<'a> { - Nums(Vec<(&'a str, u32)>), - Arrays(Vec<NumsOrArrays<'a>>), -} - -#[derive(Copy, Clone)] -pub struct SqrtDetails { - pub typ: ScalarType, - pub flush_to_zero: Option<bool>, - pub kind: SqrtKind, -} - -#[derive(Copy, Clone, Eq, PartialEq)] -pub enum SqrtKind { - Approx, - Rounding(RoundingMode), -} - -#[derive(Copy, Clone, Eq, PartialEq)] -pub struct RsqrtDetails { - pub typ: ScalarType, - pub flush_to_zero: bool, -} - -#[derive(Copy, Clone, Eq, PartialEq)] -pub struct NegDetails { - pub typ: ScalarType, - pub flush_to_zero: Option<bool>, -} - -impl<'a> NumsOrArrays<'a> { - pub fn to_vec(self, typ: ScalarType, dimensions: &mut [u32]) -> Result<Vec<u8>, PtxError> { - self.normalize_dimensions(dimensions)?; - let sizeof_t = ScalarType::from(typ).size_of() as usize; - let result_size = dimensions.iter().fold(sizeof_t, |x, y| x * (*y as usize)); - let mut result = vec![0; result_size]; - self.parse_and_copy(typ, sizeof_t, dimensions, &mut result)?; - Ok(result) - } - - fn normalize_dimensions(&self, dimensions: &mut [u32]) -> Result<(), PtxError> { - match dimensions.first_mut() { - Some(first) => { - if *first == 0 { - *first = match self { - NumsOrArrays::Nums(v) => v.len() as u32, - NumsOrArrays::Arrays(v) => v.len() as u32, - }; - } - } - None => return Err(PtxError::ZeroDimensionArray), - } - for dim in dimensions { - if *dim == 0 { - return Err(PtxError::ZeroDimensionArray); - } - } - Ok(()) - } - - fn parse_and_copy( - &self, - t: ScalarType, - size_of_t: usize, - dimensions: &[u32], - result: &mut [u8], - ) -> Result<(), PtxError> { - match dimensions { - [] => unreachable!(), - [dim] => match self { - NumsOrArrays::Nums(vec) => { - if vec.len() > *dim as usize { - return Err(PtxError::ZeroDimensionArray); - } - for (idx, (val, radix)) in vec.iter().enumerate() { - Self::parse_and_copy_single(t, idx, val, *radix, result)?; - } - } - NumsOrArrays::Arrays(_) => return Err(PtxError::ZeroDimensionArray), - }, - [first_dim, rest @ ..] => match self { - NumsOrArrays::Arrays(vec) => { - if vec.len() > *first_dim as usize { - return Err(PtxError::ZeroDimensionArray); - } - let size_of_element = rest.iter().fold(size_of_t, |x, y| x * (*y as usize)); - for (idx, this) in vec.iter().enumerate() { - this.parse_and_copy( - t, - size_of_t, - rest, - &mut result[(size_of_element * idx)..], - )?; - } - } - NumsOrArrays::Nums(_) => return Err(PtxError::ZeroDimensionArray), - }, - } - Ok(()) - } - - fn parse_and_copy_single( - t: ScalarType, - idx: usize, - str_val: &str, - radix: u32, - output: &mut [u8], - ) -> Result<(), PtxError> { - match t { - ScalarType::B8 | ScalarType::U8 => { - Self::parse_and_copy_single_t::<u8>(idx, str_val, radix, output)?; - } - ScalarType::B16 | ScalarType::U16 => { - Self::parse_and_copy_single_t::<u16>(idx, str_val, radix, output)?; - } - ScalarType::B32 | ScalarType::U32 => { - Self::parse_and_copy_single_t::<u32>(idx, str_val, radix, output)?; - } - ScalarType::B64 | ScalarType::U64 => { - Self::parse_and_copy_single_t::<u64>(idx, str_val, radix, output)?; - } - ScalarType::S8 => { - Self::parse_and_copy_single_t::<i8>(idx, str_val, radix, output)?; - } - ScalarType::S16 => { - Self::parse_and_copy_single_t::<i16>(idx, str_val, radix, output)?; - } - ScalarType::S32 => { - Self::parse_and_copy_single_t::<i32>(idx, str_val, radix, output)?; - } - ScalarType::S64 => { - Self::parse_and_copy_single_t::<i64>(idx, str_val, radix, output)?; - } - ScalarType::F16 => { - Self::parse_and_copy_single_t::<f16>(idx, str_val, radix, output)?; - } - ScalarType::F16x2 => todo!(), - ScalarType::F32 => { - Self::parse_and_copy_single_t::<f32>(idx, str_val, radix, output)?; - } - ScalarType::F64 => { - Self::parse_and_copy_single_t::<f64>(idx, str_val, radix, output)?; - } - ScalarType::Pred => todo!(), - } - Ok(()) - } - - fn parse_and_copy_single_t<T: Copy + FromStr>( - idx: usize, - str_val: &str, - _radix: u32, // TODO: use this to properly support hex literals - output: &mut [u8], - ) -> Result<(), PtxError> - where - T::Err: Into<PtxError>, - { - let typed_output = unsafe { - std::slice::from_raw_parts_mut::<T>( - output.as_mut_ptr() as *mut _, - output.len() / mem::size_of::<T>(), - ) - }; - typed_output[idx] = str_val.parse::<T>().map_err(|e| e.into())?; - Ok(()) - } -} - -pub enum ArrayOrPointer { - Array { dimensions: Vec<u32>, init: Vec<u8> }, - Pointer, -} - -bitflags! { - pub struct LinkingDirective: u8 { - const NONE = 0b000; - const EXTERN = 0b001; - const VISIBLE = 0b10; - const WEAK = 0b100; - } -} - -#[derive(Copy, Clone, PartialEq, Eq)] -pub enum TuningDirective { - MaxNReg(u32), - MaxNtid(u32, u32, u32), - ReqNtid(u32, u32, u32), - MinNCtaPerSm(u32), -} - -#[derive(Clone, Copy, PartialEq, Eq)] -pub enum ScalarKind { - Bit, - Unsigned, - Signed, - Float, - Float2, - Pred, -} - -impl ScalarType { - pub fn kind(self) -> ScalarKind { - match self { - ScalarType::U8 => ScalarKind::Unsigned, - ScalarType::U16 => ScalarKind::Unsigned, - ScalarType::U32 => ScalarKind::Unsigned, - ScalarType::U64 => ScalarKind::Unsigned, - ScalarType::S8 => ScalarKind::Signed, - ScalarType::S16 => ScalarKind::Signed, - ScalarType::S32 => ScalarKind::Signed, - ScalarType::S64 => ScalarKind::Signed, - ScalarType::B8 => ScalarKind::Bit, - ScalarType::B16 => ScalarKind::Bit, - ScalarType::B32 => ScalarKind::Bit, - ScalarType::B64 => ScalarKind::Bit, - ScalarType::F16 => ScalarKind::Float, - ScalarType::F32 => ScalarKind::Float, - ScalarType::F64 => ScalarKind::Float, - ScalarType::F16x2 => ScalarKind::Float2, - ScalarType::Pred => ScalarKind::Pred, - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn array_fails_multiple_0_dmiensions() { - let inp = NumsOrArrays::Nums(Vec::new()); - assert!(inp.to_vec(ScalarType::B8, &mut vec![0, 0]).is_err()); - } - - #[test] - fn array_fails_on_empty() { - let inp = NumsOrArrays::Nums(Vec::new()); - assert!(inp.to_vec(ScalarType::B8, &mut vec![0]).is_err()); - } - - #[test] - fn array_auto_sizes_0_dimension() { - let inp = NumsOrArrays::Arrays(vec![ - NumsOrArrays::Nums(vec![("1", 10), ("2", 10)]), - NumsOrArrays::Nums(vec![("3", 10), ("4", 10)]), - ]); - let mut dimensions = vec![0u32, 2]; - assert_eq!( - vec![1u8, 2, 3, 4], - inp.to_vec(ScalarType::B8, &mut dimensions).unwrap() - ); - assert_eq!(dimensions, vec![2u32, 2]); - } - - #[test] - fn array_fails_wrong_structure() { - let inp = NumsOrArrays::Arrays(vec![ - NumsOrArrays::Nums(vec![("1", 10), ("2", 10)]), - NumsOrArrays::Arrays(vec![NumsOrArrays::Nums(vec![("1", 10)])]), - ]); - let mut dimensions = vec![0u32, 2]; - assert!(inp.to_vec(ScalarType::B8, &mut dimensions).is_err()); - } - - #[test] - fn array_fails_too_long_component() { - let inp = NumsOrArrays::Arrays(vec![ - NumsOrArrays::Nums(vec![("1", 10), ("2", 10), ("3", 10)]), - NumsOrArrays::Nums(vec![("4", 10), ("5", 10)]), - ]); - let mut dimensions = vec![0u32, 2]; - assert!(inp.to_vec(ScalarType::B8, &mut dimensions).is_err()); - } -} diff --git a/ptx/src/lib.rs b/ptx/src/lib.rs index 5e95dae..da972f6 100644 --- a/ptx/src/lib.rs +++ b/ptx/src/lib.rs @@ -1,186 +1,6 @@ -#[cfg(test)] -extern crate paste; -#[macro_use] -extern crate lalrpop_util; -#[macro_use] -extern crate quick_error; - -extern crate bit_vec; -extern crate half; -#[cfg(test)] -extern crate hip_runtime_sys as hip; -extern crate rspirv; -extern crate spirv_headers as spirv; - -#[cfg(test)] -extern crate spirv_tools_sys as spirv_tools; - -#[macro_use] -extern crate bitflags; - -lalrpop_mod!( - #[allow(warnings)] - ptx -); - -pub mod ast; pub(crate) mod pass; #[cfg(test)] mod test; -mod translate; - -use std::fmt; - -pub use crate::ptx::ModuleParser; -use ast::PtxError; -pub use lalrpop_util::lexer::Token; -pub use lalrpop_util::ParseError; -pub use rspirv::dr::Error as SpirvError; -pub use translate::to_spirv_module; -pub use translate::KernelInfo; -pub use translate::TranslateError; - -pub trait ModuleParserExt { - fn parse_checked<'input>( - txt: &'input str, - ) -> Result<ast::Module<'input>, Vec<ParseError<usize, Token<'input>, ast::PtxError>>>; - - // Returned AST might be malformed. Some users, like logger, want to look at - // malformed AST to record information - list of kernels or such - fn parse_unchecked<'input>( - txt: &'input str, - ) -> ( - ast::Module<'input>, - Vec<ParseError<usize, Token<'input>, ast::PtxError>>, - ); -} - -impl ModuleParserExt for ModuleParser { - fn parse_checked<'input>( - txt: &'input str, - ) -> Result<ast::Module<'input>, Vec<ParseError<usize, Token<'input>, ast::PtxError>>> { - let mut errors = Vec::new(); - let maybe_ast = ptx::ModuleParser::new().parse(&mut errors, txt); - match (&*errors, maybe_ast) { - (&[], Ok(ast)) => Ok(ast), - (_, Err(unrecoverable)) => { - errors.push(unrecoverable); - Err(errors) - } - (_, Ok(_)) => Err(errors), - } - } - - fn parse_unchecked<'input>( - txt: &'input str, - ) -> ( - ast::Module<'input>, - Vec<ParseError<usize, Token<'input>, ast::PtxError>>, - ) { - let mut errors = Vec::new(); - let maybe_ast = ptx::ModuleParser::new().parse(&mut errors, txt); - let ast = match maybe_ast { - Ok(ast) => ast, - Err(unrecoverable_err) => { - errors.push(unrecoverable_err); - ast::Module { - version: (0, 0), - directives: Vec::new(), - } - } - }; - (ast, errors) - } -} - -pub struct DisplayParseError<'a, Loc, Tok, Err>(&'a str, &'a ParseError<Loc, Tok, Err>); - -impl<'a, Loc: fmt::Display + Into<usize> + Copy, Tok, Err> DisplayParseError<'a, Loc, Tok, Err> { - // unsafe because there's no guarantee that the input str is the one that this error was created from - pub unsafe fn new(error: &'a ParseError<Loc, Tok, Err>, text: &'a str) -> Self { - Self(text, error) - } -} - -impl<'a, Loc, Tok> fmt::Display for DisplayParseError<'a, Loc, Tok, PtxError> -where - Loc: fmt::Display, - Tok: fmt::Display, -{ - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self.1 { - ParseError::User { - error: PtxError::UnrecognizedStatement { start, end }, - } => self.fmt_unrecognized(f, *start, *end, "statement"), - ParseError::User { - error: PtxError::UnrecognizedDirective { start, end }, - } => self.fmt_unrecognized(f, *start, *end, "directive"), - _ => self.1.fmt(f), - } - } -} - -impl<'a, Loc, Tok, Err> DisplayParseError<'a, Loc, Tok, Err> { - fn fmt_unrecognized( - &self, - f: &mut fmt::Formatter, - start: usize, - end: usize, - kind: &'static str, - ) -> fmt::Result { - let full_substring = unsafe { self.0.get_unchecked(start..end) }; - write!( - f, - "Unrecognized {} `{}` found at {}:{}", - kind, full_substring, start, end - ) - } -} - -pub(crate) fn without_none<T>(x: Vec<Option<T>>) -> Vec<T> { - x.into_iter().filter_map(|x| x).collect() -} - -pub(crate) fn vector_index<'input>( - inp: &'input str, -) -> Result<u8, ParseError<usize, lalrpop_util::lexer::Token<'input>, ast::PtxError>> { - match inp { - "x" | "r" => Ok(0), - "y" | "g" => Ok(1), - "z" | "b" => Ok(2), - "w" | "a" => Ok(3), - _ => Err(ParseError::User { - error: ast::PtxError::WrongVectorElement, - }), - } -} - -#[cfg(test)] -mod tests { - use crate::{DisplayParseError, ModuleParser, ModuleParserExt}; - #[test] - fn error_report_unknown_instructions() { - let module = r#" - .version 6.5 - .target sm_30 - .address_size 64 +pub use pass::to_llvm_module; - .visible .entry add( - .param .u64 input, - ) - { - .reg .u64 x; - does_not_exist.u64 x, x; - ret; - }"#; - let errors = match ModuleParser::parse_checked(module) { - Err(e) => e, - Ok(_) => panic!(), - }; - assert_eq!(errors.len(), 1); - let reporter = DisplayParseError(module, &errors[0]); - let build_log_string = format!("{}", reporter); - assert!(build_log_string.contains("does_not_exist")); - } -} diff --git a/ptx/src/pass/convert_dynamic_shared_memory_usage.rs b/ptx/src/pass/convert_dynamic_shared_memory_usage.rs deleted file mode 100644 index 1dac7fd..0000000 --- a/ptx/src/pass/convert_dynamic_shared_memory_usage.rs +++ /dev/null @@ -1,299 +0,0 @@ -use std::collections::{BTreeMap, BTreeSet};
-
-use super::*;
-
-/*
- PTX represents dynamically allocated shared local memory as
- .extern .shared .b32 shared_mem[];
- In SPIRV/OpenCL world this is expressed as an additional argument to the kernel
- And in AMD compilation
- This pass looks for all uses of .extern .shared and converts them to
- an additional method argument
- The question is how this artificial argument should be expressed. There are
- several options:
- * Straight conversion:
- .shared .b32 shared_mem[]
- * Introduce .param_shared statespace:
- .param_shared .b32 shared_mem
- or
- .param_shared .b32 shared_mem[]
- * Introduce .shared_ptr <SCALAR> type:
- .param .shared_ptr .b32 shared_mem
- * Reuse .ptr hint:
- .param .u64 .ptr shared_mem
- This is the most tempting, but also the most nonsensical, .ptr is just a
- hint, which has no semantical meaning (and the output of our
- transformation has a semantical meaning - we emit additional
- "OpFunctionParameter ..." with type "OpTypePointer Workgroup ...")
-*/
-pub(super) fn run<'input>(
- module: Vec<Directive<'input>>,
- kernels_methods_call_map: &MethodsCallMap<'input>,
- new_id: &mut impl FnMut() -> SpirvWord,
-) -> Result<Vec<Directive<'input>>, TranslateError> {
- let mut globals_shared = HashMap::new();
- for dir in module.iter() {
- match dir {
- Directive::Variable(
- _,
- ast::Variable {
- state_space: ast::StateSpace::Shared,
- name,
- v_type,
- ..
- },
- ) => {
- globals_shared.insert(*name, v_type.clone());
- }
- _ => {}
- }
- }
- if globals_shared.len() == 0 {
- return Ok(module);
- }
- let mut methods_to_directly_used_shared_globals = HashMap::<_, HashSet<SpirvWord>>::new();
- let module = module
- .into_iter()
- .map(|directive| match directive {
- Directive::Method(Function {
- func_decl,
- globals,
- body: Some(statements),
- import_as,
- tuning,
- linkage,
- }) => {
- let call_key = (*func_decl).borrow().name;
- let statements = statements
- .into_iter()
- .map(|statement| {
- statement.visit_map(
- &mut |id, _: Option<(&ast::Type, ast::StateSpace)>, _, _| {
- if let Some(_) = globals_shared.get(&id) {
- methods_to_directly_used_shared_globals
- .entry(call_key)
- .or_insert_with(HashSet::new)
- .insert(id);
- }
- Ok::<_, TranslateError>(id)
- },
- )
- })
- .collect::<Result<Vec<_>, _>>()?;
- Ok::<_, TranslateError>(Directive::Method(Function {
- func_decl,
- globals,
- body: Some(statements),
- import_as,
- tuning,
- linkage,
- }))
- }
- directive => Ok(directive),
- })
- .collect::<Result<Vec<_>, _>>()?;
- // If there's a chain `kernel` -> `fn1` -> `fn2`, where only `fn2` uses extern shared,
- // make sure it gets propagated to `fn1` and `kernel`
- let methods_to_indirectly_used_shared_globals = resolve_indirect_uses_of_globals_shared(
- methods_to_directly_used_shared_globals,
- kernels_methods_call_map,
- );
- // now visit every method declaration and inject those additional arguments
- let mut directives = Vec::with_capacity(module.len());
- for directive in module.into_iter() {
- match directive {
- Directive::Method(Function {
- func_decl,
- globals,
- body: Some(statements),
- import_as,
- tuning,
- linkage,
- }) => {
- let statements = {
- let func_decl_ref = &mut (*func_decl).borrow_mut();
- let method_name = func_decl_ref.name;
- insert_arguments_remap_statements(
- new_id,
- kernels_methods_call_map,
- &globals_shared,
- &methods_to_indirectly_used_shared_globals,
- method_name,
- &mut directives,
- func_decl_ref,
- statements,
- )?
- };
- directives.push(Directive::Method(Function {
- func_decl,
- globals,
- body: Some(statements),
- import_as,
- tuning,
- linkage,
- }));
- }
- directive => directives.push(directive),
- }
- }
- Ok(directives)
-}
-
-// We need to compute two kinds of information:
-// * If it's a kernel -> size of .shared globals in use (direct or indirect)
-// * If it's a function -> does it use .shared global (directly or indirectly)
-fn resolve_indirect_uses_of_globals_shared<'input>(
- methods_use_of_globals_shared: HashMap<ast::MethodName<'input, SpirvWord>, HashSet<SpirvWord>>,
- kernels_methods_call_map: &MethodsCallMap<'input>,
-) -> HashMap<ast::MethodName<'input, SpirvWord>, BTreeSet<SpirvWord>> {
- let mut result = HashMap::new();
- for (method, callees) in kernels_methods_call_map.methods() {
- let mut indirect_globals = methods_use_of_globals_shared
- .get(&method)
- .into_iter()
- .flatten()
- .copied()
- .collect::<BTreeSet<_>>();
- for &callee in callees {
- indirect_globals.extend(
- methods_use_of_globals_shared
- .get(&ast::MethodName::Func(callee))
- .into_iter()
- .flatten()
- .copied(),
- );
- }
- result.insert(method, indirect_globals);
- }
- result
-}
-
-fn insert_arguments_remap_statements<'input>(
- new_id: &mut impl FnMut() -> SpirvWord,
- kernels_methods_call_map: &MethodsCallMap<'input>,
- globals_shared: &HashMap<SpirvWord, ast::Type>,
- methods_to_indirectly_used_shared_globals: &HashMap<
- ast::MethodName<'input, SpirvWord>,
- BTreeSet<SpirvWord>,
- >,
- method_name: ast::MethodName<SpirvWord>,
- result: &mut Vec<Directive>,
- func_decl_ref: &mut std::cell::RefMut<ast::MethodDeclaration<SpirvWord>>,
- statements: Vec<Statement<ast::Instruction<SpirvWord>, SpirvWord>>,
-) -> Result<Vec<Statement<ast::Instruction<SpirvWord>, SpirvWord>>, TranslateError> {
- let remapped_globals_in_method =
- if let Some(method_globals) = methods_to_indirectly_used_shared_globals.get(&method_name) {
- match method_name {
- ast::MethodName::Func(..) => {
- let remapped_globals = method_globals
- .iter()
- .map(|global| {
- (
- *global,
- (
- new_id(),
- globals_shared
- .get(&global)
- .unwrap_or_else(|| todo!())
- .clone(),
- ),
- )
- })
- .collect::<BTreeMap<_, _>>();
- for (_, (new_shared_global_id, shared_global_type)) in remapped_globals.iter() {
- func_decl_ref.input_arguments.push(ast::Variable {
- align: None,
- v_type: shared_global_type.clone(),
- state_space: ast::StateSpace::Shared,
- name: *new_shared_global_id,
- array_init: Vec::new(),
- });
- }
- remapped_globals
- }
- ast::MethodName::Kernel(..) => method_globals
- .iter()
- .map(|global| {
- (
- *global,
- (
- *global,
- globals_shared
- .get(&global)
- .unwrap_or_else(|| todo!())
- .clone(),
- ),
- )
- })
- .collect::<BTreeMap<_, _>>(),
- }
- } else {
- return Ok(statements);
- };
- replace_uses_of_shared_memory(
- new_id,
- methods_to_indirectly_used_shared_globals,
- statements,
- remapped_globals_in_method,
- )
-}
-
-fn replace_uses_of_shared_memory<'input>(
- new_id: &mut impl FnMut() -> SpirvWord,
- methods_to_indirectly_used_shared_globals: &HashMap<
- ast::MethodName<'input, SpirvWord>,
- BTreeSet<SpirvWord>,
- >,
- statements: Vec<ExpandedStatement>,
- remapped_globals_in_method: BTreeMap<SpirvWord, (SpirvWord, ast::Type)>,
-) -> Result<Vec<ExpandedStatement>, TranslateError> {
- let mut result = Vec::with_capacity(statements.len());
- for statement in statements {
- match statement {
- Statement::Instruction(ast::Instruction::Call {
- mut data,
- mut arguments,
- }) => {
- // We can safely skip checking call arguments,
- // because there's simply no way to pass shared ptr
- // without converting it to .b64 first
- if let Some(shared_globals_used_by_callee) =
- methods_to_indirectly_used_shared_globals
- .get(&ast::MethodName::Func(arguments.func))
- {
- for &shared_global_used_by_callee in shared_globals_used_by_callee {
- let (remapped_shared_id, type_) = remapped_globals_in_method
- .get(&shared_global_used_by_callee)
- .unwrap_or_else(|| todo!());
- data.input_arguments
- .push((type_.clone(), ast::StateSpace::Shared));
- arguments.input_arguments.push(*remapped_shared_id);
- }
- }
- result.push(Statement::Instruction(ast::Instruction::Call {
- data,
- arguments,
- }))
- }
- statement => {
- let new_statement =
- statement.visit_map(&mut |id,
- _: Option<(&ast::Type, ast::StateSpace)>,
- _,
- _| {
- Ok::<_, TranslateError>(
- if let Some((remapped_shared_id, _)) =
- remapped_globals_in_method.get(&id)
- {
- *remapped_shared_id
- } else {
- id
- },
- )
- })?;
- result.push(new_statement);
- }
- }
- }
- Ok(result)
-}
diff --git a/ptx/src/pass/convert_to_stateful_memory_access.rs b/ptx/src/pass/convert_to_stateful_memory_access.rs deleted file mode 100644 index 3b8fa93..0000000 --- a/ptx/src/pass/convert_to_stateful_memory_access.rs +++ /dev/null @@ -1,524 +0,0 @@ -use super::*;
-use ptx_parser as ast;
-use std::{
- collections::{BTreeSet, HashSet},
- iter,
- rc::Rc,
-};
-
-/*
- Our goal here is to transform
- .visible .entry foobar(.param .u64 input) {
- .reg .b64 in_addr;
- .reg .b64 in_addr2;
- ld.param.u64 in_addr, [input];
- cvta.to.global.u64 in_addr2, in_addr;
- }
- into:
- .visible .entry foobar(.param .u8 input[]) {
- .reg .u8 in_addr[];
- .reg .u8 in_addr2[];
- ld.param.u8[] in_addr, [input];
- mov.u8[] in_addr2, in_addr;
- }
- or:
- .visible .entry foobar(.reg .u8 input[]) {
- .reg .u8 in_addr[];
- .reg .u8 in_addr2[];
- mov.u8[] in_addr, input;
- mov.u8[] in_addr2, in_addr;
- }
- or:
- .visible .entry foobar(.param ptr<u8, global> input) {
- .reg ptr<u8, global> in_addr;
- .reg ptr<u8, global> in_addr2;
- ld.param.ptr<u8, global> in_addr, [input];
- mov.ptr<u8, global> in_addr2, in_addr;
- }
-*/
-// TODO: detect more patterns (mov, call via reg, call via param)
-// TODO: don't convert to ptr if the register is not ultimately used for ld/st
-// TODO: once insert_mem_ssa_statements is moved to later, move this pass after
-// argument expansion
-// TODO: propagate out of calls and into calls
-pub(super) fn run<'a, 'input>(
- func_args: Rc<RefCell<ast::MethodDeclaration<'input, SpirvWord>>>,
- func_body: Vec<TypedStatement>,
- id_defs: &mut NumericIdResolver<'a>,
-) -> Result<
- (
- Rc<RefCell<ast::MethodDeclaration<'input, SpirvWord>>>,
- Vec<TypedStatement>,
- ),
- TranslateError,
-> {
- let mut method_decl = func_args.borrow_mut();
- if !matches!(method_decl.name, ast::MethodName::Kernel(..)) {
- drop(method_decl);
- return Ok((func_args, func_body));
- }
- if Rc::strong_count(&func_args) != 1 {
- return Err(error_unreachable());
- }
- let func_args_64bit = (*method_decl)
- .input_arguments
- .iter()
- .filter_map(|arg| match arg.v_type {
- ast::Type::Scalar(ast::ScalarType::U64)
- | ast::Type::Scalar(ast::ScalarType::B64)
- | ast::Type::Scalar(ast::ScalarType::S64) => Some(arg.name),
- _ => None,
- })
- .collect::<HashSet<_>>();
- let mut stateful_markers = Vec::new();
- let mut stateful_init_reg = HashMap::<_, Vec<_>>::new();
- for statement in func_body.iter() {
- match statement {
- Statement::Instruction(ast::Instruction::Cvta {
- data:
- ast::CvtaDetails {
- state_space: ast::StateSpace::Global,
- direction: ast::CvtaDirection::GenericToExplicit,
- },
- arguments,
- }) => {
- if let (TypedOperand::Reg(dst), Some(src)) =
- (arguments.dst, arguments.src.underlying_register())
- {
- if is_64_bit_integer(id_defs, src) && is_64_bit_integer(id_defs, dst) {
- stateful_markers.push((dst, src));
- }
- }
- }
- Statement::Instruction(ast::Instruction::Ld {
- data:
- ast::LdDetails {
- state_space: ast::StateSpace::Param,
- typ: ast::Type::Scalar(ast::ScalarType::U64),
- ..
- },
- arguments,
- })
- | Statement::Instruction(ast::Instruction::Ld {
- data:
- ast::LdDetails {
- state_space: ast::StateSpace::Param,
- typ: ast::Type::Scalar(ast::ScalarType::S64),
- ..
- },
- arguments,
- })
- | Statement::Instruction(ast::Instruction::Ld {
- data:
- ast::LdDetails {
- state_space: ast::StateSpace::Param,
- typ: ast::Type::Scalar(ast::ScalarType::B64),
- ..
- },
- arguments,
- }) => {
- if let (TypedOperand::Reg(dst), Some(src)) =
- (arguments.dst, arguments.src.underlying_register())
- {
- if func_args_64bit.contains(&src) {
- multi_hash_map_append(&mut stateful_init_reg, dst, src);
- }
- }
- }
- _ => {}
- }
- }
- if stateful_markers.len() == 0 {
- drop(method_decl);
- return Ok((func_args, func_body));
- }
- let mut func_args_ptr = HashSet::new();
- let mut regs_ptr_current = HashSet::new();
- for (dst, src) in stateful_markers {
- if let Some(func_args) = stateful_init_reg.get(&src) {
- for a in func_args {
- func_args_ptr.insert(*a);
- regs_ptr_current.insert(src);
- regs_ptr_current.insert(dst);
- }
- }
- }
- // BTreeSet here to have a stable order of iteration,
- // unfortunately our tests rely on it
- let mut regs_ptr_seen = BTreeSet::new();
- while regs_ptr_current.len() > 0 {
- let mut regs_ptr_new = HashSet::new();
- for statement in func_body.iter() {
- match statement {
- Statement::Instruction(ast::Instruction::Add {
- data:
- ast::ArithDetails::Integer(ast::ArithInteger {
- type_: ast::ScalarType::U64,
- saturate: false,
- }),
- arguments,
- })
- | Statement::Instruction(ast::Instruction::Add {
- data:
- ast::ArithDetails::Integer(ast::ArithInteger {
- type_: ast::ScalarType::S64,
- saturate: false,
- }),
- arguments,
- }) => {
- // TODO: don't mark result of double pointer sub or double
- // pointer add as ptr result
- if let (TypedOperand::Reg(dst), Some(src1)) =
- (arguments.dst, arguments.src1.underlying_register())
- {
- if regs_ptr_current.contains(&src1) && !regs_ptr_seen.contains(&src1) {
- regs_ptr_new.insert(dst);
- }
- } else if let (TypedOperand::Reg(dst), Some(src2)) =
- (arguments.dst, arguments.src2.underlying_register())
- {
- if regs_ptr_current.contains(&src2) && !regs_ptr_seen.contains(&src2) {
- regs_ptr_new.insert(dst);
- }
- }
- }
-
- Statement::Instruction(ast::Instruction::Sub {
- data:
- ast::ArithDetails::Integer(ast::ArithInteger {
- type_: ast::ScalarType::U64,
- saturate: false,
- }),
- arguments,
- })
- | Statement::Instruction(ast::Instruction::Sub {
- data:
- ast::ArithDetails::Integer(ast::ArithInteger {
- type_: ast::ScalarType::S64,
- saturate: false,
- }),
- arguments,
- }) => {
- // TODO: don't mark result of double pointer sub or double
- // pointer add as ptr result
- if let (TypedOperand::Reg(dst), Some(src1)) =
- (arguments.dst, arguments.src1.underlying_register())
- {
- if regs_ptr_current.contains(&src1) && !regs_ptr_seen.contains(&src1) {
- regs_ptr_new.insert(dst);
- }
- } else if let (TypedOperand::Reg(dst), Some(src2)) =
- (arguments.dst, arguments.src2.underlying_register())
- {
- if regs_ptr_current.contains(&src2) && !regs_ptr_seen.contains(&src2) {
- regs_ptr_new.insert(dst);
- }
- }
- }
- _ => {}
- }
- }
- for id in regs_ptr_current {
- regs_ptr_seen.insert(id);
- }
- regs_ptr_current = regs_ptr_new;
- }
- drop(regs_ptr_current);
- let mut remapped_ids = HashMap::new();
- let mut result = Vec::with_capacity(regs_ptr_seen.len() + func_body.len());
- for reg in regs_ptr_seen {
- let new_id = id_defs.register_variable(
- ast::Type::Pointer(ast::ScalarType::U8, ast::StateSpace::Global),
- ast::StateSpace::Reg,
- );
- result.push(Statement::Variable(ast::Variable {
- align: None,
- name: new_id,
- array_init: Vec::new(),
- v_type: ast::Type::Pointer(ast::ScalarType::U8, ast::StateSpace::Global),
- state_space: ast::StateSpace::Reg,
- }));
- remapped_ids.insert(reg, new_id);
- }
- for arg in (*method_decl).input_arguments.iter_mut() {
- if !func_args_ptr.contains(&arg.name) {
- continue;
- }
- let new_id = id_defs.register_variable(
- ast::Type::Pointer(ast::ScalarType::U8, ast::StateSpace::Global),
- ast::StateSpace::Param,
- );
- let old_name = arg.name;
- arg.v_type = ast::Type::Pointer(ast::ScalarType::U8, ast::StateSpace::Global);
- arg.name = new_id;
- remapped_ids.insert(old_name, new_id);
- }
- for statement in func_body {
- match statement {
- l @ Statement::Label(_) => result.push(l),
- c @ Statement::Conditional(_) => result.push(c),
- c @ Statement::Constant(..) => result.push(c),
- Statement::Variable(var) => {
- if !remapped_ids.contains_key(&var.name) {
- result.push(Statement::Variable(var));
- }
- }
- Statement::Instruction(ast::Instruction::Add {
- data:
- ast::ArithDetails::Integer(ast::ArithInteger {
- type_: ast::ScalarType::U64,
- saturate: false,
- }),
- arguments,
- })
- | Statement::Instruction(ast::Instruction::Add {
- data:
- ast::ArithDetails::Integer(ast::ArithInteger {
- type_: ast::ScalarType::S64,
- saturate: false,
- }),
- arguments,
- }) if is_add_ptr_direct(&remapped_ids, &arguments) => {
- let (ptr, offset) = match arguments.src1.underlying_register() {
- Some(src1) if remapped_ids.contains_key(&src1) => {
- (remapped_ids.get(&src1).unwrap(), arguments.src2)
- }
- Some(src2) if remapped_ids.contains_key(&src2) => {
- (remapped_ids.get(&src2).unwrap(), arguments.src1)
- }
- _ => return Err(error_unreachable()),
- };
- let dst = arguments.dst.unwrap_reg()?;
- result.push(Statement::PtrAccess(PtrAccess {
- underlying_type: ast::Type::Scalar(ast::ScalarType::U8),
- state_space: ast::StateSpace::Global,
- dst: *remapped_ids.get(&dst).unwrap(),
- ptr_src: *ptr,
- offset_src: offset,
- }))
- }
- Statement::Instruction(ast::Instruction::Sub {
- data:
- ast::ArithDetails::Integer(ast::ArithInteger {
- type_: ast::ScalarType::U64,
- saturate: false,
- }),
- arguments,
- })
- | Statement::Instruction(ast::Instruction::Sub {
- data:
- ast::ArithDetails::Integer(ast::ArithInteger {
- type_: ast::ScalarType::S64,
- saturate: false,
- }),
- arguments,
- }) if is_sub_ptr_direct(&remapped_ids, &arguments) => {
- let (ptr, offset) = match arguments.src1.underlying_register() {
- Some(ref src1) => (remapped_ids.get(src1).unwrap(), arguments.src2),
- _ => return Err(error_unreachable()),
- };
- let offset_neg = id_defs.register_intermediate(Some((
- ast::Type::Scalar(ast::ScalarType::S64),
- ast::StateSpace::Reg,
- )));
- result.push(Statement::Instruction(ast::Instruction::Neg {
- data: ast::TypeFtz {
- type_: ast::ScalarType::S64,
- flush_to_zero: None,
- },
- arguments: ast::NegArgs {
- src: offset,
- dst: TypedOperand::Reg(offset_neg),
- },
- }));
- let dst = arguments.dst.unwrap_reg()?;
- result.push(Statement::PtrAccess(PtrAccess {
- underlying_type: ast::Type::Scalar(ast::ScalarType::U8),
- state_space: ast::StateSpace::Global,
- dst: *remapped_ids.get(&dst).unwrap(),
- ptr_src: *ptr,
- offset_src: TypedOperand::Reg(offset_neg),
- }))
- }
- inst @ Statement::Instruction(_) => {
- let mut post_statements = Vec::new();
- let new_statement = inst.visit_map(&mut FnVisitor::new(
- |operand, type_space, is_dst, relaxed_conversion| {
- convert_to_stateful_memory_access_postprocess(
- id_defs,
- &remapped_ids,
- &mut result,
- &mut post_statements,
- operand,
- type_space,
- is_dst,
- relaxed_conversion,
- )
- },
- ))?;
- result.push(new_statement);
- result.extend(post_statements);
- }
- repack @ Statement::RepackVector(_) => {
- let mut post_statements = Vec::new();
- let new_statement = repack.visit_map(&mut FnVisitor::new(
- |operand, type_space, is_dst, relaxed_conversion| {
- convert_to_stateful_memory_access_postprocess(
- id_defs,
- &remapped_ids,
- &mut result,
- &mut post_statements,
- operand,
- type_space,
- is_dst,
- relaxed_conversion,
- )
- },
- ))?;
- result.push(new_statement);
- result.extend(post_statements);
- }
- _ => return Err(error_unreachable()),
- }
- }
- drop(method_decl);
- Ok((func_args, result))
-}
-
-fn is_64_bit_integer(id_defs: &NumericIdResolver, id: SpirvWord) -> bool {
- match id_defs.get_typed(id) {
- Ok((ast::Type::Scalar(ast::ScalarType::U64), _, _))
- | Ok((ast::Type::Scalar(ast::ScalarType::S64), _, _))
- | Ok((ast::Type::Scalar(ast::ScalarType::B64), _, _)) => true,
- _ => false,
- }
-}
-
-fn is_add_ptr_direct(
- remapped_ids: &HashMap<SpirvWord, SpirvWord>,
- arg: &ast::AddArgs<TypedOperand>,
-) -> bool {
- match arg.dst {
- TypedOperand::Imm(..) | TypedOperand::RegOffset(..) | TypedOperand::VecMember(..) => {
- return false
- }
- TypedOperand::Reg(dst) => {
- if !remapped_ids.contains_key(&dst) {
- return false;
- }
- if let Some(ref src1_reg) = arg.src1.underlying_register() {
- if remapped_ids.contains_key(src1_reg) {
- // don't trigger optimization when adding two pointers
- if let Some(ref src2_reg) = arg.src2.underlying_register() {
- return !remapped_ids.contains_key(src2_reg);
- }
- }
- }
- if let Some(ref src2_reg) = arg.src2.underlying_register() {
- remapped_ids.contains_key(src2_reg)
- } else {
- false
- }
- }
- }
-}
-
-fn is_sub_ptr_direct(
- remapped_ids: &HashMap<SpirvWord, SpirvWord>,
- arg: &ast::SubArgs<TypedOperand>,
-) -> bool {
- match arg.dst {
- TypedOperand::Imm(..) | TypedOperand::RegOffset(..) | TypedOperand::VecMember(..) => {
- return false
- }
- TypedOperand::Reg(dst) => {
- if !remapped_ids.contains_key(&dst) {
- return false;
- }
- match arg.src1.underlying_register() {
- Some(ref src1_reg) => {
- if remapped_ids.contains_key(src1_reg) {
- // don't trigger optimization when subtracting two pointers
- arg.src2
- .underlying_register()
- .map_or(true, |ref src2_reg| !remapped_ids.contains_key(src2_reg))
- } else {
- false
- }
- }
- None => false,
- }
- }
- }
-}
-
-fn convert_to_stateful_memory_access_postprocess(
- id_defs: &mut NumericIdResolver,
- remapped_ids: &HashMap<SpirvWord, SpirvWord>,
- result: &mut Vec<TypedStatement>,
- post_statements: &mut Vec<TypedStatement>,
- operand: TypedOperand,
- type_space: Option<(&ast::Type, ast::StateSpace)>,
- is_dst: bool,
- relaxed_conversion: bool,
-) -> Result<TypedOperand, TranslateError> {
- operand.map(|operand, _| {
- Ok(match remapped_ids.get(&operand) {
- Some(new_id) => {
- let (new_operand_type, new_operand_space, _) = id_defs.get_typed(*new_id)?;
- // TODO: readd if required
- if let Some((expected_type, expected_space)) = type_space {
- let implicit_conversion = if relaxed_conversion {
- if is_dst {
- super::insert_implicit_conversions::should_convert_relaxed_dst_wrapper
- } else {
- super::insert_implicit_conversions::should_convert_relaxed_src_wrapper
- }
- } else {
- super::insert_implicit_conversions::default_implicit_conversion
- };
- if implicit_conversion(
- (new_operand_space, &new_operand_type),
- (expected_space, expected_type),
- )
- .is_ok()
- {
- return Ok(*new_id);
- }
- }
- let (old_operand_type, old_operand_space, _) = id_defs.get_typed(operand)?;
- let converting_id = id_defs
- .register_intermediate(Some((old_operand_type.clone(), old_operand_space)));
- let kind = if new_operand_space == ast::StateSpace::Reg {
- ConversionKind::Default
- } else {
- ConversionKind::PtrToPtr
- };
- if is_dst {
- post_statements.push(Statement::Conversion(ImplicitConversion {
- src: converting_id,
- dst: *new_id,
- from_type: old_operand_type,
- from_space: old_operand_space,
- to_type: new_operand_type,
- to_space: new_operand_space,
- kind,
- }));
- converting_id
- } else {
- result.push(Statement::Conversion(ImplicitConversion {
- src: *new_id,
- dst: converting_id,
- from_type: new_operand_type,
- from_space: new_operand_space,
- to_type: old_operand_type,
- to_space: old_operand_space,
- kind,
- }));
- converting_id
- }
- }
- None => operand,
- })
- })
-}
diff --git a/ptx/src/pass/convert_to_typed.rs b/ptx/src/pass/convert_to_typed.rs deleted file mode 100644 index 550c662..0000000 --- a/ptx/src/pass/convert_to_typed.rs +++ /dev/null @@ -1,138 +0,0 @@ -use super::*;
-use ptx_parser as ast;
-
-pub(crate) fn run(
- func: Vec<UnconditionalStatement>,
- fn_defs: &GlobalFnDeclResolver,
- id_defs: &mut NumericIdResolver,
-) -> Result<Vec<TypedStatement>, TranslateError> {
- let mut result = Vec::<TypedStatement>::with_capacity(func.len());
- for s in func {
- match s {
- Statement::Instruction(inst) => match inst {
- ast::Instruction::Mov {
- data,
- arguments:
- ast::MovArgs {
- dst: ast::ParsedOperand::Reg(dst_reg),
- src: ast::ParsedOperand::Reg(src_reg),
- },
- } if fn_defs.fns.contains_key(&src_reg) => {
- if data.typ != ast::Type::Scalar(ast::ScalarType::U64) {
- return Err(error_mismatched_type());
- }
- result.push(TypedStatement::FunctionPointer(FunctionPointerDetails {
- dst: dst_reg,
- src: src_reg,
- }));
- }
- ast::Instruction::Call { data, arguments } => {
- let resolver = fn_defs.get_fn_sig_resolver(arguments.func)?;
- let resolved_call = resolver.resolve_in_spirv_repr(data, arguments)?;
- let mut visitor = VectorRepackVisitor::new(&mut result, id_defs);
- let reresolved_call =
- Statement::Instruction(ast::visit_map(resolved_call, &mut visitor)?);
- visitor.func.push(reresolved_call);
- visitor.func.extend(visitor.post_stmts);
- }
- inst => {
- let mut visitor = VectorRepackVisitor::new(&mut result, id_defs);
- let instruction = Statement::Instruction(ast::visit_map(inst, &mut visitor)?);
- visitor.func.push(instruction);
- visitor.func.extend(visitor.post_stmts);
- }
- },
- Statement::Label(i) => result.push(Statement::Label(i)),
- Statement::Variable(v) => result.push(Statement::Variable(v)),
- Statement::Conditional(c) => result.push(Statement::Conditional(c)),
- _ => return Err(error_unreachable()),
- }
- }
- Ok(result)
-}
-
-struct VectorRepackVisitor<'a, 'b> {
- func: &'b mut Vec<TypedStatement>,
- id_def: &'b mut NumericIdResolver<'a>,
- post_stmts: Option<TypedStatement>,
-}
-
-impl<'a, 'b> VectorRepackVisitor<'a, 'b> {
- fn new(func: &'b mut Vec<TypedStatement>, id_def: &'b mut NumericIdResolver<'a>) -> Self {
- VectorRepackVisitor {
- func,
- id_def,
- post_stmts: None,
- }
- }
-
- fn convert_vector(
- &mut self,
- is_dst: bool,
- relaxed_type_check: bool,
- typ: &ast::Type,
- state_space: ast::StateSpace,
- idx: Vec<SpirvWord>,
- ) -> Result<SpirvWord, TranslateError> {
- // mov.u32 foobar, {a,b};
- let scalar_t = match typ {
- ast::Type::Vector(_, scalar_t) => *scalar_t,
- _ => return Err(error_mismatched_type()),
- };
- let temp_vec = self
- .id_def
- .register_intermediate(Some((typ.clone(), state_space)));
- let statement = Statement::RepackVector(RepackVectorDetails {
- is_extract: is_dst,
- typ: scalar_t,
- packed: temp_vec,
- unpacked: idx,
- relaxed_type_check,
- });
- if is_dst {
- self.post_stmts = Some(statement);
- } else {
- self.func.push(statement);
- }
- Ok(temp_vec)
- }
-}
-
-impl<'a, 'b> ast::VisitorMap<ast::ParsedOperand<SpirvWord>, TypedOperand, TranslateError>
- for VectorRepackVisitor<'a, 'b>
-{
- fn visit_ident(
- &mut self,
- ident: SpirvWord,
- _: Option<(&ptx_parser::Type, ptx_parser::StateSpace)>,
- _: bool,
- _: bool,
- ) -> Result<SpirvWord, TranslateError> {
- Ok(ident)
- }
-
- fn visit(
- &mut self,
- op: ast::ParsedOperand<SpirvWord>,
- type_space: Option<(&ptx_parser::Type, ptx_parser::StateSpace)>,
- is_dst: bool,
- relaxed_type_check: bool,
- ) -> Result<TypedOperand, TranslateError> {
- Ok(match op {
- ast::ParsedOperand::Reg(reg) => TypedOperand::Reg(reg),
- ast::ParsedOperand::RegOffset(reg, offset) => TypedOperand::RegOffset(reg, offset),
- ast::ParsedOperand::Imm(x) => TypedOperand::Imm(x),
- ast::ParsedOperand::VecMember(vec, idx) => TypedOperand::VecMember(vec, idx),
- ast::ParsedOperand::VecPack(vec) => {
- let (type_, space) = type_space.ok_or_else(|| error_mismatched_type())?;
- TypedOperand::Reg(self.convert_vector(
- is_dst,
- relaxed_type_check,
- type_,
- space,
- vec,
- )?)
- }
- })
- }
-}
diff --git a/ptx/src/pass/deparamize_functions.rs b/ptx/src/pass/deparamize_functions.rs index 74a26e2..15125b0 100644 --- a/ptx/src/pass/deparamize_functions.rs +++ b/ptx/src/pass/deparamize_functions.rs @@ -1,5 +1,3 @@ -use std::collections::BTreeMap;
-
use super::*;
pub(super) fn run<'a, 'input>(
diff --git a/ptx/src/pass/emit_llvm.rs b/ptx/src/pass/emit_llvm.rs index 5613cb0..2e9892f 100644 --- a/ptx/src/pass/emit_llvm.rs +++ b/ptx/src/pass/emit_llvm.rs @@ -19,7 +19,7 @@ // unsafe { LLVMBuildAdd(builder, lhs, rhs, dst) };
use std::array::TryFromSliceError;
-use std::convert::{TryFrom, TryInto};
+use std::convert::TryInto;
use std::ffi::{CStr, NulError};
use std::ops::Deref;
use std::{i8, ptr};
@@ -296,7 +296,7 @@ impl<'a, 'input> ModuleEmitContext<'a, 'input> { fn emit_global(
&mut self,
- linking: ast::LinkingDirective,
+ _linking: ast::LinkingDirective,
var: ast::Variable<SpirvWord>,
) -> Result<(), TranslateError> {
let name = self
@@ -326,7 +326,7 @@ impl<'a, 'input> ModuleEmitContext<'a, 'input> { unsafe { LLVMSetAlignment(global, align) };
}
if !var.array_init.is_empty() {
- self.emit_array_init(&var.v_type, &*var.array_init, global);
+ self.emit_array_init(&var.v_type, &*var.array_init, global)?;
}
Ok(())
}
@@ -412,27 +412,25 @@ fn get_input_argument_type( }
}
-struct MethodEmitContext<'a, 'input> {
+struct MethodEmitContext<'a> {
context: LLVMContextRef,
module: LLVMModuleRef,
method: LLVMValueRef,
builder: LLVMBuilderRef,
- id_defs: &'a GlobalStringIdentResolver2<'input>,
variables_builder: Builder,
resolver: &'a mut ResolveIdent,
}
-impl<'a, 'input> MethodEmitContext<'a, 'input> {
- fn new<'x>(
- parent: &'a mut ModuleEmitContext<'x, 'input>,
+impl<'a> MethodEmitContext<'a> {
+ fn new(
+ parent: &'a mut ModuleEmitContext,
method: LLVMValueRef,
variables_builder: Builder,
- ) -> MethodEmitContext<'a, 'input> {
+ ) -> MethodEmitContext<'a> {
MethodEmitContext {
context: parent.context,
module: parent.module,
builder: parent.builder.get(),
- id_defs: parent.id_defs,
variables_builder,
resolver: &mut parent.resolver,
method,
@@ -448,8 +446,6 @@ impl<'a, 'input> MethodEmitContext<'a, 'input> { Statement::Label(label) => self.emit_label_delayed(label)?,
Statement::Instruction(inst) => self.emit_instruction(inst)?,
Statement::Conditional(_) => todo!(),
- Statement::LoadVar(var) => self.emit_load_variable(var)?,
- Statement::StoreVar(store) => self.emit_store_var(store)?,
Statement::Conversion(conversion) => self.emit_conversion(conversion)?,
Statement::Constant(constant) => self.emit_constant(constant)?,
Statement::RetValue(_, values) => self.emit_ret_value(values)?,
@@ -503,13 +499,6 @@ impl<'a, 'input> MethodEmitContext<'a, 'input> { Ok(())
}
- fn emit_store_var(&mut self, store: StoreVarDetails) -> Result<(), TranslateError> {
- let ptr = self.resolver.value(store.arg.src1)?;
- let value = self.resolver.value(store.arg.src2)?;
- unsafe { LLVMBuildStore(self.builder, value, ptr) };
- Ok(())
- }
-
fn emit_instruction(
&mut self,
inst: ast::Instruction<SpirvWord>,
@@ -520,45 +509,45 @@ impl<'a, 'input> MethodEmitContext<'a, 'input> { ast::Instruction::Add { data, arguments } => self.emit_add(data, arguments),
ast::Instruction::St { data, arguments } => self.emit_st(data, arguments),
ast::Instruction::Mul { data, arguments } => self.emit_mul(data, arguments),
- ast::Instruction::Setp { data, arguments } => todo!(),
- ast::Instruction::SetpBool { data, arguments } => todo!(),
- ast::Instruction::Not { data, arguments } => todo!(),
- ast::Instruction::Or { data, arguments } => todo!(),
- ast::Instruction::And { data, arguments } => self.emit_and(arguments),
+ ast::Instruction::Setp { .. } => todo!(),
+ ast::Instruction::SetpBool { .. } => todo!(),
+ ast::Instruction::Not { .. } => todo!(),
+ ast::Instruction::Or { .. } => todo!(),
+ ast::Instruction::And { arguments, .. } => self.emit_and(arguments),
ast::Instruction::Bra { arguments } => self.emit_bra(arguments),
ast::Instruction::Call { data, arguments } => self.emit_call(data, arguments),
- ast::Instruction::Cvt { data, arguments } => todo!(),
- ast::Instruction::Shr { data, arguments } => todo!(),
- ast::Instruction::Shl { data, arguments } => todo!(),
+ ast::Instruction::Cvt { .. } => todo!(),
+ ast::Instruction::Shr { .. } => todo!(),
+ ast::Instruction::Shl { .. } => todo!(),
ast::Instruction::Ret { data } => Ok(self.emit_ret(data)),
- ast::Instruction::Cvta { data, arguments } => todo!(),
- ast::Instruction::Abs { data, arguments } => todo!(),
- ast::Instruction::Mad { data, arguments } => todo!(),
- ast::Instruction::Fma { data, arguments } => todo!(),
- ast::Instruction::Sub { data, arguments } => todo!(),
- ast::Instruction::Min { data, arguments } => todo!(),
- ast::Instruction::Max { data, arguments } => todo!(),
- ast::Instruction::Rcp { data, arguments } => todo!(),
- ast::Instruction::Sqrt { data, arguments } => todo!(),
- ast::Instruction::Rsqrt { data, arguments } => todo!(),
- ast::Instruction::Selp { data, arguments } => todo!(),
- ast::Instruction::Bar { data, arguments } => todo!(),
+ ast::Instruction::Cvta { .. } => todo!(),
+ ast::Instruction::Abs { .. } => todo!(),
+ ast::Instruction::Mad { .. } => todo!(),
+ ast::Instruction::Fma { .. } => todo!(),
+ ast::Instruction::Sub { .. } => todo!(),
+ ast::Instruction::Min { .. } => todo!(),
+ ast::Instruction::Max { .. } => todo!(),
+ ast::Instruction::Rcp { .. } => todo!(),
+ ast::Instruction::Sqrt { .. } => todo!(),
+ ast::Instruction::Rsqrt { .. } => todo!(),
+ ast::Instruction::Selp { .. } => todo!(),
+ ast::Instruction::Bar { .. } => todo!(),
ast::Instruction::Atom { data, arguments } => self.emit_atom(data, arguments),
ast::Instruction::AtomCas { data, arguments } => self.emit_atom_cas(data, arguments),
- ast::Instruction::Div { data, arguments } => todo!(),
- ast::Instruction::Neg { data, arguments } => todo!(),
- ast::Instruction::Sin { data, arguments } => todo!(),
+ ast::Instruction::Div { .. } => todo!(),
+ ast::Instruction::Neg { .. } => todo!(),
+ ast::Instruction::Sin { .. } => todo!(),
ast::Instruction::Cos { data, arguments } => self.emit_cos(data, arguments),
- ast::Instruction::Lg2 { data, arguments } => todo!(),
- ast::Instruction::Ex2 { data, arguments } => todo!(),
+ ast::Instruction::Lg2 { .. } => todo!(),
+ ast::Instruction::Ex2 { .. } => todo!(),
ast::Instruction::Clz { data, arguments } => self.emit_clz(data, arguments),
ast::Instruction::Brev { data, arguments } => self.emit_brev(data, arguments),
- ast::Instruction::Popc { data, arguments } => todo!(),
+ ast::Instruction::Popc { .. } => todo!(),
ast::Instruction::Xor { data, arguments } => self.emit_xor(data, arguments),
- ast::Instruction::Rem { data, arguments } => todo!(),
- ast::Instruction::PrmtSlow { arguments } => todo!(),
- ast::Instruction::Prmt { data, arguments } => todo!(),
- ast::Instruction::Membar { data } => todo!(),
+ ast::Instruction::Rem { .. } => todo!(),
+ ast::Instruction::PrmtSlow { .. } => todo!(),
+ ast::Instruction::Prmt { .. } => todo!(),
+ ast::Instruction::Membar { .. } => todo!(),
ast::Instruction::Trap {} => todo!(),
// replaced by a function call
ast::Instruction::Bfe { .. }
@@ -584,19 +573,6 @@ impl<'a, 'input> MethodEmitContext<'a, 'input> { Ok(())
}
- fn emit_load_variable(&mut self, var: LoadVarDetails) -> Result<(), TranslateError> {
- if var.member_index.is_some() {
- todo!()
- }
- let builder = self.builder;
- let type_ = get_type(self.context, &var.typ)?;
- let ptr = self.resolver.value(var.arg.src)?;
- self.resolver.with_result(var.arg.dst, |dst| unsafe {
- LLVMBuildLoad2(builder, type_, ptr, dst)
- });
- Ok(())
- }
-
fn emit_conversion(&mut self, conversion: ImplicitConversion) -> Result<(), TranslateError> {
let builder = self.builder;
match conversion.kind {
@@ -677,8 +653,8 @@ impl<'a, 'input> MethodEmitContext<'a, 'input> { let src1 = self.resolver.value(arguments.src1)?;
let src2 = self.resolver.value(arguments.src2)?;
let fn_ = match data {
- ast::ArithDetails::Integer(integer) => LLVMBuildAdd,
- ast::ArithDetails::Float(float) => LLVMBuildFAdd,
+ ast::ArithDetails::Integer(..) => LLVMBuildAdd,
+ ast::ArithDetails::Float(..) => LLVMBuildFAdd,
};
self.resolver.with_result(arguments.dst, |dst| unsafe {
fn_(builder, src1, src2, dst)
@@ -721,14 +697,14 @@ impl<'a, 'input> MethodEmitContext<'a, 'input> { }
}
}
- let name = match (&*data.return_arguments, &*arguments.return_arguments) {
- ([], []) => LLVM_UNNAMED.as_ptr(),
- ([(type_, _)], [dst]) => self.resolver.get_or_add_raw(*dst),
+ let name = match &*arguments.return_arguments {
+ [] => LLVM_UNNAMED.as_ptr(),
+ [dst] => self.resolver.get_or_add_raw(*dst),
_ => todo!(),
};
let type_ = get_function_type(
self.context,
- data.return_arguments.iter().map(|(type_, space)| type_),
+ data.return_arguments.iter().map(|(type_, ..)| type_),
data.input_arguments
.iter()
.map(|(type_, space)| get_input_argument_type(self.context, &type_, *space)),
@@ -951,12 +927,12 @@ impl<'a, 'input> MethodEmitContext<'a, 'input> { arguments: ast::MulArgs<SpirvWord>,
) -> Result<(), TranslateError> {
let mul_fn = match data {
- ast::MulDetails::Integer { type_, control } => match control {
+ ast::MulDetails::Integer { control, .. } => match control {
ast::MulIntControl::Low => LLVMBuildMul,
ast::MulIntControl::High => todo!(),
ast::MulIntControl::Wide => todo!(),
},
- ast::MulDetails::Float(arith_float) => LLVMBuildFMul,
+ ast::MulDetails::Float(..) => LLVMBuildFMul,
};
let src1 = self.resolver.value(arguments.src1)?;
let src2 = self.resolver.value(arguments.src2)?;
@@ -968,7 +944,7 @@ impl<'a, 'input> MethodEmitContext<'a, 'input> { fn emit_cos(
&mut self,
- data: ast::FlushToZero,
+ _data: ast::FlushToZero,
arguments: ast::CosArgs<SpirvWord>,
) -> Result<(), TranslateError> {
let llvm_fn = c"llvm.cos.f32";
diff --git a/ptx/src/pass/emit_spirv.rs b/ptx/src/pass/emit_spirv.rs deleted file mode 100644 index d522b12..0000000 --- a/ptx/src/pass/emit_spirv.rs +++ /dev/null @@ -1,2764 +0,0 @@ -use super::*;
-use half::f16;
-use ptx_parser as ast;
-use rspirv::{binary::Assemble, dr};
-use std::{
- collections::{HashMap, HashSet},
- ffi::CString,
- mem,
-};
-
-pub(super) fn run<'input>(
- mut builder: dr::Builder,
- id_defs: &GlobalStringIdResolver<'input>,
- call_map: MethodsCallMap<'input>,
- denorm_information: HashMap<
- ptx_parser::MethodName<SpirvWord>,
- HashMap<u8, (spirv::FPDenormMode, isize)>,
- >,
- directives: Vec<Directive<'input>>,
-) -> Result<(dr::Module, HashMap<String, KernelInfo>, CString), TranslateError> {
- builder.set_version(1, 3);
- emit_capabilities(&mut builder);
- emit_extensions(&mut builder);
- let opencl_id = emit_opencl_import(&mut builder);
- emit_memory_model(&mut builder);
- let mut map = TypeWordMap::new(&mut builder);
- //emit_builtins(&mut builder, &mut map, &id_defs);
- let mut kernel_info = HashMap::new();
- let (build_options, should_flush_denorms) =
- emit_denorm_build_string(&call_map, &denorm_information);
- let (directives, globals_use_map) = get_globals_use_map(directives);
- emit_directives(
- &mut builder,
- &mut map,
- &id_defs,
- opencl_id,
- should_flush_denorms,
- &call_map,
- globals_use_map,
- directives,
- &mut kernel_info,
- )?;
- Ok((builder.module(), kernel_info, build_options))
-}
-
-fn emit_capabilities(builder: &mut dr::Builder) {
- builder.capability(spirv::Capability::GenericPointer);
- builder.capability(spirv::Capability::Linkage);
- builder.capability(spirv::Capability::Addresses);
- builder.capability(spirv::Capability::Kernel);
- builder.capability(spirv::Capability::Int8);
- builder.capability(spirv::Capability::Int16);
- builder.capability(spirv::Capability::Int64);
- builder.capability(spirv::Capability::Float16);
- builder.capability(spirv::Capability::Float64);
- builder.capability(spirv::Capability::DenormFlushToZero);
- // TODO: re-enable when Intel float control extension works
- //builder.capability(spirv::Capability::FunctionFloatControlINTEL);
-}
-
-// http://htmlpreview.github.io/?https://github.com/KhronosGroup/SPIRV-Registry/blob/master/extensions/KHR/SPV_KHR_float_controls.html
-fn emit_extensions(builder: &mut dr::Builder) {
- // TODO: re-enable when Intel float control extension works
- //builder.extension("SPV_INTEL_float_controls2");
- builder.extension("SPV_KHR_float_controls");
- builder.extension("SPV_KHR_no_integer_wrap_decoration");
-}
-
-fn emit_opencl_import(builder: &mut dr::Builder) -> spirv::Word {
- builder.ext_inst_import("OpenCL.std")
-}
-
-fn emit_memory_model(builder: &mut dr::Builder) {
- builder.memory_model(
- spirv::AddressingModel::Physical64,
- spirv::MemoryModel::OpenCL,
- );
-}
-
-struct TypeWordMap {
- void: spirv::Word,
- complex: HashMap<SpirvType, SpirvWord>,
- constants: HashMap<(SpirvType, u64), SpirvWord>,
-}
-
-impl TypeWordMap {
- fn new(b: &mut dr::Builder) -> TypeWordMap {
- let void = b.type_void(None);
- TypeWordMap {
- void: void,
- complex: HashMap::<SpirvType, SpirvWord>::new(),
- constants: HashMap::new(),
- }
- }
-
- fn void(&self) -> spirv::Word {
- self.void
- }
-
- fn get_or_add_scalar(&mut self, b: &mut dr::Builder, t: ast::ScalarType) -> SpirvWord {
- let key: SpirvScalarKey = t.into();
- self.get_or_add_spirv_scalar(b, key)
- }
-
- fn get_or_add_spirv_scalar(&mut self, b: &mut dr::Builder, key: SpirvScalarKey) -> SpirvWord {
- *self.complex.entry(SpirvType::Base(key)).or_insert_with(|| {
- SpirvWord(match key {
- SpirvScalarKey::B8 => b.type_int(None, 8, 0),
- SpirvScalarKey::B16 => b.type_int(None, 16, 0),
- SpirvScalarKey::B32 => b.type_int(None, 32, 0),
- SpirvScalarKey::B64 => b.type_int(None, 64, 0),
- SpirvScalarKey::F16 => b.type_float(None, 16),
- SpirvScalarKey::F32 => b.type_float(None, 32),
- SpirvScalarKey::F64 => b.type_float(None, 64),
- SpirvScalarKey::Pred => b.type_bool(None),
- SpirvScalarKey::F16x2 => todo!(),
- })
- })
- }
-
- fn get_or_add(&mut self, b: &mut dr::Builder, t: SpirvType) -> SpirvWord {
- match t {
- SpirvType::Base(key) => self.get_or_add_spirv_scalar(b, key),
- SpirvType::Pointer(ref typ, storage) => {
- let base = self.get_or_add(b, *typ.clone());
- *self
- .complex
- .entry(t)
- .or_insert_with(|| SpirvWord(b.type_pointer(None, storage, base.0)))
- }
- SpirvType::Vector(typ, len) => {
- let base = self.get_or_add_spirv_scalar(b, typ);
- *self
- .complex
- .entry(t)
- .or_insert_with(|| SpirvWord(b.type_vector(None, base.0, len as u32)))
- }
- SpirvType::Array(typ, array_dimensions) => {
- let (base_type, length) = match &*array_dimensions {
- &[] => {
- return self.get_or_add(b, SpirvType::Base(typ));
- }
- &[len] => {
- let u32_type = self.get_or_add_scalar(b, ast::ScalarType::U32);
- let base = self.get_or_add_spirv_scalar(b, typ);
- let len_const = b.constant_u32(u32_type.0, None, len);
- (base, len_const)
- }
- array_dimensions => {
- let u32_type = self.get_or_add_scalar(b, ast::ScalarType::U32);
- let base = self
- .get_or_add(b, SpirvType::Array(typ, array_dimensions[1..].to_vec()));
- let len_const = b.constant_u32(u32_type.0, None, array_dimensions[0]);
- (base, len_const)
- }
- };
- *self
- .complex
- .entry(SpirvType::Array(typ, array_dimensions))
- .or_insert_with(|| SpirvWord(b.type_array(None, base_type.0, length)))
- }
- SpirvType::Func(ref out_params, ref in_params) => {
- let out_t = match out_params {
- Some(p) => self.get_or_add(b, *p.clone()),
- None => SpirvWord(self.void()),
- };
- let in_t = in_params
- .iter()
- .map(|t| self.get_or_add(b, t.clone()).0)
- .collect::<Vec<_>>();
- *self
- .complex
- .entry(t)
- .or_insert_with(|| SpirvWord(b.type_function(None, out_t.0, in_t)))
- }
- SpirvType::Struct(ref underlying) => {
- let underlying_ids = underlying
- .iter()
- .map(|t| self.get_or_add_spirv_scalar(b, *t).0)
- .collect::<Vec<_>>();
- *self
- .complex
- .entry(t)
- .or_insert_with(|| SpirvWord(b.type_struct(None, underlying_ids)))
- }
- }
- }
-
- fn get_or_add_fn(
- &mut self,
- b: &mut dr::Builder,
- in_params: impl Iterator<Item = SpirvType>,
- mut out_params: impl ExactSizeIterator<Item = SpirvType>,
- ) -> (SpirvWord, SpirvWord) {
- let (out_args, out_spirv_type) = if out_params.len() == 0 {
- (None, SpirvWord(self.void()))
- } else if out_params.len() == 1 {
- let arg_as_key = out_params.next().unwrap();
- (
- Some(Box::new(arg_as_key.clone())),
- self.get_or_add(b, arg_as_key),
- )
- } else {
- // TODO: support multiple return values
- todo!()
- };
- (
- out_spirv_type,
- self.get_or_add(b, SpirvType::Func(out_args, in_params.collect::<Vec<_>>())),
- )
- }
-
- fn get_or_add_constant(
- &mut self,
- b: &mut dr::Builder,
- typ: &ast::Type,
- init: &[u8],
- ) -> Result<SpirvWord, TranslateError> {
- Ok(match typ {
- ast::Type::Scalar(t) => match t {
- ast::ScalarType::B8 | ast::ScalarType::U8 | ast::ScalarType::S8 => self
- .get_or_add_constant_single::<u8, _, _>(
- b,
- *t,
- init,
- |v| v as u64,
- |b, result_type, v| b.constant_u32(result_type, None, v as u32),
- ),
- ast::ScalarType::B16 | ast::ScalarType::U16 | ast::ScalarType::S16 => self
- .get_or_add_constant_single::<u16, _, _>(
- b,
- *t,
- init,
- |v| v as u64,
- |b, result_type, v| b.constant_u32(result_type, None, v as u32),
- ),
- ast::ScalarType::B32 | ast::ScalarType::U32 | ast::ScalarType::S32 => self
- .get_or_add_constant_single::<u32, _, _>(
- b,
- *t,
- init,
- |v| v as u64,
- |b, result_type, v| b.constant_u32(result_type, None, v),
- ),
- ast::ScalarType::B64 | ast::ScalarType::U64 | ast::ScalarType::S64 => self
- .get_or_add_constant_single::<u64, _, _>(
- b,
- *t,
- init,
- |v| v,
- |b, result_type, v| b.constant_u64(result_type, None, v),
- ),
- ast::ScalarType::F16 => self.get_or_add_constant_single::<f16, _, _>(
- b,
- *t,
- init,
- |v| unsafe { mem::transmute::<_, u16>(v) } as u64,
- |b, result_type, v| b.constant_f32(result_type, None, v.to_f32()),
- ),
- ast::ScalarType::F32 => self.get_or_add_constant_single::<f32, _, _>(
- b,
- *t,
- init,
- |v| unsafe { mem::transmute::<_, u32>(v) } as u64,
- |b, result_type, v| b.constant_f32(result_type, None, v),
- ),
- ast::ScalarType::F64 => self.get_or_add_constant_single::<f64, _, _>(
- b,
- *t,
- init,
- |v| unsafe { mem::transmute::<_, u64>(v) },
- |b, result_type, v| b.constant_f64(result_type, None, v),
- ),
- ast::ScalarType::F16x2 => return Err(TranslateError::Todo),
- ast::ScalarType::Pred => self.get_or_add_constant_single::<u8, _, _>(
- b,
- *t,
- init,
- |v| v as u64,
- |b, result_type, v| {
- if v == 0 {
- b.constant_false(result_type, None)
- } else {
- b.constant_true(result_type, None)
- }
- },
- ),
- ast::ScalarType::S16x2
- | ast::ScalarType::U16x2
- | ast::ScalarType::BF16
- | ast::ScalarType::BF16x2
- | ast::ScalarType::B128 => todo!(),
- },
- ast::Type::Vector(len, typ) => {
- let result_type =
- self.get_or_add(b, SpirvType::Vector(SpirvScalarKey::from(*typ), *len));
- let size_of_t = typ.size_of();
- let components = (0..*len)
- .map(|x| {
- Ok::<_, TranslateError>(
- self.get_or_add_constant(
- b,
- &ast::Type::Scalar(*typ),
- &init[((size_of_t as usize) * (x as usize))..],
- )?
- .0,
- )
- })
- .collect::<Result<Vec<_>, _>>()?;
- SpirvWord(b.constant_composite(result_type.0, None, components.into_iter()))
- }
- ast::Type::Array(_, typ, dims) => match dims.as_slice() {
- [] => return Err(error_unreachable()),
- [dim] => {
- let result_type = self
- .get_or_add(b, SpirvType::Array(SpirvScalarKey::from(*typ), vec![*dim]));
- let size_of_t = typ.size_of();
- let components = (0..*dim)
- .map(|x| {
- Ok::<_, TranslateError>(
- self.get_or_add_constant(
- b,
- &ast::Type::Scalar(*typ),
- &init[((size_of_t as usize) * (x as usize))..],
- )?
- .0,
- )
- })
- .collect::<Result<Vec<_>, _>>()?;
- SpirvWord(b.constant_composite(result_type.0, None, components.into_iter()))
- }
- [first_dim, rest @ ..] => {
- let result_type = self.get_or_add(
- b,
- SpirvType::Array(SpirvScalarKey::from(*typ), rest.to_vec()),
- );
- let size_of_t = rest
- .iter()
- .fold(typ.size_of() as u32, |x, y| (x as u32) * (*y));
- let components = (0..*first_dim)
- .map(|x| {
- Ok::<_, TranslateError>(
- self.get_or_add_constant(
- b,
- &ast::Type::Array(None, *typ, rest.to_vec()),
- &init[((size_of_t as usize) * (x as usize))..],
- )?
- .0,
- )
- })
- .collect::<Result<Vec<_>, _>>()?;
- SpirvWord(b.constant_composite(result_type.0, None, components.into_iter()))
- }
- },
- ast::Type::Pointer(..) => return Err(error_unreachable()),
- })
- }
-
- fn get_or_add_constant_single<
- T: Copy,
- CastAsU64: FnOnce(T) -> u64,
- InsertConstant: FnOnce(&mut dr::Builder, spirv::Word, T) -> spirv::Word,
- >(
- &mut self,
- b: &mut dr::Builder,
- key: ast::ScalarType,
- init: &[u8],
- cast: CastAsU64,
- f: InsertConstant,
- ) -> SpirvWord {
- let value = unsafe { *(init.as_ptr() as *const T) };
- let value_64 = cast(value);
- let ht_key = (SpirvType::Base(SpirvScalarKey::from(key)), value_64);
- match self.constants.get(&ht_key) {
- Some(value) => *value,
- None => {
- let spirv_type = self.get_or_add_scalar(b, key);
- let result = SpirvWord(f(b, spirv_type.0, value));
- self.constants.insert(ht_key, result);
- result
- }
- }
- }
-}
-
-#[derive(PartialEq, Eq, Hash, Clone)]
-enum SpirvType {
- Base(SpirvScalarKey),
- Vector(SpirvScalarKey, u8),
- Array(SpirvScalarKey, Vec<u32>),
- Pointer(Box<SpirvType>, spirv::StorageClass),
- Func(Option<Box<SpirvType>>, Vec<SpirvType>),
- Struct(Vec<SpirvScalarKey>),
-}
-
-impl SpirvType {
- fn new(t: ast::Type) -> Self {
- match t {
- ast::Type::Scalar(t) => SpirvType::Base(t.into()),
- ast::Type::Vector(len, typ) => SpirvType::Vector(typ.into(), len),
- ast::Type::Array(_, t, len) => SpirvType::Array(t.into(), len),
- ast::Type::Pointer(pointer_t, space) => SpirvType::Pointer(
- Box::new(SpirvType::Base(pointer_t.into())),
- space_to_spirv(space),
- ),
- }
- }
-
- fn pointer_to(t: ast::Type, outer_space: spirv::StorageClass) -> Self {
- let key = Self::new(t);
- SpirvType::Pointer(Box::new(key), outer_space)
- }
-}
-
-impl From<ast::ScalarType> for SpirvType {
- fn from(t: ast::ScalarType) -> Self {
- SpirvType::Base(t.into())
- }
-}
-// SPIR-V integer type definitions are signless, more below:
-// https://www.khronos.org/registry/spir-v/specs/unified1/SPIRV.html#_a_id_unsignedsigned_a_unsigned_versus_signed_integers
-// https://www.khronos.org/registry/spir-v/specs/unified1/SPIRV.html#_validation_rules_for_kernel_a_href_capability_capabilities_a
-#[derive(PartialEq, Eq, Hash, Clone, Copy)]
-enum SpirvScalarKey {
- B8,
- B16,
- B32,
- B64,
- F16,
- F32,
- F64,
- Pred,
- F16x2,
-}
-
-impl From<ast::ScalarType> for SpirvScalarKey {
- fn from(t: ast::ScalarType) -> Self {
- match t {
- ast::ScalarType::B8 | ast::ScalarType::U8 | ast::ScalarType::S8 => SpirvScalarKey::B8,
- ast::ScalarType::B16 | ast::ScalarType::U16 | ast::ScalarType::S16 => {
- SpirvScalarKey::B16
- }
- ast::ScalarType::B32 | ast::ScalarType::U32 | ast::ScalarType::S32 => {
- SpirvScalarKey::B32
- }
- ast::ScalarType::B64 | ast::ScalarType::U64 | ast::ScalarType::S64 => {
- SpirvScalarKey::B64
- }
- ast::ScalarType::F16 => SpirvScalarKey::F16,
- ast::ScalarType::F32 => SpirvScalarKey::F32,
- ast::ScalarType::F64 => SpirvScalarKey::F64,
- ast::ScalarType::F16x2 => SpirvScalarKey::F16x2,
- ast::ScalarType::Pred => SpirvScalarKey::Pred,
- ast::ScalarType::S16x2
- | ast::ScalarType::U16x2
- | ast::ScalarType::BF16
- | ast::ScalarType::BF16x2
- | ast::ScalarType::B128 => todo!(),
- }
- }
-}
-
-fn space_to_spirv(this: ast::StateSpace) -> spirv::StorageClass {
- match this {
- ast::StateSpace::Const => spirv::StorageClass::UniformConstant,
- ast::StateSpace::Generic => spirv::StorageClass::Generic,
- ast::StateSpace::Global => spirv::StorageClass::CrossWorkgroup,
- ast::StateSpace::Local => spirv::StorageClass::Function,
- ast::StateSpace::Shared => spirv::StorageClass::Workgroup,
- ast::StateSpace::Param => spirv::StorageClass::Function,
- ast::StateSpace::Reg => spirv::StorageClass::Function,
- ast::StateSpace::ParamEntry
- | ast::StateSpace::ParamFunc
- | ast::StateSpace::SharedCluster
- | ast::StateSpace::SharedCta => todo!(),
- }
-}
-
-// TODO: remove this once we have pef-function support for denorms
-fn emit_denorm_build_string<'input>(
- call_map: &MethodsCallMap,
- denorm_information: &HashMap<
- ast::MethodName<'input, SpirvWord>,
- HashMap<u8, (spirv::FPDenormMode, isize)>,
- >,
-) -> (CString, bool) {
- let denorm_counts = denorm_information
- .iter()
- .map(|(method, meth_denorm)| {
- let f16_count = meth_denorm
- .get(&(mem::size_of::<f16>() as u8))
- .unwrap_or(&(spirv::FPDenormMode::FlushToZero, 0))
- .1;
- let f32_count = meth_denorm
- .get(&(mem::size_of::<f32>() as u8))
- .unwrap_or(&(spirv::FPDenormMode::FlushToZero, 0))
- .1;
- (method, (f16_count + f32_count))
- })
- .collect::<HashMap<_, _>>();
- let mut flush_over_preserve = 0;
- for (kernel, children) in call_map.kernels() {
- flush_over_preserve += *denorm_counts
- .get(&ast::MethodName::Kernel(kernel))
- .unwrap_or(&0);
- for child_fn in children {
- flush_over_preserve += *denorm_counts
- .get(&ast::MethodName::Func(*child_fn))
- .unwrap_or(&0);
- }
- }
- if flush_over_preserve > 0 {
- (
- CString::new("-ze-take-global-address -ze-denorms-are-zero").unwrap(),
- true,
- )
- } else {
- (CString::new("-ze-take-global-address").unwrap(), false)
- }
-}
-
-fn get_globals_use_map<'input>(
- directives: Vec<Directive<'input>>,
-) -> (
- Vec<Directive<'input>>,
- HashMap<ast::MethodName<'input, SpirvWord>, HashSet<SpirvWord>>,
-) {
- let mut known_globals = HashSet::new();
- for directive in directives.iter() {
- match directive {
- Directive::Variable(_, ast::Variable { name, .. }) => {
- known_globals.insert(*name);
- }
- Directive::Method(..) => {}
- }
- }
- let mut symbol_uses_map = HashMap::new();
- let directives = directives
- .into_iter()
- .map(|directive| match directive {
- Directive::Variable(..) | Directive::Method(Function { body: None, .. }) => directive,
- Directive::Method(Function {
- func_decl,
- body: Some(mut statements),
- globals,
- import_as,
- tuning,
- linkage,
- }) => {
- let method_name = func_decl.borrow().name;
- statements = statements
- .into_iter()
- .map(|statement| {
- statement.visit_map(
- &mut |symbol, _: Option<(&ast::Type, ast::StateSpace)>, _, _| {
- if known_globals.contains(&symbol) {
- multi_hash_map_append(
- &mut symbol_uses_map,
- method_name,
- symbol,
- );
- }
- Ok::<_, TranslateError>(symbol)
- },
- )
- })
- .collect::<Result<Vec<_>, _>>()
- .unwrap();
- Directive::Method(Function {
- func_decl,
- body: Some(statements),
- globals,
- import_as,
- tuning,
- linkage,
- })
- }
- })
- .collect::<Vec<_>>();
- (directives, symbol_uses_map)
-}
-
-fn emit_directives<'input>(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- id_defs: &GlobalStringIdResolver<'input>,
- opencl_id: spirv::Word,
- should_flush_denorms: bool,
- call_map: &MethodsCallMap<'input>,
- globals_use_map: HashMap<ast::MethodName<'input, SpirvWord>, HashSet<SpirvWord>>,
- directives: Vec<Directive<'input>>,
- kernel_info: &mut HashMap<String, KernelInfo>,
-) -> Result<(), TranslateError> {
- let empty_body = Vec::new();
- for d in directives.iter() {
- match d {
- Directive::Variable(linking, var) => {
- emit_variable(builder, map, id_defs, *linking, &var)?;
- }
- Directive::Method(f) => {
- let f_body = match &f.body {
- Some(f) => f,
- None => {
- if f.linkage.contains(ast::LinkingDirective::EXTERN) {
- &empty_body
- } else {
- continue;
- }
- }
- };
- for var in f.globals.iter() {
- emit_variable(builder, map, id_defs, ast::LinkingDirective::NONE, var)?;
- }
- let func_decl = (*f.func_decl).borrow();
- let fn_id = emit_function_header(
- builder,
- map,
- &id_defs,
- &*func_decl,
- call_map,
- &globals_use_map,
- kernel_info,
- )?;
- if matches!(func_decl.name, ast::MethodName::Kernel(_)) {
- if should_flush_denorms {
- builder.execution_mode(
- fn_id.0,
- spirv_headers::ExecutionMode::DenormFlushToZero,
- [16],
- );
- builder.execution_mode(
- fn_id.0,
- spirv_headers::ExecutionMode::DenormFlushToZero,
- [32],
- );
- builder.execution_mode(
- fn_id.0,
- spirv_headers::ExecutionMode::DenormFlushToZero,
- [64],
- );
- }
- // FP contraction happens when compiling source -> PTX and is illegal at this stage (unless you force it in cuModuleLoadDataEx)
- builder.execution_mode(
- fn_id.0,
- spirv_headers::ExecutionMode::ContractionOff,
- [],
- );
- for t in f.tuning.iter() {
- match *t {
- ast::TuningDirective::MaxNtid(nx, ny, nz) => {
- builder.execution_mode(
- fn_id.0,
- spirv_headers::ExecutionMode::MaxWorkgroupSizeINTEL,
- [nx, ny, nz],
- );
- }
- ast::TuningDirective::ReqNtid(nx, ny, nz) => {
- builder.execution_mode(
- fn_id.0,
- spirv_headers::ExecutionMode::LocalSize,
- [nx, ny, nz],
- );
- }
- // Too architecture specific
- ast::TuningDirective::MaxNReg(..)
- | ast::TuningDirective::MinNCtaPerSm(..) => {}
- }
- }
- }
- emit_function_body_ops(builder, map, id_defs, opencl_id, &f_body)?;
- emit_function_linkage(builder, id_defs, f, fn_id)?;
- builder.select_block(None)?;
- builder.end_function()?;
- }
- }
- }
- Ok(())
-}
-
-fn emit_variable<'input>(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- id_defs: &GlobalStringIdResolver<'input>,
- linking: ast::LinkingDirective,
- var: &ast::Variable<SpirvWord>,
-) -> Result<(), TranslateError> {
- let (must_init, st_class) = match var.state_space {
- ast::StateSpace::Reg | ast::StateSpace::Param | ast::StateSpace::Local => {
- (false, spirv::StorageClass::Function)
- }
- ast::StateSpace::Global => (true, spirv::StorageClass::CrossWorkgroup),
- ast::StateSpace::Shared => (false, spirv::StorageClass::Workgroup),
- ast::StateSpace::Const => (false, spirv::StorageClass::UniformConstant),
- ast::StateSpace::Generic => todo!(),
- ast::StateSpace::ParamEntry
- | ast::StateSpace::ParamFunc
- | ast::StateSpace::SharedCluster
- | ast::StateSpace::SharedCta => todo!(),
- };
- let initalizer = if var.array_init.len() > 0 {
- Some(
- map.get_or_add_constant(
- builder,
- &ast::Type::from(var.v_type.clone()),
- &*var.array_init,
- )?
- .0,
- )
- } else if must_init {
- let type_id = map.get_or_add(builder, SpirvType::new(var.v_type.clone()));
- Some(builder.constant_null(type_id.0, None))
- } else {
- None
- };
- let ptr_type_id = map.get_or_add(builder, SpirvType::pointer_to(var.v_type.clone(), st_class));
- builder.variable(ptr_type_id.0, Some(var.name.0), st_class, initalizer);
- if let Some(align) = var.align {
- builder.decorate(
- var.name.0,
- spirv::Decoration::Alignment,
- [dr::Operand::LiteralInt32(align)].iter().cloned(),
- );
- }
- if var.state_space != ast::StateSpace::Shared
- || !linking.contains(ast::LinkingDirective::EXTERN)
- {
- emit_linking_decoration(builder, id_defs, None, var.name, linking);
- }
- Ok(())
-}
-
-fn emit_function_header<'input>(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- defined_globals: &GlobalStringIdResolver<'input>,
- func_decl: &ast::MethodDeclaration<'input, SpirvWord>,
- call_map: &MethodsCallMap<'input>,
- globals_use_map: &HashMap<ast::MethodName<'input, SpirvWord>, HashSet<SpirvWord>>,
- kernel_info: &mut HashMap<String, KernelInfo>,
-) -> Result<SpirvWord, TranslateError> {
- if let ast::MethodName::Kernel(name) = func_decl.name {
- let args_lens = func_decl
- .input_arguments
- .iter()
- .map(|param| {
- (
- type_size_of(¶m.v_type),
- matches!(param.v_type, ast::Type::Pointer(..)),
- )
- })
- .collect();
- kernel_info.insert(
- name.to_string(),
- KernelInfo {
- arguments_sizes: args_lens,
- uses_shared_mem: func_decl.shared_mem.is_some(),
- },
- );
- }
- let (ret_type, func_type) = get_function_type(
- builder,
- map,
- effective_input_arguments(func_decl).map(|(_, typ)| typ),
- &func_decl.return_arguments,
- );
- let fn_id = match func_decl.name {
- ast::MethodName::Kernel(name) => {
- let fn_id = defined_globals.get_id(name)?;
- let interface = globals_use_map
- .get(&ast::MethodName::Kernel(name))
- .into_iter()
- .flatten()
- .copied()
- .chain({
- call_map
- .get_kernel_children(name)
- .copied()
- .flat_map(|subfunction| {
- globals_use_map
- .get(&ast::MethodName::Func(subfunction))
- .into_iter()
- .flatten()
- .copied()
- })
- .into_iter()
- })
- .map(|word| word.0)
- .collect::<Vec<spirv::Word>>();
- builder.entry_point(spirv::ExecutionModel::Kernel, fn_id.0, name, interface);
- fn_id
- }
- ast::MethodName::Func(name) => name,
- };
- builder.begin_function(
- ret_type.0,
- Some(fn_id.0),
- spirv::FunctionControl::NONE,
- func_type.0,
- )?;
- for (name, typ) in effective_input_arguments(func_decl) {
- let result_type = map.get_or_add(builder, typ);
- builder.function_parameter(Some(name.0), result_type.0)?;
- }
- Ok(fn_id)
-}
-
-pub fn type_size_of(this: &ast::Type) -> usize {
- match this {
- ast::Type::Scalar(typ) => typ.size_of() as usize,
- ast::Type::Vector(len, typ) => (typ.size_of() as usize) * (*len as usize),
- ast::Type::Array(_, typ, len) => len
- .iter()
- .fold(typ.size_of() as usize, |x, y| (x as usize) * (*y as usize)),
- ast::Type::Pointer(..) => mem::size_of::<usize>(),
- }
-}
-fn emit_function_body_ops<'input>(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- id_defs: &GlobalStringIdResolver<'input>,
- opencl: spirv::Word,
- func: &[ExpandedStatement],
-) -> Result<(), TranslateError> {
- for s in func {
- match s {
- Statement::Label(id) => {
- if builder.selected_block().is_some() {
- builder.branch(id.0)?;
- }
- builder.begin_block(Some(id.0))?;
- }
- _ => {
- if builder.selected_block().is_none() && builder.selected_function().is_some() {
- builder.begin_block(None)?;
- }
- }
- }
- match s {
- Statement::Label(_) => (),
- Statement::Variable(var) => {
- emit_variable(builder, map, id_defs, ast::LinkingDirective::NONE, var)?;
- }
- Statement::Constant(cnst) => {
- let typ_id = map.get_or_add_scalar(builder, cnst.typ);
- match (cnst.typ, cnst.value) {
- (ast::ScalarType::B8, ast::ImmediateValue::U64(value))
- | (ast::ScalarType::U8, ast::ImmediateValue::U64(value)) => {
- builder.constant_u32(typ_id.0, Some(cnst.dst.0), value as u8 as u32);
- }
- (ast::ScalarType::B16, ast::ImmediateValue::U64(value))
- | (ast::ScalarType::U16, ast::ImmediateValue::U64(value)) => {
- builder.constant_u32(typ_id.0, Some(cnst.dst.0), value as u16 as u32);
- }
- (ast::ScalarType::B32, ast::ImmediateValue::U64(value))
- | (ast::ScalarType::U32, ast::ImmediateValue::U64(value)) => {
- builder.constant_u32(typ_id.0, Some(cnst.dst.0), value as u32);
- }
- (ast::ScalarType::B64, ast::ImmediateValue::U64(value))
- | (ast::ScalarType::U64, ast::ImmediateValue::U64(value)) => {
- builder.constant_u64(typ_id.0, Some(cnst.dst.0), value);
- }
- (ast::ScalarType::S8, ast::ImmediateValue::U64(value)) => {
- builder.constant_u32(typ_id.0, Some(cnst.dst.0), value as i8 as u32);
- }
- (ast::ScalarType::S16, ast::ImmediateValue::U64(value)) => {
- builder.constant_u32(typ_id.0, Some(cnst.dst.0), value as i16 as u32);
- }
- (ast::ScalarType::S32, ast::ImmediateValue::U64(value)) => {
- builder.constant_u32(typ_id.0, Some(cnst.dst.0), value as i32 as u32);
- }
- (ast::ScalarType::S64, ast::ImmediateValue::U64(value)) => {
- builder.constant_u64(typ_id.0, Some(cnst.dst.0), value as i64 as u64);
- }
- (ast::ScalarType::B8, ast::ImmediateValue::S64(value))
- | (ast::ScalarType::U8, ast::ImmediateValue::S64(value)) => {
- builder.constant_u32(typ_id.0, Some(cnst.dst.0), value as u8 as u32);
- }
- (ast::ScalarType::B16, ast::ImmediateValue::S64(value))
- | (ast::ScalarType::U16, ast::ImmediateValue::S64(value)) => {
- builder.constant_u32(typ_id.0, Some(cnst.dst.0), value as u16 as u32);
- }
- (ast::ScalarType::B32, ast::ImmediateValue::S64(value))
- | (ast::ScalarType::U32, ast::ImmediateValue::S64(value)) => {
- builder.constant_u32(typ_id.0, Some(cnst.dst.0), value as u32);
- }
- (ast::ScalarType::B64, ast::ImmediateValue::S64(value))
- | (ast::ScalarType::U64, ast::ImmediateValue::S64(value)) => {
- builder.constant_u64(typ_id.0, Some(cnst.dst.0), value as u64);
- }
- (ast::ScalarType::S8, ast::ImmediateValue::S64(value)) => {
- builder.constant_u32(typ_id.0, Some(cnst.dst.0), value as i8 as u32);
- }
- (ast::ScalarType::S16, ast::ImmediateValue::S64(value)) => {
- builder.constant_u32(typ_id.0, Some(cnst.dst.0), value as i16 as u32);
- }
- (ast::ScalarType::S32, ast::ImmediateValue::S64(value)) => {
- builder.constant_u32(typ_id.0, Some(cnst.dst.0), value as i32 as u32);
- }
- (ast::ScalarType::S64, ast::ImmediateValue::S64(value)) => {
- builder.constant_u64(typ_id.0, Some(cnst.dst.0), value as u64);
- }
- (ast::ScalarType::F16, ast::ImmediateValue::F32(value)) => {
- builder.constant_f32(
- typ_id.0,
- Some(cnst.dst.0),
- f16::from_f32(value).to_f32(),
- );
- }
- (ast::ScalarType::F32, ast::ImmediateValue::F32(value)) => {
- builder.constant_f32(typ_id.0, Some(cnst.dst.0), value);
- }
- (ast::ScalarType::F64, ast::ImmediateValue::F32(value)) => {
- builder.constant_f64(typ_id.0, Some(cnst.dst.0), value as f64);
- }
- (ast::ScalarType::F16, ast::ImmediateValue::F64(value)) => {
- builder.constant_f32(
- typ_id.0,
- Some(cnst.dst.0),
- f16::from_f64(value).to_f32(),
- );
- }
- (ast::ScalarType::F32, ast::ImmediateValue::F64(value)) => {
- builder.constant_f32(typ_id.0, Some(cnst.dst.0), value as f32);
- }
- (ast::ScalarType::F64, ast::ImmediateValue::F64(value)) => {
- builder.constant_f64(typ_id.0, Some(cnst.dst.0), value);
- }
- (ast::ScalarType::Pred, ast::ImmediateValue::U64(value)) => {
- let bool_type = map.get_or_add_scalar(builder, ast::ScalarType::Pred).0;
- if value == 0 {
- builder.constant_false(bool_type, Some(cnst.dst.0));
- } else {
- builder.constant_true(bool_type, Some(cnst.dst.0));
- }
- }
- (ast::ScalarType::Pred, ast::ImmediateValue::S64(value)) => {
- let bool_type = map.get_or_add_scalar(builder, ast::ScalarType::Pred).0;
- if value == 0 {
- builder.constant_false(bool_type, Some(cnst.dst.0));
- } else {
- builder.constant_true(bool_type, Some(cnst.dst.0));
- }
- }
- _ => return Err(error_mismatched_type()),
- }
- }
- Statement::Conversion(cv) => emit_implicit_conversion(builder, map, cv)?,
- Statement::Conditional(bra) => {
- builder.branch_conditional(
- bra.predicate.0,
- bra.if_true.0,
- bra.if_false.0,
- iter::empty(),
- )?;
- }
- Statement::FunctionPointer(FunctionPointerDetails { dst, src }) => {
- // TODO: implement properly
- let zero = map.get_or_add_constant(
- builder,
- &ast::Type::Scalar(ast::ScalarType::U64),
- &vec_repr(0u64),
- )?;
- let result_type = map.get_or_add_scalar(builder, ast::ScalarType::U64);
- builder.copy_object(result_type.0, Some(dst.0), zero.0)?;
- }
- Statement::Instruction(inst) => match inst {
- ast::Instruction::PrmtSlow { .. } | ast::Instruction::Trap { .. } => todo!(),
- ast::Instruction::Call { data, arguments } => {
- let (result_type, result_id) =
- match (&*data.return_arguments, &*arguments.return_arguments) {
- ([(type_, space)], [id]) => {
- if *space != ast::StateSpace::Reg {
- return Err(error_unreachable());
- }
- (
- map.get_or_add(builder, SpirvType::new(type_.clone())).0,
- Some(id.0),
- )
- }
- ([], []) => (map.void(), None),
- _ => todo!(),
- };
- let arg_list = arguments
- .input_arguments
- .iter()
- .map(|id| id.0)
- .collect::<Vec<_>>();
- builder.function_call(result_type, result_id, arguments.func.0, arg_list)?;
- }
- ast::Instruction::Abs { data, arguments } => {
- emit_abs(builder, map, opencl, data, arguments)?
- }
- // SPIR-V does not support marking jumps as guaranteed-converged
- ast::Instruction::Bra { arguments, .. } => {
- builder.branch(arguments.src.0)?;
- }
- ast::Instruction::Ld { data, arguments } => {
- let mem_access = match data.qualifier {
- ast::LdStQualifier::Weak => spirv::MemoryAccess::NONE,
- // ld.volatile does not match Volatile OpLoad nor Relaxed OpAtomicLoad
- ast::LdStQualifier::Volatile => spirv::MemoryAccess::VOLATILE,
- _ => return Err(TranslateError::Todo),
- };
- let result_type =
- map.get_or_add(builder, SpirvType::new(ast::Type::from(data.typ.clone())));
- builder.load(
- result_type.0,
- Some(arguments.dst.0),
- arguments.src.0,
- Some(mem_access | spirv::MemoryAccess::ALIGNED),
- [dr::Operand::LiteralInt32(
- type_size_of(&ast::Type::from(data.typ.clone())) as u32,
- )]
- .iter()
- .cloned(),
- )?;
- }
- ast::Instruction::St { data, arguments } => {
- let mem_access = match data.qualifier {
- ast::LdStQualifier::Weak => spirv::MemoryAccess::NONE,
- // st.volatile does not match Volatile OpStore nor Relaxed OpAtomicStore
- ast::LdStQualifier::Volatile => spirv::MemoryAccess::VOLATILE,
- _ => return Err(TranslateError::Todo),
- };
- builder.store(
- arguments.src1.0,
- arguments.src2.0,
- Some(mem_access | spirv::MemoryAccess::ALIGNED),
- [dr::Operand::LiteralInt32(
- type_size_of(&ast::Type::from(data.typ.clone())) as u32,
- )]
- .iter()
- .cloned(),
- )?;
- }
- // SPIR-V does not support ret as guaranteed-converged
- ast::Instruction::Ret { .. } => builder.ret()?,
- ast::Instruction::Mov { data, arguments } => {
- let result_type =
- map.get_or_add(builder, SpirvType::new(ast::Type::from(data.typ.clone())));
- builder.copy_object(result_type.0, Some(arguments.dst.0), arguments.src.0)?;
- }
- ast::Instruction::Mul { data, arguments } => match data {
- ast::MulDetails::Integer { type_, control } => {
- emit_mul_int(builder, map, opencl, *type_, *control, arguments)?
- }
- ast::MulDetails::Float(ref ctr) => {
- emit_mul_float(builder, map, ctr, arguments)?
- }
- },
- ast::Instruction::Add { data, arguments } => match data {
- ast::ArithDetails::Integer(desc) => {
- emit_add_int(builder, map, desc.type_.into(), desc.saturate, arguments)?
- }
- ast::ArithDetails::Float(desc) => {
- emit_add_float(builder, map, desc, arguments)?
- }
- },
- ast::Instruction::Setp { data, arguments } => {
- if arguments.dst2.is_some() {
- todo!()
- }
- emit_setp(builder, map, data, arguments)?;
- }
- ast::Instruction::Not { data, arguments } => {
- let result_type = map.get_or_add(builder, SpirvType::from(*data));
- let result_id = Some(arguments.dst.0);
- let operand = arguments.src;
- match data {
- ast::ScalarType::Pred => {
- logical_not(builder, result_type.0, result_id, operand.0)
- }
- _ => builder.not(result_type.0, result_id, operand.0),
- }?;
- }
- ast::Instruction::Shl { data, arguments } => {
- let full_type = ast::Type::Scalar(*data);
- let size_of = type_size_of(&full_type);
- let result_type = map.get_or_add(builder, SpirvType::new(full_type));
- let offset_src = insert_shift_hack(builder, map, arguments.src2.0, size_of)?;
- builder.shift_left_logical(
- result_type.0,
- Some(arguments.dst.0),
- arguments.src1.0,
- offset_src,
- )?;
- }
- ast::Instruction::Shr { data, arguments } => {
- let full_type = ast::ScalarType::from(data.type_);
- let size_of = full_type.size_of();
- let result_type = map.get_or_add_scalar(builder, full_type).0;
- let offset_src =
- insert_shift_hack(builder, map, arguments.src2.0, size_of as usize)?;
- match data.kind {
- ptx_parser::RightShiftKind::Arithmetic => {
- builder.shift_right_arithmetic(
- result_type,
- Some(arguments.dst.0),
- arguments.src1.0,
- offset_src,
- )?;
- }
- ptx_parser::RightShiftKind::Logical => {
- builder.shift_right_logical(
- result_type,
- Some(arguments.dst.0),
- arguments.src1.0,
- offset_src,
- )?;
- }
- }
- }
- ast::Instruction::Cvt { data, arguments } => {
- emit_cvt(builder, map, opencl, data, arguments)?;
- }
- ast::Instruction::Cvta { data, arguments } => {
- // This would be only meaningful if const/slm/global pointers
- // had a different format than generic pointers, but they don't pretty much by ptx definition
- // Honestly, I have no idea why this instruction exists and is emitted by the compiler
- let result_type = map.get_or_add_scalar(builder, ast::ScalarType::B64);
- builder.copy_object(result_type.0, Some(arguments.dst.0), arguments.src.0)?;
- }
- ast::Instruction::SetpBool { .. } => todo!(),
- ast::Instruction::Mad { data, arguments } => match data {
- ast::MadDetails::Integer {
- type_,
- control,
- saturate,
- } => {
- if *saturate {
- todo!()
- }
- if type_.kind() == ast::ScalarKind::Signed {
- emit_mad_sint(builder, map, opencl, *type_, *control, arguments)?
- } else {
- emit_mad_uint(builder, map, opencl, *type_, *control, arguments)?
- }
- }
- ast::MadDetails::Float(desc) => {
- emit_mad_float(builder, map, opencl, desc, arguments)?
- }
- },
- ast::Instruction::Fma { data, arguments } => {
- emit_fma_float(builder, map, opencl, data, arguments)?
- }
- ast::Instruction::Or { data, arguments } => {
- let result_type = map.get_or_add_scalar(builder, *data).0;
- if *data == ast::ScalarType::Pred {
- builder.logical_or(
- result_type,
- Some(arguments.dst.0),
- arguments.src1.0,
- arguments.src2.0,
- )?;
- } else {
- builder.bitwise_or(
- result_type,
- Some(arguments.dst.0),
- arguments.src1.0,
- arguments.src2.0,
- )?;
- }
- }
- ast::Instruction::Sub { data, arguments } => match data {
- ast::ArithDetails::Integer(desc) => {
- emit_sub_int(builder, map, desc.type_.into(), desc.saturate, arguments)?;
- }
- ast::ArithDetails::Float(desc) => {
- emit_sub_float(builder, map, desc, arguments)?;
- }
- },
- ast::Instruction::Min { data, arguments } => {
- emit_min(builder, map, opencl, data, arguments)?;
- }
- ast::Instruction::Max { data, arguments } => {
- emit_max(builder, map, opencl, data, arguments)?;
- }
- ast::Instruction::Rcp { data, arguments } => {
- emit_rcp(builder, map, opencl, data, arguments)?;
- }
- ast::Instruction::And { data, arguments } => {
- let result_type = map.get_or_add_scalar(builder, *data);
- if *data == ast::ScalarType::Pred {
- builder.logical_and(
- result_type.0,
- Some(arguments.dst.0),
- arguments.src1.0,
- arguments.src2.0,
- )?;
- } else {
- builder.bitwise_and(
- result_type.0,
- Some(arguments.dst.0),
- arguments.src1.0,
- arguments.src2.0,
- )?;
- }
- }
- ast::Instruction::Selp { data, arguments } => {
- let result_type = map.get_or_add_scalar(builder, *data);
- builder.select(
- result_type.0,
- Some(arguments.dst.0),
- arguments.src3.0,
- arguments.src1.0,
- arguments.src2.0,
- )?;
- }
- // TODO: implement named barriers
- ast::Instruction::Bar { data, arguments } => {
- let workgroup_scope = map.get_or_add_constant(
- builder,
- &ast::Type::Scalar(ast::ScalarType::U32),
- &vec_repr(spirv::Scope::Workgroup as u32),
- )?;
- let barrier_semantics = map.get_or_add_constant(
- builder,
- &ast::Type::Scalar(ast::ScalarType::U32),
- &vec_repr(
- spirv::MemorySemantics::CROSS_WORKGROUP_MEMORY
- | spirv::MemorySemantics::WORKGROUP_MEMORY
- | spirv::MemorySemantics::SEQUENTIALLY_CONSISTENT,
- ),
- )?;
- builder.control_barrier(
- workgroup_scope.0,
- workgroup_scope.0,
- barrier_semantics.0,
- )?;
- }
- ast::Instruction::Atom { data, arguments } => {
- emit_atom(builder, map, data, arguments)?;
- }
- ast::Instruction::AtomCas { data, arguments } => {
- let result_type = map.get_or_add_scalar(builder, data.type_);
- let memory_const = map.get_or_add_constant(
- builder,
- &ast::Type::Scalar(ast::ScalarType::U32),
- &vec_repr(scope_to_spirv(data.scope) as u32),
- )?;
- let semantics_const = map.get_or_add_constant(
- builder,
- &ast::Type::Scalar(ast::ScalarType::U32),
- &vec_repr(semantics_to_spirv(data.semantics).bits()),
- )?;
- builder.atomic_compare_exchange(
- result_type.0,
- Some(arguments.dst.0),
- arguments.src1.0,
- memory_const.0,
- semantics_const.0,
- semantics_const.0,
- arguments.src3.0,
- arguments.src2.0,
- )?;
- }
- ast::Instruction::Div { data, arguments } => match data {
- ast::DivDetails::Unsigned(t) => {
- let result_type = map.get_or_add_scalar(builder, (*t).into());
- builder.u_div(
- result_type.0,
- Some(arguments.dst.0),
- arguments.src1.0,
- arguments.src2.0,
- )?;
- }
- ast::DivDetails::Signed(t) => {
- let result_type = map.get_or_add_scalar(builder, (*t).into());
- builder.s_div(
- result_type.0,
- Some(arguments.dst.0),
- arguments.src1.0,
- arguments.src2.0,
- )?;
- }
- ast::DivDetails::Float(t) => {
- let result_type = map.get_or_add_scalar(builder, t.type_.into());
- builder.f_div(
- result_type.0,
- Some(arguments.dst.0),
- arguments.src1.0,
- arguments.src2.0,
- )?;
- emit_float_div_decoration(builder, arguments.dst, t.kind);
- }
- },
- ast::Instruction::Sqrt { data, arguments } => {
- emit_sqrt(builder, map, opencl, data, arguments)?;
- }
- ast::Instruction::Rsqrt { data, arguments } => {
- let result_type = map.get_or_add_scalar(builder, data.type_.into());
- builder.ext_inst(
- result_type.0,
- Some(arguments.dst.0),
- opencl,
- spirv::CLOp::rsqrt as spirv::Word,
- [dr::Operand::IdRef(arguments.src.0)].iter().cloned(),
- )?;
- }
- ast::Instruction::Neg { data, arguments } => {
- let result_type = map.get_or_add_scalar(builder, data.type_);
- let negate_func = if data.type_.kind() == ast::ScalarKind::Float {
- dr::Builder::f_negate
- } else {
- dr::Builder::s_negate
- };
- negate_func(
- builder,
- result_type.0,
- Some(arguments.dst.0),
- arguments.src.0,
- )?;
- }
- ast::Instruction::Sin { arguments, .. } => {
- let result_type = map.get_or_add_scalar(builder, ast::ScalarType::F32);
- builder.ext_inst(
- result_type.0,
- Some(arguments.dst.0),
- opencl,
- spirv::CLOp::sin as u32,
- [dr::Operand::IdRef(arguments.src.0)].iter().cloned(),
- )?;
- }
- ast::Instruction::Cos { arguments, .. } => {
- let result_type = map.get_or_add_scalar(builder, ast::ScalarType::F32);
- builder.ext_inst(
- result_type.0,
- Some(arguments.dst.0),
- opencl,
- spirv::CLOp::cos as u32,
- [dr::Operand::IdRef(arguments.src.0)].iter().cloned(),
- )?;
- }
- ast::Instruction::Lg2 { arguments, .. } => {
- let result_type = map.get_or_add_scalar(builder, ast::ScalarType::F32);
- builder.ext_inst(
- result_type.0,
- Some(arguments.dst.0),
- opencl,
- spirv::CLOp::log2 as u32,
- [dr::Operand::IdRef(arguments.src.0)].iter().cloned(),
- )?;
- }
- ast::Instruction::Ex2 { arguments, .. } => {
- let result_type = map.get_or_add_scalar(builder, ast::ScalarType::F32);
- builder.ext_inst(
- result_type.0,
- Some(arguments.dst.0),
- opencl,
- spirv::CLOp::exp2 as u32,
- [dr::Operand::IdRef(arguments.src.0)].iter().cloned(),
- )?;
- }
- ast::Instruction::Clz { data, arguments } => {
- let result_type = map.get_or_add_scalar(builder, (*data).into());
- builder.ext_inst(
- result_type.0,
- Some(arguments.dst.0),
- opencl,
- spirv::CLOp::clz as u32,
- [dr::Operand::IdRef(arguments.src.0)].iter().cloned(),
- )?;
- }
- ast::Instruction::Brev { data, arguments } => {
- let result_type = map.get_or_add_scalar(builder, (*data).into());
- builder.bit_reverse(result_type.0, Some(arguments.dst.0), arguments.src.0)?;
- }
- ast::Instruction::Popc { data, arguments } => {
- let result_type = map.get_or_add_scalar(builder, (*data).into());
- builder.bit_count(result_type.0, Some(arguments.dst.0), arguments.src.0)?;
- }
- ast::Instruction::Xor { data, arguments } => {
- let builder_fn: fn(
- &mut dr::Builder,
- u32,
- Option<u32>,
- u32,
- u32,
- ) -> Result<u32, dr::Error> = match data {
- ast::ScalarType::Pred => emit_logical_xor_spirv,
- _ => dr::Builder::bitwise_xor,
- };
- let result_type = map.get_or_add_scalar(builder, (*data).into());
- builder_fn(
- builder,
- result_type.0,
- Some(arguments.dst.0),
- arguments.src1.0,
- arguments.src2.0,
- )?;
- }
- ast::Instruction::Bfe { .. }
- | ast::Instruction::Bfi { .. }
- | ast::Instruction::Activemask { .. } => {
- // Should have beeen replaced with a funciton call earlier
- return Err(error_unreachable());
- }
-
- ast::Instruction::Rem { data, arguments } => {
- let builder_fn = if data.kind() == ast::ScalarKind::Signed {
- dr::Builder::s_mod
- } else {
- dr::Builder::u_mod
- };
- let result_type = map.get_or_add_scalar(builder, (*data).into());
- builder_fn(
- builder,
- result_type.0,
- Some(arguments.dst.0),
- arguments.src1.0,
- arguments.src2.0,
- )?;
- }
- ast::Instruction::Prmt { data, arguments } => {
- let control = *data as u32;
- let components = [
- (control >> 0) & 0b1111,
- (control >> 4) & 0b1111,
- (control >> 8) & 0b1111,
- (control >> 12) & 0b1111,
- ];
- if components.iter().any(|&c| c > 7) {
- return Err(TranslateError::Todo);
- }
- let vec4_b8_type =
- map.get_or_add(builder, SpirvType::Vector(SpirvScalarKey::B8, 4));
- let b32_type = map.get_or_add_scalar(builder, ast::ScalarType::B32);
- let src1_vector = builder.bitcast(vec4_b8_type.0, None, arguments.src1.0)?;
- let src2_vector = builder.bitcast(vec4_b8_type.0, None, arguments.src2.0)?;
- let dst_vector = builder.vector_shuffle(
- vec4_b8_type.0,
- None,
- src1_vector,
- src2_vector,
- components,
- )?;
- builder.bitcast(b32_type.0, Some(arguments.dst.0), dst_vector)?;
- }
- ast::Instruction::Membar { data } => {
- let (scope, semantics) = match data {
- ast::MemScope::Cta => (
- spirv::Scope::Workgroup,
- spirv::MemorySemantics::CROSS_WORKGROUP_MEMORY
- | spirv::MemorySemantics::WORKGROUP_MEMORY
- | spirv::MemorySemantics::SEQUENTIALLY_CONSISTENT,
- ),
- ast::MemScope::Gpu => (
- spirv::Scope::Device,
- spirv::MemorySemantics::CROSS_WORKGROUP_MEMORY
- | spirv::MemorySemantics::WORKGROUP_MEMORY
- | spirv::MemorySemantics::SEQUENTIALLY_CONSISTENT,
- ),
- ast::MemScope::Sys => (
- spirv::Scope::CrossDevice,
- spirv::MemorySemantics::CROSS_WORKGROUP_MEMORY
- | spirv::MemorySemantics::WORKGROUP_MEMORY
- | spirv::MemorySemantics::SEQUENTIALLY_CONSISTENT,
- ),
-
- ast::MemScope::Cluster => todo!(),
- };
- let spirv_scope = map.get_or_add_constant(
- builder,
- &ast::Type::Scalar(ast::ScalarType::U32),
- &vec_repr(scope as u32),
- )?;
- let spirv_semantics = map.get_or_add_constant(
- builder,
- &ast::Type::Scalar(ast::ScalarType::U32),
- &vec_repr(semantics),
- )?;
- builder.memory_barrier(spirv_scope.0, spirv_semantics.0)?;
- }
- },
- Statement::LoadVar(details) => {
- emit_load_var(builder, map, details)?;
- }
- Statement::StoreVar(details) => {
- let dst_ptr = match details.member_index {
- Some(index) => {
- let result_ptr_type = map.get_or_add(
- builder,
- SpirvType::pointer_to(
- details.typ.clone(),
- spirv::StorageClass::Function,
- ),
- );
- let index_spirv = map.get_or_add_constant(
- builder,
- &ast::Type::Scalar(ast::ScalarType::U32),
- &vec_repr(index as u32),
- )?;
- builder.in_bounds_access_chain(
- result_ptr_type.0,
- None,
- details.arg.src1.0,
- [index_spirv.0].iter().copied(),
- )?
- }
- None => details.arg.src1.0,
- };
- builder.store(dst_ptr, details.arg.src2.0, None, iter::empty())?;
- }
- Statement::RetValue(_, id) => {
- todo!()
- //builder.ret_value(id.0)?;
- }
- Statement::PtrAccess(PtrAccess {
- underlying_type,
- state_space,
- dst,
- ptr_src,
- offset_src,
- }) => {
- let u8_pointer = map.get_or_add(
- builder,
- SpirvType::new(ast::Type::Pointer(ast::ScalarType::U8, *state_space)),
- );
- let result_type = map.get_or_add(
- builder,
- SpirvType::pointer_to(underlying_type.clone(), space_to_spirv(*state_space)),
- );
- let ptr_src_u8 = builder.bitcast(u8_pointer.0, None, ptr_src.0)?;
- let temp = builder.in_bounds_ptr_access_chain(
- u8_pointer.0,
- None,
- ptr_src_u8,
- offset_src.0,
- iter::empty(),
- )?;
- builder.bitcast(result_type.0, Some(dst.0), temp)?;
- }
- Statement::RepackVector(repack) => {
- if repack.is_extract {
- let scalar_type = map.get_or_add_scalar(builder, repack.typ);
- for (index, dst_id) in repack.unpacked.iter().enumerate() {
- builder.composite_extract(
- scalar_type.0,
- Some(dst_id.0),
- repack.packed.0,
- [index as u32].iter().copied(),
- )?;
- }
- } else {
- let vector_type = map.get_or_add(
- builder,
- SpirvType::Vector(
- SpirvScalarKey::from(repack.typ),
- repack.unpacked.len() as u8,
- ),
- );
- let mut temp_vec = builder.undef(vector_type.0, None);
- for (index, src_id) in repack.unpacked.iter().enumerate() {
- temp_vec = builder.composite_insert(
- vector_type.0,
- None,
- src_id.0,
- temp_vec,
- [index as u32].iter().copied(),
- )?;
- }
- builder.copy_object(vector_type.0, Some(repack.packed.0), temp_vec)?;
- }
- }
- Statement::VectorRead(vector_access) => todo!(),
- Statement::VectorWrite(vector_write) => todo!(),
- }
- }
- Ok(())
-}
-
-fn emit_function_linkage<'input>(
- builder: &mut dr::Builder,
- id_defs: &GlobalStringIdResolver<'input>,
- f: &Function,
- fn_name: SpirvWord,
-) -> Result<(), TranslateError> {
- if f.linkage == ast::LinkingDirective::NONE {
- return Ok(());
- };
- let linking_name = match f.func_decl.borrow().name {
- // According to SPIR-V rules linkage attributes are invalid on kernels
- ast::MethodName::Kernel(..) => return Ok(()),
- ast::MethodName::Func(fn_id) => f.import_as.as_deref().map_or_else(
- || match id_defs.reverse_variables.get(&fn_id) {
- Some(fn_name) => Ok(fn_name),
- None => Err(error_unknown_symbol()),
- },
- Result::Ok,
- )?,
- };
- emit_linking_decoration(builder, id_defs, Some(linking_name), fn_name, f.linkage);
- Ok(())
-}
-
-fn get_function_type(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- spirv_input: impl Iterator<Item = SpirvType>,
- spirv_output: &[ast::Variable<SpirvWord>],
-) -> (SpirvWord, SpirvWord) {
- map.get_or_add_fn(
- builder,
- spirv_input,
- spirv_output
- .iter()
- .map(|var| SpirvType::new(var.v_type.clone())),
- )
-}
-
-fn emit_linking_decoration<'input>(
- builder: &mut dr::Builder,
- id_defs: &GlobalStringIdResolver<'input>,
- name_override: Option<&str>,
- name: SpirvWord,
- linking: ast::LinkingDirective,
-) {
- if linking == ast::LinkingDirective::NONE {
- return;
- }
- if linking.contains(ast::LinkingDirective::VISIBLE) {
- let string_name =
- name_override.unwrap_or_else(|| id_defs.reverse_variables.get(&name).unwrap());
- builder.decorate(
- name.0,
- spirv::Decoration::LinkageAttributes,
- [
- dr::Operand::LiteralString(string_name.to_string()),
- dr::Operand::LinkageType(spirv::LinkageType::Export),
- ]
- .iter()
- .cloned(),
- );
- } else if linking.contains(ast::LinkingDirective::EXTERN) {
- let string_name =
- name_override.unwrap_or_else(|| id_defs.reverse_variables.get(&name).unwrap());
- builder.decorate(
- name.0,
- spirv::Decoration::LinkageAttributes,
- [
- dr::Operand::LiteralString(string_name.to_string()),
- dr::Operand::LinkageType(spirv::LinkageType::Import),
- ]
- .iter()
- .cloned(),
- );
- }
- // TODO: handle LinkingDirective::WEAK
-}
-
-fn effective_input_arguments<'a>(
- this: &'a ast::MethodDeclaration<'a, SpirvWord>,
-) -> impl Iterator<Item = (SpirvWord, SpirvType)> + 'a {
- let is_kernel = matches!(this.name, ast::MethodName::Kernel(_));
- this.input_arguments.iter().map(move |arg| {
- if !is_kernel && arg.state_space != ast::StateSpace::Reg {
- let spirv_type =
- SpirvType::pointer_to(arg.v_type.clone(), space_to_spirv(arg.state_space));
- (arg.name, spirv_type)
- } else {
- (arg.name, SpirvType::new(arg.v_type.clone()))
- }
- })
-}
-
-fn emit_implicit_conversion(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- cv: &ImplicitConversion,
-) -> Result<(), TranslateError> {
- let from_parts = to_parts(&cv.from_type);
- let to_parts = to_parts(&cv.to_type);
- match (from_parts.kind, to_parts.kind, &cv.kind) {
- (_, _, &ConversionKind::BitToPtr) => {
- let dst_type = map.get_or_add(
- builder,
- SpirvType::pointer_to(cv.to_type.clone(), space_to_spirv(cv.to_space)),
- );
- builder.convert_u_to_ptr(dst_type.0, Some(cv.dst.0), cv.src.0)?;
- }
- (TypeKind::Scalar, TypeKind::Scalar, &ConversionKind::Default) => {
- if from_parts.width == to_parts.width {
- let dst_type = map.get_or_add(builder, SpirvType::new(cv.to_type.clone()));
- if from_parts.scalar_kind != ast::ScalarKind::Float
- && to_parts.scalar_kind != ast::ScalarKind::Float
- {
- // It is noop, but another instruction expects result of this conversion
- builder.copy_object(dst_type.0, Some(cv.dst.0), cv.src.0)?;
- } else {
- builder.bitcast(dst_type.0, Some(cv.dst.0), cv.src.0)?;
- }
- } else {
- // This block is safe because it's illegal to implictly convert between floating point values
- let same_width_bit_type = map.get_or_add(
- builder,
- SpirvType::new(type_from_parts(TypeParts {
- scalar_kind: ast::ScalarKind::Bit,
- ..from_parts
- })),
- );
- let same_width_bit_value =
- builder.bitcast(same_width_bit_type.0, None, cv.src.0)?;
- let wide_bit_type = type_from_parts(TypeParts {
- scalar_kind: ast::ScalarKind::Bit,
- ..to_parts
- });
- let wide_bit_type_spirv =
- map.get_or_add(builder, SpirvType::new(wide_bit_type.clone()));
- if to_parts.scalar_kind == ast::ScalarKind::Unsigned
- || to_parts.scalar_kind == ast::ScalarKind::Bit
- {
- builder.u_convert(
- wide_bit_type_spirv.0,
- Some(cv.dst.0),
- same_width_bit_value,
- )?;
- } else {
- let conversion_fn = if from_parts.scalar_kind == ast::ScalarKind::Signed
- && to_parts.scalar_kind == ast::ScalarKind::Signed
- {
- dr::Builder::s_convert
- } else {
- dr::Builder::u_convert
- };
- let wide_bit_value =
- conversion_fn(builder, wide_bit_type_spirv.0, None, same_width_bit_value)?;
- emit_implicit_conversion(
- builder,
- map,
- &ImplicitConversion {
- src: SpirvWord(wide_bit_value),
- dst: cv.dst,
- from_type: wide_bit_type,
- from_space: cv.from_space,
- to_type: cv.to_type.clone(),
- to_space: cv.to_space,
- kind: ConversionKind::Default,
- },
- )?;
- }
- }
- }
- (TypeKind::Scalar, TypeKind::Scalar, &ConversionKind::SignExtend) => {
- let result_type = map.get_or_add(builder, SpirvType::new(cv.to_type.clone()));
- builder.s_convert(result_type.0, Some(cv.dst.0), cv.src.0)?;
- }
- (TypeKind::Vector, TypeKind::Scalar, &ConversionKind::Default)
- | (TypeKind::Scalar, TypeKind::Array, &ConversionKind::Default)
- | (TypeKind::Array, TypeKind::Scalar, &ConversionKind::Default) => {
- let into_type = map.get_or_add(builder, SpirvType::new(cv.to_type.clone()));
- builder.bitcast(into_type.0, Some(cv.dst.0), cv.src.0)?;
- }
- (_, _, &ConversionKind::PtrToPtr) => {
- let result_type = map.get_or_add(
- builder,
- SpirvType::Pointer(
- Box::new(SpirvType::new(cv.to_type.clone())),
- space_to_spirv(cv.to_space),
- ),
- );
- if cv.to_space == ast::StateSpace::Generic && cv.from_space != ast::StateSpace::Generic
- {
- let src = if cv.from_type != cv.to_type {
- let temp_type = map.get_or_add(
- builder,
- SpirvType::Pointer(
- Box::new(SpirvType::new(cv.to_type.clone())),
- space_to_spirv(cv.from_space),
- ),
- );
- builder.bitcast(temp_type.0, None, cv.src.0)?
- } else {
- cv.src.0
- };
- builder.ptr_cast_to_generic(result_type.0, Some(cv.dst.0), src)?;
- } else if cv.from_space == ast::StateSpace::Generic
- && cv.to_space != ast::StateSpace::Generic
- {
- let src = if cv.from_type != cv.to_type {
- let temp_type = map.get_or_add(
- builder,
- SpirvType::Pointer(
- Box::new(SpirvType::new(cv.to_type.clone())),
- space_to_spirv(cv.from_space),
- ),
- );
- builder.bitcast(temp_type.0, None, cv.src.0)?
- } else {
- cv.src.0
- };
- builder.generic_cast_to_ptr(result_type.0, Some(cv.dst.0), src)?;
- } else {
- builder.bitcast(result_type.0, Some(cv.dst.0), cv.src.0)?;
- }
- }
- (_, _, &ConversionKind::AddressOf) => {
- let dst_type = map.get_or_add(builder, SpirvType::new(cv.to_type.clone()));
- builder.convert_ptr_to_u(dst_type.0, Some(cv.dst.0), cv.src.0)?;
- }
- (TypeKind::Pointer, TypeKind::Scalar, &ConversionKind::Default) => {
- let result_type = map.get_or_add(builder, SpirvType::new(cv.to_type.clone()));
- builder.convert_ptr_to_u(result_type.0, Some(cv.dst.0), cv.src.0)?;
- }
- (TypeKind::Scalar, TypeKind::Pointer, &ConversionKind::Default) => {
- let result_type = map.get_or_add(builder, SpirvType::new(cv.to_type.clone()));
- builder.convert_u_to_ptr(result_type.0, Some(cv.dst.0), cv.src.0)?;
- }
- _ => unreachable!(),
- }
- Ok(())
-}
-
-fn vec_repr<T: Copy>(t: T) -> Vec<u8> {
- let mut result = vec![0; mem::size_of::<T>()];
- unsafe { std::ptr::copy_nonoverlapping(&t, result.as_mut_ptr() as *mut _, 1) };
- result
-}
-
-fn emit_abs(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- opencl: spirv::Word,
- d: &ast::TypeFtz,
- arg: &ast::AbsArgs<SpirvWord>,
-) -> Result<(), dr::Error> {
- let scalar_t = ast::ScalarType::from(d.type_);
- let result_type = map.get_or_add(builder, SpirvType::from(scalar_t));
- let cl_abs = if scalar_t.kind() == ast::ScalarKind::Signed {
- spirv::CLOp::s_abs
- } else {
- spirv::CLOp::fabs
- };
- builder.ext_inst(
- result_type.0,
- Some(arg.dst.0),
- opencl,
- cl_abs as spirv::Word,
- [dr::Operand::IdRef(arg.src.0)].iter().cloned(),
- )?;
- Ok(())
-}
-
-fn emit_mul_int(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- opencl: spirv::Word,
- type_: ast::ScalarType,
- control: ast::MulIntControl,
- arg: &ast::MulArgs<SpirvWord>,
-) -> Result<(), dr::Error> {
- let inst_type = map.get_or_add(builder, SpirvType::from(type_));
- match control {
- ast::MulIntControl::Low => {
- builder.i_mul(inst_type.0, Some(arg.dst.0), arg.src1.0, arg.src2.0)?;
- }
- ast::MulIntControl::High => {
- let opencl_inst = if type_.kind() == ast::ScalarKind::Signed {
- spirv::CLOp::s_mul_hi
- } else {
- spirv::CLOp::u_mul_hi
- };
- builder.ext_inst(
- inst_type.0,
- Some(arg.dst.0),
- opencl,
- opencl_inst as spirv::Word,
- [
- dr::Operand::IdRef(arg.src1.0),
- dr::Operand::IdRef(arg.src2.0),
- ]
- .iter()
- .cloned(),
- )?;
- }
- ast::MulIntControl::Wide => {
- let instr_width = type_.size_of();
- let instr_kind = type_.kind();
- let dst_type = scalar_from_parts(instr_width * 2, instr_kind);
- let dst_type_id = map.get_or_add_scalar(builder, dst_type);
- let (src1, src2) = if type_.kind() == ast::ScalarKind::Signed {
- let src1 = builder.s_convert(dst_type_id.0, None, arg.src1.0)?;
- let src2 = builder.s_convert(dst_type_id.0, None, arg.src2.0)?;
- (src1, src2)
- } else {
- let src1 = builder.u_convert(dst_type_id.0, None, arg.src1.0)?;
- let src2 = builder.u_convert(dst_type_id.0, None, arg.src2.0)?;
- (src1, src2)
- };
- builder.i_mul(dst_type_id.0, Some(arg.dst.0), src1, src2)?;
- builder.decorate(arg.dst.0, spirv::Decoration::NoSignedWrap, iter::empty());
- }
- }
- Ok(())
-}
-
-fn emit_mul_float(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- ctr: &ast::ArithFloat,
- arg: &ast::MulArgs<SpirvWord>,
-) -> Result<(), dr::Error> {
- if ctr.saturate {
- todo!()
- }
- let result_type = map.get_or_add_scalar(builder, ctr.type_.into());
- builder.f_mul(result_type.0, Some(arg.dst.0), arg.src1.0, arg.src2.0)?;
- emit_rounding_decoration(builder, arg.dst, ctr.rounding);
- Ok(())
-}
-
-fn scalar_from_parts(width: u8, kind: ast::ScalarKind) -> ast::ScalarType {
- match kind {
- ast::ScalarKind::Float => match width {
- 2 => ast::ScalarType::F16,
- 4 => ast::ScalarType::F32,
- 8 => ast::ScalarType::F64,
- _ => unreachable!(),
- },
- ast::ScalarKind::Bit => match width {
- 1 => ast::ScalarType::B8,
- 2 => ast::ScalarType::B16,
- 4 => ast::ScalarType::B32,
- 8 => ast::ScalarType::B64,
- _ => unreachable!(),
- },
- ast::ScalarKind::Signed => match width {
- 1 => ast::ScalarType::S8,
- 2 => ast::ScalarType::S16,
- 4 => ast::ScalarType::S32,
- 8 => ast::ScalarType::S64,
- _ => unreachable!(),
- },
- ast::ScalarKind::Unsigned => match width {
- 1 => ast::ScalarType::U8,
- 2 => ast::ScalarType::U16,
- 4 => ast::ScalarType::U32,
- 8 => ast::ScalarType::U64,
- _ => unreachable!(),
- },
- ast::ScalarKind::Pred => ast::ScalarType::Pred,
- }
-}
-
-fn emit_rounding_decoration(
- builder: &mut dr::Builder,
- dst: SpirvWord,
- rounding: Option<ast::RoundingMode>,
-) {
- if let Some(rounding) = rounding {
- builder.decorate(
- dst.0,
- spirv::Decoration::FPRoundingMode,
- [rounding_to_spirv(rounding)].iter().cloned(),
- );
- }
-}
-
-fn rounding_to_spirv(this: ast::RoundingMode) -> rspirv::dr::Operand {
- let mode = match this {
- ast::RoundingMode::NearestEven => spirv::FPRoundingMode::RTE,
- ast::RoundingMode::Zero => spirv::FPRoundingMode::RTZ,
- ast::RoundingMode::PositiveInf => spirv::FPRoundingMode::RTP,
- ast::RoundingMode::NegativeInf => spirv::FPRoundingMode::RTN,
- };
- rspirv::dr::Operand::FPRoundingMode(mode)
-}
-
-fn emit_add_int(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- typ: ast::ScalarType,
- saturate: bool,
- arg: &ast::AddArgs<SpirvWord>,
-) -> Result<(), dr::Error> {
- if saturate {
- todo!()
- }
- let inst_type = map.get_or_add(builder, SpirvType::from(ast::ScalarType::from(typ)));
- builder.i_add(inst_type.0, Some(arg.dst.0), arg.src1.0, arg.src2.0)?;
- Ok(())
-}
-
-fn emit_add_float(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- desc: &ast::ArithFloat,
- arg: &ast::AddArgs<SpirvWord>,
-) -> Result<(), dr::Error> {
- let inst_type = map.get_or_add(builder, SpirvType::from(ast::ScalarType::from(desc.type_)));
- builder.f_add(inst_type.0, Some(arg.dst.0), arg.src1.0, arg.src2.0)?;
- emit_rounding_decoration(builder, arg.dst, desc.rounding);
- Ok(())
-}
-
-fn emit_setp(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- setp: &ast::SetpData,
- arg: &ast::SetpArgs<SpirvWord>,
-) -> Result<(), dr::Error> {
- let result_type = map
- .get_or_add(builder, SpirvType::Base(SpirvScalarKey::Pred))
- .0;
- let result_id = Some(arg.dst1.0);
- let operand_1 = arg.src1.0;
- let operand_2 = arg.src2.0;
- match setp.cmp_op {
- ast::SetpCompareOp::Integer(ast::SetpCompareInt::Eq) => {
- builder.i_equal(result_type, result_id, operand_1, operand_2)
- }
- ast::SetpCompareOp::Float(ast::SetpCompareFloat::Eq) => {
- builder.f_ord_equal(result_type, result_id, operand_1, operand_2)
- }
- ast::SetpCompareOp::Integer(ast::SetpCompareInt::NotEq) => {
- builder.i_not_equal(result_type, result_id, operand_1, operand_2)
- }
- ast::SetpCompareOp::Float(ast::SetpCompareFloat::NotEq) => {
- builder.f_ord_not_equal(result_type, result_id, operand_1, operand_2)
- }
- ast::SetpCompareOp::Integer(ast::SetpCompareInt::UnsignedLess) => {
- builder.u_less_than(result_type, result_id, operand_1, operand_2)
- }
- ast::SetpCompareOp::Integer(ast::SetpCompareInt::SignedLess) => {
- builder.s_less_than(result_type, result_id, operand_1, operand_2)
- }
- ast::SetpCompareOp::Float(ast::SetpCompareFloat::Less) => {
- builder.f_ord_less_than(result_type, result_id, operand_1, operand_2)
- }
- ast::SetpCompareOp::Integer(ast::SetpCompareInt::UnsignedLessOrEq) => {
- builder.u_less_than_equal(result_type, result_id, operand_1, operand_2)
- }
- ast::SetpCompareOp::Integer(ast::SetpCompareInt::SignedLessOrEq) => {
- builder.s_less_than_equal(result_type, result_id, operand_1, operand_2)
- }
- ast::SetpCompareOp::Float(ast::SetpCompareFloat::LessOrEq) => {
- builder.f_ord_less_than_equal(result_type, result_id, operand_1, operand_2)
- }
- ast::SetpCompareOp::Integer(ast::SetpCompareInt::UnsignedGreater) => {
- builder.u_greater_than(result_type, result_id, operand_1, operand_2)
- }
- ast::SetpCompareOp::Integer(ast::SetpCompareInt::SignedGreater) => {
- builder.s_greater_than(result_type, result_id, operand_1, operand_2)
- }
- ast::SetpCompareOp::Float(ast::SetpCompareFloat::Greater) => {
- builder.f_ord_greater_than(result_type, result_id, operand_1, operand_2)
- }
- ast::SetpCompareOp::Integer(ast::SetpCompareInt::UnsignedGreaterOrEq) => {
- builder.u_greater_than_equal(result_type, result_id, operand_1, operand_2)
- }
- ast::SetpCompareOp::Integer(ast::SetpCompareInt::SignedGreaterOrEq) => {
- builder.s_greater_than_equal(result_type, result_id, operand_1, operand_2)
- }
- ast::SetpCompareOp::Float(ast::SetpCompareFloat::GreaterOrEq) => {
- builder.f_ord_greater_than_equal(result_type, result_id, operand_1, operand_2)
- }
- ast::SetpCompareOp::Float(ast::SetpCompareFloat::NanEq) => {
- builder.f_unord_equal(result_type, result_id, operand_1, operand_2)
- }
- ast::SetpCompareOp::Float(ast::SetpCompareFloat::NanNotEq) => {
- builder.f_unord_not_equal(result_type, result_id, operand_1, operand_2)
- }
- ast::SetpCompareOp::Float(ast::SetpCompareFloat::NanLess) => {
- builder.f_unord_less_than(result_type, result_id, operand_1, operand_2)
- }
- ast::SetpCompareOp::Float(ast::SetpCompareFloat::NanLessOrEq) => {
- builder.f_unord_less_than_equal(result_type, result_id, operand_1, operand_2)
- }
- ast::SetpCompareOp::Float(ast::SetpCompareFloat::NanGreater) => {
- builder.f_unord_greater_than(result_type, result_id, operand_1, operand_2)
- }
- ast::SetpCompareOp::Float(ast::SetpCompareFloat::NanGreaterOrEq) => {
- builder.f_unord_greater_than_equal(result_type, result_id, operand_1, operand_2)
- }
- ast::SetpCompareOp::Float(ast::SetpCompareFloat::IsAnyNan) => {
- let temp1 = builder.is_nan(result_type, None, operand_1)?;
- let temp2 = builder.is_nan(result_type, None, operand_2)?;
- builder.logical_or(result_type, result_id, temp1, temp2)
- }
- ast::SetpCompareOp::Float(ast::SetpCompareFloat::IsNotNan) => {
- let temp1 = builder.is_nan(result_type, None, operand_1)?;
- let temp2 = builder.is_nan(result_type, None, operand_2)?;
- let any_nan = builder.logical_or(result_type, None, temp1, temp2)?;
- logical_not(builder, result_type, result_id, any_nan)
- }
- _ => todo!(),
- }?;
- Ok(())
-}
-
-// HACK ALERT
-// Temporary workaround until IGC gets its shit together
-// Currently IGC carries two copies of SPIRV-LLVM translator
-// a new one in /llvm-spirv/ and old one in /IGC/AdaptorOCL/SPIRV/.
-// Obviously, old and buggy one is used for compiling L0 SPIRV
-// https://github.com/intel/intel-graphics-compiler/issues/148
-fn logical_not(
- builder: &mut dr::Builder,
- result_type: spirv::Word,
- result_id: Option<spirv::Word>,
- operand: spirv::Word,
-) -> Result<spirv::Word, dr::Error> {
- let const_true = builder.constant_true(result_type, None);
- let const_false = builder.constant_false(result_type, None);
- builder.select(result_type, result_id, operand, const_false, const_true)
-}
-
-// HACK ALERT
-// For some reason IGC fails linking if the value and shift size are of different type
-fn insert_shift_hack(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- offset_var: spirv::Word,
- size_of: usize,
-) -> Result<spirv::Word, TranslateError> {
- let result_type = match size_of {
- 2 => map.get_or_add_scalar(builder, ast::ScalarType::B16),
- 8 => map.get_or_add_scalar(builder, ast::ScalarType::B64),
- 4 => return Ok(offset_var),
- _ => return Err(error_unreachable()),
- };
- Ok(builder.u_convert(result_type.0, None, offset_var)?)
-}
-
-fn emit_cvt(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- opencl: spirv::Word,
- dets: &ast::CvtDetails,
- arg: &ast::CvtArgs<SpirvWord>,
-) -> Result<(), TranslateError> {
- match dets.mode {
- ptx_parser::CvtMode::SignExtend => {
- let cv = ImplicitConversion {
- src: arg.src,
- dst: arg.dst,
- from_type: dets.from.into(),
- from_space: ast::StateSpace::Reg,
- to_type: dets.to.into(),
- to_space: ast::StateSpace::Reg,
- kind: ConversionKind::SignExtend,
- };
- emit_implicit_conversion(builder, map, &cv)?;
- }
- ptx_parser::CvtMode::ZeroExtend
- | ptx_parser::CvtMode::Truncate
- | ptx_parser::CvtMode::Bitcast => {
- let cv = ImplicitConversion {
- src: arg.src,
- dst: arg.dst,
- from_type: dets.from.into(),
- from_space: ast::StateSpace::Reg,
- to_type: dets.to.into(),
- to_space: ast::StateSpace::Reg,
- kind: ConversionKind::Default,
- };
- emit_implicit_conversion(builder, map, &cv)?;
- }
- ptx_parser::CvtMode::SaturateUnsignedToSigned => {
- let result_type = map.get_or_add(builder, SpirvType::from(dets.to));
- builder.sat_convert_u_to_s(result_type.0, Some(arg.dst.0), arg.src.0)?;
- }
- ptx_parser::CvtMode::SaturateSignedToUnsigned => {
- let result_type = map.get_or_add(builder, SpirvType::from(dets.to));
- builder.sat_convert_s_to_u(result_type.0, Some(arg.dst.0), arg.src.0)?;
- }
- ptx_parser::CvtMode::FPExtend { flush_to_zero } => {
- let result_type = map.get_or_add(builder, SpirvType::from(dets.to));
- builder.f_convert(result_type.0, Some(arg.dst.0), arg.src.0)?;
- }
- ptx_parser::CvtMode::FPTruncate {
- rounding,
- flush_to_zero,
- } => {
- let result_type = map.get_or_add(builder, SpirvType::from(dets.to));
- builder.f_convert(result_type.0, Some(arg.dst.0), arg.src.0)?;
- emit_rounding_decoration(builder, arg.dst, Some(rounding));
- }
- ptx_parser::CvtMode::FPRound {
- integer_rounding,
- flush_to_zero,
- } => {
- if flush_to_zero == Some(true) {
- todo!()
- }
- let result_type = map.get_or_add(builder, SpirvType::from(dets.to));
- match integer_rounding {
- Some(ast::RoundingMode::NearestEven) => {
- builder.ext_inst(
- result_type.0,
- Some(arg.dst.0),
- opencl,
- spirv::CLOp::rint as u32,
- [dr::Operand::IdRef(arg.src.0)].iter().cloned(),
- )?;
- }
- Some(ast::RoundingMode::Zero) => {
- builder.ext_inst(
- result_type.0,
- Some(arg.dst.0),
- opencl,
- spirv::CLOp::trunc as u32,
- [dr::Operand::IdRef(arg.src.0)].iter().cloned(),
- )?;
- }
- Some(ast::RoundingMode::NegativeInf) => {
- builder.ext_inst(
- result_type.0,
- Some(arg.dst.0),
- opencl,
- spirv::CLOp::floor as u32,
- [dr::Operand::IdRef(arg.src.0)].iter().cloned(),
- )?;
- }
- Some(ast::RoundingMode::PositiveInf) => {
- builder.ext_inst(
- result_type.0,
- Some(arg.dst.0),
- opencl,
- spirv::CLOp::ceil as u32,
- [dr::Operand::IdRef(arg.src.0)].iter().cloned(),
- )?;
- }
- None => {
- builder.copy_object(result_type.0, Some(arg.dst.0), arg.src.0)?;
- }
- }
- }
- ptx_parser::CvtMode::SignedFromFP {
- rounding,
- flush_to_zero,
- } => {
- let dest_t: ast::ScalarType = dets.to.into();
- let result_type = map.get_or_add(builder, SpirvType::from(dest_t));
- builder.convert_f_to_s(result_type.0, Some(arg.dst.0), arg.src.0)?;
- emit_rounding_decoration(builder, arg.dst, Some(rounding));
- }
- ptx_parser::CvtMode::UnsignedFromFP {
- rounding,
- flush_to_zero,
- } => {
- let dest_t: ast::ScalarType = dets.to.into();
- let result_type = map.get_or_add(builder, SpirvType::from(dest_t));
- builder.convert_f_to_u(result_type.0, Some(arg.dst.0), arg.src.0)?;
- emit_rounding_decoration(builder, arg.dst, Some(rounding));
- }
- ptx_parser::CvtMode::FPFromSigned(rounding) => {
- let dest_t: ast::ScalarType = dets.to.into();
- let result_type = map.get_or_add(builder, SpirvType::from(dest_t));
- builder.convert_s_to_f(result_type.0, Some(arg.dst.0), arg.src.0)?;
- emit_rounding_decoration(builder, arg.dst, Some(rounding));
- }
- ptx_parser::CvtMode::FPFromUnsigned(rounding) => {
- let dest_t: ast::ScalarType = dets.to.into();
- let result_type = map.get_or_add(builder, SpirvType::from(dest_t));
- builder.convert_u_to_f(result_type.0, Some(arg.dst.0), arg.src.0)?;
- emit_rounding_decoration(builder, arg.dst, Some(rounding));
- }
- }
- Ok(())
-}
-
-fn emit_mad_uint(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- opencl: spirv::Word,
- type_: ast::ScalarType,
- control: ast::MulIntControl,
- arg: &ast::MadArgs<SpirvWord>,
-) -> Result<(), dr::Error> {
- let inst_type = map
- .get_or_add(builder, SpirvType::from(ast::ScalarType::from(type_)))
- .0;
- match control {
- ast::MulIntControl::Low => {
- let mul_result = builder.i_mul(inst_type, None, arg.src1.0, arg.src2.0)?;
- builder.i_add(inst_type, Some(arg.dst.0), arg.src3.0, mul_result)?;
- }
- ast::MulIntControl::High => {
- builder.ext_inst(
- inst_type,
- Some(arg.dst.0),
- opencl,
- spirv::CLOp::u_mad_hi as spirv::Word,
- [
- dr::Operand::IdRef(arg.src1.0),
- dr::Operand::IdRef(arg.src2.0),
- dr::Operand::IdRef(arg.src3.0),
- ]
- .iter()
- .cloned(),
- )?;
- }
- ast::MulIntControl::Wide => todo!(),
- };
- Ok(())
-}
-
-fn emit_mad_sint(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- opencl: spirv::Word,
- type_: ast::ScalarType,
- control: ast::MulIntControl,
- arg: &ast::MadArgs<SpirvWord>,
-) -> Result<(), dr::Error> {
- let inst_type = map.get_or_add(builder, SpirvType::from(type_)).0;
- match control {
- ast::MulIntControl::Low => {
- let mul_result = builder.i_mul(inst_type, None, arg.src1.0, arg.src2.0)?;
- builder.i_add(inst_type, Some(arg.dst.0), arg.src3.0, mul_result)?;
- }
- ast::MulIntControl::High => {
- builder.ext_inst(
- inst_type,
- Some(arg.dst.0),
- opencl,
- spirv::CLOp::s_mad_hi as spirv::Word,
- [
- dr::Operand::IdRef(arg.src1.0),
- dr::Operand::IdRef(arg.src2.0),
- dr::Operand::IdRef(arg.src3.0),
- ]
- .iter()
- .cloned(),
- )?;
- }
- ast::MulIntControl::Wide => todo!(),
- };
- Ok(())
-}
-
-fn emit_mad_float(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- opencl: spirv::Word,
- desc: &ast::ArithFloat,
- arg: &ast::MadArgs<SpirvWord>,
-) -> Result<(), dr::Error> {
- let inst_type = map
- .get_or_add(builder, SpirvType::from(ast::ScalarType::from(desc.type_)))
- .0;
- builder.ext_inst(
- inst_type,
- Some(arg.dst.0),
- opencl,
- spirv::CLOp::mad as spirv::Word,
- [
- dr::Operand::IdRef(arg.src1.0),
- dr::Operand::IdRef(arg.src2.0),
- dr::Operand::IdRef(arg.src3.0),
- ]
- .iter()
- .cloned(),
- )?;
- Ok(())
-}
-
-fn emit_fma_float(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- opencl: spirv::Word,
- desc: &ast::ArithFloat,
- arg: &ast::FmaArgs<SpirvWord>,
-) -> Result<(), dr::Error> {
- let inst_type = map
- .get_or_add(builder, SpirvType::from(ast::ScalarType::from(desc.type_)))
- .0;
- builder.ext_inst(
- inst_type,
- Some(arg.dst.0),
- opencl,
- spirv::CLOp::fma as spirv::Word,
- [
- dr::Operand::IdRef(arg.src1.0),
- dr::Operand::IdRef(arg.src2.0),
- dr::Operand::IdRef(arg.src3.0),
- ]
- .iter()
- .cloned(),
- )?;
- Ok(())
-}
-
-fn emit_sub_int(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- typ: ast::ScalarType,
- saturate: bool,
- arg: &ast::SubArgs<SpirvWord>,
-) -> Result<(), dr::Error> {
- if saturate {
- todo!()
- }
- let inst_type = map
- .get_or_add(builder, SpirvType::from(ast::ScalarType::from(typ)))
- .0;
- builder.i_sub(inst_type, Some(arg.dst.0), arg.src1.0, arg.src2.0)?;
- Ok(())
-}
-
-fn emit_sub_float(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- desc: &ast::ArithFloat,
- arg: &ast::SubArgs<SpirvWord>,
-) -> Result<(), dr::Error> {
- let inst_type = map
- .get_or_add(builder, SpirvType::from(ast::ScalarType::from(desc.type_)))
- .0;
- builder.f_sub(inst_type, Some(arg.dst.0), arg.src1.0, arg.src2.0)?;
- emit_rounding_decoration(builder, arg.dst, desc.rounding);
- Ok(())
-}
-
-fn emit_min(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- opencl: spirv::Word,
- desc: &ast::MinMaxDetails,
- arg: &ast::MinArgs<SpirvWord>,
-) -> Result<(), dr::Error> {
- let cl_op = match desc {
- ast::MinMaxDetails::Signed(_) => spirv::CLOp::s_min,
- ast::MinMaxDetails::Unsigned(_) => spirv::CLOp::u_min,
- ast::MinMaxDetails::Float(_) => spirv::CLOp::fmin,
- };
- let inst_type = map.get_or_add(builder, SpirvType::from(desc.type_()));
- builder.ext_inst(
- inst_type.0,
- Some(arg.dst.0),
- opencl,
- cl_op as spirv::Word,
- [
- dr::Operand::IdRef(arg.src1.0),
- dr::Operand::IdRef(arg.src2.0),
- ]
- .iter()
- .cloned(),
- )?;
- Ok(())
-}
-
-fn emit_max(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- opencl: spirv::Word,
- desc: &ast::MinMaxDetails,
- arg: &ast::MaxArgs<SpirvWord>,
-) -> Result<(), dr::Error> {
- let cl_op = match desc {
- ast::MinMaxDetails::Signed(_) => spirv::CLOp::s_max,
- ast::MinMaxDetails::Unsigned(_) => spirv::CLOp::u_max,
- ast::MinMaxDetails::Float(_) => spirv::CLOp::fmax,
- };
- let inst_type = map.get_or_add(builder, SpirvType::from(desc.type_()));
- builder.ext_inst(
- inst_type.0,
- Some(arg.dst.0),
- opencl,
- cl_op as spirv::Word,
- [
- dr::Operand::IdRef(arg.src1.0),
- dr::Operand::IdRef(arg.src2.0),
- ]
- .iter()
- .cloned(),
- )?;
- Ok(())
-}
-
-fn emit_rcp(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- opencl: spirv::Word,
- desc: &ast::RcpData,
- arg: &ast::RcpArgs<SpirvWord>,
-) -> Result<(), TranslateError> {
- let is_f64 = desc.type_ == ast::ScalarType::F64;
- let (instr_type, constant) = if is_f64 {
- (ast::ScalarType::F64, vec_repr(1.0f64))
- } else {
- (ast::ScalarType::F32, vec_repr(1.0f32))
- };
- let result_type = map.get_or_add_scalar(builder, instr_type);
- let rounding = match desc.kind {
- ptx_parser::RcpKind::Approx => {
- builder.ext_inst(
- result_type.0,
- Some(arg.dst.0),
- opencl,
- spirv::CLOp::native_recip as u32,
- [dr::Operand::IdRef(arg.src.0)].iter().cloned(),
- )?;
- return Ok(());
- }
- ptx_parser::RcpKind::Compliant(rounding) => rounding,
- };
- let one = map.get_or_add_constant(builder, &ast::Type::Scalar(instr_type), &constant)?;
- builder.f_div(result_type.0, Some(arg.dst.0), one.0, arg.src.0)?;
- emit_rounding_decoration(builder, arg.dst, Some(rounding));
- builder.decorate(
- arg.dst.0,
- spirv::Decoration::FPFastMathMode,
- [dr::Operand::FPFastMathMode(
- spirv::FPFastMathMode::ALLOW_RECIP,
- )]
- .iter()
- .cloned(),
- );
- Ok(())
-}
-
-fn emit_atom(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- details: &ast::AtomDetails,
- arg: &ast::AtomArgs<SpirvWord>,
-) -> Result<(), TranslateError> {
- let spirv_op = match details.op {
- ptx_parser::AtomicOp::And => dr::Builder::atomic_and,
- ptx_parser::AtomicOp::Or => dr::Builder::atomic_or,
- ptx_parser::AtomicOp::Xor => dr::Builder::atomic_xor,
- ptx_parser::AtomicOp::Exchange => dr::Builder::atomic_exchange,
- ptx_parser::AtomicOp::Add => dr::Builder::atomic_i_add,
- ptx_parser::AtomicOp::IncrementWrap | ptx_parser::AtomicOp::DecrementWrap => {
- return Err(error_unreachable())
- }
- ptx_parser::AtomicOp::SignedMin => dr::Builder::atomic_s_min,
- ptx_parser::AtomicOp::UnsignedMin => dr::Builder::atomic_u_min,
- ptx_parser::AtomicOp::SignedMax => dr::Builder::atomic_s_max,
- ptx_parser::AtomicOp::UnsignedMax => dr::Builder::atomic_u_max,
- ptx_parser::AtomicOp::FloatAdd => dr::Builder::atomic_f_add_ext,
- ptx_parser::AtomicOp::FloatMin => todo!(),
- ptx_parser::AtomicOp::FloatMax => todo!(),
- };
- let result_type = map.get_or_add(builder, SpirvType::new(details.type_.clone()));
- let memory_const = map.get_or_add_constant(
- builder,
- &ast::Type::Scalar(ast::ScalarType::U32),
- &vec_repr(scope_to_spirv(details.scope) as u32),
- )?;
- let semantics_const = map.get_or_add_constant(
- builder,
- &ast::Type::Scalar(ast::ScalarType::U32),
- &vec_repr(semantics_to_spirv(details.semantics).bits()),
- )?;
- spirv_op(
- builder,
- result_type.0,
- Some(arg.dst.0),
- arg.src1.0,
- memory_const.0,
- semantics_const.0,
- arg.src2.0,
- )?;
- Ok(())
-}
-
-fn scope_to_spirv(this: ast::MemScope) -> spirv::Scope {
- match this {
- ast::MemScope::Cta => spirv::Scope::Workgroup,
- ast::MemScope::Gpu => spirv::Scope::Device,
- ast::MemScope::Sys => spirv::Scope::CrossDevice,
- ptx_parser::MemScope::Cluster => todo!(),
- }
-}
-
-fn semantics_to_spirv(this: ast::AtomSemantics) -> spirv::MemorySemantics {
- match this {
- ast::AtomSemantics::Relaxed => spirv::MemorySemantics::RELAXED,
- ast::AtomSemantics::Acquire => spirv::MemorySemantics::ACQUIRE,
- ast::AtomSemantics::Release => spirv::MemorySemantics::RELEASE,
- ast::AtomSemantics::AcqRel => spirv::MemorySemantics::ACQUIRE_RELEASE,
- }
-}
-
-fn emit_float_div_decoration(builder: &mut dr::Builder, dst: SpirvWord, kind: ast::DivFloatKind) {
- match kind {
- ast::DivFloatKind::Approx => {
- builder.decorate(
- dst.0,
- spirv::Decoration::FPFastMathMode,
- [dr::Operand::FPFastMathMode(
- spirv::FPFastMathMode::ALLOW_RECIP,
- )]
- .iter()
- .cloned(),
- );
- }
- ast::DivFloatKind::Rounding(rnd) => {
- emit_rounding_decoration(builder, dst, Some(rnd));
- }
- ast::DivFloatKind::ApproxFull => {}
- }
-}
-
-fn emit_sqrt(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- opencl: spirv::Word,
- details: &ast::RcpData,
- a: &ast::SqrtArgs<SpirvWord>,
-) -> Result<(), TranslateError> {
- let result_type = map.get_or_add_scalar(builder, details.type_.into());
- let (ocl_op, rounding) = match details.kind {
- ast::RcpKind::Approx => (spirv::CLOp::sqrt, None),
- ast::RcpKind::Compliant(rnd) => (spirv::CLOp::sqrt, Some(rnd)),
- };
- builder.ext_inst(
- result_type.0,
- Some(a.dst.0),
- opencl,
- ocl_op as spirv::Word,
- [dr::Operand::IdRef(a.src.0)].iter().cloned(),
- )?;
- emit_rounding_decoration(builder, a.dst, rounding);
- Ok(())
-}
-
-// TODO: check what kind of assembly do we emit
-fn emit_logical_xor_spirv(
- builder: &mut dr::Builder,
- result_type: spirv::Word,
- result_id: Option<spirv::Word>,
- op1: spirv::Word,
- op2: spirv::Word,
-) -> Result<spirv::Word, dr::Error> {
- let temp_or = builder.logical_or(result_type, None, op1, op2)?;
- let temp_and = builder.logical_and(result_type, None, op1, op2)?;
- let temp_neg = logical_not(builder, result_type, None, temp_and)?;
- builder.logical_and(result_type, result_id, temp_or, temp_neg)
-}
-
-fn emit_load_var(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- details: &LoadVarDetails,
-) -> Result<(), TranslateError> {
- let result_type = map.get_or_add(builder, SpirvType::new(details.typ.clone()));
- match details.member_index {
- Some((index, Some(width))) => {
- let vector_type = match details.typ {
- ast::Type::Scalar(scalar_t) => ast::Type::Vector(width, scalar_t),
- _ => return Err(error_mismatched_type()),
- };
- let vector_type_spirv = map.get_or_add(builder, SpirvType::new(vector_type));
- let vector_temp = builder.load(
- vector_type_spirv.0,
- None,
- details.arg.src.0,
- None,
- iter::empty(),
- )?;
- builder.composite_extract(
- result_type.0,
- Some(details.arg.dst.0),
- vector_temp,
- [index as u32].iter().copied(),
- )?;
- }
- Some((index, None)) => {
- let result_ptr_type = map.get_or_add(
- builder,
- SpirvType::pointer_to(details.typ.clone(), spirv::StorageClass::Function),
- );
- let index_spirv = map.get_or_add_constant(
- builder,
- &ast::Type::Scalar(ast::ScalarType::U32),
- &vec_repr(index as u32),
- )?;
- let src = builder.in_bounds_access_chain(
- result_ptr_type.0,
- None,
- details.arg.src.0,
- [index_spirv.0].iter().copied(),
- )?;
- builder.load(
- result_type.0,
- Some(details.arg.dst.0),
- src,
- None,
- iter::empty(),
- )?;
- }
- None => {
- builder.load(
- result_type.0,
- Some(details.arg.dst.0),
- details.arg.src.0,
- None,
- iter::empty(),
- )?;
- }
- };
- Ok(())
-}
-
-fn to_parts(this: &ast::Type) -> TypeParts {
- match this {
- ast::Type::Scalar(scalar) => TypeParts {
- kind: TypeKind::Scalar,
- state_space: ast::StateSpace::Reg,
- scalar_kind: scalar.kind(),
- width: scalar.size_of(),
- components: Vec::new(),
- },
- ast::Type::Vector(components, scalar) => TypeParts {
- kind: TypeKind::Vector,
- state_space: ast::StateSpace::Reg,
- scalar_kind: scalar.kind(),
- width: scalar.size_of(),
- components: vec![*components as u32],
- },
- ast::Type::Array(_, scalar, components) => TypeParts {
- kind: TypeKind::Array,
- state_space: ast::StateSpace::Reg,
- scalar_kind: scalar.kind(),
- width: scalar.size_of(),
- components: components.clone(),
- },
- ast::Type::Pointer(scalar, space) => TypeParts {
- kind: TypeKind::Pointer,
- state_space: *space,
- scalar_kind: scalar.kind(),
- width: scalar.size_of(),
- components: Vec::new(),
- },
- }
-}
-
-fn type_from_parts(t: TypeParts) -> ast::Type {
- match t.kind {
- TypeKind::Scalar => ast::Type::Scalar(scalar_from_parts(t.width, t.scalar_kind)),
- TypeKind::Vector => ast::Type::Vector(
- t.components[0] as u8,
- scalar_from_parts(t.width, t.scalar_kind),
- ),
- TypeKind::Array => ast::Type::Array(
- None,
- scalar_from_parts(t.width, t.scalar_kind),
- t.components,
- ),
- TypeKind::Pointer => {
- ast::Type::Pointer(scalar_from_parts(t.width, t.scalar_kind), t.state_space)
- }
- }
-}
-
-#[derive(Eq, PartialEq, Clone)]
-struct TypeParts {
- kind: TypeKind,
- scalar_kind: ast::ScalarKind,
- width: u8,
- state_space: ast::StateSpace,
- components: Vec<u32>,
-}
-
-#[derive(Eq, PartialEq, Copy, Clone)]
-enum TypeKind {
- Scalar,
- Vector,
- Array,
- Pointer,
-}
diff --git a/ptx/src/pass/expand_arguments.rs b/ptx/src/pass/expand_arguments.rs deleted file mode 100644 index e496c75..0000000 --- a/ptx/src/pass/expand_arguments.rs +++ /dev/null @@ -1,181 +0,0 @@ -use super::*;
-use ptx_parser as ast;
-
-pub(super) fn run<'a, 'b>(
- func: Vec<TypedStatement>,
- id_def: &'b mut MutableNumericIdResolver<'a>,
-) -> Result<Vec<ExpandedStatement>, TranslateError> {
- let mut result = Vec::with_capacity(func.len());
- for s in func {
- match s {
- Statement::Label(id) => result.push(Statement::Label(id)),
- Statement::Conditional(bra) => result.push(Statement::Conditional(bra)),
- Statement::LoadVar(details) => result.push(Statement::LoadVar(details)),
- Statement::StoreVar(details) => result.push(Statement::StoreVar(details)),
- Statement::RetValue(d, id) => result.push(Statement::RetValue(d, id)),
- Statement::Conversion(conv) => result.push(Statement::Conversion(conv)),
- Statement::Constant(c) => result.push(Statement::Constant(c)),
- Statement::FunctionPointer(d) => result.push(Statement::FunctionPointer(d)),
- s => {
- let (new_statement, post_stmts) = {
- let mut visitor = FlattenArguments::new(&mut result, id_def);
- (s.visit_map(&mut visitor)?, visitor.post_stmts)
- };
- result.push(new_statement);
- result.extend(post_stmts);
- }
- }
- }
- Ok(result)
-}
-
-struct FlattenArguments<'a, 'b> {
- func: &'b mut Vec<ExpandedStatement>,
- id_def: &'b mut MutableNumericIdResolver<'a>,
- post_stmts: Vec<ExpandedStatement>,
-}
-
-impl<'a, 'b> FlattenArguments<'a, 'b> {
- fn new(
- func: &'b mut Vec<ExpandedStatement>,
- id_def: &'b mut MutableNumericIdResolver<'a>,
- ) -> Self {
- FlattenArguments {
- func,
- id_def,
- post_stmts: Vec::new(),
- }
- }
-
- fn reg(&mut self, name: SpirvWord) -> Result<SpirvWord, TranslateError> {
- Ok(name)
- }
-
- fn reg_offset(
- &mut self,
- reg: SpirvWord,
- offset: i32,
- type_space: Option<(&ptx_parser::Type, ptx_parser::StateSpace)>,
- _is_dst: bool,
- ) -> Result<SpirvWord, TranslateError> {
- let (type_, state_space) = if let Some((type_, state_space)) = type_space {
- (type_, state_space)
- } else {
- return Err(TranslateError::UntypedSymbol);
- };
- if state_space == ast::StateSpace::Reg {
- let (reg_type, reg_space) = self.id_def.get_typed(reg)?;
- if reg_space != ast::StateSpace::Reg {
- return Err(error_mismatched_type());
- }
- let reg_scalar_type = match reg_type {
- ast::Type::Scalar(underlying_type) => underlying_type,
- _ => return Err(error_mismatched_type()),
- };
- let id_constant_stmt = self
- .id_def
- .register_intermediate(reg_type.clone(), ast::StateSpace::Reg);
- self.func.push(Statement::Constant(ConstantDefinition {
- dst: id_constant_stmt,
- typ: reg_scalar_type,
- value: ast::ImmediateValue::S64(offset as i64),
- }));
- let arith_details = match reg_scalar_type.kind() {
- ast::ScalarKind::Signed => ast::ArithDetails::Integer(ast::ArithInteger {
- type_: reg_scalar_type,
- saturate: false,
- }),
- ast::ScalarKind::Unsigned | ast::ScalarKind::Bit => {
- ast::ArithDetails::Integer(ast::ArithInteger {
- type_: reg_scalar_type,
- saturate: false,
- })
- }
- _ => return Err(error_unreachable()),
- };
- let id_add_result = self.id_def.register_intermediate(reg_type, state_space);
- self.func
- .push(Statement::Instruction(ast::Instruction::Add {
- data: arith_details,
- arguments: ast::AddArgs {
- dst: id_add_result,
- src1: reg,
- src2: id_constant_stmt,
- },
- }));
- Ok(id_add_result)
- } else {
- let id_constant_stmt = self.id_def.register_intermediate(
- ast::Type::Scalar(ast::ScalarType::S64),
- ast::StateSpace::Reg,
- );
- self.func.push(Statement::Constant(ConstantDefinition {
- dst: id_constant_stmt,
- typ: ast::ScalarType::S64,
- value: ast::ImmediateValue::S64(offset as i64),
- }));
- let dst = self
- .id_def
- .register_intermediate(type_.clone(), state_space);
- self.func.push(Statement::PtrAccess(PtrAccess {
- underlying_type: type_.clone(),
- state_space: state_space,
- dst,
- ptr_src: reg,
- offset_src: id_constant_stmt,
- }));
- Ok(dst)
- }
- }
-
- fn immediate(
- &mut self,
- value: ast::ImmediateValue,
- type_space: Option<(&ptx_parser::Type, ptx_parser::StateSpace)>,
- ) -> Result<SpirvWord, TranslateError> {
- let (scalar_t, state_space) =
- if let Some((ast::Type::Scalar(scalar), state_space)) = type_space {
- (*scalar, state_space)
- } else {
- return Err(TranslateError::UntypedSymbol);
- };
- let id = self
- .id_def
- .register_intermediate(ast::Type::Scalar(scalar_t), state_space);
- self.func.push(Statement::Constant(ConstantDefinition {
- dst: id,
- typ: scalar_t,
- value,
- }));
- Ok(id)
- }
-}
-
-impl<'a, 'b> ast::VisitorMap<TypedOperand, SpirvWord, TranslateError> for FlattenArguments<'a, 'b> {
- fn visit(
- &mut self,
- args: TypedOperand,
- type_space: Option<(&ptx_parser::Type, ptx_parser::StateSpace)>,
- is_dst: bool,
- _relaxed_type_check: bool,
- ) -> Result<SpirvWord, TranslateError> {
- match args {
- TypedOperand::Reg(r) => self.reg(r),
- TypedOperand::Imm(x) => self.immediate(x, type_space),
- TypedOperand::RegOffset(reg, offset) => {
- self.reg_offset(reg, offset, type_space, is_dst)
- }
- TypedOperand::VecMember(..) => Err(error_unreachable()),
- }
- }
-
- fn visit_ident(
- &mut self,
- name: <TypedOperand as ptx_parser::Operand>::Ident,
- _type_space: Option<(&ptx_parser::Type, ptx_parser::StateSpace)>,
- _is_dst: bool,
- _relaxed_type_check: bool,
- ) -> Result<<SpirvWord as ptx_parser::Operand>::Ident, TranslateError> {
- self.reg(name)
- }
-}
diff --git a/ptx/src/pass/expand_operands.rs b/ptx/src/pass/expand_operands.rs index 1125d39..f2de786 100644 --- a/ptx/src/pass/expand_operands.rs +++ b/ptx/src/pass/expand_operands.rs @@ -281,7 +281,7 @@ impl<'a, 'b> ast::VisitorMap<ast::ParsedOperand<SpirvWord>, SpirvWord, Translate fn visit_ident(
&mut self,
- name: <TypedOperand as ast::Operand>::Ident,
+ name: SpirvWord,
_type_space: Option<(&ast::Type, ast::StateSpace)>,
_is_dst: bool,
_relaxed_type_check: bool,
diff --git a/ptx/src/pass/extract_globals.rs b/ptx/src/pass/extract_globals.rs deleted file mode 100644 index 37e477f..0000000 --- a/ptx/src/pass/extract_globals.rs +++ /dev/null @@ -1,254 +0,0 @@ -use super::*;
-
-pub(super) fn run<'input, 'b>(
- sorted_statements: Vec<ExpandedStatement>,
- ptx_impl_imports: &mut HashMap<String, Directive>,
- id_def: &mut NumericIdResolver,
-) -> Result<(Vec<ExpandedStatement>, Vec<ast::Variable<SpirvWord>>), TranslateError> {
- let mut local = Vec::with_capacity(sorted_statements.len());
- let mut global = Vec::new();
- for statement in sorted_statements {
- match statement {
- Statement::Variable(
- var @ ast::Variable {
- state_space: ast::StateSpace::Shared,
- ..
- },
- )
- | Statement::Variable(
- var @ ast::Variable {
- state_space: ast::StateSpace::Global,
- ..
- },
- ) => global.push(var),
- Statement::Instruction(ast::Instruction::Bfe { data, arguments }) => {
- let fn_name = [ZLUDA_PTX_PREFIX, "bfe_", scalar_to_ptx_name(data)].concat();
- local.push(instruction_to_fn_call(
- id_def,
- ptx_impl_imports,
- ast::Instruction::Bfe { data, arguments },
- fn_name,
- )?);
- }
- Statement::Instruction(ast::Instruction::Bfi { data, arguments }) => {
- let fn_name = [ZLUDA_PTX_PREFIX, "bfi_", scalar_to_ptx_name(data)].concat();
- local.push(instruction_to_fn_call(
- id_def,
- ptx_impl_imports,
- ast::Instruction::Bfi { data, arguments },
- fn_name,
- )?);
- }
- Statement::Instruction(ast::Instruction::Brev { data, arguments }) => {
- let fn_name: String =
- [ZLUDA_PTX_PREFIX, "brev_", scalar_to_ptx_name(data)].concat();
- local.push(instruction_to_fn_call(
- id_def,
- ptx_impl_imports,
- ast::Instruction::Brev { data, arguments },
- fn_name,
- )?);
- }
- Statement::Instruction(ast::Instruction::Activemask { arguments }) => {
- let fn_name = [ZLUDA_PTX_PREFIX, "activemask"].concat();
- local.push(instruction_to_fn_call(
- id_def,
- ptx_impl_imports,
- ast::Instruction::Activemask { arguments },
- fn_name,
- )?);
- }
- Statement::Instruction(ast::Instruction::Atom {
- data:
- data @ ast::AtomDetails {
- op: ast::AtomicOp::IncrementWrap,
- semantics,
- scope,
- space,
- ..
- },
- arguments,
- }) => {
- let fn_name = [
- ZLUDA_PTX_PREFIX,
- "atom_",
- semantics_to_ptx_name(semantics),
- "_",
- scope_to_ptx_name(scope),
- "_",
- space_to_ptx_name(space),
- "_inc",
- ]
- .concat();
- local.push(instruction_to_fn_call(
- id_def,
- ptx_impl_imports,
- ast::Instruction::Atom { data, arguments },
- fn_name,
- )?);
- }
- Statement::Instruction(ast::Instruction::Atom {
- data:
- data @ ast::AtomDetails {
- op: ast::AtomicOp::DecrementWrap,
- semantics,
- scope,
- space,
- ..
- },
- arguments,
- }) => {
- let fn_name = [
- ZLUDA_PTX_PREFIX,
- "atom_",
- semantics_to_ptx_name(semantics),
- "_",
- scope_to_ptx_name(scope),
- "_",
- space_to_ptx_name(space),
- "_dec",
- ]
- .concat();
- local.push(instruction_to_fn_call(
- id_def,
- ptx_impl_imports,
- ast::Instruction::Atom { data, arguments },
- fn_name,
- )?);
- }
- Statement::Instruction(ast::Instruction::Atom {
- data:
- data @ ast::AtomDetails {
- op: ast::AtomicOp::FloatAdd,
- semantics,
- scope,
- space,
- ..
- },
- arguments,
- }) => {
- let scalar_type = match data.type_ {
- ptx_parser::Type::Scalar(scalar) => scalar,
- _ => return Err(error_unreachable()),
- };
- let fn_name = [
- ZLUDA_PTX_PREFIX,
- "atom_",
- semantics_to_ptx_name(semantics),
- "_",
- scope_to_ptx_name(scope),
- "_",
- space_to_ptx_name(space),
- "_add_",
- scalar_to_ptx_name(scalar_type),
- ]
- .concat();
- local.push(instruction_to_fn_call(
- id_def,
- ptx_impl_imports,
- ast::Instruction::Atom { data, arguments },
- fn_name,
- )?);
- }
- s => local.push(s),
- }
- }
- Ok((local, global))
-}
-
-fn instruction_to_fn_call(
- id_defs: &mut NumericIdResolver,
- ptx_impl_imports: &mut HashMap<String, Directive>,
- inst: ast::Instruction<SpirvWord>,
- fn_name: String,
-) -> Result<ExpandedStatement, TranslateError> {
- let mut arguments = Vec::new();
- ast::visit_map(inst, &mut |operand,
- type_space: Option<(
- &ast::Type,
- ast::StateSpace,
- )>,
- is_dst,
- _| {
- let (typ, space) = match type_space {
- Some((typ, space)) => (typ.clone(), space),
- None => return Err(error_unreachable()),
- };
- arguments.push((operand, is_dst, typ, space));
- Ok(SpirvWord(0))
- })?;
- let return_arguments_count = arguments
- .iter()
- .position(|(desc, is_dst, _, _)| !is_dst)
- .unwrap_or(arguments.len());
- let (return_arguments, input_arguments) = arguments.split_at(return_arguments_count);
- let fn_id = register_external_fn_call(
- id_defs,
- ptx_impl_imports,
- fn_name,
- return_arguments
- .iter()
- .map(|(_, _, typ, state)| (typ, *state)),
- input_arguments
- .iter()
- .map(|(_, _, typ, state)| (typ, *state)),
- )?;
- Ok(Statement::Instruction(ast::Instruction::Call {
- data: ast::CallDetails {
- uniform: false,
- return_arguments: return_arguments
- .iter()
- .map(|(_, _, typ, state)| (typ.clone(), *state))
- .collect::<Vec<_>>(),
- input_arguments: input_arguments
- .iter()
- .map(|(_, _, typ, state)| (typ.clone(), *state))
- .collect::<Vec<_>>(),
- },
- arguments: ast::CallArgs {
- return_arguments: return_arguments
- .iter()
- .map(|(name, _, _, _)| *name)
- .collect::<Vec<_>>(),
- func: fn_id,
- input_arguments: input_arguments
- .iter()
- .map(|(name, _, _, _)| *name)
- .collect::<Vec<_>>(),
- },
- }))
-}
-
-fn semantics_to_ptx_name(this: ast::AtomSemantics) -> &'static str {
- match this {
- ast::AtomSemantics::Relaxed => "relaxed",
- ast::AtomSemantics::Acquire => "acquire",
- ast::AtomSemantics::Release => "release",
- ast::AtomSemantics::AcqRel => "acq_rel",
- }
-}
-
-fn scope_to_ptx_name(this: ast::MemScope) -> &'static str {
- match this {
- ast::MemScope::Cta => "cta",
- ast::MemScope::Gpu => "gpu",
- ast::MemScope::Sys => "sys",
- ast::MemScope::Cluster => "cluster",
- }
-}
-
-fn space_to_ptx_name(this: ast::StateSpace) -> &'static str {
- match this {
- ast::StateSpace::Generic => "generic",
- ast::StateSpace::Global => "global",
- ast::StateSpace::Shared => "shared",
- ast::StateSpace::Reg => "reg",
- ast::StateSpace::Const => "const",
- ast::StateSpace::Local => "local",
- ast::StateSpace::Param => "param",
- ast::StateSpace::SharedCluster => "shared_cluster",
- ast::StateSpace::ParamEntry => "param_entry",
- ast::StateSpace::SharedCta => "shared_cta",
- ast::StateSpace::ParamFunc => "param_func",
- }
-}
diff --git a/ptx/src/pass/fix_special_registers.rs b/ptx/src/pass/fix_special_registers.rs deleted file mode 100644 index c029016..0000000 --- a/ptx/src/pass/fix_special_registers.rs +++ /dev/null @@ -1,130 +0,0 @@ -use super::*;
-use std::collections::HashMap;
-
-pub(super) fn run<'a, 'b, 'input>(
- ptx_impl_imports: &'a mut HashMap<String, Directive<'input>>,
- typed_statements: Vec<TypedStatement>,
- numeric_id_defs: &'a mut NumericIdResolver<'b>,
-) -> Result<Vec<TypedStatement>, TranslateError> {
- let result = Vec::with_capacity(typed_statements.len());
- let mut sreg_sresolver = SpecialRegisterResolver {
- ptx_impl_imports,
- numeric_id_defs,
- result,
- };
- for statement in typed_statements {
- let statement = statement.visit_map(&mut sreg_sresolver)?;
- sreg_sresolver.result.push(statement);
- }
- Ok(sreg_sresolver.result)
-}
-
-struct SpecialRegisterResolver<'a, 'b, 'input> {
- ptx_impl_imports: &'a mut HashMap<String, Directive<'input>>,
- numeric_id_defs: &'a mut NumericIdResolver<'b>,
- result: Vec<TypedStatement>,
-}
-
-impl<'a, 'b, 'input> ast::VisitorMap<TypedOperand, TypedOperand, TranslateError>
- for SpecialRegisterResolver<'a, 'b, 'input>
-{
- fn visit(
- &mut self,
- operand: TypedOperand,
- _type_space: Option<(&ptx_parser::Type, ptx_parser::StateSpace)>,
- is_dst: bool,
- _relaxed_type_check: bool,
- ) -> Result<TypedOperand, TranslateError> {
- operand.map(|name, vector_index| self.replace_sreg(name, is_dst, vector_index))
- }
-
- fn visit_ident(
- &mut self,
- args: SpirvWord,
- _type_space: Option<(&ptx_parser::Type, ptx_parser::StateSpace)>,
- is_dst: bool,
- _relaxed_type_check: bool,
- ) -> Result<SpirvWord, TranslateError> {
- self.replace_sreg(args, is_dst, None)
- }
-}
-
-impl<'a, 'b, 'input> SpecialRegisterResolver<'a, 'b, 'input> {
- fn replace_sreg(
- &mut self,
- name: SpirvWord,
- is_dst: bool,
- vector_index: Option<u8>,
- ) -> Result<SpirvWord, TranslateError> {
- if let Some(sreg) = self.numeric_id_defs.special_registers.get(name) {
- if is_dst {
- return Err(error_mismatched_type());
- }
- let input_arguments = match (vector_index, sreg.get_function_input_type()) {
- (Some(idx), Some(inp_type)) => {
- if inp_type != ast::ScalarType::U8 {
- return Err(TranslateError::Unreachable);
- }
- let constant = self.numeric_id_defs.register_intermediate(Some((
- ast::Type::Scalar(inp_type),
- ast::StateSpace::Reg,
- )));
- self.result.push(Statement::Constant(ConstantDefinition {
- dst: constant,
- typ: inp_type,
- value: ast::ImmediateValue::U64(idx as u64),
- }));
- vec![(
- TypedOperand::Reg(constant),
- ast::Type::Scalar(inp_type),
- ast::StateSpace::Reg,
- )]
- }
- (None, None) => Vec::new(),
- _ => return Err(error_mismatched_type()),
- };
- let ocl_fn_name = [ZLUDA_PTX_PREFIX, sreg.get_unprefixed_function_name()].concat();
- let return_type = sreg.get_function_return_type();
- let fn_result = self.numeric_id_defs.register_intermediate(Some((
- ast::Type::Scalar(return_type),
- ast::StateSpace::Reg,
- )));
- let return_arguments = vec![(
- fn_result,
- ast::Type::Scalar(return_type),
- ast::StateSpace::Reg,
- )];
- let fn_call = register_external_fn_call(
- self.numeric_id_defs,
- self.ptx_impl_imports,
- ocl_fn_name.to_string(),
- return_arguments.iter().map(|(_, typ, space)| (typ, *space)),
- input_arguments.iter().map(|(_, typ, space)| (typ, *space)),
- )?;
- let data = ast::CallDetails {
- uniform: false,
- return_arguments: return_arguments
- .iter()
- .map(|(_, typ, space)| (typ.clone(), *space))
- .collect(),
- input_arguments: input_arguments
- .iter()
- .map(|(_, typ, space)| (typ.clone(), *space))
- .collect(),
- };
- let arguments = ast::CallArgs {
- return_arguments: return_arguments.iter().map(|(name, _, _)| *name).collect(),
- func: fn_call,
- input_arguments: input_arguments.iter().map(|(name, _, _)| *name).collect(),
- };
- self.result
- .push(Statement::Instruction(ast::Instruction::Call {
- data,
- arguments,
- }));
- Ok(fn_result)
- } else {
- Ok(name)
- }
- }
-}
diff --git a/ptx/src/pass/insert_explicit_load_store.rs b/ptx/src/pass/insert_explicit_load_store.rs index b5c63cc..60c4a14 100644 --- a/ptx/src/pass/insert_explicit_load_store.rs +++ b/ptx/src/pass/insert_explicit_load_store.rs @@ -1,7 +1,4 @@ use super::*;
-use ptx_parser::VisitorMap;
-use rustc_hash::FxHashSet;
-
// This pass:
// * Turns all .local, .param and .reg in-body variables into .local variables
// (if _not_ an input method argument)
diff --git a/ptx/src/pass/insert_implicit_conversions.rs b/ptx/src/pass/insert_implicit_conversions.rs deleted file mode 100644 index 2a6ea5a..0000000 --- a/ptx/src/pass/insert_implicit_conversions.rs +++ /dev/null @@ -1,445 +0,0 @@ -use std::mem;
-
-use super::*;
-use ptx_parser as ast;
-
-/*
- There are several kinds of implicit conversions in PTX:
- * auto-bitcast: https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#type-information-for-instructions-and-operands
- * special ld/st/cvt conversion rules: https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#operand-size-exceeding-instruction-type-size
- - ld.param: not documented, but for instruction `ld.param.<type> x, [y]`,
- semantics are to first zext/chop/bitcast `y` as needed and then do
- documented special ld/st/cvt conversion rules for destination operands
- - st.param [x] y (used as function return arguments) same rule as above applies
- - generic/global ld: for instruction `ld x, [y]`, y must be of type
- b64/u64/s64, which is bitcast to a pointer, dereferenced and then
- documented special ld/st/cvt conversion rules are applied to dst
- - generic/global st: for instruction `st [x], y`, x must be of type
- b64/u64/s64, which is bitcast to a pointer
-*/
-pub(super) fn run(
- func: Vec<ExpandedStatement>,
- id_def: &mut MutableNumericIdResolver,
-) -> Result<Vec<ExpandedStatement>, TranslateError> {
- let mut result = Vec::with_capacity(func.len());
- for s in func.into_iter() {
- match s {
- Statement::Instruction(inst) => {
- insert_implicit_conversions_impl(
- &mut result,
- id_def,
- Statement::Instruction(inst),
- )?;
- }
- Statement::PtrAccess(access) => {
- insert_implicit_conversions_impl(
- &mut result,
- id_def,
- Statement::PtrAccess(access),
- )?;
- }
- Statement::RepackVector(repack) => {
- insert_implicit_conversions_impl(
- &mut result,
- id_def,
- Statement::RepackVector(repack),
- )?;
- }
- Statement::VectorRead(vector_read) => {
- insert_implicit_conversions_impl(
- &mut result,
- id_def,
- Statement::VectorRead(vector_read),
- )?;
- }
- Statement::VectorWrite(vector_write) => {
- insert_implicit_conversions_impl(
- &mut result,
- id_def,
- Statement::VectorWrite(vector_write),
- )?;
- }
- s @ Statement::Conditional(_)
- | s @ Statement::Conversion(_)
- | s @ Statement::Label(_)
- | s @ Statement::Constant(_)
- | s @ Statement::Variable(_)
- | s @ Statement::LoadVar(..)
- | s @ Statement::StoreVar(..)
- | s @ Statement::RetValue(..)
- | s @ Statement::FunctionPointer(..) => result.push(s),
- }
- }
- Ok(result)
-}
-
-fn insert_implicit_conversions_impl(
- func: &mut Vec<ExpandedStatement>,
- id_def: &mut MutableNumericIdResolver,
- stmt: ExpandedStatement,
-) -> Result<(), TranslateError> {
- let mut post_conv = Vec::new();
- let statement = stmt.visit_map::<SpirvWord, TranslateError>(
- &mut |operand,
- type_state: Option<(&ast::Type, ast::StateSpace)>,
- is_dst,
- relaxed_type_check| {
- let (instr_type, instruction_space) = match type_state {
- None => return Ok(operand),
- Some(t) => t,
- };
- let (operand_type, operand_space) = id_def.get_typed(operand)?;
- let conversion_fn = if relaxed_type_check {
- if is_dst {
- should_convert_relaxed_dst_wrapper
- } else {
- should_convert_relaxed_src_wrapper
- }
- } else {
- default_implicit_conversion
- };
- match conversion_fn(
- (operand_space, &operand_type),
- (instruction_space, instr_type),
- )? {
- Some(conv_kind) => {
- let conv_output = if is_dst { &mut post_conv } else { &mut *func };
- let mut from_type = instr_type.clone();
- let mut from_space = instruction_space;
- let mut to_type = operand_type;
- let mut to_space = operand_space;
- let mut src =
- id_def.register_intermediate(instr_type.clone(), instruction_space);
- let mut dst = operand;
- let result = Ok::<_, TranslateError>(src);
- if !is_dst {
- mem::swap(&mut src, &mut dst);
- mem::swap(&mut from_type, &mut to_type);
- mem::swap(&mut from_space, &mut to_space);
- }
- conv_output.push(Statement::Conversion(ImplicitConversion {
- src,
- dst,
- from_type,
- from_space,
- to_type,
- to_space,
- kind: conv_kind,
- }));
- result
- }
- None => Ok(operand),
- }
- },
- )?;
- func.push(statement);
- func.append(&mut post_conv);
- Ok(())
-}
-
-pub(crate) fn default_implicit_conversion(
- (operand_space, operand_type): (ast::StateSpace, &ast::Type),
- (instruction_space, instruction_type): (ast::StateSpace, &ast::Type),
-) -> Result<Option<ConversionKind>, TranslateError> {
- if instruction_space == ast::StateSpace::Reg {
- if operand_space == ast::StateSpace::Reg {
- if let (ast::Type::Vector(vec_len, vec_underlying_type), ast::Type::Scalar(scalar)) =
- (operand_type, instruction_type)
- {
- if scalar.kind() == ast::ScalarKind::Bit
- && scalar.size_of() == (vec_underlying_type.size_of() * vec_len)
- {
- return Ok(Some(ConversionKind::Default));
- }
- }
- } else if is_addressable(operand_space) {
- return Ok(Some(ConversionKind::AddressOf));
- }
- }
- if instruction_space != operand_space {
- default_implicit_conversion_space(
- (operand_space, operand_type),
- (instruction_space, instruction_type),
- )
- } else if instruction_type != operand_type {
- default_implicit_conversion_type(instruction_space, operand_type, instruction_type)
- } else {
- Ok(None)
- }
-}
-
-fn is_addressable(this: ast::StateSpace) -> bool {
- match this {
- ast::StateSpace::Const
- | ast::StateSpace::Generic
- | ast::StateSpace::Global
- | ast::StateSpace::Local
- | ast::StateSpace::Shared => true,
- ast::StateSpace::Param | ast::StateSpace::Reg => false,
- ast::StateSpace::SharedCluster
- | ast::StateSpace::SharedCta
- | ast::StateSpace::ParamEntry
- | ast::StateSpace::ParamFunc => todo!(),
- }
-}
-
-// Space is different
-fn default_implicit_conversion_space(
- (operand_space, operand_type): (ast::StateSpace, &ast::Type),
- (instruction_space, instruction_type): (ast::StateSpace, &ast::Type),
-) -> Result<Option<ConversionKind>, TranslateError> {
- if (instruction_space == ast::StateSpace::Generic && coerces_to_generic(operand_space))
- || (operand_space == ast::StateSpace::Generic && coerces_to_generic(instruction_space))
- {
- Ok(Some(ConversionKind::PtrToPtr))
- } else if operand_space == ast::StateSpace::Reg {
- match operand_type {
- ast::Type::Pointer(operand_ptr_type, operand_ptr_space)
- if *operand_ptr_space == instruction_space =>
- {
- if instruction_type != &ast::Type::Scalar(*operand_ptr_type) {
- Ok(Some(ConversionKind::PtrToPtr))
- } else {
- Ok(None)
- }
- }
- // TODO: 32 bit
- ast::Type::Scalar(ast::ScalarType::B64)
- | ast::Type::Scalar(ast::ScalarType::U64)
- | ast::Type::Scalar(ast::ScalarType::S64) => match instruction_space {
- ast::StateSpace::Global
- | ast::StateSpace::Generic
- | ast::StateSpace::Const
- | ast::StateSpace::Local
- | ast::StateSpace::Shared => Ok(Some(ConversionKind::BitToPtr)),
- _ => Err(error_mismatched_type()),
- },
- ast::Type::Scalar(ast::ScalarType::B32)
- | ast::Type::Scalar(ast::ScalarType::U32)
- | ast::Type::Scalar(ast::ScalarType::S32) => match instruction_space {
- ast::StateSpace::Const | ast::StateSpace::Local | ast::StateSpace::Shared => {
- Ok(Some(ConversionKind::BitToPtr))
- }
- _ => Err(error_mismatched_type()),
- },
- _ => Err(error_mismatched_type()),
- }
- } else if instruction_space == ast::StateSpace::Reg {
- match instruction_type {
- ast::Type::Pointer(instruction_ptr_type, instruction_ptr_space)
- if operand_space == *instruction_ptr_space =>
- {
- if operand_type != &ast::Type::Scalar(*instruction_ptr_type) {
- Ok(Some(ConversionKind::PtrToPtr))
- } else {
- Ok(None)
- }
- }
- _ => Err(error_mismatched_type()),
- }
- } else {
- Err(error_mismatched_type())
- }
-}
-
-// Space is same, but type is different
-fn default_implicit_conversion_type(
- space: ast::StateSpace,
- operand_type: &ast::Type,
- instruction_type: &ast::Type,
-) -> Result<Option<ConversionKind>, TranslateError> {
- if space == ast::StateSpace::Reg {
- if should_bitcast(instruction_type, operand_type) {
- Ok(Some(ConversionKind::Default))
- } else {
- Err(TranslateError::MismatchedType)
- }
- } else {
- Ok(Some(ConversionKind::PtrToPtr))
- }
-}
-
-fn coerces_to_generic(this: ast::StateSpace) -> bool {
- match this {
- ast::StateSpace::Global
- | ast::StateSpace::Const
- | ast::StateSpace::Local
- | ptx_parser::StateSpace::SharedCta
- | ast::StateSpace::SharedCluster
- | ast::StateSpace::Shared => true,
- ast::StateSpace::Reg
- | ast::StateSpace::Param
- | ast::StateSpace::ParamEntry
- | ast::StateSpace::ParamFunc
- | ast::StateSpace::Generic => false,
- }
-}
-
-fn should_bitcast(instr: &ast::Type, operand: &ast::Type) -> bool {
- match (instr, operand) {
- (ast::Type::Scalar(inst), ast::Type::Scalar(operand)) => {
- if inst.size_of() != operand.size_of() {
- return false;
- }
- match inst.kind() {
- ast::ScalarKind::Bit => operand.kind() != ast::ScalarKind::Bit,
- ast::ScalarKind::Float => operand.kind() == ast::ScalarKind::Bit,
- ast::ScalarKind::Signed => {
- operand.kind() == ast::ScalarKind::Bit
- || operand.kind() == ast::ScalarKind::Unsigned
- }
- ast::ScalarKind::Unsigned => {
- operand.kind() == ast::ScalarKind::Bit
- || operand.kind() == ast::ScalarKind::Signed
- }
- ast::ScalarKind::Pred => false,
- }
- }
- (ast::Type::Vector(_, inst), ast::Type::Vector(_, operand))
- | (ast::Type::Array(_, inst, _), ast::Type::Array(_, operand, _)) => {
- should_bitcast(&ast::Type::Scalar(*inst), &ast::Type::Scalar(*operand))
- }
- _ => false,
- }
-}
-
-pub(crate) fn should_convert_relaxed_dst_wrapper(
- (operand_space, operand_type): (ast::StateSpace, &ast::Type),
- (instruction_space, instruction_type): (ast::StateSpace, &ast::Type),
-) -> Result<Option<ConversionKind>, TranslateError> {
- if operand_space != instruction_space {
- return Err(TranslateError::MismatchedType);
- }
- if operand_type == instruction_type {
- return Ok(None);
- }
- match should_convert_relaxed_dst(operand_type, instruction_type) {
- conv @ Some(_) => Ok(conv),
- None => Err(TranslateError::MismatchedType),
- }
-}
-
-// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#operand-size-exceeding-instruction-type-size__relaxed-type-checking-rules-destination-operands
-fn should_convert_relaxed_dst(
- dst_type: &ast::Type,
- instr_type: &ast::Type,
-) -> Option<ConversionKind> {
- if dst_type == instr_type {
- return None;
- }
- match (dst_type, instr_type) {
- (ast::Type::Scalar(dst_type), ast::Type::Scalar(instr_type)) => match instr_type.kind() {
- ast::ScalarKind::Bit => {
- if instr_type.size_of() <= dst_type.size_of() {
- Some(ConversionKind::Default)
- } else {
- None
- }
- }
- ast::ScalarKind::Signed => {
- if dst_type.kind() != ast::ScalarKind::Float {
- if instr_type.size_of() == dst_type.size_of() {
- Some(ConversionKind::Default)
- } else if instr_type.size_of() < dst_type.size_of() {
- Some(ConversionKind::SignExtend)
- } else {
- None
- }
- } else {
- None
- }
- }
- ast::ScalarKind::Unsigned => {
- if instr_type.size_of() <= dst_type.size_of()
- && dst_type.kind() != ast::ScalarKind::Float
- {
- Some(ConversionKind::Default)
- } else {
- None
- }
- }
- ast::ScalarKind::Float => {
- if instr_type.size_of() <= dst_type.size_of()
- && dst_type.kind() == ast::ScalarKind::Bit
- {
- Some(ConversionKind::Default)
- } else {
- None
- }
- }
- ast::ScalarKind::Pred => None,
- },
- (ast::Type::Vector(_, dst_type), ast::Type::Vector(_, instr_type))
- | (ast::Type::Array(_, dst_type, _), ast::Type::Array(_, instr_type, _)) => {
- should_convert_relaxed_dst(
- &ast::Type::Scalar(*dst_type),
- &ast::Type::Scalar(*instr_type),
- )
- }
- _ => None,
- }
-}
-
-pub(crate) fn should_convert_relaxed_src_wrapper(
- (operand_space, operand_type): (ast::StateSpace, &ast::Type),
- (instruction_space, instruction_type): (ast::StateSpace, &ast::Type),
-) -> Result<Option<ConversionKind>, TranslateError> {
- if operand_space != instruction_space {
- return Err(error_mismatched_type());
- }
- if operand_type == instruction_type {
- return Ok(None);
- }
- match should_convert_relaxed_src(operand_type, instruction_type) {
- conv @ Some(_) => Ok(conv),
- None => Err(error_mismatched_type()),
- }
-}
-
-// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#operand-size-exceeding-instruction-type-size__relaxed-type-checking-rules-source-operands
-fn should_convert_relaxed_src(
- src_type: &ast::Type,
- instr_type: &ast::Type,
-) -> Option<ConversionKind> {
- if src_type == instr_type {
- return None;
- }
- match (src_type, instr_type) {
- (ast::Type::Scalar(src_type), ast::Type::Scalar(instr_type)) => match instr_type.kind() {
- ast::ScalarKind::Bit => {
- if instr_type.size_of() <= src_type.size_of() {
- Some(ConversionKind::Default)
- } else {
- None
- }
- }
- ast::ScalarKind::Signed | ast::ScalarKind::Unsigned => {
- if instr_type.size_of() <= src_type.size_of()
- && src_type.kind() != ast::ScalarKind::Float
- {
- Some(ConversionKind::Default)
- } else {
- None
- }
- }
- ast::ScalarKind::Float => {
- if instr_type.size_of() <= src_type.size_of()
- && src_type.kind() == ast::ScalarKind::Bit
- {
- Some(ConversionKind::Default)
- } else {
- None
- }
- }
- ast::ScalarKind::Pred => None,
- },
- (ast::Type::Vector(_, dst_type), ast::Type::Vector(_, instr_type))
- | (ast::Type::Array(_, dst_type, _), ast::Type::Array(_, instr_type, _)) => {
- should_convert_relaxed_src(
- &ast::Type::Scalar(*dst_type),
- &ast::Type::Scalar(*instr_type),
- )
- }
- _ => None,
- }
-}
diff --git a/ptx/src/pass/insert_mem_ssa_statements.rs b/ptx/src/pass/insert_mem_ssa_statements.rs deleted file mode 100644 index 8d53d37..0000000 --- a/ptx/src/pass/insert_mem_ssa_statements.rs +++ /dev/null @@ -1,276 +0,0 @@ -use super::*;
-use ptx_parser as ast;
-
-/*
- How do we handle arguments:
- - input .params in kernels
- .param .b64 in_arg
- get turned into this SPIR-V:
- %1 = OpFunctionParameter %ulong
- %2 = OpVariable %_ptr_Function_ulong Function
- OpStore %2 %1
- We do this for two reasons. One, common treatment for argument-declared
- .param variables and .param variables inside function (we assume that
- at SPIR-V level every .param is a pointer in Function storage class)
- - input .params in functions
- .param .b64 in_arg
- get turned into this SPIR-V:
- %1 = OpFunctionParameter %_ptr_Function_ulong
- - input .regs
- .reg .b64 in_arg
- get turned into the same SPIR-V as kernel .params:
- %1 = OpFunctionParameter %ulong
- %2 = OpVariable %_ptr_Function_ulong Function
- OpStore %2 %1
- - output .regs
- .reg .b64 out_arg
- get just a variable declaration:
- %2 = OpVariable %%_ptr_Function_ulong Function
- - output .params don't exist, they have been moved to input positions
- by an earlier pass
- Distinguishing betweem kernel .params and function .params is not the
- cleanest solution. Alternatively, we could "deparamize" all kernel .param
- arguments by turning them into .reg arguments like this:
- .param .b64 arg -> .reg ptr<.b64,.param> arg
- This has the massive downside that this transformation would have to run
- very early and would muddy up already difficult code. It's simpler to just
- have an if here
-*/
-pub(super) fn run<'a, 'b>(
- func: Vec<TypedStatement>,
- id_def: &mut NumericIdResolver,
- fn_decl: &'a mut ast::MethodDeclaration<'b, SpirvWord>,
-) -> Result<Vec<TypedStatement>, TranslateError> {
- let mut result = Vec::with_capacity(func.len());
- for arg in fn_decl.input_arguments.iter_mut() {
- insert_mem_ssa_argument(
- id_def,
- &mut result,
- arg,
- matches!(fn_decl.name, ast::MethodName::Kernel(_)),
- );
- }
- for arg in fn_decl.return_arguments.iter() {
- insert_mem_ssa_argument_reg_return(&mut result, arg);
- }
- for s in func {
- match s {
- Statement::Instruction(inst) => match inst {
- ast::Instruction::Ret { data } => {
- // TODO: handle multiple output args
- match &fn_decl.return_arguments[..] {
- [return_reg] => {
- let new_id = id_def.register_intermediate(Some((
- return_reg.v_type.clone(),
- ast::StateSpace::Reg,
- )));
- result.push(Statement::LoadVar(LoadVarDetails {
- arg: ast::LdArgs {
- dst: new_id,
- src: return_reg.name,
- },
- typ: return_reg.v_type.clone(),
- member_index: None,
- }));
- unimplemented!()
- //result.push(Statement::RetValue(data, new_id));
- }
- [] => result.push(Statement::Instruction(ast::Instruction::Ret { data })),
- _ => unimplemented!(),
- }
- }
- inst => insert_mem_ssa_statement_default(
- id_def,
- &mut result,
- Statement::Instruction(inst),
- )?,
- },
- Statement::Conditional(bra) => {
- insert_mem_ssa_statement_default(id_def, &mut result, Statement::Conditional(bra))?
- }
- Statement::Conversion(conv) => {
- insert_mem_ssa_statement_default(id_def, &mut result, Statement::Conversion(conv))?
- }
- Statement::PtrAccess(ptr_access) => insert_mem_ssa_statement_default(
- id_def,
- &mut result,
- Statement::PtrAccess(ptr_access),
- )?,
- Statement::RepackVector(repack) => insert_mem_ssa_statement_default(
- id_def,
- &mut result,
- Statement::RepackVector(repack),
- )?,
- Statement::FunctionPointer(func_ptr) => insert_mem_ssa_statement_default(
- id_def,
- &mut result,
- Statement::FunctionPointer(func_ptr),
- )?,
- s @ Statement::Variable(_) | s @ Statement::Label(_) | s @ Statement::Constant(..) => {
- result.push(s)
- }
- _ => return Err(error_unreachable()),
- }
- }
- Ok(result)
-}
-
-fn insert_mem_ssa_argument(
- id_def: &mut NumericIdResolver,
- func: &mut Vec<TypedStatement>,
- arg: &mut ast::Variable<SpirvWord>,
- is_kernel: bool,
-) {
- if !is_kernel && arg.state_space == ast::StateSpace::Param {
- return;
- }
- let new_id = id_def.register_intermediate(Some((arg.v_type.clone(), arg.state_space)));
- func.push(Statement::Variable(ast::Variable {
- align: arg.align,
- v_type: arg.v_type.clone(),
- state_space: ast::StateSpace::Reg,
- name: arg.name,
- array_init: Vec::new(),
- }));
- func.push(Statement::StoreVar(StoreVarDetails {
- arg: ast::StArgs {
- src1: arg.name,
- src2: new_id,
- },
- typ: arg.v_type.clone(),
- member_index: None,
- }));
- arg.name = new_id;
-}
-
-fn insert_mem_ssa_argument_reg_return(
- func: &mut Vec<TypedStatement>,
- arg: &ast::Variable<SpirvWord>,
-) {
- func.push(Statement::Variable(ast::Variable {
- align: arg.align,
- v_type: arg.v_type.clone(),
- state_space: arg.state_space,
- name: arg.name,
- array_init: arg.array_init.clone(),
- }));
-}
-
-fn insert_mem_ssa_statement_default<'a, 'input>(
- id_def: &'a mut NumericIdResolver<'input>,
- func: &'a mut Vec<TypedStatement>,
- stmt: TypedStatement,
-) -> Result<(), TranslateError> {
- let mut visitor = InsertMemSSAVisitor {
- id_def,
- func,
- post_statements: Vec::new(),
- };
- let new_stmt = stmt.visit_map(&mut visitor)?;
- visitor.func.push(new_stmt);
- visitor.func.extend(visitor.post_statements);
- Ok(())
-}
-
-struct InsertMemSSAVisitor<'a, 'input> {
- id_def: &'a mut NumericIdResolver<'input>,
- func: &'a mut Vec<TypedStatement>,
- post_statements: Vec<TypedStatement>,
-}
-
-impl<'a, 'input> InsertMemSSAVisitor<'a, 'input> {
- fn symbol(
- &mut self,
- symbol: SpirvWord,
- member_index: Option<u8>,
- expected: Option<(&ast::Type, ast::StateSpace)>,
- is_dst: bool,
- ) -> Result<SpirvWord, TranslateError> {
- if expected.is_none() {
- return Ok(symbol);
- };
- let (mut var_type, var_space, is_variable) = self.id_def.get_typed(symbol)?;
- if var_space != ast::StateSpace::Reg || !is_variable {
- return Ok(symbol);
- };
- let member_index = match member_index {
- Some(idx) => {
- let vector_width = match var_type {
- ast::Type::Vector(width, scalar_t) => {
- var_type = ast::Type::Scalar(scalar_t);
- width
- }
- _ => return Err(error_mismatched_type()),
- };
- Some((
- idx,
- if self.id_def.special_registers.get(symbol).is_some() {
- Some(vector_width)
- } else {
- None
- },
- ))
- }
- None => None,
- };
- let generated_id = self
- .id_def
- .register_intermediate(Some((var_type.clone(), ast::StateSpace::Reg)));
- if !is_dst {
- self.func.push(Statement::LoadVar(LoadVarDetails {
- arg: ast::LdArgs {
- dst: generated_id,
- src: symbol,
- },
- typ: var_type,
- member_index,
- }));
- } else {
- self.post_statements
- .push(Statement::StoreVar(StoreVarDetails {
- arg: ast::StArgs {
- src1: symbol,
- src2: generated_id,
- },
- typ: var_type,
- member_index: member_index.map(|(idx, _)| idx),
- }));
- }
- Ok(generated_id)
- }
-}
-
-impl<'a, 'input> ast::VisitorMap<TypedOperand, TypedOperand, TranslateError>
- for InsertMemSSAVisitor<'a, 'input>
-{
- fn visit(
- &mut self,
- operand: TypedOperand,
- type_space: Option<(&ast::Type, ast::StateSpace)>,
- is_dst: bool,
- _relaxed_type_check: bool,
- ) -> Result<TypedOperand, TranslateError> {
- Ok(match operand {
- TypedOperand::Reg(reg) => {
- TypedOperand::Reg(self.symbol(reg, None, type_space, is_dst)?)
- }
- TypedOperand::RegOffset(reg, offset) => {
- TypedOperand::RegOffset(self.symbol(reg, None, type_space, is_dst)?, offset)
- }
- op @ TypedOperand::Imm(..) => op,
- TypedOperand::VecMember(symbol, index) => {
- TypedOperand::Reg(self.symbol(symbol, Some(index), type_space, is_dst)?)
- }
- })
- }
-
- fn visit_ident(
- &mut self,
- args: SpirvWord,
- type_space: Option<(&ptx_parser::Type, ptx_parser::StateSpace)>,
- is_dst: bool,
- relaxed_type_check: bool,
- ) -> Result<SpirvWord, TranslateError> {
- self.symbol(args, None, type_space, is_dst)
- }
-}
diff --git a/ptx/src/pass/mod.rs b/ptx/src/pass/mod.rs index ae6adce..65292eb 100644 --- a/ptx/src/pass/mod.rs +++ b/ptx/src/pass/mod.rs @@ -1,41 +1,24 @@ use ptx_parser as ast;
-use rspirv::{binary::Assemble, dr};
+use quick_error::quick_error;
use rustc_hash::FxHashMap;
use std::hash::Hash;
-use std::num::NonZeroU8;
use std::{
borrow::Cow,
- cell::RefCell,
- collections::{hash_map, HashMap, HashSet},
+ collections::{hash_map, HashMap},
ffi::CString,
iter,
- marker::PhantomData,
- mem,
- rc::Rc,
};
use strum::IntoEnumIterator;
use strum_macros::EnumIter;
-mod convert_dynamic_shared_memory_usage;
-mod convert_to_stateful_memory_access;
-mod convert_to_typed;
mod deparamize_functions;
pub(crate) mod emit_llvm;
-mod emit_spirv;
-mod expand_arguments;
mod expand_operands;
-mod extract_globals;
-mod fix_special_registers;
mod fix_special_registers2;
mod hoist_globals;
mod insert_explicit_load_store;
-mod insert_implicit_conversions;
mod insert_implicit_conversions2;
-mod insert_mem_ssa_statements;
-mod normalize_identifiers;
mod normalize_identifiers2;
-mod normalize_labels;
-mod normalize_predicates;
mod normalize_predicates2;
mod replace_instructions_with_function_calls;
mod resolve_function_pointers;
@@ -43,42 +26,18 @@ mod resolve_function_pointers; static ZLUDA_PTX_IMPL: &'static [u8] = include_bytes!("../../lib/zluda_ptx_impl.bc");
const ZLUDA_PTX_PREFIX: &'static str = "__zluda_ptx_impl_";
-pub fn to_llvm_module<'input>(ast: ast::Module<'input>) -> Result<Module, TranslateError> {
- let mut id_defs = GlobalStringIdResolver::<'input>::new(SpirvWord(1));
- let mut ptx_impl_imports = HashMap::new();
- let directives = ast
- .directives
- .into_iter()
- .filter_map(|directive| {
- translate_directive(&mut id_defs, &mut ptx_impl_imports, directive).transpose()
- })
- .collect::<Result<Vec<_>, _>>()?;
- let directives = hoist_function_globals(directives);
- let must_link_ptx_impl = ptx_impl_imports.len() > 0;
- let mut directives = ptx_impl_imports
- .into_iter()
- .map(|(_, v)| v)
- .chain(directives.into_iter())
- .collect::<Vec<_>>();
- let mut builder = dr::Builder::new();
- builder.reserve_ids(id_defs.current_id().0);
- let call_map = MethodsCallMap::new(&directives);
- let mut directives =
- convert_dynamic_shared_memory_usage::run(directives, &call_map, &mut || {
- SpirvWord(builder.id())
- })?;
- normalize_variable_decls(&mut directives);
- let denorm_information = compute_denorm_information(&directives);
- todo!()
- /*
- let llvm_ir: emit_llvm::MemoryBuffer = emit_llvm::run(&id_defs, call_map, directives)?;
- Ok(Module {
- llvm_ir,
- kernel_info: HashMap::new(),
- }) */
+quick_error! {
+ #[derive(Debug)]
+ pub enum TranslateError {
+ UnknownSymbol {}
+ UntypedSymbol {}
+ MismatchedType {}
+ Unreachable {}
+ Todo {}
+ }
}
-pub fn to_llvm_module2<'input>(ast: ast::Module<'input>) -> Result<Module, TranslateError> {
+pub fn to_llvm_module<'input>(ast: ast::Module<'input>) -> Result<Module, TranslateError> {
let mut flat_resolver = GlobalStringIdentResolver2::<'input>::new(SpirvWord(1));
let mut scoped_resolver = ScopedResolver::new(&mut flat_resolver);
let sreg_map = SpecialRegistersMap2::new(&mut scoped_resolver)?;
@@ -99,122 +58,6 @@ pub fn to_llvm_module2<'input>(ast: ast::Module<'input>) -> Result<Module, Trans })
}
-fn translate_directive<'input, 'a>(
- id_defs: &'a mut GlobalStringIdResolver<'input>,
- ptx_impl_imports: &'a mut HashMap<String, Directive<'input>>,
- d: ast::Directive<'input, ast::ParsedOperand<&'input str>>,
-) -> Result<Option<Directive<'input>>, TranslateError> {
- Ok(match d {
- ast::Directive::Variable(linking, var) => Some(Directive::Variable(
- linking,
- ast::Variable {
- align: var.align,
- v_type: var.v_type.clone(),
- state_space: var.state_space,
- name: id_defs.get_or_add_def_typed(var.name, var.v_type, var.state_space, true),
- array_init: var.array_init,
- },
- )),
- ast::Directive::Method(linkage, f) => {
- translate_function(id_defs, ptx_impl_imports, linkage, f)?.map(Directive::Method)
- }
- })
-}
-
-type ParsedFunction<'a> = ast::Function<'a, &'a str, ast::Statement<ast::ParsedOperand<&'a str>>>;
-
-fn translate_function<'input, 'a>(
- id_defs: &'a mut GlobalStringIdResolver<'input>,
- ptx_impl_imports: &'a mut HashMap<String, Directive<'input>>,
- linkage: ast::LinkingDirective,
- f: ParsedFunction<'input>,
-) -> Result<Option<Function<'input>>, TranslateError> {
- let import_as = match &f.func_directive {
- ast::MethodDeclaration {
- name: ast::MethodName::Func(func_name),
- ..
- } if *func_name == "__assertfail" || *func_name == "vprintf" => {
- Some([ZLUDA_PTX_PREFIX, func_name].concat())
- }
- _ => None,
- };
- let (str_resolver, fn_resolver, fn_decl) = id_defs.start_fn(&f.func_directive)?;
- let mut func = to_ssa(
- ptx_impl_imports,
- str_resolver,
- fn_resolver,
- fn_decl,
- f.body,
- f.tuning,
- linkage,
- )?;
- func.import_as = import_as;
- if func.import_as.is_some() {
- ptx_impl_imports.insert(
- func.import_as.as_ref().unwrap().clone(),
- Directive::Method(func),
- );
- Ok(None)
- } else {
- Ok(Some(func))
- }
-}
-
-fn to_ssa<'input, 'b>(
- ptx_impl_imports: &'b mut HashMap<String, Directive<'input>>,
- mut id_defs: FnStringIdResolver<'input, 'b>,
- fn_defs: GlobalFnDeclResolver<'input, 'b>,
- func_decl: Rc<RefCell<ast::MethodDeclaration<'input, SpirvWord>>>,
- f_body: Option<Vec<ast::Statement<ast::ParsedOperand<&'input str>>>>,
- tuning: Vec<ast::TuningDirective>,
- linkage: ast::LinkingDirective,
-) -> Result<Function<'input>, TranslateError> {
- //deparamize_function_decl(&func_decl)?;
- let f_body = match f_body {
- Some(vec) => vec,
- None => {
- return Ok(Function {
- func_decl: func_decl,
- body: None,
- globals: Vec::new(),
- import_as: None,
- tuning,
- linkage,
- })
- }
- };
- let normalized_ids = normalize_identifiers::run(&mut id_defs, &fn_defs, f_body)?;
- let mut numeric_id_defs = id_defs.finish();
- let unadorned_statements = normalize_predicates::run(normalized_ids, &mut numeric_id_defs)?;
- let typed_statements =
- convert_to_typed::run(unadorned_statements, &fn_defs, &mut numeric_id_defs)?;
- let typed_statements =
- fix_special_registers::run(ptx_impl_imports, typed_statements, &mut numeric_id_defs)?;
- let (func_decl, typed_statements) =
- convert_to_stateful_memory_access::run(func_decl, typed_statements, &mut numeric_id_defs)?;
- let ssa_statements = insert_mem_ssa_statements::run(
- typed_statements,
- &mut numeric_id_defs,
- &mut (*func_decl).borrow_mut(),
- )?;
- let mut numeric_id_defs = numeric_id_defs.finish();
- let expanded_statements = expand_arguments::run(ssa_statements, &mut numeric_id_defs)?;
- let expanded_statements =
- insert_implicit_conversions::run(expanded_statements, &mut numeric_id_defs)?;
- let mut numeric_id_defs = numeric_id_defs.unmut();
- let labeled_statements = normalize_labels::run(expanded_statements, &mut numeric_id_defs);
- let (f_body, globals) =
- extract_globals::run(labeled_statements, ptx_impl_imports, &mut numeric_id_defs)?;
- Ok(Function {
- func_decl: func_decl,
- globals: globals,
- body: Some(f_body),
- import_as: None,
- tuning,
- linkage,
- })
-}
-
pub struct Module {
pub llvm_ir: emit_llvm::MemoryBuffer,
pub kernel_info: HashMap<String, KernelInfo>,
@@ -226,135 +69,6 @@ impl Module { }
}
-struct GlobalStringIdResolver<'input> {
- current_id: SpirvWord,
- variables: HashMap<Cow<'input, str>, SpirvWord>,
- pub(crate) reverse_variables: HashMap<SpirvWord, &'input str>,
- variables_type_check: HashMap<SpirvWord, Option<(ast::Type, ast::StateSpace, bool)>>,
- special_registers: SpecialRegistersMap,
- fns: HashMap<SpirvWord, FnSigMapper<'input>>,
-}
-
-impl<'input> GlobalStringIdResolver<'input> {
- fn new(start_id: SpirvWord) -> Self {
- Self {
- current_id: start_id,
- variables: HashMap::new(),
- reverse_variables: HashMap::new(),
- variables_type_check: HashMap::new(),
- special_registers: SpecialRegistersMap::new(),
- fns: HashMap::new(),
- }
- }
-
- fn get_or_add_def(&mut self, id: &'input str) -> SpirvWord {
- self.get_or_add_impl(id, None)
- }
-
- fn get_or_add_def_typed(
- &mut self,
- id: &'input str,
- typ: ast::Type,
- state_space: ast::StateSpace,
- is_variable: bool,
- ) -> SpirvWord {
- self.get_or_add_impl(id, Some((typ, state_space, is_variable)))
- }
-
- fn get_or_add_impl(
- &mut self,
- id: &'input str,
- typ: Option<(ast::Type, ast::StateSpace, bool)>,
- ) -> SpirvWord {
- let id = match self.variables.entry(Cow::Borrowed(id)) {
- hash_map::Entry::Occupied(e) => *(e.get()),
- hash_map::Entry::Vacant(e) => {
- let numeric_id = self.current_id;
- e.insert(numeric_id);
- self.reverse_variables.insert(numeric_id, id);
- self.current_id.0 += 1;
- numeric_id
- }
- };
- self.variables_type_check.insert(id, typ);
- id
- }
-
- fn get_id(&self, id: &str) -> Result<SpirvWord, TranslateError> {
- self.variables
- .get(id)
- .copied()
- .ok_or_else(error_unknown_symbol)
- }
-
- fn current_id(&self) -> SpirvWord {
- self.current_id
- }
-
- fn start_fn<'b>(
- &'b mut self,
- header: &'b ast::MethodDeclaration<'input, &'input str>,
- ) -> Result<
- (
- FnStringIdResolver<'input, 'b>,
- GlobalFnDeclResolver<'input, 'b>,
- Rc<RefCell<ast::MethodDeclaration<'input, SpirvWord>>>,
- ),
- TranslateError,
- > {
- // In case a function decl was inserted earlier we want to use its id
- let name_id = self.get_or_add_def(header.name());
- let mut fn_resolver = FnStringIdResolver {
- current_id: &mut self.current_id,
- global_variables: &self.variables,
- global_type_check: &self.variables_type_check,
- special_registers: &mut self.special_registers,
- variables: vec![HashMap::new(); 1],
- type_check: HashMap::new(),
- };
- let return_arguments = rename_fn_params(&mut fn_resolver, &header.return_arguments);
- let input_arguments = rename_fn_params(&mut fn_resolver, &header.input_arguments);
- let name = match header.name {
- ast::MethodName::Kernel(name) => ast::MethodName::Kernel(name),
- ast::MethodName::Func(_) => ast::MethodName::Func(name_id),
- };
- let fn_decl = ast::MethodDeclaration {
- return_arguments,
- name,
- input_arguments,
- shared_mem: None,
- };
- let new_fn_decl = if !matches!(fn_decl.name, ast::MethodName::Kernel(_)) {
- let resolver = FnSigMapper::remap_to_spirv_repr(fn_decl);
- let new_fn_decl = resolver.func_decl.clone();
- self.fns.insert(name_id, resolver);
- new_fn_decl
- } else {
- Rc::new(RefCell::new(fn_decl))
- };
- Ok((
- fn_resolver,
- GlobalFnDeclResolver { fns: &self.fns },
- new_fn_decl,
- ))
- }
-}
-
-fn rename_fn_params<'a, 'b>(
- fn_resolver: &mut FnStringIdResolver<'a, 'b>,
- args: &'b [ast::Variable<&'a str>],
-) -> Vec<ast::Variable<SpirvWord>> {
- args.iter()
- .map(|a| ast::Variable {
- name: fn_resolver.add_def(a.name, Some((a.v_type.clone(), a.state_space)), true),
- v_type: a.v_type.clone(),
- state_space: a.state_space,
- align: a.align,
- array_init: a.array_init.clone(),
- })
- .collect()
-}
-
pub struct KernelInfo {
pub arguments_sizes: Vec<(usize, bool)>,
pub uses_shared_mem: bool,
@@ -371,18 +85,6 @@ enum PtxSpecialRegister { }
impl PtxSpecialRegister {
- fn try_parse(s: &str) -> Option<Self> {
- match s {
- "%tid" => Some(Self::Tid),
- "%ntid" => Some(Self::Ntid),
- "%ctaid" => Some(Self::Ctaid),
- "%nctaid" => Some(Self::Nctaid),
- "%clock" => Some(Self::Clock),
- "%lanemask_lt" => Some(Self::LanemaskLt),
- _ => None,
- }
- }
-
fn as_str(self) -> &'static str {
match self {
Self::Tid => "%tid",
@@ -437,208 +139,6 @@ impl PtxSpecialRegister { }
}
-struct SpecialRegistersMap {
- reg_to_id: HashMap<PtxSpecialRegister, SpirvWord>,
- id_to_reg: HashMap<SpirvWord, PtxSpecialRegister>,
-}
-
-impl SpecialRegistersMap {
- fn new() -> Self {
- SpecialRegistersMap {
- reg_to_id: HashMap::new(),
- id_to_reg: HashMap::new(),
- }
- }
-
- fn get(&self, id: SpirvWord) -> Option<PtxSpecialRegister> {
- self.id_to_reg.get(&id).copied()
- }
-
- fn get_or_add(&mut self, current_id: &mut SpirvWord, reg: PtxSpecialRegister) -> SpirvWord {
- match self.reg_to_id.entry(reg) {
- hash_map::Entry::Occupied(e) => *e.get(),
- hash_map::Entry::Vacant(e) => {
- let numeric_id = SpirvWord(current_id.0);
- current_id.0 += 1;
- e.insert(numeric_id);
- self.id_to_reg.insert(numeric_id, reg);
- numeric_id
- }
- }
- }
-}
-
-struct FnStringIdResolver<'input, 'b> {
- current_id: &'b mut SpirvWord,
- global_variables: &'b HashMap<Cow<'input, str>, SpirvWord>,
- global_type_check: &'b HashMap<SpirvWord, Option<(ast::Type, ast::StateSpace, bool)>>,
- special_registers: &'b mut SpecialRegistersMap,
- variables: Vec<HashMap<Cow<'input, str>, SpirvWord>>,
- type_check: HashMap<SpirvWord, Option<(ast::Type, ast::StateSpace, bool)>>,
-}
-
-impl<'a, 'b> FnStringIdResolver<'a, 'b> {
- fn finish(self) -> NumericIdResolver<'b> {
- NumericIdResolver {
- current_id: self.current_id,
- global_type_check: self.global_type_check,
- type_check: self.type_check,
- special_registers: self.special_registers,
- }
- }
-
- fn start_block(&mut self) {
- self.variables.push(HashMap::new())
- }
-
- fn end_block(&mut self) {
- self.variables.pop();
- }
-
- fn get_id(&mut self, id: &str) -> Result<SpirvWord, TranslateError> {
- for scope in self.variables.iter().rev() {
- match scope.get(id) {
- Some(id) => return Ok(*id),
- None => continue,
- }
- }
- match self.global_variables.get(id) {
- Some(id) => Ok(*id),
- None => {
- let sreg = PtxSpecialRegister::try_parse(id).ok_or_else(error_unknown_symbol)?;
- Ok(self.special_registers.get_or_add(self.current_id, sreg))
- }
- }
- }
-
- fn add_def(
- &mut self,
- id: &'a str,
- typ: Option<(ast::Type, ast::StateSpace)>,
- is_variable: bool,
- ) -> SpirvWord {
- let numeric_id = *self.current_id;
- self.variables
- .last_mut()
- .unwrap()
- .insert(Cow::Borrowed(id), numeric_id);
- self.type_check.insert(
- numeric_id,
- typ.map(|(typ, space)| (typ, space, is_variable)),
- );
- self.current_id.0 += 1;
- numeric_id
- }
-
- #[must_use]
- fn add_defs(
- &mut self,
- base_id: &'a str,
- count: u32,
- typ: ast::Type,
- state_space: ast::StateSpace,
- is_variable: bool,
- ) -> impl Iterator<Item = SpirvWord> {
- let numeric_id = *self.current_id;
- for i in 0..count {
- self.variables.last_mut().unwrap().insert(
- Cow::Owned(format!("{}{}", base_id, i)),
- SpirvWord(numeric_id.0 + i),
- );
- self.type_check.insert(
- SpirvWord(numeric_id.0 + i),
- Some((typ.clone(), state_space, is_variable)),
- );
- }
- self.current_id.0 += count;
- (0..count)
- .into_iter()
- .map(move |i| SpirvWord(i + numeric_id.0))
- }
-}
-
-struct NumericIdResolver<'b> {
- current_id: &'b mut SpirvWord,
- global_type_check: &'b HashMap<SpirvWord, Option<(ast::Type, ast::StateSpace, bool)>>,
- type_check: HashMap<SpirvWord, Option<(ast::Type, ast::StateSpace, bool)>>,
- special_registers: &'b mut SpecialRegistersMap,
-}
-
-impl<'b> NumericIdResolver<'b> {
- fn finish(self) -> MutableNumericIdResolver<'b> {
- MutableNumericIdResolver { base: self }
- }
-
- fn get_typed(
- &self,
- id: SpirvWord,
- ) -> Result<(ast::Type, ast::StateSpace, bool), TranslateError> {
- match self.type_check.get(&id) {
- Some(Some(x)) => Ok(x.clone()),
- Some(None) => Err(TranslateError::UntypedSymbol),
- None => match self.special_registers.get(id) {
- Some(x) => Ok((x.get_type(), ast::StateSpace::Reg, true)),
- None => match self.global_type_check.get(&id) {
- Some(Some(result)) => Ok(result.clone()),
- Some(None) | None => Err(TranslateError::UntypedSymbol),
- },
- },
- }
- }
-
- // This is for identifiers which will be emitted later as OpVariable
- // They are candidates for insertion of LoadVar/StoreVar
- fn register_variable(&mut self, typ: ast::Type, state_space: ast::StateSpace) -> SpirvWord {
- let new_id = *self.current_id;
- self.type_check
- .insert(new_id, Some((typ, state_space, true)));
- self.current_id.0 += 1;
- new_id
- }
-
- fn register_intermediate(&mut self, typ: Option<(ast::Type, ast::StateSpace)>) -> SpirvWord {
- let new_id = *self.current_id;
- self.type_check
- .insert(new_id, typ.map(|(t, space)| (t, space, false)));
- self.current_id.0 += 1;
- new_id
- }
-}
-
-struct MutableNumericIdResolver<'b> {
- base: NumericIdResolver<'b>,
-}
-
-impl<'b> MutableNumericIdResolver<'b> {
- fn unmut(self) -> NumericIdResolver<'b> {
- self.base
- }
-
- fn get_typed(&self, id: SpirvWord) -> Result<(ast::Type, ast::StateSpace), TranslateError> {
- self.base.get_typed(id).map(|(t, space, _)| (t, space))
- }
-
- fn register_intermediate(&mut self, typ: ast::Type, state_space: ast::StateSpace) -> SpirvWord {
- self.base.register_intermediate(Some((typ, state_space)))
- }
-}
-
-quick_error! {
- #[derive(Debug)]
- pub enum TranslateError {
- UnknownSymbol {}
- UntypedSymbol {}
- MismatchedType {}
- Spirv(err: rspirv::dr::Error) {
- from()
- display("{}", err)
- cause(err)
- }
- Unreachable {}
- Todo {}
- }
-}
-
#[cfg(debug_assertions)]
fn error_unreachable() -> TranslateError {
unreachable!()
@@ -669,105 +169,12 @@ fn error_mismatched_type() -> TranslateError { TranslateError::MismatchedType
}
-pub struct GlobalFnDeclResolver<'input, 'a> {
- fns: &'a HashMap<SpirvWord, FnSigMapper<'input>>,
-}
-
-impl<'input, 'a> GlobalFnDeclResolver<'input, 'a> {
- fn get_fn_sig_resolver(&self, id: SpirvWord) -> Result<&FnSigMapper<'input>, TranslateError> {
- self.fns.get(&id).ok_or_else(error_unknown_symbol)
- }
-}
-
-struct FnSigMapper<'input> {
- // true - stays as return argument
- // false - is moved to input argument
- return_param_args: Vec<bool>,
- func_decl: Rc<RefCell<ast::MethodDeclaration<'input, SpirvWord>>>,
-}
-
-impl<'input> FnSigMapper<'input> {
- fn remap_to_spirv_repr(mut method: ast::MethodDeclaration<'input, SpirvWord>) -> Self {
- let return_param_args = method
- .return_arguments
- .iter()
- .map(|a| a.state_space != ast::StateSpace::Param)
- .collect::<Vec<_>>();
- let mut new_return_arguments = Vec::new();
- for arg in method.return_arguments.into_iter() {
- if arg.state_space == ast::StateSpace::Param {
- method.input_arguments.push(arg);
- } else {
- new_return_arguments.push(arg);
- }
- }
- method.return_arguments = new_return_arguments;
- FnSigMapper {
- return_param_args,
- func_decl: Rc::new(RefCell::new(method)),
- }
- }
-
- fn resolve_in_spirv_repr(
- &self,
- data: ast::CallDetails,
- arguments: ast::CallArgs<ast::ParsedOperand<SpirvWord>>,
- ) -> Result<ast::Instruction<ast::ParsedOperand<SpirvWord>>, TranslateError> {
- let func_decl = (*self.func_decl).borrow();
- let mut data_return = Vec::new();
- let mut arguments_return = Vec::new();
- let mut data_input = data.input_arguments;
- let mut arguments_input = arguments.input_arguments;
- let mut func_decl_return_iter = func_decl.return_arguments.iter();
- let mut func_decl_input_iter = func_decl.input_arguments[arguments_input.len()..].iter();
- for (idx, id) in arguments.return_arguments.iter().enumerate() {
- let stays_as_return = match self.return_param_args.get(idx) {
- Some(x) => *x,
- None => return Err(TranslateError::MismatchedType),
- };
- if stays_as_return {
- if let Some(var) = func_decl_return_iter.next() {
- data_return.push((var.v_type.clone(), var.state_space));
- arguments_return.push(*id);
- } else {
- return Err(TranslateError::MismatchedType);
- }
- } else {
- if let Some(var) = func_decl_input_iter.next() {
- data_input.push((var.v_type.clone(), var.state_space));
- arguments_input.push(ast::ParsedOperand::Reg(*id));
- } else {
- return Err(TranslateError::MismatchedType);
- }
- }
- }
- if arguments_return.len() != func_decl.return_arguments.len()
- || arguments_input.len() != func_decl.input_arguments.len()
- {
- return Err(TranslateError::MismatchedType);
- }
- let data = ast::CallDetails {
- uniform: data.uniform,
- return_arguments: data_return,
- input_arguments: data_input,
- };
- let arguments = ast::CallArgs {
- func: arguments.func,
- return_arguments: arguments_return,
- input_arguments: arguments_input,
- };
- Ok(ast::Instruction::Call { data, arguments })
- }
-}
-
enum Statement<I, P: ast::Operand> {
Label(SpirvWord),
Variable(ast::Variable<P::Ident>),
Instruction(I),
// SPIR-V compatible replacement for PTX predicates
Conditional(BrachCondition),
- LoadVar(LoadVarDetails),
- StoreVar(StoreVarDetails),
Conversion(ImplicitConversion),
Constant(ConstantDefinition),
RetValue(ast::RetData, Vec<(SpirvWord, ast::Type)>),
@@ -820,52 +227,6 @@ impl<T: ast::Operand<Ident = SpirvWord>> Statement<ast::Instruction<T>, T> { if_false,
})
}
- Statement::LoadVar(LoadVarDetails {
- arg,
- typ,
- member_index,
- }) => {
- let dst = visitor.visit_ident(
- arg.dst,
- Some((&typ, ast::StateSpace::Reg)),
- true,
- false,
- )?;
- let src = visitor.visit_ident(
- arg.src,
- Some((&typ, ast::StateSpace::Local)),
- false,
- false,
- )?;
- Statement::LoadVar(LoadVarDetails {
- arg: ast::LdArgs { dst, src },
- typ,
- member_index,
- })
- }
- Statement::StoreVar(StoreVarDetails {
- arg,
- typ,
- member_index,
- }) => {
- let src1 = visitor.visit_ident(
- arg.src1,
- Some((&typ, ast::StateSpace::Local)),
- false,
- false,
- )?;
- let src2 = visitor.visit_ident(
- arg.src2,
- Some((&typ, ast::StateSpace::Reg)),
- false,
- false,
- )?;
- Statement::StoreVar(StoreVarDetails {
- arg: ast::StArgs { src1, src2 },
- typ,
- member_index,
- })
- }
Statement::Conversion(ImplicitConversion {
src,
dst,
@@ -1103,22 +464,6 @@ struct BrachCondition { if_true: SpirvWord,
if_false: SpirvWord,
}
-struct LoadVarDetails {
- arg: ast::LdArgs<SpirvWord>,
- typ: ast::Type,
- // (index, vector_width)
- // HACK ALERT
- // For some reason IGC explodes when you try to load from builtin vectors
- // using OpInBoundsAccessChain, the one true way to do it is to
- // OpLoad+OpCompositeExtract
- member_index: Option<(u8, Option<u8>)>,
-}
-
-struct StoreVarDetails {
- arg: ast::StArgs<SpirvWord>,
- typ: ast::Type,
- member_index: Option<u8>,
-}
#[derive(Clone)]
struct ImplicitConversion {
@@ -1169,14 +514,14 @@ struct FunctionPointerDetails { }
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
-struct SpirvWord(spirv::Word);
+pub struct SpirvWord(u32);
-impl From<spirv::Word> for SpirvWord {
- fn from(value: spirv::Word) -> Self {
+impl From<u32> for SpirvWord {
+ fn from(value: u32) -> Self {
Self(value)
}
}
-impl From<SpirvWord> for spirv::Word {
+impl From<SpirvWord> for u32 {
fn from(value: SpirvWord) -> Self {
value.0
}
@@ -1190,31 +535,6 @@ impl ast::Operand for SpirvWord { }
}
-fn pred_map_variable<U, T, F: FnMut(T) -> Result<U, TranslateError>>(
- this: ast::PredAt<T>,
- f: &mut F,
-) -> Result<ast::PredAt<U>, TranslateError> {
- let new_label = f(this.label)?;
- Ok(ast::PredAt {
- not: this.not,
- label: new_label,
- })
-}
-
-pub(crate) enum Directive<'input> {
- Variable(ast::LinkingDirective, ast::Variable<SpirvWord>),
- Method(Function<'input>),
-}
-
-pub(crate) struct Function<'input> {
- pub func_decl: Rc<RefCell<ast::MethodDeclaration<'input, SpirvWord>>>,
- pub globals: Vec<ast::Variable<SpirvWord>>,
- pub body: Option<Vec<ExpandedStatement>>,
- import_as: Option<String>,
- tuning: Vec<ast::TuningDirective>,
- linkage: ast::LinkingDirective,
-}
-
type ExpandedStatement = Statement<ast::Instruction<SpirvWord>, SpirvWord>;
type NormalizedStatement = Statement<
@@ -1225,578 +545,12 @@ type NormalizedStatement = Statement< ast::ParsedOperand<SpirvWord>,
>;
-type UnconditionalStatement =
- Statement<ast::Instruction<ast::ParsedOperand<SpirvWord>>, ast::ParsedOperand<SpirvWord>>;
-
-type TypedStatement = Statement<ast::Instruction<TypedOperand>, TypedOperand>;
-
-#[derive(Copy, Clone)]
-enum TypedOperand {
- Reg(SpirvWord),
- RegOffset(SpirvWord, i32),
- Imm(ast::ImmediateValue),
- VecMember(SpirvWord, u8),
-}
-
-impl TypedOperand {
- fn map<Err>(
- self,
- fn_: impl FnOnce(SpirvWord, Option<u8>) -> Result<SpirvWord, Err>,
- ) -> Result<Self, Err> {
- Ok(match self {
- TypedOperand::Reg(reg) => TypedOperand::Reg(fn_(reg, None)?),
- TypedOperand::RegOffset(reg, off) => TypedOperand::RegOffset(fn_(reg, None)?, off),
- TypedOperand::Imm(imm) => TypedOperand::Imm(imm),
- TypedOperand::VecMember(reg, idx) => TypedOperand::VecMember(fn_(reg, Some(idx))?, idx),
- })
- }
-
- fn underlying_register(&self) -> Option<SpirvWord> {
- match self {
- Self::Reg(r) | Self::RegOffset(r, _) | Self::VecMember(r, _) => Some(*r),
- Self::Imm(_) => None,
- }
- }
-
- fn unwrap_reg(&self) -> Result<SpirvWord, TranslateError> {
- match self {
- TypedOperand::Reg(reg) => Ok(*reg),
- _ => Err(error_unreachable()),
- }
- }
-}
-
-impl ast::Operand for TypedOperand {
- type Ident = SpirvWord;
-
- fn from_ident(ident: Self::Ident) -> Self {
- TypedOperand::Reg(ident)
- }
-}
-
-impl<Fn> ast::VisitorMap<TypedOperand, TypedOperand, TranslateError>
- for FnVisitor<TypedOperand, TypedOperand, TranslateError, Fn>
-where
- Fn: FnMut(
- TypedOperand,
- Option<(&ast::Type, ast::StateSpace)>,
- bool,
- bool,
- ) -> Result<TypedOperand, TranslateError>,
-{
- fn visit(
- &mut self,
- args: TypedOperand,
- type_space: Option<(&ast::Type, ast::StateSpace)>,
- is_dst: bool,
- relaxed_type_check: bool,
- ) -> Result<TypedOperand, TranslateError> {
- (self.fn_)(args, type_space, is_dst, relaxed_type_check)
- }
-
- fn visit_ident(
- &mut self,
- args: SpirvWord,
- type_space: Option<(&ast::Type, ast::StateSpace)>,
- is_dst: bool,
- relaxed_type_check: bool,
- ) -> Result<SpirvWord, TranslateError> {
- match (self.fn_)(
- TypedOperand::Reg(args),
- type_space,
- is_dst,
- relaxed_type_check,
- )? {
- TypedOperand::Reg(reg) => Ok(reg),
- _ => Err(TranslateError::Unreachable),
- }
- }
-}
-
-struct FnVisitor<
- T,
- U,
- Err,
- Fn: FnMut(T, Option<(&ast::Type, ast::StateSpace)>, bool, bool) -> Result<U, Err>,
-> {
- fn_: Fn,
- _marker: PhantomData<fn(T) -> Result<U, Err>>,
-}
-
-impl<
- T,
- U,
- Err,
- Fn: FnMut(T, Option<(&ast::Type, ast::StateSpace)>, bool, bool) -> Result<U, Err>,
- > FnVisitor<T, U, Err, Fn>
-{
- fn new(fn_: Fn) -> Self {
- Self {
- fn_,
- _marker: PhantomData,
- }
- }
-}
-
-fn register_external_fn_call<'a>(
- id_defs: &mut NumericIdResolver,
- ptx_impl_imports: &mut HashMap<String, Directive>,
- name: String,
- return_arguments: impl Iterator<Item = (&'a ast::Type, ast::StateSpace)>,
- input_arguments: impl Iterator<Item = (&'a ast::Type, ast::StateSpace)>,
-) -> Result<SpirvWord, TranslateError> {
- match ptx_impl_imports.entry(name) {
- hash_map::Entry::Vacant(entry) => {
- let fn_id = id_defs.register_intermediate(None);
- let return_arguments = fn_arguments_to_variables(id_defs, return_arguments);
- let input_arguments = fn_arguments_to_variables(id_defs, input_arguments);
- let func_decl = ast::MethodDeclaration::<SpirvWord> {
- return_arguments,
- name: ast::MethodName::Func(fn_id),
- input_arguments,
- shared_mem: None,
- };
- let func = Function {
- func_decl: Rc::new(RefCell::new(func_decl)),
- globals: Vec::new(),
- body: None,
- import_as: Some(entry.key().clone()),
- tuning: Vec::new(),
- linkage: ast::LinkingDirective::EXTERN,
- };
- entry.insert(Directive::Method(func));
- Ok(fn_id)
- }
- hash_map::Entry::Occupied(entry) => match entry.get() {
- Directive::Method(Function { func_decl, .. }) => match (**func_decl).borrow().name {
- ast::MethodName::Func(fn_id) => Ok(fn_id),
- ast::MethodName::Kernel(_) => Err(error_unreachable()),
- },
- _ => Err(error_unreachable()),
- },
- }
-}
-
-fn fn_arguments_to_variables<'a>(
- id_defs: &mut NumericIdResolver,
- args: impl Iterator<Item = (&'a ast::Type, ast::StateSpace)>,
-) -> Vec<ast::Variable<SpirvWord>> {
- args.map(|(typ, space)| ast::Variable {
- align: None,
- v_type: typ.clone(),
- state_space: space,
- name: id_defs.register_intermediate(None),
- array_init: Vec::new(),
- })
- .collect::<Vec<_>>()
-}
-
-fn hoist_function_globals(directives: Vec<Directive>) -> Vec<Directive> {
- let mut result = Vec::with_capacity(directives.len());
- for directive in directives {
- match directive {
- Directive::Method(method) => {
- for variable in method.globals {
- result.push(Directive::Variable(ast::LinkingDirective::NONE, variable));
- }
- result.push(Directive::Method(Function {
- globals: Vec::new(),
- ..method
- }))
- }
- _ => result.push(directive),
- }
- }
- result
-}
-
-struct MethodsCallMap<'input> {
- map: HashMap<ast::MethodName<'input, SpirvWord>, HashSet<SpirvWord>>,
-}
-
-impl<'input> MethodsCallMap<'input> {
- fn new(module: &[Directive<'input>]) -> Self {
- let mut directly_called_by = HashMap::new();
- for directive in module {
- match directive {
- Directive::Method(Function {
- func_decl,
- body: Some(statements),
- ..
- }) => {
- let call_key: ast::MethodName<_> = (**func_decl).borrow().name;
- if let hash_map::Entry::Vacant(entry) = directly_called_by.entry(call_key) {
- entry.insert(Vec::new());
- }
- for statement in statements {
- match statement {
- Statement::Instruction(ast::Instruction::Call { data, arguments }) => {
- multi_hash_map_append(
- &mut directly_called_by,
- call_key,
- arguments.func,
- );
- }
- _ => {}
- }
- }
- }
- _ => {}
- }
- }
- let mut result = HashMap::new();
- for (&method_key, children) in directly_called_by.iter() {
- let mut visited = HashSet::new();
- for child in children {
- Self::add_call_map_single(&directly_called_by, &mut visited, *child);
- }
- result.insert(method_key, visited);
- }
- MethodsCallMap { map: result }
- }
-
- fn add_call_map_single(
- directly_called_by: &HashMap<ast::MethodName<'input, SpirvWord>, Vec<SpirvWord>>,
- visited: &mut HashSet<SpirvWord>,
- current: SpirvWord,
- ) {
- if !visited.insert(current) {
- return;
- }
- if let Some(children) = directly_called_by.get(&ast::MethodName::Func(current)) {
- for child in children {
- Self::add_call_map_single(directly_called_by, visited, *child);
- }
- }
- }
-
- fn get_kernel_children(&self, name: &'input str) -> impl Iterator<Item = &SpirvWord> {
- self.map
- .get(&ast::MethodName::Kernel(name))
- .into_iter()
- .flatten()
- }
-
- fn kernels(&self) -> impl Iterator<Item = (&'input str, &HashSet<SpirvWord>)> {
- self.map
- .iter()
- .filter_map(|(method, children)| match method {
- ast::MethodName::Kernel(kernel) => Some((*kernel, children)),
- ast::MethodName::Func(..) => None,
- })
- }
-
- fn methods(
- &self,
- ) -> impl Iterator<Item = (ast::MethodName<'input, SpirvWord>, &HashSet<SpirvWord>)> {
- self.map
- .iter()
- .map(|(method, children)| (*method, children))
- }
-
- fn visit_callees(&self, method: ast::MethodName<'input, SpirvWord>, f: impl FnMut(SpirvWord)) {
- self.map
- .get(&method)
- .into_iter()
- .flatten()
- .copied()
- .for_each(f);
- }
-}
-
-fn multi_hash_map_append<
- K: Eq + std::hash::Hash,
- V,
- Collection: std::iter::Extend<V> + std::default::Default,
->(
- m: &mut HashMap<K, Collection>,
- key: K,
- value: V,
-) {
- match m.entry(key) {
- hash_map::Entry::Occupied(mut entry) => {
- entry.get_mut().extend(iter::once(value));
- }
- hash_map::Entry::Vacant(entry) => {
- entry.insert(Default::default()).extend(iter::once(value));
- }
- }
-}
-
-fn normalize_variable_decls(directives: &mut Vec<Directive>) {
- for directive in directives {
- match directive {
- Directive::Method(Function {
- body: Some(func), ..
- }) => {
- func[1..].sort_by_key(|s| match s {
- Statement::Variable(_) => 0,
- _ => 1,
- });
- }
- _ => (),
- }
- }
-}
-
-// HACK ALERT!
-// This function is a "good enough" heuristic of whetever to mark f16/f32 operations
-// in the kernel as flushing denorms to zero or preserving them
-// PTX support per-instruction ftz information. Unfortunately SPIR-V has no
-// such capability, so instead we guesstimate which use is more common in the kernel
-// and emit suitable execution mode
-fn compute_denorm_information<'input>(
- module: &[Directive<'input>],
-) -> HashMap<ast::MethodName<'input, SpirvWord>, HashMap<u8, (spirv::FPDenormMode, isize)>> {
- let mut denorm_methods = HashMap::new();
- for directive in module {
- match directive {
- Directive::Variable(..) | Directive::Method(Function { body: None, .. }) => {}
- Directive::Method(Function {
- func_decl,
- body: Some(statements),
- ..
- }) => {
- let mut flush_counter = DenormCountMap::new();
- let method_key = (**func_decl).borrow().name;
- for statement in statements {
- match statement {
- Statement::Instruction(inst) => {
- if let Some((flush, width)) = flush_to_zero(inst) {
- denorm_count_map_update(&mut flush_counter, width, flush);
- }
- }
- Statement::LoadVar(..) => {}
- Statement::StoreVar(..) => {}
- Statement::Conditional(_) => {}
- Statement::Conversion(_) => {}
- Statement::Constant(_) => {}
- Statement::RetValue(_, _) => {}
- Statement::Label(_) => {}
- Statement::Variable(_) => {}
- Statement::PtrAccess { .. } => {}
- Statement::VectorRead { .. } => {}
- Statement::VectorWrite { .. } => {}
- Statement::RepackVector(_) => {}
- Statement::FunctionPointer(_) => {}
- }
- }
- denorm_methods.insert(method_key, flush_counter);
- }
- }
- }
- denorm_methods
- .into_iter()
- .map(|(name, v)| {
- let width_to_denorm = v
- .into_iter()
- .map(|(k, flush_over_preserve)| {
- let mode = if flush_over_preserve > 0 {
- spirv::FPDenormMode::FlushToZero
- } else {
- spirv::FPDenormMode::Preserve
- };
- (k, (mode, flush_over_preserve))
- })
- .collect();
- (name, width_to_denorm)
- })
- .collect()
-}
-
-fn flush_to_zero(this: &ast::Instruction<SpirvWord>) -> Option<(bool, u8)> {
- match this {
- ast::Instruction::Ld { .. } => None,
- ast::Instruction::St { .. } => None,
- ast::Instruction::Mov { .. } => None,
- ast::Instruction::Not { .. } => None,
- ast::Instruction::Bra { .. } => None,
- ast::Instruction::Shl { .. } => None,
- ast::Instruction::Shr { .. } => None,
- ast::Instruction::Ret { .. } => None,
- ast::Instruction::Call { .. } => None,
- ast::Instruction::Or { .. } => None,
- ast::Instruction::And { .. } => None,
- ast::Instruction::Cvta { .. } => None,
- ast::Instruction::Selp { .. } => None,
- ast::Instruction::Bar { .. } => None,
- ast::Instruction::Atom { .. } => None,
- ast::Instruction::AtomCas { .. } => None,
- ast::Instruction::Sub {
- data: ast::ArithDetails::Integer(_),
- ..
- } => None,
- ast::Instruction::Add {
- data: ast::ArithDetails::Integer(_),
- ..
- } => None,
- ast::Instruction::Mul {
- data: ast::MulDetails::Integer { .. },
- ..
- } => None,
- ast::Instruction::Mad {
- data: ast::MadDetails::Integer { .. },
- ..
- } => None,
- ast::Instruction::Min {
- data: ast::MinMaxDetails::Signed(_),
- ..
- } => None,
- ast::Instruction::Min {
- data: ast::MinMaxDetails::Unsigned(_),
- ..
- } => None,
- ast::Instruction::Max {
- data: ast::MinMaxDetails::Signed(_),
- ..
- } => None,
- ast::Instruction::Max {
- data: ast::MinMaxDetails::Unsigned(_),
- ..
- } => None,
- ast::Instruction::Cvt {
- data:
- ast::CvtDetails {
- mode:
- ast::CvtMode::ZeroExtend
- | ast::CvtMode::SignExtend
- | ast::CvtMode::Truncate
- | ast::CvtMode::Bitcast
- | ast::CvtMode::SaturateUnsignedToSigned
- | ast::CvtMode::SaturateSignedToUnsigned
- | ast::CvtMode::FPFromSigned(_)
- | ast::CvtMode::FPFromUnsigned(_),
- ..
- },
- ..
- } => None,
- ast::Instruction::Div {
- data: ast::DivDetails::Unsigned(_),
- ..
- } => None,
- ast::Instruction::Div {
- data: ast::DivDetails::Signed(_),
- ..
- } => None,
- ast::Instruction::Clz { .. } => None,
- ast::Instruction::Brev { .. } => None,
- ast::Instruction::Popc { .. } => None,
- ast::Instruction::Xor { .. } => None,
- ast::Instruction::Bfe { .. } => None,
- ast::Instruction::Bfi { .. } => None,
- ast::Instruction::Rem { .. } => None,
- ast::Instruction::Prmt { .. } => None,
- ast::Instruction::Activemask { .. } => None,
- ast::Instruction::Membar { .. } => None,
- ast::Instruction::Sub {
- data: ast::ArithDetails::Float(float_control),
- ..
- }
- | ast::Instruction::Add {
- data: ast::ArithDetails::Float(float_control),
- ..
- }
- | ast::Instruction::Mul {
- data: ast::MulDetails::Float(float_control),
- ..
- }
- | ast::Instruction::Mad {
- data: ast::MadDetails::Float(float_control),
- ..
- } => float_control
- .flush_to_zero
- .map(|ftz| (ftz, float_control.type_.size_of())),
- ast::Instruction::Fma { data, .. } => {
- data.flush_to_zero.map(|ftz| (ftz, data.type_.size_of()))
- }
- ast::Instruction::Setp { data, .. } => {
- data.flush_to_zero.map(|ftz| (ftz, data.type_.size_of()))
- }
- ast::Instruction::SetpBool { data, .. } => data
- .base
- .flush_to_zero
- .map(|ftz| (ftz, data.base.type_.size_of())),
- ast::Instruction::Abs { data, .. }
- | ast::Instruction::Rsqrt { data, .. }
- | ast::Instruction::Neg { data, .. }
- | ast::Instruction::Ex2 { data, .. } => {
- data.flush_to_zero.map(|ftz| (ftz, data.type_.size_of()))
- }
- ast::Instruction::Min {
- data: ast::MinMaxDetails::Float(float_control),
- ..
- }
- | ast::Instruction::Max {
- data: ast::MinMaxDetails::Float(float_control),
- ..
- } => float_control
- .flush_to_zero
- .map(|ftz| (ftz, ast::ScalarType::from(float_control.type_).size_of())),
- ast::Instruction::Sqrt { data, .. } | ast::Instruction::Rcp { data, .. } => {
- data.flush_to_zero.map(|ftz| (ftz, data.type_.size_of()))
- }
- // Modifier .ftz can only be specified when either .dtype or .atype
- // is .f32 and applies only to single precision (.f32) inputs and results.
- ast::Instruction::Cvt {
- data:
- ast::CvtDetails {
- mode:
- ast::CvtMode::FPExtend { flush_to_zero }
- | ast::CvtMode::FPTruncate { flush_to_zero, .. }
- | ast::CvtMode::FPRound { flush_to_zero, .. }
- | ast::CvtMode::SignedFromFP { flush_to_zero, .. }
- | ast::CvtMode::UnsignedFromFP { flush_to_zero, .. },
- ..
- },
- ..
- } => flush_to_zero.map(|ftz| (ftz, 4)),
- ast::Instruction::Div {
- data:
- ast::DivDetails::Float(ast::DivFloatDetails {
- type_,
- flush_to_zero,
- ..
- }),
- ..
- } => flush_to_zero.map(|ftz| (ftz, type_.size_of())),
- ast::Instruction::Sin { data, .. }
- | ast::Instruction::Cos { data, .. }
- | ast::Instruction::Lg2 { data, .. } => {
- Some((data.flush_to_zero, mem::size_of::<f32>() as u8))
- }
- ptx_parser::Instruction::PrmtSlow { .. } => None,
- ptx_parser::Instruction::Trap {} => None,
- }
-}
-
-type DenormCountMap<T> = HashMap<T, isize>;
-
-fn denorm_count_map_update<T: Eq + Hash>(map: &mut DenormCountMap<T>, key: T, value: bool) {
- let num_value = if value { 1 } else { -1 };
- denorm_count_map_update_impl(map, key, num_value);
-}
-
-fn denorm_count_map_update_impl<T: Eq + Hash>(
- map: &mut DenormCountMap<T>,
- key: T,
- num_value: isize,
-) {
- match map.entry(key) {
- hash_map::Entry::Occupied(mut counter) => {
- *(counter.get_mut()) += num_value;
- }
- hash_map::Entry::Vacant(entry) => {
- entry.insert(num_value);
- }
- }
-}
-
-pub(crate) enum Directive2<'input, Instruction, Operand: ast::Operand> {
+enum Directive2<'input, Instruction, Operand: ast::Operand> {
Variable(ast::LinkingDirective, ast::Variable<SpirvWord>),
Method(Function2<'input, Instruction, Operand>),
}
-pub(crate) struct Function2<'input, Instruction, Operand: ast::Operand> {
+struct Function2<'input, Instruction, Operand: ast::Operand> {
pub func_decl: ast::MethodDeclaration<'input, SpirvWord>,
pub globals: Vec<ast::Variable<SpirvWord>>,
pub body: Option<Vec<Statement<Instruction, Operand>>>,
@@ -2039,19 +793,6 @@ impl SpecialRegistersMap2 { self.id_to_reg.get(&id).copied()
}
- fn get_or_add(&mut self, current_id: &mut SpirvWord, reg: PtxSpecialRegister) -> SpirvWord {
- match self.reg_to_id.entry(reg) {
- hash_map::Entry::Occupied(e) => *e.get(),
- hash_map::Entry::Vacant(e) => {
- let numeric_id = SpirvWord(current_id.0);
- current_id.0 += 1;
- e.insert(numeric_id);
- self.id_to_reg.insert(numeric_id, reg);
- numeric_id
- }
- }
- }
-
fn generate_declarations<'a, 'input>(
resolver: &'a mut GlobalStringIdentResolver2<'input>,
) -> impl ExactSizeIterator<
@@ -2139,3 +880,6 @@ fn scalar_to_ptx_name(this: ast::ScalarType) -> &'static str { ast::ScalarType::Pred => "pred",
}
}
+
+type UnconditionalStatement =
+ Statement<ast::Instruction<ast::ParsedOperand<SpirvWord>>, ast::ParsedOperand<SpirvWord>>;
diff --git a/ptx/src/pass/normalize_identifiers.rs b/ptx/src/pass/normalize_identifiers.rs deleted file mode 100644 index b598345..0000000 --- a/ptx/src/pass/normalize_identifiers.rs +++ /dev/null @@ -1,80 +0,0 @@ -use super::*;
-use ptx_parser as ast;
-
-pub(crate) fn run<'input, 'b>(
- id_defs: &mut FnStringIdResolver<'input, 'b>,
- fn_defs: &GlobalFnDeclResolver<'input, 'b>,
- func: Vec<ast::Statement<ast::ParsedOperand<&'input str>>>,
-) -> Result<Vec<NormalizedStatement>, TranslateError> {
- for s in func.iter() {
- match s {
- ast::Statement::Label(id) => {
- id_defs.add_def(*id, None, false);
- }
- _ => (),
- }
- }
- let mut result = Vec::new();
- for s in func {
- expand_map_variables(id_defs, fn_defs, &mut result, s)?;
- }
- Ok(result)
-}
-
-fn expand_map_variables<'a, 'b>(
- id_defs: &mut FnStringIdResolver<'a, 'b>,
- fn_defs: &GlobalFnDeclResolver<'a, 'b>,
- result: &mut Vec<NormalizedStatement>,
- s: ast::Statement<ast::ParsedOperand<&'a str>>,
-) -> Result<(), TranslateError> {
- match s {
- ast::Statement::Block(block) => {
- id_defs.start_block();
- for s in block {
- expand_map_variables(id_defs, fn_defs, result, s)?;
- }
- id_defs.end_block();
- }
- ast::Statement::Label(name) => result.push(Statement::Label(id_defs.get_id(name)?)),
- ast::Statement::Instruction(p, i) => result.push(Statement::Instruction((
- p.map(|p| pred_map_variable(p, &mut |id| id_defs.get_id(id)))
- .transpose()?,
- ast::visit_map(i, &mut |id,
- _: Option<(&ast::Type, ast::StateSpace)>,
- _: bool,
- _: bool| {
- id_defs.get_id(id)
- })?,
- ))),
- ast::Statement::Variable(var) => {
- let var_type = var.var.v_type.clone();
- match var.count {
- Some(count) => {
- for new_id in
- id_defs.add_defs(var.var.name, count, var_type, var.var.state_space, true)
- {
- result.push(Statement::Variable(ast::Variable {
- align: var.var.align,
- v_type: var.var.v_type.clone(),
- state_space: var.var.state_space,
- name: new_id,
- array_init: var.var.array_init.clone(),
- }))
- }
- }
- None => {
- let new_id =
- id_defs.add_def(var.var.name, Some((var_type, var.var.state_space)), true);
- result.push(Statement::Variable(ast::Variable {
- align: var.var.align,
- v_type: var.var.v_type.clone(),
- state_space: var.var.state_space,
- name: new_id,
- array_init: var.var.array_init,
- }));
- }
- }
- }
- };
- Ok(())
-}
diff --git a/ptx/src/pass/normalize_identifiers2.rs b/ptx/src/pass/normalize_identifiers2.rs index ae90e64..5155886 100644 --- a/ptx/src/pass/normalize_identifiers2.rs +++ b/ptx/src/pass/normalize_identifiers2.rs @@ -1,6 +1,5 @@ use super::*;
use ptx_parser as ast;
-use rustc_hash::FxHashMap;
pub(crate) fn run<'input, 'b>(
resolver: &mut ScopedResolver<'input, 'b>,
diff --git a/ptx/src/pass/normalize_labels.rs b/ptx/src/pass/normalize_labels.rs deleted file mode 100644 index 13295d8..0000000 --- a/ptx/src/pass/normalize_labels.rs +++ /dev/null @@ -1,50 +0,0 @@ -use std::{collections::HashSet, iter};
-
-use super::*;
-
-pub(super) fn run(
- func: Vec<ExpandedStatement>,
- id_def: &mut NumericIdResolver,
-) -> Vec<ExpandedStatement> {
- let mut labels_in_use = HashSet::new();
- for s in func.iter() {
- match s {
- Statement::Instruction(i) => {
- if let Some(target) = jump_target(i) {
- labels_in_use.insert(target);
- }
- }
- Statement::Conditional(cond) => {
- labels_in_use.insert(cond.if_true);
- labels_in_use.insert(cond.if_false);
- }
- Statement::Variable(..)
- | Statement::LoadVar(..)
- | Statement::StoreVar(..)
- | Statement::RetValue(..)
- | Statement::Conversion(..)
- | Statement::Constant(..)
- | Statement::Label(..)
- | Statement::PtrAccess { .. }
- | Statement::VectorRead { .. }
- | Statement::VectorWrite { .. }
- | Statement::RepackVector(..)
- | Statement::FunctionPointer(..) => {}
- }
- }
- iter::once(Statement::Label(id_def.register_intermediate(None)))
- .chain(func.into_iter().filter(|s| match s {
- Statement::Label(i) => labels_in_use.contains(i),
- _ => true,
- }))
- .collect::<Vec<_>>()
-}
-
-fn jump_target<T: ast::Operand<Ident = SpirvWord>>(
- this: &ast::Instruction<T>,
-) -> Option<SpirvWord> {
- match this {
- ast::Instruction::Bra { arguments } => Some(arguments.src),
- _ => None,
- }
-}
diff --git a/ptx/src/pass/normalize_predicates.rs b/ptx/src/pass/normalize_predicates.rs deleted file mode 100644 index c971cfa..0000000 --- a/ptx/src/pass/normalize_predicates.rs +++ /dev/null @@ -1,44 +0,0 @@ -use super::*;
-use ptx_parser as ast;
-
-pub(crate) fn run(
- func: Vec<NormalizedStatement>,
- id_def: &mut NumericIdResolver,
-) -> Result<Vec<UnconditionalStatement>, TranslateError> {
- let mut result = Vec::with_capacity(func.len());
- for s in func {
- match s {
- Statement::Label(id) => result.push(Statement::Label(id)),
- Statement::Instruction((pred, inst)) => {
- if let Some(pred) = pred {
- let if_true = id_def.register_intermediate(None);
- let if_false = id_def.register_intermediate(None);
- let folded_bra = match &inst {
- ast::Instruction::Bra { arguments, .. } => Some(arguments.src),
- _ => None,
- };
- let mut branch = BrachCondition {
- predicate: pred.label,
- if_true: folded_bra.unwrap_or(if_true),
- if_false,
- };
- if pred.not {
- std::mem::swap(&mut branch.if_true, &mut branch.if_false);
- }
- result.push(Statement::Conditional(branch));
- if folded_bra.is_none() {
- result.push(Statement::Label(if_true));
- result.push(Statement::Instruction(inst));
- }
- result.push(Statement::Label(if_false));
- } else {
- result.push(Statement::Instruction(inst));
- }
- }
- Statement::Variable(var) => result.push(Statement::Variable(var)),
- // Blocks are flattened when resolving ids
- _ => return Err(error_unreachable()),
- }
- }
- Ok(result)
-}
diff --git a/ptx/src/ptx.lalrpop b/ptx/src/ptx.lalrpop deleted file mode 100644 index e3a4022..0000000 --- a/ptx/src/ptx.lalrpop +++ /dev/null @@ -1,2198 +0,0 @@ -use crate::ast; -use crate::ast::UnwrapWithVec; -use crate::{without_none, vector_index}; - -use lalrpop_util::ParseError; -use std::convert::TryInto; - -grammar<'err>(errors: &'err mut Vec<ParseError<usize, Token<'input>, ast::PtxError>>); - -extern { - type Error = ast::PtxError; -} - -match { - r"\s+" => { }, - r"//[^\n\r]*[\n\r]*" => { }, - r"/\*[^*]*\*+(?:[^/*][^*]*\*+)*/" => { }, - r"0[fF][0-9a-zA-Z]{8}" => F32NumToken, - r"0[dD][0-9a-zA-Z]{16}" => F64NumToken, - r"0[xX][0-9a-zA-Z]+U?" => HexNumToken, - r"[0-9]+U?" => DecimalNumToken, - r#""[^"]*""# => String, - r"[0-9]+\.[0-9]+" => VersionNumber, - "!", - "(", ")", - "+", - "-", - ",", - ".", - ":", - ";", - "@", - "[", "]", - "{", "}", - "<", ">", - "|", - "=", - ".acq_rel", - ".acquire", - ".add", - ".address_size", - ".align", - ".aligned", - ".and", - ".approx", - ".b16", - ".b32", - ".b64", - ".b8", - ".ca", - ".cas", - ".cg", - ".const", - ".cs", - ".cta", - ".cv", - ".dec", - ".entry", - ".eq", - ".equ", - ".exch", - ".extern", - ".f16", - ".f16x2", - ".f32", - ".f64", - ".file", - ".ftz", - ".full", - ".func", - ".ge", - ".geu", - ".gl", - ".global", - ".gpu", - ".gt", - ".gtu", - ".hi", - ".hs", - ".inc", - ".le", - ".leu", - ".lo", - ".loc", - ".local", - ".ls", - ".lt", - ".ltu", - ".lu", - ".max", - ".maxnreg", - ".maxntid", - ".minnctapersm", - ".min", - ".nan", - ".NaN", - ".nc", - ".ne", - ".neu", - ".num", - ".or", - ".param", - ".pragma", - ".pred", - ".reg", - ".relaxed", - ".release", - ".reqntid", - ".rm", - ".rmi", - ".rn", - ".rni", - ".rp", - ".rpi", - ".rz", - ".rzi", - ".s16", - ".s32", - ".s64", - ".s8" , - ".sat", - ".section", - ".shared", - ".sync", - ".sys", - ".target", - ".to", - ".u16", - ".u32", - ".u64", - ".u8" , - ".uni", - ".v2", - ".v4", - ".version", - ".visible", - ".volatile", - ".wb", - ".weak", - ".wide", - ".wt", - ".xor", -} else { - // IF YOU ARE ADDING A NEW TOKEN HERE ALSO ADD IT BELOW TO ExtendedID - "abs", - "activemask", - "add", - "and", - "atom", - "bar", - "barrier", - "bfe", - "bfi", - "bra", - "brev", - "call", - "clz", - "cos", - "cvt", - "cvta", - "debug", - "div", - "ex2", - "fma", - "ld", - "lg2", - "mad", - "map_f64_to_f32", - "max", - "membar", - "min", - "mov", - "mul", - "neg", - "not", - "or", - "popc", - "prmt", - "rcp", - "rem", - "ret", - "rsqrt", - "selp", - "setp", - "shl", - "shr", - "sin", - r"sm_[0-9]+" => ShaderModel, - "sqrt", - "st", - "sub", - "texmode_independent", - "texmode_unified", - "xor", -} else { - // https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#identifiers - r"[a-zA-Z][a-zA-Z0-9_$]*|[_$%][a-zA-Z0-9_$]+" => ID, - r"\.[a-zA-Z][a-zA-Z0-9_$]*" => DotID, -} - -ExtendedID : &'input str = { - "abs", - "activemask", - "add", - "and", - "atom", - "bar", - "barrier", - "bfe", - "bfi", - "bra", - "brev", - "call", - "clz", - "cos", - "cvt", - "cvta", - "debug", - "div", - "ex2", - "fma", - "ld", - "lg2", - "mad", - "map_f64_to_f32", - "max", - "membar", - "min", - "mov", - "mul", - "neg", - "not", - "or", - "popc", - "prmt", - "rcp", - "rem", - "ret", - "rsqrt", - "selp", - "setp", - "shl", - "shr", - "sin", - ShaderModel, - "sqrt", - "st", - "sub", - "texmode_independent", - "texmode_unified", - "xor", - ID -} - -NumToken: (&'input str, u32, bool) = { - <s:HexNumToken> => { - if s.ends_with('U') { - (&s[2..s.len() - 1], 16, true) - } else { - (&s[2..], 16, false) - } - }, - <s:DecimalNumToken> => { - let radix = if s.starts_with('0') { 8 } else { 10 }; - if s.ends_with('U') { - (&s[..s.len() - 1], radix, true) - } else { - (s, radix, false) - } - } -} - -F32Num: f32 = { - <s:F32NumToken> => { - match u32::from_str_radix(&s[2..], 16) { - Ok(x) => unsafe { std::mem::transmute::<_, f32>(x) }, - Err(err) => { - errors.push(ParseError::User { error: ast::PtxError::from(err) }); - 0.0 - } - } - - } -} - -F64Num: f64 = { - <s:F64NumToken> => { - match u64::from_str_radix(&s[2..], 16) { - Ok(x) => unsafe { std::mem::transmute::<_, f64>(x) }, - Err(err) => { - errors.push(ParseError::User { error: ast::PtxError::from(err) }); - 0.0 - } - } - } -} - -U8Num: u8 = { - <x:NumToken> => { - let (text, radix, _) = x; - match u8::from_str_radix(text, radix) { - Ok(x) => x, - Err(err) => { - errors.push(ParseError::User { error: ast::PtxError::from(err) }); - 0 - } - } - } -} - -U16Num: u16 = { - <x:NumToken> => { - let (text, radix, _) = x; - match u16::from_str_radix(text, radix) { - Ok(x) => x, - Err(err) => { - errors.push(ParseError::User { error: ast::PtxError::from(err) }); - 0 - } - } - } -} - -U32Num: u32 = { - <x:NumToken> => { - let (text, radix, _) = x; - match u32::from_str_radix(text, radix) { - Ok(x) => x, - Err(err) => { - errors.push(ParseError::User { error: ast::PtxError::from(err) }); - 0 - } - } - } -} - -// TODO: handle negative number properly -S32Num: i32 = { - <sign:"-"?> <x:NumToken> => { - let (text, radix, _) = x; - match i32::from_str_radix(text, radix) { - Ok(x) => if sign.is_some() { -x } else { x }, - Err(err) => { - errors.push(ParseError::User { error: ast::PtxError::from(err) }); - 0 - } - } - } -} - -pub Module: ast::Module<'input> = { - <v:Version> Target <d:Directive*> => { - ast::Module { version: v, directives: without_none(d) } - } -}; - -Version: (u8, u8) = { - ".version" <v:VersionNumber> => { - let dot = v.find('.').unwrap(); - let major = v[..dot].parse::<u8>().unwrap_or_else(|err| { - errors.push(ParseError::User { error: ast::PtxError::from(err) }); - 0 - }); - let minor = v[dot+1..].parse::<u8>().unwrap_or_else(|err| { - errors.push(ParseError::User { error: ast::PtxError::from(err) }); - 0 - }); - (major,minor) - } -} - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#ptx-module-directives-target -Target = { - ".target" Comma<TargetSpecifier> -}; - -TargetSpecifier = { - ShaderModel, - "texmode_unified", - "texmode_independent", - "debug", - "map_f64_to_f32" -}; - -Directive: Option<ast::Directive<'input, ast::ParsedArgParams<'input>>> = { - AddressSize => None, - <f:Function> => { - let (linking, func) = f; - Some(ast::Directive::Method(linking, func)) - }, - File => None, - Section => None, - <v:ModuleVariable> ";" => { - let (linking, var) = v; - Some(ast::Directive::Variable(linking, var)) - }, - @L ! @R => { - let (start, _, end)= (<>); - errors.push(ParseError::User { error: - ast::PtxError::UnrecognizedDirective { start, end } - }); - None - } -}; - -AddressSize = { - ".address_size" U8Num -}; - -Function: (ast::LinkingDirective, ast::Function<'input, &'input str, ast::Statement<ast::ParsedArgParams<'input>>>) = { - <linking:LinkingDirectives> - <func_directive:MethodDeclaration> - <tuning:TuningDirective*> - <body:FunctionBody> => { - (linking, ast::Function{func_directive, tuning, body}) - } -}; - -LinkingDirective: ast::LinkingDirective = { - ".extern" => ast::LinkingDirective::EXTERN, - ".visible" => ast::LinkingDirective::VISIBLE, - ".weak" => ast::LinkingDirective::WEAK, -}; - -TuningDirective: ast::TuningDirective = { - ".maxnreg" <ncta:U32Num> => ast::TuningDirective::MaxNReg(ncta), - ".maxntid" <nx:U32Num> => ast::TuningDirective::MaxNtid(nx, 1, 1), - ".maxntid" <nx:U32Num> "," <ny:U32Num> => ast::TuningDirective::MaxNtid(nx, ny, 1), - ".maxntid" <nx:U32Num> "," <ny:U32Num> "," <nz:U32Num> => ast::TuningDirective::MaxNtid(nx, ny, nz), - ".reqntid" <nx:U32Num> => ast::TuningDirective::ReqNtid(nx, 1, 1), - ".reqntid" <nx:U32Num> "," <ny:U32Num> => ast::TuningDirective::ReqNtid(nx, ny, 1), - ".reqntid" <nx:U32Num> "," <ny:U32Num> "," <nz:U32Num> => ast::TuningDirective::ReqNtid(nx, ny, nz), - ".minnctapersm" <ncta:U32Num> => ast::TuningDirective::MinNCtaPerSm(ncta), -}; - -LinkingDirectives: ast::LinkingDirective = { - <ldirs:LinkingDirective*> => { - ldirs.into_iter().fold(ast::LinkingDirective::NONE, |x, y| x | y) - } -} - -MethodDeclaration: ast::MethodDeclaration<'input, &'input str> = { - ".entry" <name:ExtendedID> <input_arguments:KernelArguments> => { - let return_arguments = Vec::new(); - let name = ast::MethodName::Kernel(name); - ast::MethodDeclaration{ return_arguments, name, input_arguments, shared_mem: None } - }, - ".func" <return_arguments:FnArguments?> <name:ExtendedID> <input_arguments:FnArguments> => { - let return_arguments = return_arguments.unwrap_or_else(|| Vec::new()); - let name = ast::MethodName::Func(name); - ast::MethodDeclaration{ return_arguments, name, input_arguments, shared_mem: None } - } -}; - -KernelArguments: Vec<ast::Variable<&'input str>> = { - "(" <args:Comma<KernelInput>> ")" => args -}; - -FnArguments: Vec<ast::Variable<&'input str>> = { - "(" <args:Comma<FnInput>> ")" => args -}; - -KernelInput: ast::Variable<&'input str> = { - <v:ParamDeclaration> => { - let (align, v_type, name) = v; - ast::Variable { - align, - v_type, - state_space: ast::StateSpace::Param, - name, - array_init: Vec::new() - } - } -} - -FnInput: ast::Variable<&'input str> = { - <v:RegVariable> => { - let (align, v_type, name) = v; - let state_space = ast::StateSpace::Reg; - ast::Variable{ align, v_type, state_space, name, array_init: Vec::new() } - }, - <v:ParamDeclaration> => { - let (align, v_type, name) = v; - let state_space = ast::StateSpace::Param; - ast::Variable{ align, v_type, state_space, name, array_init: Vec::new() } - } -} - -FunctionBody: Option<Vec<ast::Statement<ast::ParsedArgParams<'input>>>> = { - "{" <s:Statement*> "}" => { Some(without_none(s)) }, - ";" => { None } -}; - -StateSpaceSpecifier: ast::StateSpace = { - ".reg" => ast::StateSpace::Reg, - ".const" => ast::StateSpace::Const, - ".global" => ast::StateSpace::Global, - ".local" => ast::StateSpace::Local, - ".shared" => ast::StateSpace::Shared, - ".param" => ast::StateSpace::Param, // used to prepare function call -}; - -#[inline] -ScalarType: ast::ScalarType = { - ".f16" => ast::ScalarType::F16, - ".f16x2" => ast::ScalarType::F16x2, - ".pred" => ast::ScalarType::Pred, - ".b8" => ast::ScalarType::B8, - ".b16" => ast::ScalarType::B16, - ".b32" => ast::ScalarType::B32, - ".b64" => ast::ScalarType::B64, - ".u8" => ast::ScalarType::U8, - ".u16" => ast::ScalarType::U16, - ".u32" => ast::ScalarType::U32, - ".u64" => ast::ScalarType::U64, - ".s8" => ast::ScalarType::S8, - ".s16" => ast::ScalarType::S16, - ".s32" => ast::ScalarType::S32, - ".s64" => ast::ScalarType::S64, - ".f32" => ast::ScalarType::F32, - ".f64" => ast::ScalarType::F64, -}; - -Statement: Option<ast::Statement<ast::ParsedArgParams<'input>>> = { - <l:Label> => Some(ast::Statement::Label(l)), - DebugDirective => None, - <v:MultiVariable> ";" => Some(ast::Statement::Variable(v)), - <p:PredAt?> <i:Instruction> ";" => Some(ast::Statement::Instruction(p, i)), - PragmaStatement => None, - "{" <s:Statement*> "}" => Some(ast::Statement::Block(without_none(s))), - @L ! ";" @R => { - let (start, _, _, end) = (<>); - errors.push(ParseError::User { error: - ast::PtxError::UnrecognizedStatement { start, end } - }); - None - } -}; - -PragmaStatement: () = { - ".pragma" String ";" -} - -DebugDirective: () = { - DebugLocation -}; - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#debugging-directives-loc -DebugLocation = { - ".loc" U32Num U32Num U32Num -}; - -Label: &'input str = { - <id:ExtendedID> ":" => id -}; - -Align: u32 = { - ".align" <x:U32Num> => x -}; - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#parameterized-variable-names -MultiVariable: ast::MultiVariable<&'input str> = { - <var:Variable> <count:VariableParam?> => ast::MultiVariable{<>} -} - -VariableParam: u32 = { - "<" <n:U32Num> ">" => n -} - -Variable: ast::Variable<&'input str> = { - <v:RegVariable> => { - let (align, v_type, name) = v; - let state_space = ast::StateSpace::Reg; - ast::Variable {align, v_type, state_space, name, array_init: Vec::new()} - }, - LocalVariable, - <v:ParamVariable> => { - let (align, array_init, v_type, name) = v; - let state_space = ast::StateSpace::Param; - ast::Variable {align, v_type, state_space, name, array_init} - }, - SharedVariable, -}; - -RegVariable: (Option<u32>, ast::Type, &'input str) = { - ".reg" <var:VariableScalar<ScalarType>> => { - let (align, t, name) = var; - let v_type = ast::Type::Scalar(t); - (align, v_type, name) - }, - ".reg" <var:VariableVector<SizedScalarType>> => { - let (align, v_len, t, name) = var; - let v_type = ast::Type::Vector(t, v_len); - (align, v_type, name) - } -} - -LocalVariable: ast::Variable<&'input str> = { - ".local" <var:VariableScalar<SizedScalarType>> => { - let (align, t, name) = var; - let v_type = ast::Type::Scalar(t); - let state_space = ast::StateSpace::Local; - ast::Variable { align, v_type, state_space, name, array_init: Vec::new() } - }, - ".local" <var:VariableVector<SizedScalarType>> => { - let (align, v_len, t, name) = var; - let v_type = ast::Type::Vector(t, v_len); - let state_space = ast::StateSpace::Local; - ast::Variable { align, v_type, state_space, name, array_init: Vec::new() } - }, - ".local" <var:VariableArrayOrPointer<SizedScalarType>> => { - let (align, t, name, arr_or_ptr) = var; - let state_space = ast::StateSpace::Local; - let (v_type, array_init) = match arr_or_ptr { - ast::ArrayOrPointer::Array { dimensions, init } => { - (ast::Type::Array(t, dimensions), init) - } - ast::ArrayOrPointer::Pointer => { - errors.push(ParseError::User { error: ast::PtxError::ZeroDimensionArray }); - (ast::Type::Array(t, Vec::new()), Vec::new()) - } - }; - ast::Variable { align, v_type, state_space, name, array_init } - } -} - -SharedVariable: ast::Variable<&'input str> = { - ".shared" <var:VariableScalar<SizedScalarType>> => { - let (align, t, name) = var; - let state_space = ast::StateSpace::Shared; - let v_type = ast::Type::Scalar(t); - ast::Variable { align, v_type, state_space, name, array_init: Vec::new() } - }, - ".shared" <var:VariableVector<SizedScalarType>> => { - let (align, v_len, t, name) = var; - let state_space = ast::StateSpace::Shared; - let v_type = ast::Type::Vector(t, v_len); - ast::Variable { align, v_type, state_space, name, array_init: Vec::new() } - }, - ".shared" <var:VariableArrayOrPointer<SizedScalarType>> => { - let (align, t, name, arr_or_ptr) = var; - let state_space = ast::StateSpace::Shared; - let (v_type, array_init) = match arr_or_ptr { - ast::ArrayOrPointer::Array { dimensions, init } => { - (ast::Type::Array(t, dimensions), init) - } - ast::ArrayOrPointer::Pointer => { - errors.push(ParseError::User { error: ast::PtxError::ZeroDimensionArray }); - (ast::Type::Array(t, Vec::new()), Vec::new()) - } - }; - ast::Variable { align, v_type, state_space, name, array_init } - } -} - -ModuleVariable: (ast::LinkingDirective, ast::Variable<&'input str>) = { - <linking:LinkingDirectives> <state_space:VariableStateSpace> <def:GlobalVariableDefinitionNoArray> => { - let (align, v_type, name, array_init) = def; - (linking, ast::Variable { align, v_type, state_space, name, array_init }) - }, - <linking:LinkingDirectives> <space:VariableStateSpace> <var:VariableArrayOrPointer<SizedScalarType>> => { - let (align, t, name, arr_or_ptr) = var; - let (v_type, state_space, array_init) = match arr_or_ptr { - ast::ArrayOrPointer::Array { dimensions, init } => { - (ast::Type::Array(t, dimensions), space, init) - } - ast::ArrayOrPointer::Pointer => { - if !linking.contains(ast::LinkingDirective::EXTERN) { - errors.push(ParseError::User { error: ast::PtxError::NonExternPointer }); - } - (ast::Type::Array(t, Vec::new()), space, Vec::new()) - } - }; - (linking, ast::Variable{ align, v_type, state_space, name, array_init }) - } -} - -VariableStateSpace: ast::StateSpace = { - ".const" => ast::StateSpace::Const, - ".global" => ast::StateSpace::Global, - ".shared" => ast::StateSpace::Shared, -}; - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#parameter-state-space -ParamVariable: (Option<u32>, Vec<u8>, ast::Type, &'input str) = { - ".param" <var:VariableScalar<LdStScalarType>> => { - let (align, t, name) = var; - let v_type = ast::Type::Scalar(t); - (align, Vec::new(), v_type, name) - }, - ".param" <var:VariableArrayOrPointer<SizedScalarType>> => { - let (align, t, name, arr_or_ptr) = var; - let (v_type, array_init) = match arr_or_ptr { - ast::ArrayOrPointer::Array { dimensions, init } => { - (ast::Type::Array(t, dimensions), init) - } - ast::ArrayOrPointer::Pointer => { - (ast::Type::Scalar(t), Vec::new()) - } - }; - (align, array_init, v_type, name) - } -} - -ParamDeclaration: (Option<u32>, ast::Type, &'input str) = { - <var:ParamVariable> => { - let (align, array_init, v_type, name) = var; - if array_init.len() > 0 { - errors.push(ParseError::User { error: ast::PtxError::ArrayInitalizer }); - } - (align, v_type, name) - } -} - -GlobalVariableDefinitionNoArray: (Option<u32>, ast::Type, &'input str, Vec<u8>) = { - <scalar:VariableScalar<SizedScalarType>> => { - let (align, t, name) = scalar; - let v_type = ast::Type::Scalar(t); - (align, v_type, name, Vec::new()) - }, - <var:VariableVector<SizedScalarType>> => { - let (align, v_len, t, name) = var; - let v_type = ast::Type::Vector(t, v_len); - (align, v_type, name, Vec::new()) - }, -} - -#[inline] -SizedScalarType: ast::ScalarType = { - ".b8" => ast::ScalarType::B8, - ".b16" => ast::ScalarType::B16, - ".b32" => ast::ScalarType::B32, - ".b64" => ast::ScalarType::B64, - ".u8" => ast::ScalarType::U8, - ".u16" => ast::ScalarType::U16, - ".u32" => ast::ScalarType::U32, - ".u64" => ast::ScalarType::U64, - ".s8" => ast::ScalarType::S8, - ".s16" => ast::ScalarType::S16, - ".s32" => ast::ScalarType::S32, - ".s64" => ast::ScalarType::S64, - ".f16" => ast::ScalarType::F16, - ".f16x2" => ast::ScalarType::F16x2, - ".f32" => ast::ScalarType::F32, - ".f64" => ast::ScalarType::F64, -} - -#[inline] -LdStScalarType: ast::ScalarType = { - ".b8" => ast::ScalarType::B8, - ".b16" => ast::ScalarType::B16, - ".b32" => ast::ScalarType::B32, - ".b64" => ast::ScalarType::B64, - ".u8" => ast::ScalarType::U8, - ".u16" => ast::ScalarType::U16, - ".u32" => ast::ScalarType::U32, - ".u64" => ast::ScalarType::U64, - ".s8" => ast::ScalarType::S8, - ".s16" => ast::ScalarType::S16, - ".s32" => ast::ScalarType::S32, - ".s64" => ast::ScalarType::S64, - ".f16" => ast::ScalarType::F16, - ".f32" => ast::ScalarType::F32, - ".f64" => ast::ScalarType::F64, -} - -Instruction: ast::Instruction<ast::ParsedArgParams<'input>> = { - InstLd, - InstMov, - InstMul, - InstAdd, - InstSetp, - InstNot, - InstBra, - InstCvt, - InstShl, - InstShr, - InstSt, - InstRet, - InstCvta, - InstCall, - InstAbs, - InstMad, - InstFma, - InstOr, - InstAnd, - InstSub, - InstMin, - InstMax, - InstRcp, - InstSelp, - InstBar, - InstAtom, - InstAtomCas, - InstDiv, - InstSqrt, - InstRsqrt, - InstNeg, - InstSin, - InstCos, - InstLg2, - InstEx2, - InstClz, - InstBrev, - InstPopc, - InstXor, - InstRem, - InstBfe, - InstBfi, - InstPrmt, - InstActivemask, - InstMembar, -}; - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-ld -InstLd: ast::Instruction<ast::ParsedArgParams<'input>> = { - "ld" <q:LdStQualifier?> <ss:LdNonGlobalStateSpace?> <cop:LdCacheOperator?> <t:LdStType> <dst:DstOperandVec> "," <src:MemoryOperand> => { - ast::Instruction::Ld( - ast::LdDetails { - qualifier: q.unwrap_or(ast::LdStQualifier::Weak), - state_space: ss.unwrap_or(ast::StateSpace::Generic), - caching: cop.unwrap_or(ast::LdCacheOperator::Cached), - typ: t, - non_coherent: false - }, - ast::Arg2Ld { dst:dst, src:src } - ) - }, - "ld" <q:LdStQualifier?> ".global" <cop:LdCacheOperator?> <t:LdStType> <dst:DstOperandVec> "," <src:MemoryOperand> => { - ast::Instruction::Ld( - ast::LdDetails { - qualifier: q.unwrap_or(ast::LdStQualifier::Weak), - state_space: ast::StateSpace::Global, - caching: cop.unwrap_or(ast::LdCacheOperator::Cached), - typ: t, - non_coherent: false - }, - ast::Arg2Ld { dst:dst, src:src } - ) - }, - "ld" ".global" <cop:LdNcCacheOperator?> ".nc" <t:LdStType> <dst:DstOperandVec> "," <src:MemoryOperand> => { - ast::Instruction::Ld( - ast::LdDetails { - qualifier: ast::LdStQualifier::Weak, - state_space: ast::StateSpace::Global, - caching: cop.unwrap_or(ast::LdCacheOperator::Cached), - typ: t, - non_coherent: true - }, - ast::Arg2Ld { dst:dst, src:src } - ) - } -}; - -LdStType: ast::Type = { - <v:VectorPrefix> <t:LdStScalarType> => ast::Type::Vector(t, v), - <t:LdStScalarType> => ast::Type::Scalar(t), -} - -LdStQualifier: ast::LdStQualifier = { - ".weak" => ast::LdStQualifier::Weak, - ".volatile" => ast::LdStQualifier::Volatile, - ".relaxed" <s:MemScope> => ast::LdStQualifier::Relaxed(s), - ".acquire" <s:MemScope> => ast::LdStQualifier::Acquire(s), -}; - -MemScope: ast::MemScope = { - ".cta" => ast::MemScope::Cta, - ".gpu" => ast::MemScope::Gpu, - ".sys" => ast::MemScope::Sys -}; - -MembarLevel: ast::MemScope = { - ".cta" => ast::MemScope::Cta, - ".gl" => ast::MemScope::Gpu, - ".sys" => ast::MemScope::Sys -}; - -LdNonGlobalStateSpace: ast::StateSpace = { - ".const" => ast::StateSpace::Const, - ".local" => ast::StateSpace::Local, - ".param" => ast::StateSpace::Param, - ".shared" => ast::StateSpace::Shared, -}; - -LdCacheOperator: ast::LdCacheOperator = { - ".ca" => ast::LdCacheOperator::Cached, - ".cg" => ast::LdCacheOperator::L2Only, - ".cs" => ast::LdCacheOperator::Streaming, - ".lu" => ast::LdCacheOperator::LastUse, - ".cv" => ast::LdCacheOperator::Uncached, -}; - -LdNcCacheOperator: ast::LdCacheOperator = { - ".ca" => ast::LdCacheOperator::Cached, - ".cg" => ast::LdCacheOperator::L2Only, - ".cs" => ast::LdCacheOperator::Streaming, -}; - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-mov -InstMov: ast::Instruction<ast::ParsedArgParams<'input>> = { - "mov" <pref:VectorPrefix?> <t:MovScalarType> <dst:DstOperandVec> "," <src:SrcOperandVec> => { - let mov_type = match pref { - Some(vec_width) => ast::Type::Vector(t, vec_width), - None => ast::Type::Scalar(t) - }; - let details = ast::MovDetails::new(mov_type); - ast::Instruction::Mov( - details, - ast::Arg2Mov { dst, src } - ) - } -} - -#[inline] -MovScalarType: ast::ScalarType = { - ".b16" => ast::ScalarType::B16, - ".b32" => ast::ScalarType::B32, - ".b64" => ast::ScalarType::B64, - ".u16" => ast::ScalarType::U16, - ".u32" => ast::ScalarType::U32, - ".u64" => ast::ScalarType::U64, - ".s16" => ast::ScalarType::S16, - ".s32" => ast::ScalarType::S32, - ".s64" => ast::ScalarType::S64, - ".f32" => ast::ScalarType::F32, - ".f64" => ast::ScalarType::F64, - ".pred" => ast::ScalarType::Pred -}; - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#integer-arithmetic-instructions-mul -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#floating-point-instructions-mul -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#half-precision-floating-point-instructions-mul -InstMul: ast::Instruction<ast::ParsedArgParams<'input>> = { - "mul" <d:MulDetails> <a:Arg3> => ast::Instruction::Mul(d, a) -}; - -MulDetails: ast::MulDetails = { - <ctr:MulIntControl> <t:UIntType> => ast::MulDetails::Unsigned(ast::MulUInt{ - typ: t, - control: ctr - }), - <ctr:MulIntControl> <t:SIntType> => ast::MulDetails::Signed(ast::MulSInt{ - typ: t, - control: ctr - }), - <f:ArithFloat> => ast::MulDetails::Float(f) -}; - -MulIntControl: ast::MulIntControl = { - ".hi" => ast::MulIntControl::High, - ".lo" => ast::MulIntControl::Low, - ".wide" => ast::MulIntControl::Wide -}; - -#[inline] -RoundingModeFloat : ast::RoundingMode = { - ".rn" => ast::RoundingMode::NearestEven, - ".rz" => ast::RoundingMode::Zero, - ".rm" => ast::RoundingMode::NegativeInf, - ".rp" => ast::RoundingMode::PositiveInf, -}; - -RoundingModeInt : ast::RoundingMode = { - ".rni" => ast::RoundingMode::NearestEven, - ".rzi" => ast::RoundingMode::Zero, - ".rmi" => ast::RoundingMode::NegativeInf, - ".rpi" => ast::RoundingMode::PositiveInf, -}; - -IntType : ast::ScalarType = { - ".u16" => ast::ScalarType::U16, - ".u32" => ast::ScalarType::U32, - ".u64" => ast::ScalarType::U64, - ".s16" => ast::ScalarType::S16, - ".s32" => ast::ScalarType::S32, - ".s64" => ast::ScalarType::S64, -}; - -IntType3264: ast::ScalarType = { - ".u32" => ast::ScalarType::U32, - ".u64" => ast::ScalarType::U64, - ".s32" => ast::ScalarType::S32, - ".s64" => ast::ScalarType::S64, -} - -UIntType: ast::ScalarType = { - ".u16" => ast::ScalarType::U16, - ".u32" => ast::ScalarType::U32, - ".u64" => ast::ScalarType::U64, -}; - -SIntType: ast::ScalarType = { - ".s16" => ast::ScalarType::S16, - ".s32" => ast::ScalarType::S32, - ".s64" => ast::ScalarType::S64, -}; - -FloatType: ast::ScalarType = { - ".f16" => ast::ScalarType::F16, - ".f16x2" => ast::ScalarType::F16x2, - ".f32" => ast::ScalarType::F32, - ".f64" => ast::ScalarType::F64, -}; - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#integer-arithmetic-instructions-add -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#floating-point-instructions-add -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#half-precision-floating-point-instructions-add -InstAdd: ast::Instruction<ast::ParsedArgParams<'input>> = { - "add" <d:ArithDetails> <a:Arg3> => ast::Instruction::Add(d, a) -}; - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#comparison-and-selection-instructions-setp -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#half-precision-comparison-instructions-setp -// TODO: support f16 setp -InstSetp: ast::Instruction<ast::ParsedArgParams<'input>> = { - "setp" <d:SetpMode> <a:Arg4Setp> => ast::Instruction::Setp(d, a), - "setp" <d:SetpBoolMode> <a:Arg5Setp> => ast::Instruction::SetpBool(d, a), -}; - -SetpMode: ast::SetpData = { - <cmp_op:SetpCompareOp> <t:SetpTypeNoF32> => ast::SetpData { - typ: t, - flush_to_zero: None, - cmp_op: cmp_op, - }, - <cmp_op:SetpCompareOp> <ftz:".ftz"?> ".f32" => ast::SetpData { - typ: ast::ScalarType::F32, - flush_to_zero: Some(ftz.is_some()), - cmp_op: cmp_op, - } - -}; - -SetpBoolMode: ast::SetpBoolData = { - <cmp_op:SetpCompareOp> <bool_op:SetpBoolPostOp> <t:SetpTypeNoF32> => ast::SetpBoolData { - typ: t, - flush_to_zero: None, - cmp_op: cmp_op, - bool_op: bool_op, - }, - <cmp_op:SetpCompareOp> <bool_op:SetpBoolPostOp> <ftz:".ftz"?> ".f32" => ast::SetpBoolData { - typ: ast::ScalarType::F32, - flush_to_zero: Some(ftz.is_some()), - cmp_op: cmp_op, - bool_op: bool_op, - } -}; - -SetpCompareOp: ast::SetpCompareOp = { - ".eq" => ast::SetpCompareOp::Eq, - ".ne" => ast::SetpCompareOp::NotEq, - ".lt" => ast::SetpCompareOp::Less, - ".le" => ast::SetpCompareOp::LessOrEq, - ".gt" => ast::SetpCompareOp::Greater, - ".ge" => ast::SetpCompareOp::GreaterOrEq, - ".lo" => ast::SetpCompareOp::Less, - ".ls" => ast::SetpCompareOp::LessOrEq, - ".hi" => ast::SetpCompareOp::Greater, - ".hs" => ast::SetpCompareOp::GreaterOrEq, - ".equ" => ast::SetpCompareOp::NanEq, - ".neu" => ast::SetpCompareOp::NanNotEq, - ".ltu" => ast::SetpCompareOp::NanLess, - ".leu" => ast::SetpCompareOp::NanLessOrEq, - ".gtu" => ast::SetpCompareOp::NanGreater, - ".geu" => ast::SetpCompareOp::NanGreaterOrEq, - ".num" => ast::SetpCompareOp::IsNotNan, - ".nan" => ast::SetpCompareOp::IsAnyNan, -}; - -SetpBoolPostOp: ast::SetpBoolPostOp = { - ".and" => ast::SetpBoolPostOp::And, - ".or" => ast::SetpBoolPostOp::Or, - ".xor" => ast::SetpBoolPostOp::Xor, -}; - -SetpTypeNoF32: ast::ScalarType = { - ".b16" => ast::ScalarType::B16, - ".b32" => ast::ScalarType::B32, - ".b64" => ast::ScalarType::B64, - ".u16" => ast::ScalarType::U16, - ".u32" => ast::ScalarType::U32, - ".u64" => ast::ScalarType::U64, - ".s16" => ast::ScalarType::S16, - ".s32" => ast::ScalarType::S32, - ".s64" => ast::ScalarType::S64, - ".f64" => ast::ScalarType::F64, -}; - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#logic-and-shift-instructions-not -InstNot: ast::Instruction<ast::ParsedArgParams<'input>> = { - "not" <t:BooleanType> <a:Arg2> => ast::Instruction::Not(t, a) -}; - -BooleanType: ast::ScalarType = { - ".pred" => ast::ScalarType::Pred, - ".b16" => ast::ScalarType::B16, - ".b32" => ast::ScalarType::B32, - ".b64" => ast::ScalarType::B64, -}; - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#control-flow-instructions-at -PredAt: ast::PredAt<&'input str> = { - "@" <label:ExtendedID> => ast::PredAt { not: false, label:label }, - "@" "!" <label:ExtendedID> => ast::PredAt { not: true, label:label } -}; - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#control-flow-instructions-bra -InstBra: ast::Instruction<ast::ParsedArgParams<'input>> = { - "bra" <u:".uni"?> <a:Arg1> => ast::Instruction::Bra(ast::BraData{ uniform: u.is_some() }, a) -}; - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-cvt -InstCvt: ast::Instruction<ast::ParsedArgParams<'input>> = { - "cvt" <s:".sat"?> <dst_t:CvtTypeInt> <src_t:CvtTypeInt> <a:Arg2> => { - ast::Instruction::Cvt(ast::CvtDetails::new_int_from_int_checked( - s.is_some(), - dst_t, - src_t, - errors - ), - a) - }, - "cvt" <r:RoundingModeFloat> <f:".ftz"?> <s:".sat"?> <dst_t:CvtTypeFloat> <src_t:CvtTypeInt> <a:Arg2> => { - ast::Instruction::Cvt(ast::CvtDetails::new_float_from_int_checked( - r, - f.is_some(), - s.is_some(), - dst_t, - src_t, - errors - ), - a) - }, - "cvt" <r:RoundingModeInt> <f:".ftz"?> <s:".sat"?> <dst_t:CvtTypeInt> <src_t:CvtTypeFloat> <a:Arg2> => { - ast::Instruction::Cvt(ast::CvtDetails::new_int_from_float_checked( - r, - f.is_some(), - s.is_some(), - dst_t, - src_t, - errors - ), - a) - }, - "cvt" <r:RoundingModeInt?> <s:".sat"?> ".f16" ".f16" <a:Arg2> => { - ast::Instruction::Cvt(ast::CvtDetails::FloatFromFloat( - ast::CvtDesc { - rounding: r, - flush_to_zero: None, - saturate: s.is_some(), - dst: ast::ScalarType::F16, - src: ast::ScalarType::F16 - } - ), a) - }, - "cvt" <f:".ftz"?> <s:".sat"?> ".f32" ".f16" <a:Arg2> => { - ast::Instruction::Cvt(ast::CvtDetails::FloatFromFloat( - ast::CvtDesc { - rounding: None, - flush_to_zero: Some(f.is_some()), - saturate: s.is_some(), - dst: ast::ScalarType::F32, - src: ast::ScalarType::F16 - } - ), a) - }, - "cvt" <s:".sat"?> ".f64" ".f16" <a:Arg2> => { - ast::Instruction::Cvt(ast::CvtDetails::FloatFromFloat( - ast::CvtDesc { - rounding: None, - flush_to_zero: None, - saturate: s.is_some(), - dst: ast::ScalarType::F64, - src: ast::ScalarType::F16 - } - ), a) - }, - "cvt" <r:RoundingModeFloat> <f:".ftz"?> <s:".sat"?> ".f16" ".f32" <a:Arg2> => { - ast::Instruction::Cvt(ast::CvtDetails::FloatFromFloat( - ast::CvtDesc { - rounding: Some(r), - flush_to_zero: Some(f.is_some()), - saturate: s.is_some(), - dst: ast::ScalarType::F16, - src: ast::ScalarType::F32 - } - ), a) - }, - "cvt" <r:RoundingModeInt?> <f:".ftz"?> <s:".sat"?> ".f32" ".f32" <a:Arg2> => { - ast::Instruction::Cvt(ast::CvtDetails::FloatFromFloat( - ast::CvtDesc { - rounding: r, - flush_to_zero: Some(f.is_some()), - saturate: s.is_some(), - dst: ast::ScalarType::F32, - src: ast::ScalarType::F32 - } - ), a) - }, - "cvt" <s:".sat"?> <f:".ftz"?> ".f64" ".f32" <a:Arg2> => { - ast::Instruction::Cvt(ast::CvtDetails::FloatFromFloat( - ast::CvtDesc { - rounding: None, - flush_to_zero: Some(f.is_some()), - saturate: s.is_some(), - dst: ast::ScalarType::F64, - src: ast::ScalarType::F32 - } - ), a) - }, - "cvt" <r:RoundingModeFloat> <s:".sat"?> ".f16" ".f64" <a:Arg2> => { - ast::Instruction::Cvt(ast::CvtDetails::FloatFromFloat( - ast::CvtDesc { - rounding: Some(r), - flush_to_zero: None, - saturate: s.is_some(), - dst: ast::ScalarType::F16, - src: ast::ScalarType::F64 - } - ), a) - }, - "cvt" <r:RoundingModeFloat> <f:".ftz"?> <s:".sat"?> ".f32" ".f64" <a:Arg2> => { - ast::Instruction::Cvt(ast::CvtDetails::FloatFromFloat( - ast::CvtDesc { - rounding: Some(r), - flush_to_zero: Some(s.is_some()), - saturate: s.is_some(), - dst: ast::ScalarType::F32, - src: ast::ScalarType::F64 - } - ), a) - }, - "cvt" <r:RoundingModeInt?> <s:".sat"?> ".f64" ".f64" <a:Arg2> => { - ast::Instruction::Cvt(ast::CvtDetails::FloatFromFloat( - ast::CvtDesc { - rounding: r, - flush_to_zero: None, - saturate: s.is_some(), - dst: ast::ScalarType::F64, - src: ast::ScalarType::F64 - } - ), a) - }, -}; - -CvtTypeInt: ast::ScalarType = { - ".u8" => ast::ScalarType::U8, - ".u16" => ast::ScalarType::U16, - ".u32" => ast::ScalarType::U32, - ".u64" => ast::ScalarType::U64, - ".s8" => ast::ScalarType::S8, - ".s16" => ast::ScalarType::S16, - ".s32" => ast::ScalarType::S32, - ".s64" => ast::ScalarType::S64, -}; - -CvtTypeFloat: ast::ScalarType = { - ".f16" => ast::ScalarType::F16, - ".f32" => ast::ScalarType::F32, - ".f64" => ast::ScalarType::F64, -}; - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#logic-and-shift-instructions-shl -InstShl: ast::Instruction<ast::ParsedArgParams<'input>> = { - "shl" <t:ShlType> <a:Arg3> => ast::Instruction::Shl(t, a) -}; - -ShlType: ast::ScalarType = { - ".b16" => ast::ScalarType::B16, - ".b32" => ast::ScalarType::B32, - ".b64" => ast::ScalarType::B64, -}; - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#logic-and-shift-instructions-shr -InstShr: ast::Instruction<ast::ParsedArgParams<'input>> = { - "shr" <t:ShrType> <a:Arg3> => ast::Instruction::Shr(t, a) -}; - -ShrType: ast::ScalarType = { - ".b16" => ast::ScalarType::B16, - ".b32" => ast::ScalarType::B32, - ".b64" => ast::ScalarType::B64, - ".u16" => ast::ScalarType::U16, - ".u32" => ast::ScalarType::U32, - ".u64" => ast::ScalarType::U64, - ".s16" => ast::ScalarType::S16, - ".s32" => ast::ScalarType::S32, - ".s64" => ast::ScalarType::S64, -}; - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-st -// Warning: NVIDIA documentation is incorrect, you can specify scope only once -InstSt: ast::Instruction<ast::ParsedArgParams<'input>> = { - "st" <q:LdStQualifier?> <ss:StStateSpace?> <cop:StCacheOperator?> <t:LdStType> <src1:MemoryOperand> "," <src2:SrcOperandVec> => { - ast::Instruction::St( - ast::StData { - qualifier: q.unwrap_or(ast::LdStQualifier::Weak), - state_space: ss.unwrap_or(ast::StateSpace::Generic), - caching: cop.unwrap_or(ast::StCacheOperator::Writeback), - typ: t - }, - ast::Arg2St { src1:src1, src2:src2 } - ) - } -}; - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#using-addresses-arrays-and-vectors -MemoryOperand: ast::Operand<&'input str> = { - "[" <o:Operand> "]" => o -} - -StStateSpace: ast::StateSpace = { - ".global" => ast::StateSpace::Global, - ".local" => ast::StateSpace::Local, - ".param" => ast::StateSpace::Param, - ".shared" => ast::StateSpace::Shared, -}; - -StCacheOperator: ast::StCacheOperator = { - ".wb" => ast::StCacheOperator::Writeback, - ".cg" => ast::StCacheOperator::L2Only, - ".cs" => ast::StCacheOperator::Streaming, - ".wt" => ast::StCacheOperator::Writethrough, -}; - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#control-flow-instructions-ret -InstRet: ast::Instruction<ast::ParsedArgParams<'input>> = { - "ret" <u:".uni"?> => ast::Instruction::Ret(ast::RetData { uniform: u.is_some() }) -}; - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-cvta -InstCvta: ast::Instruction<ast::ParsedArgParams<'input>> = { - "cvta" <from:CvtaStateSpace> <s:CvtaSize> <a:Arg2> => { - ast::Instruction::Cvta(ast::CvtaDetails { - to: ast::StateSpace::Generic, - from, - size: s - }, - a) - }, - "cvta" ".to" <to:CvtaStateSpace> <s:CvtaSize> <a:Arg2> => { - ast::Instruction::Cvta(ast::CvtaDetails { - to, - from: ast::StateSpace::Generic, - size: s - }, - a) - } -} - -CvtaStateSpace: ast::StateSpace = { - ".const" => ast::StateSpace::Const, - ".global" => ast::StateSpace::Global, - ".local" => ast::StateSpace::Local, - ".shared" => ast::StateSpace::Shared, -} - -CvtaSize: ast::CvtaSize = { - ".u32" => ast::CvtaSize::U32, - ".u64" => ast::CvtaSize::U64, -} - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#control-flow-instructions-call -InstCall: ast::Instruction<ast::ParsedArgParams<'input>> = { - "call" <u:".uni"?> <args:ArgCall> => { - let (ret_params, func, param_list) = args; - ast::Instruction::Call(ast::CallInst { uniform: u.is_some(), ret_params, func, param_list }) - } -}; - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#integer-arithmetic-instructions-abs -InstAbs: ast::Instruction<ast::ParsedArgParams<'input>> = { - "abs" <t:SignedIntType> <a:Arg2> => { - ast::Instruction::Abs(ast::AbsDetails { flush_to_zero: None, typ: t }, a) - }, - "abs" <f:".ftz"?> ".f32" <a:Arg2> => { - ast::Instruction::Abs(ast::AbsDetails { flush_to_zero: Some(f.is_some()), typ: ast::ScalarType::F32 }, a) - }, - "abs" ".f64" <a:Arg2> => { - ast::Instruction::Abs(ast::AbsDetails { flush_to_zero: None, typ: ast::ScalarType::F64 }, a) - }, - "abs" <f:".ftz"?> ".f16" <a:Arg2> => { - ast::Instruction::Abs(ast::AbsDetails { flush_to_zero: Some(f.is_some()), typ: ast::ScalarType::F16 }, a) - }, - "abs" <f:".ftz"?> ".f16x2" <a:Arg2> => { - ast::Instruction::Abs(ast::AbsDetails { flush_to_zero: Some(f.is_some()), typ: ast::ScalarType::F16x2 }, a) - }, -}; - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#integer-arithmetic-instructions-mad -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#floating-point-instructions-mad -InstMad: ast::Instruction<ast::ParsedArgParams<'input>> = { - "mad" <d:MulDetails> <a:Arg4> => ast::Instruction::Mad(d, a), - "mad" ".hi" ".sat" ".s32" => todo!(), -}; - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#floating-point-instructions-fma -InstFma: ast::Instruction<ast::ParsedArgParams<'input>> = { - "fma" <f:ArithFloatMustRound> <a:Arg4> => ast::Instruction::Fma(f, a), -}; - -SignedIntType: ast::ScalarType = { - ".s16" => ast::ScalarType::S16, - ".s32" => ast::ScalarType::S32, - ".s64" => ast::ScalarType::S64, -}; - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#logic-and-shift-instructions-or -InstOr: ast::Instruction<ast::ParsedArgParams<'input>> = { - "or" <d:BooleanType> <a:Arg3> => ast::Instruction::Or(d, a), -}; - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#logic-and-shift-instructions-and -InstAnd: ast::Instruction<ast::ParsedArgParams<'input>> = { - "and" <d:BooleanType> <a:Arg3> => ast::Instruction::And(d, a), -}; - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#floating-point-instructions-rcp -InstRcp: ast::Instruction<ast::ParsedArgParams<'input>> = { - "rcp" <rounding:RcpRoundingMode> <ftz:".ftz"?> ".f32" <a:Arg2> => { - let details = ast::RcpDetails { - rounding, - flush_to_zero: Some(ftz.is_some()), - is_f64: false, - }; - ast::Instruction::Rcp(details, a) - }, - "rcp" <rn:RoundingModeFloat> ".f64" <a:Arg2> => { - let details = ast::RcpDetails { - rounding: Some(rn), - flush_to_zero: None, - is_f64: true, - }; - ast::Instruction::Rcp(details, a) - } -}; - -RcpRoundingMode: Option<ast::RoundingMode> = { - ".approx" => None, - <r:RoundingModeFloat> => Some(r) -}; - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#integer-arithmetic-instructions-sub -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#floating-point-instructions-sub -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#half-precision-floating-point-instructions-sub -InstSub: ast::Instruction<ast::ParsedArgParams<'input>> = { - "sub" <d:ArithDetails> <a:Arg3> => ast::Instruction::Sub(d, a), -}; - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#integer-arithmetic-instructions-min -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#floating-point-instructions-min -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#half-precision-floating-point-instructions-min -InstMin: ast::Instruction<ast::ParsedArgParams<'input>> = { - "min" <d:MinMaxDetails> <a:Arg3> => ast::Instruction::Min(d, a), -}; - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#integer-arithmetic-instructions-max -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#floating-point-instructions-max -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#half-precision-floating-point-instructions-max -InstMax: ast::Instruction<ast::ParsedArgParams<'input>> = { - "max" <d:MinMaxDetails> <a:Arg3> => ast::Instruction::Max(d, a), -}; - -MinMaxDetails: ast::MinMaxDetails = { - <t:UIntType> => ast::MinMaxDetails::Unsigned(t), - <t:SIntType> => ast::MinMaxDetails::Signed(t), - <ftz:".ftz"?> <nan:".NaN"?> ".f32" => ast::MinMaxDetails::Float( - ast::MinMaxFloat{ flush_to_zero: Some(ftz.is_some()), nan: nan.is_some(), typ: ast::ScalarType::F32 } - ), - ".f64" => ast::MinMaxDetails::Float( - ast::MinMaxFloat{ flush_to_zero: None, nan: false, typ: ast::ScalarType::F64 } - ), - <ftz:".ftz"?> <nan:".NaN"?> ".f16" => ast::MinMaxDetails::Float( - ast::MinMaxFloat{ flush_to_zero: Some(ftz.is_some()), nan: nan.is_some(), typ: ast::ScalarType::F16 } - ), - <ftz:".ftz"?> <nan:".NaN"?> ".f16x2" => ast::MinMaxDetails::Float( - ast::MinMaxFloat{ flush_to_zero: Some(ftz.is_some()), nan: nan.is_some(), typ: ast::ScalarType::F16x2 } - ) -} - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#comparison-and-selection-instructions-selp -InstSelp: ast::Instruction<ast::ParsedArgParams<'input>> = { - "selp" <t:SelpType> <a:Arg4> => ast::Instruction::Selp(t, a), -}; - -SelpType: ast::ScalarType = { - ".b16" => ast::ScalarType::B16, - ".b32" => ast::ScalarType::B32, - ".b64" => ast::ScalarType::B64, - ".u16" => ast::ScalarType::U16, - ".u32" => ast::ScalarType::U32, - ".u64" => ast::ScalarType::U64, - ".s16" => ast::ScalarType::S16, - ".s32" => ast::ScalarType::S32, - ".s64" => ast::ScalarType::S64, - ".f32" => ast::ScalarType::F32, - ".f64" => ast::ScalarType::F64, -}; - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#parallel-synchronization-and-communication-instructions-bar -InstBar: ast::Instruction<ast::ParsedArgParams<'input>> = { - "bar" ".sync" <a:Arg1Bar> => ast::Instruction::Bar(ast::BarDetails::SyncAligned, a), - "barrier" ".sync" <a:Arg1Bar> => ast::Instruction::Bar(ast::BarDetails::SyncAligned, a), - "barrier" ".sync" ".aligned" <a:Arg1Bar> => ast::Instruction::Bar(ast::BarDetails::SyncAligned, a), -} - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#parallel-synchronization-and-communication-instructions-atom -// The documentation does not mention all spported operations: -// * Operation .add requires .u32 or .s32 or .u64 or .f64 or f16 or f16x2 or .f32 -// * Operation .inc requires .u32 type for instuction -// * Operation .dec requires .u32 type for instuction -// Otherwise as documented -InstAtom: ast::Instruction<ast::ParsedArgParams<'input>> = { - "atom" <sema:AtomSemantics?> <scope:MemScope?> <space:AtomSpace?> <op:AtomBitOp> <typ:BitType> <a:Arg3Atom> => { - let details = ast::AtomDetails { - semantics: sema.unwrap_or(ast::AtomSemantics::Relaxed), - scope: scope.unwrap_or(ast::MemScope::Gpu), - space: space.unwrap_or(ast::StateSpace::Generic), - inner: ast::AtomInnerDetails::Bit { op, typ } - }; - ast::Instruction::Atom(details,a) - }, - "atom" <sema:AtomSemantics?> <scope:MemScope?> <space:AtomSpace?> ".inc" ".u32" <a:Arg3Atom> => { - let details = ast::AtomDetails { - semantics: sema.unwrap_or(ast::AtomSemantics::Relaxed), - scope: scope.unwrap_or(ast::MemScope::Gpu), - space: space.unwrap_or(ast::StateSpace::Generic), - inner: ast::AtomInnerDetails::Unsigned { - op: ast::AtomUIntOp::Inc, - typ: ast::ScalarType::U32 - } - }; - ast::Instruction::Atom(details,a) - }, - "atom" <sema:AtomSemantics?> <scope:MemScope?> <space:AtomSpace?> ".dec" ".u32" <a:Arg3Atom> => { - let details = ast::AtomDetails { - semantics: sema.unwrap_or(ast::AtomSemantics::Relaxed), - scope: scope.unwrap_or(ast::MemScope::Gpu), - space: space.unwrap_or(ast::StateSpace::Generic), - inner: ast::AtomInnerDetails::Unsigned { - op: ast::AtomUIntOp::Dec, - typ: ast::ScalarType::U32 - } - }; - ast::Instruction::Atom(details,a) - }, - "atom" <sema:AtomSemantics?> <scope:MemScope?> <space:AtomSpace?> ".add" <typ:FloatType> <a:Arg3Atom> => { - let op = ast::AtomFloatOp::Add; - let details = ast::AtomDetails { - semantics: sema.unwrap_or(ast::AtomSemantics::Relaxed), - scope: scope.unwrap_or(ast::MemScope::Gpu), - space: space.unwrap_or(ast::StateSpace::Generic), - inner: ast::AtomInnerDetails::Float { op, typ } - }; - ast::Instruction::Atom(details,a) - }, - "atom" <sema:AtomSemantics?> <scope:MemScope?> <space:AtomSpace?> <op: AtomUIntOp> <typ:UIntType3264> <a:Arg3Atom> => { - let details = ast::AtomDetails { - semantics: sema.unwrap_or(ast::AtomSemantics::Relaxed), - scope: scope.unwrap_or(ast::MemScope::Gpu), - space: space.unwrap_or(ast::StateSpace::Generic), - inner: ast::AtomInnerDetails::Unsigned { op, typ } - }; - ast::Instruction::Atom(details,a) - }, - "atom" <sema:AtomSemantics?> <scope:MemScope?> <space:AtomSpace?> <op: AtomSIntOp> <typ:SIntType3264> <a:Arg3Atom> => { - let details = ast::AtomDetails { - semantics: sema.unwrap_or(ast::AtomSemantics::Relaxed), - scope: scope.unwrap_or(ast::MemScope::Gpu), - space: space.unwrap_or(ast::StateSpace::Generic), - inner: ast::AtomInnerDetails::Signed { op, typ } - }; - ast::Instruction::Atom(details,a) - } -} - -InstAtomCas: ast::Instruction<ast::ParsedArgParams<'input>> = { - "atom" <sema:AtomSemantics?> <scope:MemScope?> <space:AtomSpace?> ".cas" <typ:BitType> <a:Arg4Atom> => { - let details = ast::AtomCasDetails { - semantics: sema.unwrap_or(ast::AtomSemantics::Relaxed), - scope: scope.unwrap_or(ast::MemScope::Gpu), - space: space.unwrap_or(ast::StateSpace::Generic), - typ, - }; - ast::Instruction::AtomCas(details,a) - }, -} - -AtomSemantics: ast::AtomSemantics = { - ".relaxed" => ast::AtomSemantics::Relaxed, - ".acquire" => ast::AtomSemantics::Acquire, - ".release" => ast::AtomSemantics::Release, - ".acq_rel" => ast::AtomSemantics::AcquireRelease -} - -AtomSpace: ast::StateSpace = { - ".global" => ast::StateSpace::Global, - ".shared" => ast::StateSpace::Shared -} - -AtomBitOp: ast::AtomBitOp = { - ".and" => ast::AtomBitOp::And, - ".or" => ast::AtomBitOp::Or, - ".xor" => ast::AtomBitOp::Xor, - ".exch" => ast::AtomBitOp::Exchange, -} - -AtomUIntOp: ast::AtomUIntOp = { - ".add" => ast::AtomUIntOp::Add, - ".min" => ast::AtomUIntOp::Min, - ".max" => ast::AtomUIntOp::Max, -} - -AtomSIntOp: ast::AtomSIntOp = { - ".add" => ast::AtomSIntOp::Add, - ".min" => ast::AtomSIntOp::Min, - ".max" => ast::AtomSIntOp::Max, -} - -BitType: ast::ScalarType = { - ".b32" => ast::ScalarType::B32, - ".b64" => ast::ScalarType::B64, -} - -UIntType3264: ast::ScalarType = { - ".u32" => ast::ScalarType::U32, - ".u64" => ast::ScalarType::U64, -} - -SIntType3264: ast::ScalarType = { - ".s32" => ast::ScalarType::S32, - ".s64" => ast::ScalarType::S64, -} - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#floating-point-instructions-div -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#integer-arithmetic-instructions-div -InstDiv: ast::Instruction<ast::ParsedArgParams<'input>> = { - "div" <t:UIntType> <a:Arg3> => ast::Instruction::Div(ast::DivDetails::Unsigned(t), a), - "div" <t:SIntType> <a:Arg3> => ast::Instruction::Div(ast::DivDetails::Signed(t), a), - "div" <kind:DivFloatKind> <ftz:".ftz"?> ".f32" <a:Arg3> => { - let inner = ast::DivFloatDetails { - typ: ast::ScalarType::F32, - flush_to_zero: Some(ftz.is_some()), - kind - }; - ast::Instruction::Div(ast::DivDetails::Float(inner), a) - }, - "div" <rnd:RoundingModeFloat> ".f64" <a:Arg3> => { - let inner = ast::DivFloatDetails { - typ: ast::ScalarType::F64, - flush_to_zero: None, - kind: ast::DivFloatKind::Rounding(rnd) - }; - ast::Instruction::Div(ast::DivDetails::Float(inner), a) - }, -} - -DivFloatKind: ast::DivFloatKind = { - ".approx" => ast::DivFloatKind::Approx, - ".full" => ast::DivFloatKind::Full, - <rnd:RoundingModeFloat> => ast::DivFloatKind::Rounding(rnd), -} - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#floating-point-instructions-sqrt -InstSqrt: ast::Instruction<ast::ParsedArgParams<'input>> = { - "sqrt" ".approx" <ftz:".ftz"?> ".f32" <a:Arg2> => { - let details = ast::SqrtDetails { - typ: ast::ScalarType::F32, - flush_to_zero: Some(ftz.is_some()), - kind: ast::SqrtKind::Approx, - }; - ast::Instruction::Sqrt(details, a) - }, - "sqrt" <rnd:RoundingModeFloat> <ftz:".ftz"?> ".f32" <a:Arg2> => { - let details = ast::SqrtDetails { - typ: ast::ScalarType::F32, - flush_to_zero: Some(ftz.is_some()), - kind: ast::SqrtKind::Rounding(rnd), - }; - ast::Instruction::Sqrt(details, a) - }, - "sqrt" <rnd:RoundingModeFloat> ".f64" <a:Arg2> => { - let details = ast::SqrtDetails { - typ: ast::ScalarType::F64, - flush_to_zero: None, - kind: ast::SqrtKind::Rounding(rnd), - }; - ast::Instruction::Sqrt(details, a) - } -} - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#floating-point-instructions-rsqrt -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#floating-point-instructions-rsqrt-approx-ftz-f64 -InstRsqrt: ast::Instruction<ast::ParsedArgParams<'input>> = { - "rsqrt" ".approx" <ftz:".ftz"?> ".f32" <a:Arg2> => { - let details = ast::RsqrtDetails { - typ: ast::ScalarType::F32, - flush_to_zero: ftz.is_some(), - }; - ast::Instruction::Rsqrt(details, a) - }, - "rsqrt" ".approx" <ftz:".ftz"?> ".f64" <a:Arg2> => { - let details = ast::RsqrtDetails { - typ: ast::ScalarType::F64, - flush_to_zero: ftz.is_some(), - }; - ast::Instruction::Rsqrt(details, a) - }, -} - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#integer-arithmetic-instructions-neg -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#floating-point-instructions-neg -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#half-precision-floating-point-instructions-neg -InstNeg: ast::Instruction<ast::ParsedArgParams<'input>> = { - "neg" <ftz:".ftz"?> <typ:NegTypeFtz> <a:Arg2> => { - let details = ast::NegDetails { - typ, - flush_to_zero: Some(ftz.is_some()), - }; - ast::Instruction::Neg(details, a) - }, - "neg" <typ:NegTypeNonFtz> <a:Arg2> => { - let details = ast::NegDetails { - typ, - flush_to_zero: None, - }; - ast::Instruction::Neg(details, a) - }, -} - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#floating-point-instructions-sin -InstSin: ast::Instruction<ast::ParsedArgParams<'input>> = { - "sin" ".approx" <ftz:".ftz"?> ".f32" <arg:Arg2> => { - ast::Instruction::Sin{ flush_to_zero: ftz.is_some(), arg } - }, -} - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#floating-point-instructions-cos -InstCos: ast::Instruction<ast::ParsedArgParams<'input>> = { - "cos" ".approx" <ftz:".ftz"?> ".f32" <arg:Arg2> => { - ast::Instruction::Cos{ flush_to_zero: ftz.is_some(), arg } - }, -} - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#floating-point-instructions-lg2 -InstLg2: ast::Instruction<ast::ParsedArgParams<'input>> = { - "lg2" ".approx" <ftz:".ftz"?> ".f32" <arg:Arg2> => { - ast::Instruction::Lg2{ flush_to_zero: ftz.is_some(), arg } - }, -} - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#floating-point-instructions-ex2 -InstEx2: ast::Instruction<ast::ParsedArgParams<'input>> = { - "ex2" ".approx" <ftz:".ftz"?> ".f32" <arg:Arg2> => { - ast::Instruction::Ex2{ flush_to_zero: ftz.is_some(), arg } - }, -} - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#integer-arithmetic-instructions-clz -InstClz: ast::Instruction<ast::ParsedArgParams<'input>> = { - "clz" <typ:BitType> <arg:Arg2> => ast::Instruction::Clz{ <> } -} - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#integer-arithmetic-instructions-brev -InstBrev: ast::Instruction<ast::ParsedArgParams<'input>> = { - "brev" <typ:BitType> <arg:Arg2> => ast::Instruction::Brev{ <> } -} - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#integer-arithmetic-instructions-popc -InstPopc: ast::Instruction<ast::ParsedArgParams<'input>> = { - "popc" <typ:BitType> <arg:Arg2> => ast::Instruction::Popc{ <> } -} - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#logic-and-shift-instructions-xor -InstXor: ast::Instruction<ast::ParsedArgParams<'input>> = { - "xor" <typ:BooleanType> <arg:Arg3> => ast::Instruction::Xor{ <> } -} - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#integer-arithmetic-instructions-bfe -InstBfe: ast::Instruction<ast::ParsedArgParams<'input>> = { - "bfe" <typ:IntType3264> <arg:Arg4> => ast::Instruction::Bfe{ <> } -} - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#integer-arithmetic-instructions-bfi -InstBfi: ast::Instruction<ast::ParsedArgParams<'input>> = { - "bfi" <typ:BitType> <arg:Arg5> => ast::Instruction::Bfi{ <> } -} - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-prmt -InstPrmt: ast::Instruction<ast::ParsedArgParams<'input>> = { - "prmt" ".b32" <arg:Arg3> "," <control:U16Num> => ast::Instruction::Prmt{ <> } -} - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#integer-arithmetic-instructions-rem -InstRem: ast::Instruction<ast::ParsedArgParams<'input>> = { - "rem" <typ:IntType> <arg:Arg3> => ast::Instruction::Rem{ <> } -} - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#parallel-synchronization-and-communication-instructions-activemask -InstActivemask: ast::Instruction<ast::ParsedArgParams<'input>> = { - "activemask" ".b32" <arg:Arg1> => ast::Instruction::Activemask{ <> } -} - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#parallel-synchronization-and-communication-instructions-membar -InstMembar: ast::Instruction<ast::ParsedArgParams<'input>> = { - "membar" <level:MembarLevel> => ast::Instruction::Membar{ <> } -} - -NegTypeFtz: ast::ScalarType = { - ".f16" => ast::ScalarType::F16, - ".f16x2" => ast::ScalarType::F16x2, - ".f32" => ast::ScalarType::F32, -} - -NegTypeNonFtz: ast::ScalarType = { - ".s16" => ast::ScalarType::S16, - ".s32" => ast::ScalarType::S32, - ".s64" => ast::ScalarType::S64, - ".f64" => ast::ScalarType::F64 -} - -ArithDetails: ast::ArithDetails = { - <t:UIntType> => ast::ArithDetails::Unsigned(t), - <t:SIntType> => ast::ArithDetails::Signed(ast::ArithSInt { - typ: t, - saturate: false, - }), - ".sat" ".s32" => ast::ArithDetails::Signed(ast::ArithSInt { - typ: ast::ScalarType::S32, - saturate: true, - }), - <f:ArithFloat> => ast::ArithDetails::Float(f) -} - -ArithFloat: ast::ArithFloat = { - <rn:RoundingModeFloat?> <ftz:".ftz"?> <sat:".sat"?> ".f32" => ast::ArithFloat { - typ: ast::ScalarType::F32, - rounding: rn, - flush_to_zero: Some(ftz.is_some()), - saturate: sat.is_some(), - }, - <rn:RoundingModeFloat?> ".f64" => ast::ArithFloat { - typ: ast::ScalarType::F64, - rounding: rn, - flush_to_zero: None, - saturate: false, - }, - <rn:".rn"?> <ftz:".ftz"?> <sat:".sat"?> ".f16" => ast::ArithFloat { - typ: ast::ScalarType::F16, - rounding: rn.map(|_| ast::RoundingMode::NearestEven), - flush_to_zero: Some(ftz.is_some()), - saturate: sat.is_some(), - }, - <rn:".rn"?> <ftz:".ftz"?> <sat:".sat"?> ".f16x2" => ast::ArithFloat { - typ: ast::ScalarType::F16x2, - rounding: rn.map(|_| ast::RoundingMode::NearestEven), - flush_to_zero: Some(ftz.is_some()), - saturate: sat.is_some(), - }, -} - -ArithFloatMustRound: ast::ArithFloat = { - <rn:RoundingModeFloat> <ftz:".ftz"?> <sat:".sat"?> ".f32" => ast::ArithFloat { - typ: ast::ScalarType::F32, - rounding: Some(rn), - flush_to_zero: Some(ftz.is_some()), - saturate: sat.is_some(), - }, - <rn:RoundingModeFloat> ".f64" => ast::ArithFloat { - typ: ast::ScalarType::F64, - rounding: Some(rn), - flush_to_zero: None, - saturate: false, - }, - ".rn" <ftz:".ftz"?> <sat:".sat"?> ".f16" => ast::ArithFloat { - typ: ast::ScalarType::F16, - rounding: Some(ast::RoundingMode::NearestEven), - flush_to_zero: Some(ftz.is_some()), - saturate: sat.is_some(), - }, - ".rn" <ftz:".ftz"?> <sat:".sat"?> ".f16x2" => ast::ArithFloat { - typ: ast::ScalarType::F16x2, - rounding: Some(ast::RoundingMode::NearestEven), - flush_to_zero: Some(ftz.is_some()), - saturate: sat.is_some(), - }, -} - -Operand: ast::Operand<&'input str> = { - <r:ExtendedID> => ast::Operand::Reg(r), - <r:ExtendedID> "+" <offset:S32Num> => ast::Operand::RegOffset(r, offset), - <x:ImmediateValue> => ast::Operand::Imm(x) -}; - -CallOperand: ast::Operand<&'input str> = { - <r:ExtendedID> => ast::Operand::Reg(r), - <x:ImmediateValue> => ast::Operand::Imm(x) -}; - -// TODO: start parsing whole constants sub-language: -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#constants -ImmediateValue: ast::ImmediateValue = { - // TODO: treat negation correctly - <neg:"-"?> <x:NumToken> => { - let (num, radix, is_unsigned) = x; - if neg.is_some() { - match i64::from_str_radix(num, radix) { - Ok(x) => ast::ImmediateValue::S64(-x), - Err(err) => { - errors.push(ParseError::User { error: ast::PtxError::from(err) }); - ast::ImmediateValue::S64(0) - } - } - } else if is_unsigned { - match u64::from_str_radix(num, radix) { - Ok(x) => ast::ImmediateValue::U64(x), - Err(err) => { - errors.push(ParseError::User { error: ast::PtxError::from(err) }); - ast::ImmediateValue::U64(0) - } - } - } else { - match i64::from_str_radix(num, radix) { - Ok(x) => ast::ImmediateValue::S64(x), - Err(_) => { - match u64::from_str_radix(num, radix) { - Ok(x) => ast::ImmediateValue::U64(x), - Err(err) => { - errors.push(ParseError::User { error: ast::PtxError::from(err) }); - ast::ImmediateValue::U64(0) - } - } - } - } - } - }, - <f:F32Num> => { - ast::ImmediateValue::F32(f) - }, - <f:F64Num> => { - ast::ImmediateValue::F64(f) - } -} - -Arg1: ast::Arg1<ast::ParsedArgParams<'input>> = { - <src:ExtendedID> => ast::Arg1{<>} -}; - -Arg1Bar: ast::Arg1Bar<ast::ParsedArgParams<'input>> = { - <src:Operand> => ast::Arg1Bar{<>} -}; - -Arg2: ast::Arg2<ast::ParsedArgParams<'input>> = { - <dst:DstOperand> "," <src:Operand> => ast::Arg2{<>} -}; - -MemberOperand: (&'input str, u8) = { - <pref:ExtendedID> "." <suf:ExtendedID> => { - let suf_idx = match vector_index(suf) { - Ok(x) => x, - Err(err) => { - errors.push(err); - 0 - } - }; - (pref, suf_idx) - }, - <pref:ExtendedID> <suf:DotID> => { - let suf_idx = match vector_index(&suf[1..]) { - Ok(x) => x, - Err(err) => { - errors.push(err); - 0 - } - }; - (pref, suf_idx) - } -}; - -VectorExtract: Vec<&'input str> = { - "{" <r1:ExtendedID> "," <r2:ExtendedID> "}" => { - vec![r1, r2] - }, - "{" <r1:ExtendedID> "," <r2:ExtendedID> "," <r3:ExtendedID> "," <r4:ExtendedID> "}" => { - vec![r1, r2, r3, r4] - }, -}; - -Arg3: ast::Arg3<ast::ParsedArgParams<'input>> = { - <dst:DstOperand> "," <src1:Operand> "," <src2:Operand> => ast::Arg3{<>} -}; - -Arg3Atom: ast::Arg3<ast::ParsedArgParams<'input>> = { - <dst:DstOperand> "," "[" <src1:Operand> "]" "," <src2:Operand> => ast::Arg3{<>} -}; - -Arg4: ast::Arg4<ast::ParsedArgParams<'input>> = { - <dst:DstOperand> "," <src1:Operand> "," <src2:Operand> "," <src3:Operand> => ast::Arg4{<>} -}; - -Arg4Atom: ast::Arg4<ast::ParsedArgParams<'input>> = { - <dst:DstOperand> "," "[" <src1:Operand> "]" "," <src2:Operand> "," <src3:Operand> => ast::Arg4{<>} -}; - -Arg4Setp: ast::Arg4Setp<ast::ParsedArgParams<'input>> = { - <dst1:ExtendedID> <dst2:OptionalDst?> "," <src1:Operand> "," <src2:Operand> => ast::Arg4Setp{<>} -}; - -Arg5: ast::Arg5<ast::ParsedArgParams<'input>> = { - <dst:DstOperand> "," <src1:Operand> "," <src2:Operand> "," <src3:Operand> "," <src4:Operand> => ast::Arg5{<>} -}; - -// TODO: pass src3 negation somewhere -Arg5Setp: ast::Arg5Setp<ast::ParsedArgParams<'input>> = { - <dst1:ExtendedID> <dst2:OptionalDst?> "," <src1:Operand> "," <src2:Operand> "," "!"? <src3:Operand> => ast::Arg5Setp{<>} -}; - -ArgCall: (Vec<&'input str>, &'input str, Vec<ast::Operand<&'input str>>) = { - "(" <ret_params:Comma<ExtendedID>> ")" "," <func:ExtendedID> "," "(" <param_list:Comma<CallOperand>> ")" => { - (ret_params, func, param_list) - }, - "(" <ret_params:Comma<ExtendedID>> ")" "," <func:ExtendedID> => { - (ret_params, func, Vec::new()) - }, - <func:ExtendedID> "," "(" <param_list:Comma<CallOperand>> ")" => (Vec::new(), func, param_list), - <func:ExtendedID> => (Vec::new(), func, Vec::<ast::Operand<_>>::new()), -}; - -OptionalDst: &'input str = { - "|" <dst2:ExtendedID> => dst2 -} - -SrcOperand: ast::Operand<&'input str> = { - <r:ExtendedID> => ast::Operand::Reg(r), - <r:ExtendedID> "+" <offset:S32Num> => ast::Operand::RegOffset(r, offset), - <x:ImmediateValue> => ast::Operand::Imm(x), - <mem_op:MemberOperand> => { - let (reg, idx) = mem_op; - ast::Operand::VecMember(reg, idx) - } -} - -SrcOperandVec: ast::Operand<&'input str> = { - <normal:SrcOperand> => normal, - <vec:VectorExtract> => ast::Operand::VecPack(vec), -} - -DstOperand: ast::Operand<&'input str> = { - <r:ExtendedID> => ast::Operand::Reg(r), - <mem_op:MemberOperand> => { - let (reg, idx) = mem_op; - ast::Operand::VecMember(reg, idx) - } -} - -DstOperandVec: ast::Operand<&'input str> = { - <normal:DstOperand> => normal, - <vec:VectorExtract> => ast::Operand::VecPack(vec), -} - -VectorPrefix: u8 = { - ".v2" => 2, - ".v4" => 4 -}; - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#debugging-directives-file -File = { - ".file" U32Num String ("," U32Num "," U32Num)? -}; - -// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#debugging-directives-section -Section = { - ".section" DotID "{" SectionDwarfLines* "}" -}; - -SectionDwarfLines: () = { - AnyBitType Comma<U32Num>, - ".b32" SectionLabel, - ".b64" SectionLabel, - ".b32" SectionLabel "+" U32Num, - ".b64" SectionLabel "+" U32Num, -}; - -SectionLabel = { - ID, - DotID -}; - -AnyBitType = { - ".b8", ".b16", ".b32", ".b64" -}; - -VariableScalar<T>: (Option<u32>, T, &'input str) = { - <align:Align?> <v_type:T> <name:ExtendedID> => { - (align, v_type, name) - } -} - -VariableVector<T>: (Option<u32>, u8, T, &'input str) = { - <align:Align?> <v_len:VectorPrefix> <v_type:T> <name:ExtendedID> => { - (align, v_len, v_type, name) - } -} - -// empty dimensions [0] means it's a pointer -VariableArrayOrPointer<T>: (Option<u32>, T, &'input str, ast::ArrayOrPointer) = { - <align:Align?> <typ:SizedScalarType> <name:ExtendedID> <dims:ArrayDimensions> <init:ArrayInitializer?> => { - let mut dims = dims; - let array_init = match init { - Some(init) => { - let init_vec = match init.to_vec(typ, &mut dims) { - Err(error) => { - errors.push(ParseError::User { error }); - Vec::new() - } - Ok(x) => x - }; - ast::ArrayOrPointer::Array { dimensions: dims, init: init_vec } - } - None => { - if dims.len() > 1 && dims.contains(&0) { - errors.push(ParseError::User { error: ast::PtxError::ZeroDimensionArray }); - } - match &*dims { - [0] => ast::ArrayOrPointer::Pointer, - _ => ast::ArrayOrPointer::Array { dimensions: dims, init: Vec::new() } - } - } - }; - (align, typ, name, array_init) - } -} - -// [0] and [] are treated the same -ArrayDimensions: Vec<u32> = { - ArrayEmptyDimension => vec![0u32], - ArrayEmptyDimension <dims:ArrayDimension+> => { - let mut dims = dims; - let mut result = vec![0u32]; - result.append(&mut dims); - result - }, - <dims:ArrayDimension+> => dims -} - -ArrayEmptyDimension = { - "[" "]" -} - -ArrayDimension: u32 = { - "[" <n:U32Num> "]" => n, -} - -ArrayInitializer: ast::NumsOrArrays<'input> = { - "=" <nums:NumsOrArraysBracket> => nums -} - -NumsOrArraysBracket: ast::NumsOrArrays<'input> = { - "{" <nums:NumsOrArrays> "}" => nums -} - -NumsOrArrays: ast::NumsOrArrays<'input> = { - <n:Comma<NumsOrArraysBracket>> => ast::NumsOrArrays::Arrays(n), - <n:CommaNonEmpty<NumToken>> => ast::NumsOrArrays::Nums(n.into_iter().map(|(x,radix,_)| (x, radix)).collect()), -} - -Comma<T>: Vec<T> = { - <v:(<T> ",")*> <e:T?> => match e { - None => v, - Some(e) => { - let mut v = v; - v.push(e); - v - } - } -}; - -CommaNonEmpty<T>: Vec<T> = { - <v:(<T> ",")*> <e:T> => { - let mut v = v; - v.push(e); - v - } -}; - -#[inline] -Or<T1, T2>: T1 = { - T1, - T2 -} - -#[inline] -Or3<T1, T2, T3>: T1 = { - T1, - T2, - T3 -}
\ No newline at end of file diff --git a/ptx/src/test/mod.rs b/ptx/src/test/mod.rs index 0785f3e..e9943f4 100644 --- a/ptx/src/test/mod.rs +++ b/ptx/src/test/mod.rs @@ -1,18 +1,15 @@ -use super::ptx; -use super::TranslateError; +use crate::pass::TranslateError; +use ptx_parser as ast; mod spirv_run; -fn parse_and_assert(s: &str) { - let mut errors = Vec::new(); - ptx::ModuleParser::new().parse(&mut errors, s).unwrap(); - assert!(errors.len() == 0); +fn parse_and_assert(ptx_text: &str) { + ast::parse_module_checked(ptx_text).unwrap(); } -fn compile_and_assert(s: &str) -> Result<(), TranslateError> { - let mut errors = Vec::new(); - let ast = ptx::ModuleParser::new().parse(&mut errors, s).unwrap(); - crate::to_spirv_module(ast)?; +fn compile_and_assert(ptx_text: &str) -> Result<(), TranslateError> { + let ast = ast::parse_module_checked(ptx_text).unwrap(); + crate::to_llvm_module(ast)?; Ok(()) } diff --git a/ptx/src/test/spirv_run/activemask.spvtxt b/ptx/src/test/spirv_run/activemask.spvtxt deleted file mode 100644 index 0753c95..0000000 --- a/ptx/src/test/spirv_run/activemask.spvtxt +++ /dev/null @@ -1,45 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %18 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "activemask" - OpExecutionMode %1 ContractionOff - OpDecorate %15 LinkageAttributes "__zluda_ptx_impl__activemask" Import - %void = OpTypeVoid - %uint = OpTypeInt 32 0 - %21 = OpTypeFunction %uint - %ulong = OpTypeInt 64 0 - %23 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong -%_ptr_Function_uint = OpTypePointer Function %uint -%_ptr_Generic_uint = OpTypePointer Generic %uint - %15 = OpFunction %uint None %21 - OpFunctionEnd - %1 = OpFunction %void None %23 - %6 = OpFunctionParameter %ulong - %7 = OpFunctionParameter %ulong - %14 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_uint Function - OpStore %2 %6 - OpStore %3 %7 - %8 = OpLoad %ulong %3 Aligned 8 - OpStore %4 %8 - %9 = OpFunctionCall %uint %15 - OpStore %5 %9 - %10 = OpLoad %ulong %4 - %11 = OpLoad %uint %5 - %12 = OpConvertUToPtr %_ptr_Generic_uint %10 - %13 = OpCopyObject %uint %11 - OpStore %12 %13 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/add.spvtxt b/ptx/src/test/spirv_run/add.spvtxt deleted file mode 100644 index b468693..0000000 --- a/ptx/src/test/spirv_run/add.spvtxt +++ /dev/null @@ -1,47 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %23 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "add" - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %26 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong -%_ptr_Generic_ulong = OpTypePointer Generic %ulong - %ulong_1 = OpConstant %ulong 1 - %1 = OpFunction %void None %26 - %8 = OpFunctionParameter %ulong - %9 = OpFunctionParameter %ulong - %21 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_ulong Function - %7 = OpVariable %_ptr_Function_ulong Function - OpStore %2 %8 - OpStore %3 %9 - %10 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %19 = OpConvertUToPtr %_ptr_Generic_ulong %13 - %12 = OpLoad %ulong %19 Aligned 8 - OpStore %6 %12 - %15 = OpLoad %ulong %6 - %14 = OpIAdd %ulong %15 %ulong_1 - OpStore %7 %14 - %16 = OpLoad %ulong %5 - %17 = OpLoad %ulong %7 - %20 = OpConvertUToPtr %_ptr_Generic_ulong %16 - OpStore %20 %17 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/add_non_coherent.spvtxt b/ptx/src/test/spirv_run/add_non_coherent.spvtxt deleted file mode 100644 index 99da980..0000000 --- a/ptx/src/test/spirv_run/add_non_coherent.spvtxt +++ /dev/null @@ -1,47 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %23 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "add_non_coherent" - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %26 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong -%_ptr_CrossWorkgroup_ulong = OpTypePointer CrossWorkgroup %ulong - %ulong_1 = OpConstant %ulong 1 - %1 = OpFunction %void None %26 - %8 = OpFunctionParameter %ulong - %9 = OpFunctionParameter %ulong - %21 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_ulong Function - %7 = OpVariable %_ptr_Function_ulong Function - OpStore %2 %8 - OpStore %3 %9 - %10 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %19 = OpConvertUToPtr %_ptr_CrossWorkgroup_ulong %13 - %12 = OpLoad %ulong %19 Aligned 8 - OpStore %6 %12 - %15 = OpLoad %ulong %6 - %14 = OpIAdd %ulong %15 %ulong_1 - OpStore %7 %14 - %16 = OpLoad %ulong %5 - %17 = OpLoad %ulong %7 - %20 = OpConvertUToPtr %_ptr_CrossWorkgroup_ulong %16 - OpStore %20 %17 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/add_tuning.spvtxt b/ptx/src/test/spirv_run/add_tuning.spvtxt deleted file mode 100644 index d65f04d..0000000 --- a/ptx/src/test/spirv_run/add_tuning.spvtxt +++ /dev/null @@ -1,55 +0,0 @@ -; SPIR-V -; Version: 1.3 -; Generator: rspirv -; Bound: 29 -OpCapability GenericPointer -OpCapability Linkage -OpCapability Addresses -OpCapability Kernel -OpCapability Int8 -OpCapability Int16 -OpCapability Int64 -OpCapability Float16 -OpCapability Float64 -OpCapability DenormFlushToZero -%23 = OpExtInstImport "OpenCL.std" -OpMemoryModel Physical64 OpenCL -OpEntryPoint Kernel %1 "add_tuning" -OpExecutionMode %1 ContractionOff -; OpExecutionMode %1 MaxWorkgroupSizeINTEL 256 1 1 -OpDecorate %1 LinkageAttributes "add_tuning" Export -%24 = OpTypeVoid -%25 = OpTypeInt 64 0 -%26 = OpTypeFunction %24 %25 %25 -%27 = OpTypePointer Function %25 -%28 = OpTypePointer Generic %25 -%18 = OpConstant %25 1 -%1 = OpFunction %24 None %26 -%8 = OpFunctionParameter %25 -%9 = OpFunctionParameter %25 -%21 = OpLabel -%2 = OpVariable %27 Function -%3 = OpVariable %27 Function -%4 = OpVariable %27 Function -%5 = OpVariable %27 Function -%6 = OpVariable %27 Function -%7 = OpVariable %27 Function -OpStore %2 %8 -OpStore %3 %9 -%10 = OpLoad %25 %2 Aligned 8 -OpStore %4 %10 -%11 = OpLoad %25 %3 Aligned 8 -OpStore %5 %11 -%13 = OpLoad %25 %4 -%19 = OpConvertUToPtr %28 %13 -%12 = OpLoad %25 %19 Aligned 8 -OpStore %6 %12 -%15 = OpLoad %25 %6 -%14 = OpIAdd %25 %15 %18 -OpStore %7 %14 -%16 = OpLoad %25 %5 -%17 = OpLoad %25 %7 -%20 = OpConvertUToPtr %28 %16 -OpStore %20 %17 Aligned 8 -OpReturn -OpFunctionEnd
\ No newline at end of file diff --git a/ptx/src/test/spirv_run/and.spvtxt b/ptx/src/test/spirv_run/and.spvtxt deleted file mode 100644 index f66639a..0000000 --- a/ptx/src/test/spirv_run/and.spvtxt +++ /dev/null @@ -1,62 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %31 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "and" - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %34 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %uint = OpTypeInt 32 0 -%_ptr_Function_uint = OpTypePointer Function %uint -%_ptr_Generic_uint = OpTypePointer Generic %uint - %ulong_4 = OpConstant %ulong 4 - %uchar = OpTypeInt 8 0 -%_ptr_Generic_uchar = OpTypePointer Generic %uchar - %1 = OpFunction %void None %34 - %8 = OpFunctionParameter %ulong - %9 = OpFunctionParameter %ulong - %29 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_uint Function - %7 = OpVariable %_ptr_Function_uint Function - OpStore %2 %8 - OpStore %3 %9 - %10 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %23 = OpConvertUToPtr %_ptr_Generic_uint %13 - %12 = OpLoad %uint %23 Aligned 4 - OpStore %6 %12 - %15 = OpLoad %ulong %4 - %24 = OpConvertUToPtr %_ptr_Generic_uint %15 - %41 = OpBitcast %_ptr_Generic_uchar %24 - %42 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %41 %ulong_4 - %22 = OpBitcast %_ptr_Generic_uint %42 - %14 = OpLoad %uint %22 Aligned 4 - OpStore %7 %14 - %17 = OpLoad %uint %6 - %18 = OpLoad %uint %7 - %26 = OpCopyObject %uint %17 - %27 = OpCopyObject %uint %18 - %25 = OpBitwiseAnd %uint %26 %27 - %16 = OpCopyObject %uint %25 - OpStore %6 %16 - %19 = OpLoad %ulong %5 - %20 = OpLoad %uint %6 - %28 = OpConvertUToPtr %_ptr_Generic_uint %19 - OpStore %28 %20 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/assertfail.spvtxt b/ptx/src/test/spirv_run/assertfail.spvtxt deleted file mode 100644 index 8ed84fa..0000000 --- a/ptx/src/test/spirv_run/assertfail.spvtxt +++ /dev/null @@ -1,105 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %67 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %12 "assertfail" - OpDecorate %1 LinkageAttributes "__zluda_ptx_impl____assertfail" Import - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 -%_ptr_Function_ulong = OpTypePointer Function %ulong - %uint = OpTypeInt 32 0 -%_ptr_Function_uint = OpTypePointer Function %uint - %73 = OpTypeFunction %void %_ptr_Function_ulong %_ptr_Function_ulong %_ptr_Function_uint %_ptr_Function_ulong %_ptr_Function_ulong - %74 = OpTypeFunction %void %ulong %ulong - %uint_0 = OpConstant %uint 0 - %ulong_0 = OpConstant %ulong 0 - %uchar = OpTypeInt 8 0 -%_ptr_Function_uchar = OpTypePointer Function %uchar - %ulong_0_0 = OpConstant %ulong 0 - %ulong_0_1 = OpConstant %ulong 0 - %ulong_0_2 = OpConstant %ulong 0 - %ulong_0_3 = OpConstant %ulong 0 -%_ptr_Generic_ulong = OpTypePointer Generic %ulong - %ulong_1 = OpConstant %ulong 1 - %1 = OpFunction %void None %73 - %61 = OpFunctionParameter %_ptr_Function_ulong - %62 = OpFunctionParameter %_ptr_Function_ulong - %63 = OpFunctionParameter %_ptr_Function_uint - %64 = OpFunctionParameter %_ptr_Function_ulong - %65 = OpFunctionParameter %_ptr_Function_ulong - OpFunctionEnd - %12 = OpFunction %void None %74 - %25 = OpFunctionParameter %ulong - %26 = OpFunctionParameter %ulong - %60 = OpLabel - %13 = OpVariable %_ptr_Function_ulong Function - %14 = OpVariable %_ptr_Function_ulong Function - %15 = OpVariable %_ptr_Function_ulong Function - %16 = OpVariable %_ptr_Function_ulong Function - %17 = OpVariable %_ptr_Function_ulong Function - %18 = OpVariable %_ptr_Function_ulong Function - %19 = OpVariable %_ptr_Function_uint Function - %20 = OpVariable %_ptr_Function_ulong Function - %21 = OpVariable %_ptr_Function_ulong Function - %22 = OpVariable %_ptr_Function_uint Function - %23 = OpVariable %_ptr_Function_ulong Function - %24 = OpVariable %_ptr_Function_ulong Function - OpStore %13 %25 - OpStore %14 %26 - %27 = OpLoad %ulong %13 Aligned 8 - OpStore %15 %27 - %28 = OpLoad %ulong %14 Aligned 8 - OpStore %16 %28 - %53 = OpCopyObject %uint %uint_0 - %29 = OpCopyObject %uint %53 - OpStore %19 %29 - %30 = OpLoad %ulong %15 - %77 = OpBitcast %_ptr_Function_uchar %20 - %78 = OpInBoundsPtrAccessChain %_ptr_Function_uchar %77 %ulong_0 - %43 = OpBitcast %_ptr_Function_ulong %78 - %54 = OpCopyObject %ulong %30 - OpStore %43 %54 Aligned 8 - %31 = OpLoad %ulong %15 - %79 = OpBitcast %_ptr_Function_uchar %21 - %80 = OpInBoundsPtrAccessChain %_ptr_Function_uchar %79 %ulong_0_0 - %45 = OpBitcast %_ptr_Function_ulong %80 - %55 = OpCopyObject %ulong %31 - OpStore %45 %55 Aligned 8 - %32 = OpLoad %uint %19 - %81 = OpBitcast %_ptr_Function_uchar %22 - %82 = OpInBoundsPtrAccessChain %_ptr_Function_uchar %81 %ulong_0_1 - %47 = OpBitcast %_ptr_Function_uint %82 - OpStore %47 %32 Aligned 4 - %33 = OpLoad %ulong %15 - %83 = OpBitcast %_ptr_Function_uchar %23 - %84 = OpInBoundsPtrAccessChain %_ptr_Function_uchar %83 %ulong_0_2 - %49 = OpBitcast %_ptr_Function_ulong %84 - %56 = OpCopyObject %ulong %33 - OpStore %49 %56 Aligned 8 - %34 = OpLoad %ulong %15 - %85 = OpBitcast %_ptr_Function_uchar %24 - %86 = OpInBoundsPtrAccessChain %_ptr_Function_uchar %85 %ulong_0_3 - %51 = OpBitcast %_ptr_Function_ulong %86 - %57 = OpCopyObject %ulong %34 - OpStore %51 %57 Aligned 8 - %87 = OpFunctionCall %void %1 %20 %21 %22 %23 %24 - %36 = OpLoad %ulong %15 - %58 = OpConvertUToPtr %_ptr_Generic_ulong %36 - %35 = OpLoad %ulong %58 Aligned 8 - OpStore %17 %35 - %38 = OpLoad %ulong %17 - %37 = OpIAdd %ulong %38 %ulong_1 - OpStore %18 %37 - %39 = OpLoad %ulong %16 - %40 = OpLoad %ulong %18 - %59 = OpConvertUToPtr %_ptr_Generic_ulong %39 - OpStore %59 %40 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/atom_add.spvtxt b/ptx/src/test/spirv_run/atom_add.spvtxt deleted file mode 100644 index 987fdef..0000000 --- a/ptx/src/test/spirv_run/atom_add.spvtxt +++ /dev/null @@ -1,85 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - OpCapability DenormFlushToZero - OpExtension "SPV_KHR_float_controls" - OpExtension "SPV_KHR_no_integer_wrap_decoration" - %38 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "atom_add" %4 - OpExecutionMode %1 ContractionOff - OpDecorate %4 Alignment 4 - %void = OpTypeVoid - %uint = OpTypeInt 32 0 - %uchar = OpTypeInt 8 0 - %uint_1024 = OpConstant %uint 1024 -%_arr_uchar_uint_1024 = OpTypeArray %uchar %uint_1024 -%_ptr_Workgroup__arr_uchar_uint_1024 = OpTypePointer Workgroup %_arr_uchar_uint_1024 - %4 = OpVariable %_ptr_Workgroup__arr_uchar_uint_1024 Workgroup - %ulong = OpTypeInt 64 0 - %46 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong -%_ptr_Function_uint = OpTypePointer Function %uint -%_ptr_Generic_uint = OpTypePointer Generic %uint - %ulong_4 = OpConstant %ulong 4 -%_ptr_Generic_uchar = OpTypePointer Generic %uchar -%_ptr_Workgroup_uint = OpTypePointer Workgroup %uint - %uint_1 = OpConstant %uint 1 - %uint_0 = OpConstant %uint 0 - %ulong_4_0 = OpConstant %ulong 4 - %1 = OpFunction %void None %46 - %9 = OpFunctionParameter %ulong - %10 = OpFunctionParameter %ulong - %36 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_ulong Function - %7 = OpVariable %_ptr_Function_uint Function - %8 = OpVariable %_ptr_Function_uint Function - OpStore %2 %9 - OpStore %3 %10 - %11 = OpLoad %ulong %2 Aligned 8 - OpStore %5 %11 - %12 = OpLoad %ulong %3 Aligned 8 - OpStore %6 %12 - %14 = OpLoad %ulong %5 - %29 = OpConvertUToPtr %_ptr_Generic_uint %14 - %13 = OpLoad %uint %29 Aligned 4 - OpStore %7 %13 - %16 = OpLoad %ulong %5 - %30 = OpConvertUToPtr %_ptr_Generic_uint %16 - %51 = OpBitcast %_ptr_Generic_uchar %30 - %52 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %51 %ulong_4 - %26 = OpBitcast %_ptr_Generic_uint %52 - %15 = OpLoad %uint %26 Aligned 4 - OpStore %8 %15 - %17 = OpLoad %uint %7 - %31 = OpBitcast %_ptr_Workgroup_uint %4 - OpStore %31 %17 Aligned 4 - %19 = OpLoad %uint %8 - %32 = OpBitcast %_ptr_Workgroup_uint %4 - %18 = OpAtomicIAdd %uint %32 %uint_1 %uint_0 %19 - OpStore %7 %18 - %33 = OpBitcast %_ptr_Workgroup_uint %4 - %20 = OpLoad %uint %33 Aligned 4 - OpStore %8 %20 - %21 = OpLoad %ulong %6 - %22 = OpLoad %uint %7 - %34 = OpConvertUToPtr %_ptr_Generic_uint %21 - OpStore %34 %22 Aligned 4 - %23 = OpLoad %ulong %6 - %24 = OpLoad %uint %8 - %35 = OpConvertUToPtr %_ptr_Generic_uint %23 - %56 = OpBitcast %_ptr_Generic_uchar %35 - %57 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %56 %ulong_4_0 - %28 = OpBitcast %_ptr_Generic_uint %57 - OpStore %28 %24 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/atom_add_float.spvtxt b/ptx/src/test/spirv_run/atom_add_float.spvtxt deleted file mode 100644 index 067c347..0000000 --- a/ptx/src/test/spirv_run/atom_add_float.spvtxt +++ /dev/null @@ -1,90 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - OpCapability DenormFlushToZero - OpExtension "SPV_KHR_float_controls" - OpExtension "SPV_KHR_no_integer_wrap_decoration" - %42 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "atom_add_float" %4 - OpExecutionMode %1 ContractionOff - OpDecorate %37 LinkageAttributes "__zluda_ptx_impl__atom_relaxed_gpu_shared_add_f32" Import - OpDecorate %4 Alignment 4 - %void = OpTypeVoid - %float = OpTypeFloat 32 -%_ptr_Workgroup_float = OpTypePointer Workgroup %float - %46 = OpTypeFunction %float %_ptr_Workgroup_float %float - %uint = OpTypeInt 32 0 - %uchar = OpTypeInt 8 0 - %uint_1024 = OpConstant %uint 1024 -%_arr_uchar_uint_1024 = OpTypeArray %uchar %uint_1024 -%_ptr_Workgroup__arr_uchar_uint_1024 = OpTypePointer Workgroup %_arr_uchar_uint_1024 - %4 = OpVariable %_ptr_Workgroup__arr_uchar_uint_1024 Workgroup - %ulong = OpTypeInt 64 0 - %53 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong -%_ptr_Function_float = OpTypePointer Function %float -%_ptr_Generic_float = OpTypePointer Generic %float - %ulong_4 = OpConstant %ulong 4 -%_ptr_Generic_uchar = OpTypePointer Generic %uchar - %ulong_4_0 = OpConstant %ulong 4 - %37 = OpFunction %float None %46 - %39 = OpFunctionParameter %_ptr_Workgroup_float - %40 = OpFunctionParameter %float - OpFunctionEnd - %1 = OpFunction %void None %53 - %9 = OpFunctionParameter %ulong - %10 = OpFunctionParameter %ulong - %36 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_ulong Function - %7 = OpVariable %_ptr_Function_float Function - %8 = OpVariable %_ptr_Function_float Function - OpStore %2 %9 - OpStore %3 %10 - %11 = OpLoad %ulong %2 Aligned 8 - OpStore %5 %11 - %12 = OpLoad %ulong %3 Aligned 8 - OpStore %6 %12 - %14 = OpLoad %ulong %5 - %29 = OpConvertUToPtr %_ptr_Generic_float %14 - %13 = OpLoad %float %29 Aligned 4 - OpStore %7 %13 - %16 = OpLoad %ulong %5 - %30 = OpConvertUToPtr %_ptr_Generic_float %16 - %58 = OpBitcast %_ptr_Generic_uchar %30 - %59 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %58 %ulong_4 - %26 = OpBitcast %_ptr_Generic_float %59 - %15 = OpLoad %float %26 Aligned 4 - OpStore %8 %15 - %17 = OpLoad %float %7 - %31 = OpBitcast %_ptr_Workgroup_float %4 - OpStore %31 %17 Aligned 4 - %19 = OpLoad %float %8 - %32 = OpBitcast %_ptr_Workgroup_float %4 - %18 = OpFunctionCall %float %37 %32 %19 - OpStore %7 %18 - %33 = OpBitcast %_ptr_Workgroup_float %4 - %20 = OpLoad %float %33 Aligned 4 - OpStore %8 %20 - %21 = OpLoad %ulong %6 - %22 = OpLoad %float %7 - %34 = OpConvertUToPtr %_ptr_Generic_float %21 - OpStore %34 %22 Aligned 4 - %23 = OpLoad %ulong %6 - %24 = OpLoad %float %8 - %35 = OpConvertUToPtr %_ptr_Generic_float %23 - %60 = OpBitcast %_ptr_Generic_uchar %35 - %61 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %60 %ulong_4_0 - %28 = OpBitcast %_ptr_Generic_float %61 - OpStore %28 %24 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/atom_cas.spvtxt b/ptx/src/test/spirv_run/atom_cas.spvtxt deleted file mode 100644 index 7c2f4fa..0000000 --- a/ptx/src/test/spirv_run/atom_cas.spvtxt +++ /dev/null @@ -1,77 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %39 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "atom_cas" - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %42 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %uint = OpTypeInt 32 0 -%_ptr_Function_uint = OpTypePointer Function %uint -%_ptr_Generic_uint = OpTypePointer Generic %uint - %ulong_4 = OpConstant %ulong 4 - %uchar = OpTypeInt 8 0 -%_ptr_Generic_uchar = OpTypePointer Generic %uchar - %uint_100 = OpConstant %uint 100 - %uint_1 = OpConstant %uint 1 - %uint_0 = OpConstant %uint 0 - %ulong_4_0 = OpConstant %ulong 4 - %ulong_4_1 = OpConstant %ulong 4 - %1 = OpFunction %void None %42 - %8 = OpFunctionParameter %ulong - %9 = OpFunctionParameter %ulong - %37 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_uint Function - %7 = OpVariable %_ptr_Function_uint Function - OpStore %2 %8 - OpStore %3 %9 - %10 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %30 = OpConvertUToPtr %_ptr_Generic_uint %13 - %12 = OpLoad %uint %30 Aligned 4 - OpStore %6 %12 - %15 = OpLoad %ulong %4 - %16 = OpLoad %uint %6 - %31 = OpConvertUToPtr %_ptr_Generic_uint %15 - %49 = OpBitcast %_ptr_Generic_uchar %31 - %50 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %49 %ulong_4 - %24 = OpBitcast %_ptr_Generic_uint %50 - %33 = OpCopyObject %uint %16 - %32 = OpAtomicCompareExchange %uint %24 %uint_1 %uint_0 %uint_0 %uint_100 %33 - %14 = OpCopyObject %uint %32 - OpStore %6 %14 - %18 = OpLoad %ulong %4 - %34 = OpConvertUToPtr %_ptr_Generic_uint %18 - %53 = OpBitcast %_ptr_Generic_uchar %34 - %54 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %53 %ulong_4_0 - %27 = OpBitcast %_ptr_Generic_uint %54 - %17 = OpLoad %uint %27 Aligned 4 - OpStore %7 %17 - %19 = OpLoad %ulong %5 - %20 = OpLoad %uint %6 - %35 = OpConvertUToPtr %_ptr_Generic_uint %19 - OpStore %35 %20 Aligned 4 - %21 = OpLoad %ulong %5 - %22 = OpLoad %uint %7 - %36 = OpConvertUToPtr %_ptr_Generic_uint %21 - %55 = OpBitcast %_ptr_Generic_uchar %36 - %56 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %55 %ulong_4_1 - %29 = OpBitcast %_ptr_Generic_uint %56 - OpStore %29 %22 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/atom_inc.spvtxt b/ptx/src/test/spirv_run/atom_inc.spvtxt deleted file mode 100644 index 4855cd4..0000000 --- a/ptx/src/test/spirv_run/atom_inc.spvtxt +++ /dev/null @@ -1,87 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %47 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "atom_inc" - OpDecorate %38 LinkageAttributes "__zluda_ptx_impl__atom_relaxed_gpu_generic_inc" Import - OpDecorate %42 LinkageAttributes "__zluda_ptx_impl__atom_relaxed_gpu_global_inc" Import - %void = OpTypeVoid - %uint = OpTypeInt 32 0 -%_ptr_Generic_uint = OpTypePointer Generic %uint - %51 = OpTypeFunction %uint %_ptr_Generic_uint %uint -%_ptr_CrossWorkgroup_uint = OpTypePointer CrossWorkgroup %uint - %53 = OpTypeFunction %uint %_ptr_CrossWorkgroup_uint %uint - %ulong = OpTypeInt 64 0 - %55 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong -%_ptr_Function_uint = OpTypePointer Function %uint - %uint_101 = OpConstant %uint 101 - %uint_101_0 = OpConstant %uint 101 - %ulong_4 = OpConstant %ulong 4 - %uchar = OpTypeInt 8 0 -%_ptr_Generic_uchar = OpTypePointer Generic %uchar - %ulong_8 = OpConstant %ulong 8 - %38 = OpFunction %uint None %51 - %40 = OpFunctionParameter %_ptr_Generic_uint - %41 = OpFunctionParameter %uint - OpFunctionEnd - %42 = OpFunction %uint None %53 - %44 = OpFunctionParameter %_ptr_CrossWorkgroup_uint - %45 = OpFunctionParameter %uint - OpFunctionEnd - %1 = OpFunction %void None %55 - %9 = OpFunctionParameter %ulong - %10 = OpFunctionParameter %ulong - %37 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_uint Function - %7 = OpVariable %_ptr_Function_uint Function - %8 = OpVariable %_ptr_Function_uint Function - OpStore %2 %9 - OpStore %3 %10 - %11 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %11 - %12 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %12 - %14 = OpLoad %ulong %4 - %31 = OpConvertUToPtr %_ptr_Generic_uint %14 - %13 = OpFunctionCall %uint %38 %31 %uint_101 - OpStore %6 %13 - %16 = OpLoad %ulong %4 - %32 = OpConvertUToPtr %_ptr_CrossWorkgroup_uint %16 - %15 = OpFunctionCall %uint %42 %32 %uint_101_0 - OpStore %7 %15 - %18 = OpLoad %ulong %4 - %33 = OpConvertUToPtr %_ptr_Generic_uint %18 - %17 = OpLoad %uint %33 Aligned 4 - OpStore %8 %17 - %19 = OpLoad %ulong %5 - %20 = OpLoad %uint %6 - %34 = OpConvertUToPtr %_ptr_Generic_uint %19 - OpStore %34 %20 Aligned 4 - %21 = OpLoad %ulong %5 - %22 = OpLoad %uint %7 - %35 = OpConvertUToPtr %_ptr_Generic_uint %21 - %60 = OpBitcast %_ptr_Generic_uchar %35 - %61 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %60 %ulong_4 - %28 = OpBitcast %_ptr_Generic_uint %61 - OpStore %28 %22 Aligned 4 - %23 = OpLoad %ulong %5 - %24 = OpLoad %uint %8 - %36 = OpConvertUToPtr %_ptr_Generic_uint %23 - %62 = OpBitcast %_ptr_Generic_uchar %36 - %63 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %62 %ulong_8 - %30 = OpBitcast %_ptr_Generic_uint %63 - OpStore %30 %24 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/b64tof64.spvtxt b/ptx/src/test/spirv_run/b64tof64.spvtxt deleted file mode 100644 index 54ac111..0000000 --- a/ptx/src/test/spirv_run/b64tof64.spvtxt +++ /dev/null @@ -1,50 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %24 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "b64tof64" - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %27 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %double = OpTypeFloat 64 -%_ptr_Function_double = OpTypePointer Function %double -%_ptr_Generic_ulong = OpTypePointer Generic %ulong - %1 = OpFunction %void None %27 - %8 = OpFunctionParameter %ulong - %9 = OpFunctionParameter %ulong - %22 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_double Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_ulong Function - %7 = OpVariable %_ptr_Function_ulong Function - OpStore %2 %8 - OpStore %3 %9 - %18 = OpBitcast %_ptr_Function_double %2 - %10 = OpLoad %double %18 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %6 %11 - %13 = OpLoad %double %4 - %19 = OpBitcast %ulong %13 - %12 = OpCopyObject %ulong %19 - OpStore %5 %12 - %15 = OpLoad %ulong %5 - %20 = OpConvertUToPtr %_ptr_Generic_ulong %15 - %14 = OpLoad %ulong %20 Aligned 8 - OpStore %7 %14 - %16 = OpLoad %ulong %6 - %17 = OpLoad %ulong %7 - %21 = OpConvertUToPtr %_ptr_Generic_ulong %16 - OpStore %21 %17 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/bfe.spvtxt b/ptx/src/test/spirv_run/bfe.spvtxt deleted file mode 100644 index 0001808..0000000 --- a/ptx/src/test/spirv_run/bfe.spvtxt +++ /dev/null @@ -1,76 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %40 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "bfe" - OpDecorate %34 LinkageAttributes "__zluda_ptx_impl__bfe_u32" Import - %void = OpTypeVoid - %uint = OpTypeInt 32 0 - %43 = OpTypeFunction %uint %uint %uint %uint - %ulong = OpTypeInt 64 0 - %45 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong -%_ptr_Function_uint = OpTypePointer Function %uint -%_ptr_Generic_uint = OpTypePointer Generic %uint - %ulong_4 = OpConstant %ulong 4 - %uchar = OpTypeInt 8 0 -%_ptr_Generic_uchar = OpTypePointer Generic %uchar - %ulong_8 = OpConstant %ulong 8 - %34 = OpFunction %uint None %43 - %36 = OpFunctionParameter %uint - %37 = OpFunctionParameter %uint - %38 = OpFunctionParameter %uint - OpFunctionEnd - %1 = OpFunction %void None %45 - %9 = OpFunctionParameter %ulong - %10 = OpFunctionParameter %ulong - %33 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_uint Function - %7 = OpVariable %_ptr_Function_uint Function - %8 = OpVariable %_ptr_Function_uint Function - OpStore %2 %9 - OpStore %3 %10 - %11 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %11 - %12 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %12 - %14 = OpLoad %ulong %4 - %29 = OpConvertUToPtr %_ptr_Generic_uint %14 - %13 = OpLoad %uint %29 Aligned 4 - OpStore %6 %13 - %16 = OpLoad %ulong %4 - %30 = OpConvertUToPtr %_ptr_Generic_uint %16 - %51 = OpBitcast %_ptr_Generic_uchar %30 - %52 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %51 %ulong_4 - %26 = OpBitcast %_ptr_Generic_uint %52 - %15 = OpLoad %uint %26 Aligned 4 - OpStore %7 %15 - %18 = OpLoad %ulong %4 - %31 = OpConvertUToPtr %_ptr_Generic_uint %18 - %53 = OpBitcast %_ptr_Generic_uchar %31 - %54 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %53 %ulong_8 - %28 = OpBitcast %_ptr_Generic_uint %54 - %17 = OpLoad %uint %28 Aligned 4 - OpStore %8 %17 - %20 = OpLoad %uint %6 - %21 = OpLoad %uint %7 - %22 = OpLoad %uint %8 - %19 = OpFunctionCall %uint %34 %20 %21 %22 - OpStore %6 %19 - %23 = OpLoad %ulong %5 - %24 = OpLoad %uint %6 - %32 = OpConvertUToPtr %_ptr_Generic_uint %23 - OpStore %32 %24 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/bfi.spvtxt b/ptx/src/test/spirv_run/bfi.spvtxt deleted file mode 100644 index 1979939..0000000 --- a/ptx/src/test/spirv_run/bfi.spvtxt +++ /dev/null @@ -1,90 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %51 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "bfi" - OpDecorate %44 LinkageAttributes "__zluda_ptx_impl__bfi_b32" Import - %void = OpTypeVoid - %uint = OpTypeInt 32 0 - %54 = OpTypeFunction %uint %uint %uint %uint %uint - %ulong = OpTypeInt 64 0 - %56 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong -%_ptr_Function_uint = OpTypePointer Function %uint -%_ptr_Generic_uint = OpTypePointer Generic %uint - %ulong_4 = OpConstant %ulong 4 - %uchar = OpTypeInt 8 0 -%_ptr_Generic_uchar = OpTypePointer Generic %uchar - %ulong_8 = OpConstant %ulong 8 - %ulong_12 = OpConstant %ulong 12 - %44 = OpFunction %uint None %54 - %46 = OpFunctionParameter %uint - %47 = OpFunctionParameter %uint - %48 = OpFunctionParameter %uint - %49 = OpFunctionParameter %uint - OpFunctionEnd - %1 = OpFunction %void None %56 - %10 = OpFunctionParameter %ulong - %11 = OpFunctionParameter %ulong - %43 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_uint Function - %7 = OpVariable %_ptr_Function_uint Function - %8 = OpVariable %_ptr_Function_uint Function - %9 = OpVariable %_ptr_Function_uint Function - OpStore %2 %10 - OpStore %3 %11 - %12 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %12 - %13 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %13 - %15 = OpLoad %ulong %4 - %35 = OpConvertUToPtr %_ptr_Generic_uint %15 - %14 = OpLoad %uint %35 Aligned 4 - OpStore %6 %14 - %17 = OpLoad %ulong %4 - %36 = OpConvertUToPtr %_ptr_Generic_uint %17 - %62 = OpBitcast %_ptr_Generic_uchar %36 - %63 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %62 %ulong_4 - %30 = OpBitcast %_ptr_Generic_uint %63 - %16 = OpLoad %uint %30 Aligned 4 - OpStore %7 %16 - %19 = OpLoad %ulong %4 - %37 = OpConvertUToPtr %_ptr_Generic_uint %19 - %64 = OpBitcast %_ptr_Generic_uchar %37 - %65 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %64 %ulong_8 - %32 = OpBitcast %_ptr_Generic_uint %65 - %18 = OpLoad %uint %32 Aligned 4 - OpStore %8 %18 - %21 = OpLoad %ulong %4 - %38 = OpConvertUToPtr %_ptr_Generic_uint %21 - %66 = OpBitcast %_ptr_Generic_uchar %38 - %67 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %66 %ulong_12 - %34 = OpBitcast %_ptr_Generic_uint %67 - %20 = OpLoad %uint %34 Aligned 4 - OpStore %9 %20 - %23 = OpLoad %uint %6 - %24 = OpLoad %uint %7 - %25 = OpLoad %uint %8 - %26 = OpLoad %uint %9 - %40 = OpCopyObject %uint %23 - %41 = OpCopyObject %uint %24 - %39 = OpFunctionCall %uint %44 %40 %41 %25 %26 - %22 = OpCopyObject %uint %39 - OpStore %6 %22 - %27 = OpLoad %ulong %5 - %28 = OpLoad %uint %6 - %42 = OpConvertUToPtr %_ptr_Generic_uint %27 - OpStore %42 %28 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/block.spvtxt b/ptx/src/test/spirv_run/block.spvtxt deleted file mode 100644 index 6921c04..0000000 --- a/ptx/src/test/spirv_run/block.spvtxt +++ /dev/null @@ -1,52 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %27 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "block" - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %30 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong -%_ptr_Generic_ulong = OpTypePointer Generic %ulong - %ulong_1 = OpConstant %ulong 1 - %ulong_1_0 = OpConstant %ulong 1 - %1 = OpFunction %void None %30 - %9 = OpFunctionParameter %ulong - %10 = OpFunctionParameter %ulong - %25 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_ulong Function - %7 = OpVariable %_ptr_Function_ulong Function - %8 = OpVariable %_ptr_Function_ulong Function - OpStore %2 %9 - OpStore %3 %10 - %11 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %11 - %12 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %12 - %14 = OpLoad %ulong %4 - %23 = OpConvertUToPtr %_ptr_Generic_ulong %14 - %13 = OpLoad %ulong %23 Aligned 8 - OpStore %6 %13 - %16 = OpLoad %ulong %6 - %15 = OpIAdd %ulong %16 %ulong_1 - OpStore %7 %15 - %18 = OpLoad %ulong %8 - %17 = OpIAdd %ulong %18 %ulong_1_0 - OpStore %8 %17 - %19 = OpLoad %ulong %5 - %20 = OpLoad %ulong %7 - %24 = OpConvertUToPtr %_ptr_Generic_ulong %19 - OpStore %24 %20 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/bra.spvtxt b/ptx/src/test/spirv_run/bra.spvtxt deleted file mode 100644 index c2c1e1c..0000000 --- a/ptx/src/test/spirv_run/bra.spvtxt +++ /dev/null @@ -1,57 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %29 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "bra" - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %32 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong -%_ptr_Generic_ulong = OpTypePointer Generic %ulong - %ulong_1 = OpConstant %ulong 1 - %ulong_2 = OpConstant %ulong 2 - %1 = OpFunction %void None %32 - %11 = OpFunctionParameter %ulong - %12 = OpFunctionParameter %ulong - %27 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %7 = OpVariable %_ptr_Function_ulong Function - %8 = OpVariable %_ptr_Function_ulong Function - %9 = OpVariable %_ptr_Function_ulong Function - %10 = OpVariable %_ptr_Function_ulong Function - OpStore %2 %11 - OpStore %3 %12 - %13 = OpLoad %ulong %2 Aligned 8 - OpStore %7 %13 - %14 = OpLoad %ulong %3 Aligned 8 - OpStore %8 %14 - %16 = OpLoad %ulong %7 - %25 = OpConvertUToPtr %_ptr_Generic_ulong %16 - %15 = OpLoad %ulong %25 Aligned 8 - OpStore %9 %15 - OpBranch %4 - %4 = OpLabel - %18 = OpLoad %ulong %9 - %17 = OpIAdd %ulong %18 %ulong_1 - OpStore %10 %17 - OpBranch %6 - %35 = OpLabel - %20 = OpLoad %ulong %9 - %19 = OpIAdd %ulong %20 %ulong_2 - OpStore %10 %19 - OpBranch %6 - %6 = OpLabel - %21 = OpLoad %ulong %8 - %22 = OpLoad %ulong %10 - %26 = OpConvertUToPtr %_ptr_Generic_ulong %21 - OpStore %26 %22 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/brev.spvtxt b/ptx/src/test/spirv_run/brev.spvtxt deleted file mode 100644 index 7341adb..0000000 --- a/ptx/src/test/spirv_run/brev.spvtxt +++ /dev/null @@ -1,52 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %24 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "brev" - OpDecorate %20 LinkageAttributes "__zluda_ptx_impl__brev_b32" Import - %void = OpTypeVoid - %uint = OpTypeInt 32 0 - %27 = OpTypeFunction %uint %uint - %ulong = OpTypeInt 64 0 - %29 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong -%_ptr_Function_uint = OpTypePointer Function %uint -%_ptr_Generic_uint = OpTypePointer Generic %uint - %20 = OpFunction %uint None %27 - %22 = OpFunctionParameter %uint - OpFunctionEnd - %1 = OpFunction %void None %29 - %7 = OpFunctionParameter %ulong - %8 = OpFunctionParameter %ulong - %19 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_uint Function - OpStore %2 %7 - OpStore %3 %8 - %9 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %9 - %10 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %10 - %12 = OpLoad %ulong %4 - %17 = OpConvertUToPtr %_ptr_Generic_uint %12 - %11 = OpLoad %uint %17 Aligned 4 - OpStore %6 %11 - %14 = OpLoad %uint %6 - %13 = OpFunctionCall %uint %20 %14 - OpStore %6 %13 - %15 = OpLoad %ulong %5 - %16 = OpLoad %uint %6 - %18 = OpConvertUToPtr %_ptr_Generic_uint %15 - OpStore %18 %16 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/call.spvtxt b/ptx/src/test/spirv_run/call.spvtxt deleted file mode 100644 index c29984e..0000000 --- a/ptx/src/test/spirv_run/call.spvtxt +++ /dev/null @@ -1,71 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - OpCapability DenormFlushToZero - %37 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %4 "call" - OpExecutionMode %4 ContractionOff - OpDecorate %4 LinkageAttributes "call" Export - OpDecorate %1 LinkageAttributes "incr" Export - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %40 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong -%_ptr_CrossWorkgroup_ulong = OpTypePointer CrossWorkgroup %ulong - %44 = OpTypeFunction %void %_ptr_Function_ulong %_ptr_Function_ulong - %ulong_1 = OpConstant %ulong 1 - %4 = OpFunction %void None %40 - %12 = OpFunctionParameter %ulong - %13 = OpFunctionParameter %ulong - %26 = OpLabel - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_ulong Function - %7 = OpVariable %_ptr_Function_ulong Function - %8 = OpVariable %_ptr_Function_ulong Function - %9 = OpVariable %_ptr_Function_ulong Function - %10 = OpVariable %_ptr_Function_ulong Function - %11 = OpVariable %_ptr_Function_ulong Function - OpStore %5 %12 - OpStore %6 %13 - %14 = OpLoad %ulong %5 Aligned 8 - OpStore %7 %14 - %15 = OpLoad %ulong %6 Aligned 8 - OpStore %8 %15 - %17 = OpLoad %ulong %7 - %22 = OpConvertUToPtr %_ptr_CrossWorkgroup_ulong %17 - %16 = OpLoad %ulong %22 Aligned 8 - OpStore %9 %16 - %18 = OpLoad %ulong %9 - %23 = OpBitcast %_ptr_Function_ulong %10 - %24 = OpCopyObject %ulong %18 - OpStore %23 %24 Aligned 8 - %43 = OpFunctionCall %void %1 %10 %11 - %19 = OpLoad %ulong %11 Aligned 8 - OpStore %9 %19 - %20 = OpLoad %ulong %8 - %21 = OpLoad %ulong %9 - %25 = OpConvertUToPtr %_ptr_CrossWorkgroup_ulong %20 - OpStore %25 %21 Aligned 8 - OpReturn - OpFunctionEnd - %1 = OpFunction %void None %44 - %28 = OpFunctionParameter %_ptr_Function_ulong - %27 = OpFunctionParameter %_ptr_Function_ulong - %35 = OpLabel - %29 = OpVariable %_ptr_Function_ulong Function - %30 = OpLoad %ulong %28 Aligned 8 - OpStore %29 %30 - %32 = OpLoad %ulong %29 - %31 = OpIAdd %ulong %32 %ulong_1 - OpStore %29 %31 - %33 = OpLoad %ulong %29 - OpStore %27 %33 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/clz.spvtxt b/ptx/src/test/spirv_run/clz.spvtxt deleted file mode 100644 index 1feb5a0..0000000 --- a/ptx/src/test/spirv_run/clz.spvtxt +++ /dev/null @@ -1,52 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - OpCapability DenormFlushToZero - OpExtension "SPV_KHR_float_controls" - OpExtension "SPV_KHR_no_integer_wrap_decoration" - %22 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "clz" - OpExecutionMode %1 ContractionOff - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %25 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %uint = OpTypeInt 32 0 -%_ptr_Function_uint = OpTypePointer Function %uint -%_ptr_Generic_uint = OpTypePointer Generic %uint - %1 = OpFunction %void None %25 - %7 = OpFunctionParameter %ulong - %8 = OpFunctionParameter %ulong - %20 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_uint Function - OpStore %2 %7 - OpStore %3 %8 - %9 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %9 - %10 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %10 - %12 = OpLoad %ulong %4 - %17 = OpConvertUToPtr %_ptr_Generic_uint %12 - %11 = OpLoad %uint %17 Aligned 4 - OpStore %6 %11 - %14 = OpLoad %uint %6 - %18 = OpExtInst %uint %22 clz %14 - %13 = OpCopyObject %uint %18 - OpStore %6 %13 - %15 = OpLoad %ulong %5 - %16 = OpLoad %uint %6 - %19 = OpConvertUToPtr %_ptr_Generic_uint %15 - OpStore %19 %16 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/const.spvtxt b/ptx/src/test/spirv_run/const.spvtxt deleted file mode 100644 index 49ed9c3..0000000 --- a/ptx/src/test/spirv_run/const.spvtxt +++ /dev/null @@ -1,112 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %53 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %2 "const" %1 - OpExecutionMode %2 ContractionOff - OpDecorate %1 Alignment 8 - %void = OpTypeVoid - %uint = OpTypeInt 32 0 - %ushort = OpTypeInt 16 0 - %uint_4 = OpConstant %uint 4 -%_arr_ushort_uint_4 = OpTypeArray %ushort %uint_4 - %ushort_10 = OpConstant %ushort 10 - %ushort_20 = OpConstant %ushort 20 - %ushort_30 = OpConstant %ushort 30 - %ushort_40 = OpConstant %ushort 40 - %63 = OpConstantComposite %_arr_ushort_uint_4 %ushort_10 %ushort_20 %ushort_30 %ushort_40 - %uint_4_0 = OpConstant %uint 4 -%_ptr_UniformConstant__arr_ushort_uint_4 = OpTypePointer UniformConstant %_arr_ushort_uint_4 - %1 = OpVariable %_ptr_UniformConstant__arr_ushort_uint_4 UniformConstant %63 - %ulong = OpTypeInt 64 0 - %67 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong -%_ptr_Function_ushort = OpTypePointer Function %ushort -%_ptr_UniformConstant_ushort = OpTypePointer UniformConstant %ushort - %ulong_2 = OpConstant %ulong 2 - %uchar = OpTypeInt 8 0 -%_ptr_UniformConstant_uchar = OpTypePointer UniformConstant %uchar - %ulong_4 = OpConstant %ulong 4 - %ulong_6 = OpConstant %ulong 6 -%_ptr_Generic_ushort = OpTypePointer Generic %ushort - %ulong_2_0 = OpConstant %ulong 2 -%_ptr_Generic_uchar = OpTypePointer Generic %uchar - %ulong_4_0 = OpConstant %ulong 4 - %ulong_6_0 = OpConstant %ulong 6 - %2 = OpFunction %void None %67 - %11 = OpFunctionParameter %ulong - %12 = OpFunctionParameter %ulong - %51 = OpLabel - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_ulong Function - %7 = OpVariable %_ptr_Function_ushort Function - %8 = OpVariable %_ptr_Function_ushort Function - %9 = OpVariable %_ptr_Function_ushort Function - %10 = OpVariable %_ptr_Function_ushort Function - OpStore %3 %11 - OpStore %4 %12 - %13 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %13 - %14 = OpLoad %ulong %4 Aligned 8 - OpStore %6 %14 - %39 = OpBitcast %_ptr_UniformConstant_ushort %1 - %15 = OpLoad %ushort %39 Aligned 2 - OpStore %7 %15 - %40 = OpBitcast %_ptr_UniformConstant_ushort %1 - %73 = OpBitcast %_ptr_UniformConstant_uchar %40 - %74 = OpInBoundsPtrAccessChain %_ptr_UniformConstant_uchar %73 %ulong_2 - %28 = OpBitcast %_ptr_UniformConstant_ushort %74 - %16 = OpLoad %ushort %28 Aligned 2 - OpStore %8 %16 - %41 = OpBitcast %_ptr_UniformConstant_ushort %1 - %75 = OpBitcast %_ptr_UniformConstant_uchar %41 - %76 = OpInBoundsPtrAccessChain %_ptr_UniformConstant_uchar %75 %ulong_4 - %30 = OpBitcast %_ptr_UniformConstant_ushort %76 - %17 = OpLoad %ushort %30 Aligned 2 - OpStore %9 %17 - %42 = OpBitcast %_ptr_UniformConstant_ushort %1 - %77 = OpBitcast %_ptr_UniformConstant_uchar %42 - %78 = OpInBoundsPtrAccessChain %_ptr_UniformConstant_uchar %77 %ulong_6 - %32 = OpBitcast %_ptr_UniformConstant_ushort %78 - %18 = OpLoad %ushort %32 Aligned 2 - OpStore %10 %18 - %19 = OpLoad %ulong %6 - %20 = OpLoad %ushort %7 - %43 = OpConvertUToPtr %_ptr_Generic_ushort %19 - %44 = OpCopyObject %ushort %20 - OpStore %43 %44 Aligned 2 - %21 = OpLoad %ulong %6 - %22 = OpLoad %ushort %8 - %45 = OpConvertUToPtr %_ptr_Generic_ushort %21 - %81 = OpBitcast %_ptr_Generic_uchar %45 - %82 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %81 %ulong_2_0 - %34 = OpBitcast %_ptr_Generic_ushort %82 - %46 = OpCopyObject %ushort %22 - OpStore %34 %46 Aligned 2 - %23 = OpLoad %ulong %6 - %24 = OpLoad %ushort %9 - %47 = OpConvertUToPtr %_ptr_Generic_ushort %23 - %83 = OpBitcast %_ptr_Generic_uchar %47 - %84 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %83 %ulong_4_0 - %36 = OpBitcast %_ptr_Generic_ushort %84 - %48 = OpCopyObject %ushort %24 - OpStore %36 %48 Aligned 2 - %25 = OpLoad %ulong %6 - %26 = OpLoad %ushort %10 - %49 = OpConvertUToPtr %_ptr_Generic_ushort %25 - %85 = OpBitcast %_ptr_Generic_uchar %49 - %86 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %85 %ulong_6_0 - %38 = OpBitcast %_ptr_Generic_ushort %86 - %50 = OpCopyObject %ushort %26 - OpStore %38 %50 Aligned 2 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/constant_f32.spvtxt b/ptx/src/test/spirv_run/constant_f32.spvtxt deleted file mode 100644 index b331ae6..0000000 --- a/ptx/src/test/spirv_run/constant_f32.spvtxt +++ /dev/null @@ -1,48 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %22 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "constant_f32" - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %25 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %float = OpTypeFloat 32 -%_ptr_Function_float = OpTypePointer Function %float -%_ptr_Generic_float = OpTypePointer Generic %float - %float_0_5 = OpConstant %float 0.5 - %1 = OpFunction %void None %25 - %7 = OpFunctionParameter %ulong - %8 = OpFunctionParameter %ulong - %20 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_float Function - OpStore %2 %7 - OpStore %3 %8 - %9 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %9 - %10 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %10 - %12 = OpLoad %ulong %4 - %18 = OpConvertUToPtr %_ptr_Generic_float %12 - %11 = OpLoad %float %18 Aligned 4 - OpStore %6 %11 - %14 = OpLoad %float %6 - %13 = OpFMul %float %14 %float_0_5 - OpStore %6 %13 - %15 = OpLoad %ulong %5 - %16 = OpLoad %float %6 - %19 = OpConvertUToPtr %_ptr_Generic_float %15 - OpStore %19 %16 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/constant_negative.spvtxt b/ptx/src/test/spirv_run/constant_negative.spvtxt deleted file mode 100644 index 9a5c7de..0000000 --- a/ptx/src/test/spirv_run/constant_negative.spvtxt +++ /dev/null @@ -1,48 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %22 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "constant_negative" - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %25 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %uint = OpTypeInt 32 0 -%_ptr_Function_uint = OpTypePointer Function %uint -%_ptr_Generic_uint = OpTypePointer Generic %uint -%uint_4294967295 = OpConstant %uint 4294967295 - %1 = OpFunction %void None %25 - %7 = OpFunctionParameter %ulong - %8 = OpFunctionParameter %ulong - %20 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_uint Function - OpStore %2 %7 - OpStore %3 %8 - %9 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %9 - %10 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %10 - %12 = OpLoad %ulong %4 - %18 = OpConvertUToPtr %_ptr_Generic_uint %12 - %11 = OpLoad %uint %18 Aligned 4 - OpStore %6 %11 - %14 = OpLoad %uint %6 - %13 = OpIMul %uint %14 %uint_4294967295 - OpStore %6 %13 - %15 = OpLoad %ulong %5 - %16 = OpLoad %uint %6 - %19 = OpConvertUToPtr %_ptr_Generic_uint %15 - OpStore %19 %16 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/cos.spvtxt b/ptx/src/test/spirv_run/cos.spvtxt deleted file mode 100644 index a79cdbe..0000000 --- a/ptx/src/test/spirv_run/cos.spvtxt +++ /dev/null @@ -1,48 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %21 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "cos" - OpExecutionMode %1 ContractionOff - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %24 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %float = OpTypeFloat 32 -%_ptr_Function_float = OpTypePointer Function %float -%_ptr_Generic_float = OpTypePointer Generic %float - %1 = OpFunction %void None %24 - %7 = OpFunctionParameter %ulong - %8 = OpFunctionParameter %ulong - %19 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_float Function - OpStore %2 %7 - OpStore %3 %8 - %9 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %9 - %10 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %10 - %12 = OpLoad %ulong %4 - %17 = OpConvertUToPtr %_ptr_Generic_float %12 - %11 = OpLoad %float %17 Aligned 4 - OpStore %6 %11 - %14 = OpLoad %float %6 - %13 = OpExtInst %float %21 cos %14 - OpStore %6 %13 - %15 = OpLoad %ulong %5 - %16 = OpLoad %float %6 - %18 = OpConvertUToPtr %_ptr_Generic_float %15 - OpStore %18 %16 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/cvt_f64_f32.spvtxt b/ptx/src/test/spirv_run/cvt_f64_f32.spvtxt deleted file mode 100644 index 907cce4..0000000 --- a/ptx/src/test/spirv_run/cvt_f64_f32.spvtxt +++ /dev/null @@ -1,55 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %22 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "cvt_f64_f32" - OpExecutionMode %1 DenormFlushToZero 16 - OpExecutionMode %1 DenormFlushToZero 32 - OpExecutionMode %1 DenormFlushToZero 64 - OpExecutionMode %1 ContractionOff - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %25 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %float = OpTypeFloat 32 -%_ptr_Function_float = OpTypePointer Function %float - %double = OpTypeFloat 64 -%_ptr_Function_double = OpTypePointer Function %double -%_ptr_CrossWorkgroup_float = OpTypePointer CrossWorkgroup %float -%_ptr_Generic_double = OpTypePointer Generic %double - %1 = OpFunction %void None %25 - %8 = OpFunctionParameter %ulong - %9 = OpFunctionParameter %ulong - %20 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_float Function - %7 = OpVariable %_ptr_Function_double Function - OpStore %2 %8 - OpStore %3 %9 - %10 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %18 = OpConvertUToPtr %_ptr_CrossWorkgroup_float %13 - %12 = OpLoad %float %18 Aligned 4 - OpStore %6 %12 - %15 = OpLoad %float %6 - %14 = OpFConvert %double %15 - OpStore %7 %14 - %16 = OpLoad %ulong %5 - %17 = OpLoad %double %7 - %19 = OpConvertUToPtr %_ptr_Generic_double %16 - OpStore %19 %17 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/cvt_rni.spvtxt b/ptx/src/test/spirv_run/cvt_rni.spvtxt deleted file mode 100644 index e10999c..0000000 --- a/ptx/src/test/spirv_run/cvt_rni.spvtxt +++ /dev/null @@ -1,69 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %34 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "cvt_rni" - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %37 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %float = OpTypeFloat 32 -%_ptr_Function_float = OpTypePointer Function %float -%_ptr_Generic_float = OpTypePointer Generic %float - %ulong_4 = OpConstant %ulong 4 - %uchar = OpTypeInt 8 0 -%_ptr_Generic_uchar = OpTypePointer Generic %uchar - %ulong_4_0 = OpConstant %ulong 4 - %1 = OpFunction %void None %37 - %8 = OpFunctionParameter %ulong - %9 = OpFunctionParameter %ulong - %32 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_float Function - %7 = OpVariable %_ptr_Function_float Function - OpStore %2 %8 - OpStore %3 %9 - %10 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %28 = OpConvertUToPtr %_ptr_Generic_float %13 - %12 = OpLoad %float %28 Aligned 4 - OpStore %6 %12 - %15 = OpLoad %ulong %4 - %29 = OpConvertUToPtr %_ptr_Generic_float %15 - %44 = OpBitcast %_ptr_Generic_uchar %29 - %45 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %44 %ulong_4 - %25 = OpBitcast %_ptr_Generic_float %45 - %14 = OpLoad %float %25 Aligned 4 - OpStore %7 %14 - %17 = OpLoad %float %6 - %16 = OpExtInst %float %34 rint %17 - OpStore %6 %16 - %19 = OpLoad %float %7 - %18 = OpExtInst %float %34 rint %19 - OpStore %7 %18 - %20 = OpLoad %ulong %5 - %21 = OpLoad %float %6 - %30 = OpConvertUToPtr %_ptr_Generic_float %20 - OpStore %30 %21 Aligned 4 - %22 = OpLoad %ulong %5 - %23 = OpLoad %float %7 - %31 = OpConvertUToPtr %_ptr_Generic_float %22 - %46 = OpBitcast %_ptr_Generic_uchar %31 - %47 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %46 %ulong_4_0 - %27 = OpBitcast %_ptr_Generic_float %47 - OpStore %27 %23 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/cvt_rzi.spvtxt b/ptx/src/test/spirv_run/cvt_rzi.spvtxt deleted file mode 100644 index 7dda454..0000000 --- a/ptx/src/test/spirv_run/cvt_rzi.spvtxt +++ /dev/null @@ -1,69 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %34 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "cvt_rzi" - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %37 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %float = OpTypeFloat 32 -%_ptr_Function_float = OpTypePointer Function %float -%_ptr_Generic_float = OpTypePointer Generic %float - %ulong_4 = OpConstant %ulong 4 - %uchar = OpTypeInt 8 0 -%_ptr_Generic_uchar = OpTypePointer Generic %uchar - %ulong_4_0 = OpConstant %ulong 4 - %1 = OpFunction %void None %37 - %8 = OpFunctionParameter %ulong - %9 = OpFunctionParameter %ulong - %32 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_float Function - %7 = OpVariable %_ptr_Function_float Function - OpStore %2 %8 - OpStore %3 %9 - %10 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %28 = OpConvertUToPtr %_ptr_Generic_float %13 - %12 = OpLoad %float %28 Aligned 4 - OpStore %6 %12 - %15 = OpLoad %ulong %4 - %29 = OpConvertUToPtr %_ptr_Generic_float %15 - %44 = OpBitcast %_ptr_Generic_uchar %29 - %45 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %44 %ulong_4 - %25 = OpBitcast %_ptr_Generic_float %45 - %14 = OpLoad %float %25 Aligned 4 - OpStore %7 %14 - %17 = OpLoad %float %6 - %16 = OpExtInst %float %34 trunc %17 - OpStore %6 %16 - %19 = OpLoad %float %7 - %18 = OpExtInst %float %34 trunc %19 - OpStore %7 %18 - %20 = OpLoad %ulong %5 - %21 = OpLoad %float %6 - %30 = OpConvertUToPtr %_ptr_Generic_float %20 - OpStore %30 %21 Aligned 4 - %22 = OpLoad %ulong %5 - %23 = OpLoad %float %7 - %31 = OpConvertUToPtr %_ptr_Generic_float %22 - %46 = OpBitcast %_ptr_Generic_uchar %31 - %47 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %46 %ulong_4_0 - %27 = OpBitcast %_ptr_Generic_float %47 - OpStore %27 %23 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/cvt_s16_s8.spvtxt b/ptx/src/test/spirv_run/cvt_s16_s8.spvtxt deleted file mode 100644 index 92322ec..0000000 --- a/ptx/src/test/spirv_run/cvt_s16_s8.spvtxt +++ /dev/null @@ -1,59 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - OpCapability DenormFlushToZero - OpExtension "SPV_KHR_float_controls" - OpExtension "SPV_KHR_no_integer_wrap_decoration" - %24 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "cvt_s16_s8" - OpExecutionMode %1 ContractionOff - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %27 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %uint = OpTypeInt 32 0 -%_ptr_Function_uint = OpTypePointer Function %uint -%_ptr_CrossWorkgroup_uint = OpTypePointer CrossWorkgroup %uint - %uchar = OpTypeInt 8 0 - %ushort = OpTypeInt 16 0 -%_ptr_Generic_uint = OpTypePointer Generic %uint - %1 = OpFunction %void None %27 - %8 = OpFunctionParameter %ulong - %9 = OpFunctionParameter %ulong - %22 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_uint Function - %7 = OpVariable %_ptr_Function_uint Function - OpStore %2 %8 - OpStore %3 %9 - %10 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %18 = OpConvertUToPtr %_ptr_CrossWorkgroup_uint %13 - %12 = OpLoad %uint %18 Aligned 4 - OpStore %7 %12 - %15 = OpLoad %uint %7 - %32 = OpBitcast %uint %15 - %34 = OpUConvert %uchar %32 - %20 = OpCopyObject %uchar %34 - %19 = OpSConvert %ushort %20 - %14 = OpSConvert %uint %19 - OpStore %6 %14 - %16 = OpLoad %ulong %5 - %17 = OpLoad %uint %6 - %21 = OpConvertUToPtr %_ptr_Generic_uint %16 - OpStore %21 %17 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/cvt_s32_f32.spvtxt b/ptx/src/test/spirv_run/cvt_s32_f32.spvtxt deleted file mode 100644 index c1229d4..0000000 --- a/ptx/src/test/spirv_run/cvt_s32_f32.spvtxt +++ /dev/null @@ -1,82 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %42 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "cvt_s32_f32" - OpDecorate %32 FPRoundingMode RTP - OpDecorate %34 FPRoundingMode RTP - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %45 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %uint = OpTypeInt 32 0 -%_ptr_Function_uint = OpTypePointer Function %uint - %float = OpTypeFloat 32 -%_ptr_Generic_float = OpTypePointer Generic %float - %ulong_4 = OpConstant %ulong 4 - %uchar = OpTypeInt 8 0 -%_ptr_Generic_uchar = OpTypePointer Generic %uchar -%_ptr_CrossWorkgroup_uint = OpTypePointer CrossWorkgroup %uint - %ulong_4_0 = OpConstant %ulong 4 -%_ptr_CrossWorkgroup_uchar = OpTypePointer CrossWorkgroup %uchar - %1 = OpFunction %void None %45 - %8 = OpFunctionParameter %ulong - %9 = OpFunctionParameter %ulong - %40 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_uint Function - %7 = OpVariable %_ptr_Function_uint Function - OpStore %2 %8 - OpStore %3 %9 - %10 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %29 = OpConvertUToPtr %_ptr_Generic_float %13 - %28 = OpLoad %float %29 Aligned 4 - %12 = OpBitcast %uint %28 - OpStore %6 %12 - %15 = OpLoad %ulong %4 - %30 = OpConvertUToPtr %_ptr_Generic_float %15 - %53 = OpBitcast %_ptr_Generic_uchar %30 - %54 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %53 %ulong_4 - %25 = OpBitcast %_ptr_Generic_float %54 - %31 = OpLoad %float %25 Aligned 4 - %14 = OpBitcast %uint %31 - OpStore %7 %14 - %17 = OpLoad %uint %6 - %33 = OpBitcast %float %17 - %32 = OpConvertFToS %uint %33 - %16 = OpCopyObject %uint %32 - OpStore %6 %16 - %19 = OpLoad %uint %7 - %35 = OpBitcast %float %19 - %34 = OpConvertFToS %uint %35 - %18 = OpCopyObject %uint %34 - OpStore %7 %18 - %20 = OpLoad %ulong %5 - %21 = OpLoad %uint %6 - %36 = OpConvertUToPtr %_ptr_CrossWorkgroup_uint %20 - %37 = OpCopyObject %uint %21 - OpStore %36 %37 Aligned 4 - %22 = OpLoad %ulong %5 - %23 = OpLoad %uint %7 - %38 = OpConvertUToPtr %_ptr_CrossWorkgroup_uint %22 - %57 = OpBitcast %_ptr_CrossWorkgroup_uchar %38 - %58 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uchar %57 %ulong_4_0 - %27 = OpBitcast %_ptr_CrossWorkgroup_uint %58 - %39 = OpCopyObject %uint %23 - OpStore %27 %39 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/cvt_s64_s32.spvtxt b/ptx/src/test/spirv_run/cvt_s64_s32.spvtxt deleted file mode 100644 index 1165290..0000000 --- a/ptx/src/test/spirv_run/cvt_s64_s32.spvtxt +++ /dev/null @@ -1,55 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - OpCapability DenormFlushToZero - OpExtension "SPV_KHR_float_controls" - OpExtension "SPV_KHR_no_integer_wrap_decoration" - %24 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "cvt_s64_s32" - OpExecutionMode %1 ContractionOff - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %27 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %uint = OpTypeInt 32 0 -%_ptr_Function_uint = OpTypePointer Function %uint -%_ptr_Generic_uint = OpTypePointer Generic %uint -%_ptr_Generic_ulong = OpTypePointer Generic %ulong - %1 = OpFunction %void None %27 - %8 = OpFunctionParameter %ulong - %9 = OpFunctionParameter %ulong - %22 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_uint Function - %7 = OpVariable %_ptr_Function_ulong Function - OpStore %2 %8 - OpStore %3 %9 - %10 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %19 = OpConvertUToPtr %_ptr_Generic_uint %13 - %18 = OpLoad %uint %19 Aligned 4 - %12 = OpCopyObject %uint %18 - OpStore %6 %12 - %15 = OpLoad %uint %6 - %14 = OpSConvert %ulong %15 - OpStore %7 %14 - %16 = OpLoad %ulong %5 - %17 = OpLoad %ulong %7 - %20 = OpConvertUToPtr %_ptr_Generic_ulong %16 - %21 = OpCopyObject %ulong %17 - OpStore %20 %21 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/cvt_sat_s_u.spvtxt b/ptx/src/test/spirv_run/cvt_sat_s_u.spvtxt deleted file mode 100644 index 07b228e..0000000 --- a/ptx/src/test/spirv_run/cvt_sat_s_u.spvtxt +++ /dev/null @@ -1,56 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - OpCapability DenormFlushToZero - OpExtension "SPV_KHR_float_controls" - OpExtension "SPV_KHR_no_integer_wrap_decoration" - %25 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "cvt_sat_s_u" - OpExecutionMode %1 ContractionOff - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %28 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %uint = OpTypeInt 32 0 -%_ptr_Function_uint = OpTypePointer Function %uint -%_ptr_Generic_uint = OpTypePointer Generic %uint - %1 = OpFunction %void None %28 - %9 = OpFunctionParameter %ulong - %10 = OpFunctionParameter %ulong - %23 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_uint Function - %7 = OpVariable %_ptr_Function_uint Function - %8 = OpVariable %_ptr_Function_uint Function - OpStore %2 %9 - OpStore %3 %10 - %11 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %11 - %12 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %12 - %14 = OpLoad %ulong %4 - %21 = OpConvertUToPtr %_ptr_Generic_uint %14 - %13 = OpLoad %uint %21 Aligned 4 - OpStore %6 %13 - %16 = OpLoad %uint %6 - %15 = OpSatConvertSToU %uint %16 - OpStore %7 %15 - %18 = OpLoad %uint %7 - %17 = OpCopyObject %uint %18 - OpStore %8 %17 - %19 = OpLoad %ulong %5 - %20 = OpLoad %uint %8 - %22 = OpConvertUToPtr %_ptr_Generic_uint %19 - OpStore %22 %20 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/cvta.spvtxt b/ptx/src/test/spirv_run/cvta.spvtxt deleted file mode 100644 index e7a5655..0000000 --- a/ptx/src/test/spirv_run/cvta.spvtxt +++ /dev/null @@ -1,65 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %37 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "cvta" - %void = OpTypeVoid - %uchar = OpTypeInt 8 0 -%_ptr_CrossWorkgroup_uchar = OpTypePointer CrossWorkgroup %uchar - %41 = OpTypeFunction %void %_ptr_CrossWorkgroup_uchar %_ptr_CrossWorkgroup_uchar -%_ptr_Function__ptr_CrossWorkgroup_uchar = OpTypePointer Function %_ptr_CrossWorkgroup_uchar - %float = OpTypeFloat 32 -%_ptr_Function_float = OpTypePointer Function %float - %ulong = OpTypeInt 64 0 -%_ptr_Function_ulong = OpTypePointer Function %ulong -%_ptr_CrossWorkgroup_float = OpTypePointer CrossWorkgroup %float - %1 = OpFunction %void None %41 - %17 = OpFunctionParameter %_ptr_CrossWorkgroup_uchar - %18 = OpFunctionParameter %_ptr_CrossWorkgroup_uchar - %35 = OpLabel - %2 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function - %3 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function - %7 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function - %8 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function - %6 = OpVariable %_ptr_Function_float Function - OpStore %2 %17 - OpStore %3 %18 - %10 = OpBitcast %_ptr_Function_ulong %2 - %9 = OpLoad %ulong %10 Aligned 8 - %19 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %9 - OpStore %7 %19 - %12 = OpBitcast %_ptr_Function_ulong %3 - %11 = OpLoad %ulong %12 Aligned 8 - %20 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %11 - OpStore %8 %20 - %21 = OpLoad %_ptr_CrossWorkgroup_uchar %7 - %14 = OpConvertPtrToU %ulong %21 - %30 = OpCopyObject %ulong %14 - %29 = OpCopyObject %ulong %30 - %13 = OpCopyObject %ulong %29 - %22 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %13 - OpStore %7 %22 - %23 = OpLoad %_ptr_CrossWorkgroup_uchar %8 - %16 = OpConvertPtrToU %ulong %23 - %32 = OpCopyObject %ulong %16 - %31 = OpCopyObject %ulong %32 - %15 = OpCopyObject %ulong %31 - %24 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %15 - OpStore %8 %24 - %26 = OpLoad %_ptr_CrossWorkgroup_uchar %7 - %33 = OpBitcast %_ptr_CrossWorkgroup_float %26 - %25 = OpLoad %float %33 Aligned 4 - OpStore %6 %25 - %27 = OpLoad %_ptr_CrossWorkgroup_uchar %8 - %28 = OpLoad %float %6 - %34 = OpBitcast %_ptr_CrossWorkgroup_float %27 - OpStore %34 %28 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/div_approx.spvtxt b/ptx/src/test/spirv_run/div_approx.spvtxt deleted file mode 100644 index 858ec8d..0000000 --- a/ptx/src/test/spirv_run/div_approx.spvtxt +++ /dev/null @@ -1,60 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %28 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "div_approx" - OpDecorate %16 FPFastMathMode AllowRecip - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %31 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %float = OpTypeFloat 32 -%_ptr_Function_float = OpTypePointer Function %float -%_ptr_Generic_float = OpTypePointer Generic %float - %ulong_4 = OpConstant %ulong 4 - %uchar = OpTypeInt 8 0 -%_ptr_Generic_uchar = OpTypePointer Generic %uchar - %1 = OpFunction %void None %31 - %8 = OpFunctionParameter %ulong - %9 = OpFunctionParameter %ulong - %26 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_float Function - %7 = OpVariable %_ptr_Function_float Function - OpStore %2 %8 - OpStore %3 %9 - %10 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %23 = OpConvertUToPtr %_ptr_Generic_float %13 - %12 = OpLoad %float %23 Aligned 4 - OpStore %6 %12 - %15 = OpLoad %ulong %4 - %24 = OpConvertUToPtr %_ptr_Generic_float %15 - %38 = OpBitcast %_ptr_Generic_uchar %24 - %39 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %38 %ulong_4 - %22 = OpBitcast %_ptr_Generic_float %39 - %14 = OpLoad %float %22 Aligned 4 - OpStore %7 %14 - %17 = OpLoad %float %6 - %18 = OpLoad %float %7 - %16 = OpFDiv %float %17 %18 - OpStore %6 %16 - %19 = OpLoad %ulong %5 - %20 = OpLoad %float %6 - %25 = OpConvertUToPtr %_ptr_Generic_float %19 - OpStore %25 %20 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/ex2.spvtxt b/ptx/src/test/spirv_run/ex2.spvtxt deleted file mode 100644 index 29e5e86..0000000 --- a/ptx/src/test/spirv_run/ex2.spvtxt +++ /dev/null @@ -1,48 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %21 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "ex2" - OpExecutionMode %1 ContractionOff - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %24 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %float = OpTypeFloat 32 -%_ptr_Function_float = OpTypePointer Function %float -%_ptr_Generic_float = OpTypePointer Generic %float - %1 = OpFunction %void None %24 - %7 = OpFunctionParameter %ulong - %8 = OpFunctionParameter %ulong - %19 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_float Function - OpStore %2 %7 - OpStore %3 %8 - %9 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %9 - %10 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %10 - %12 = OpLoad %ulong %4 - %17 = OpConvertUToPtr %_ptr_Generic_float %12 - %11 = OpLoad %float %17 Aligned 4 - OpStore %6 %11 - %14 = OpLoad %float %6 - %13 = OpExtInst %float %21 exp2 %14 - OpStore %6 %13 - %15 = OpLoad %ulong %5 - %16 = OpLoad %float %6 - %18 = OpConvertUToPtr %_ptr_Generic_float %15 - OpStore %18 %16 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/extern_func.spvtxt b/ptx/src/test/spirv_run/extern_func.spvtxt deleted file mode 100644 index b757029..0000000 --- a/ptx/src/test/spirv_run/extern_func.spvtxt +++ /dev/null @@ -1,75 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - OpCapability DenormFlushToZero - %31 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %4 "extern_func" - OpExecutionMode %4 ContractionOff - OpDecorate %1 LinkageAttributes "foobar" Import - OpDecorate %12 Alignment 16 - OpDecorate %4 LinkageAttributes "extern_func" Export - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 -%_ptr_Function_ulong = OpTypePointer Function %ulong - %uint = OpTypeInt 32 0 - %uchar = OpTypeInt 8 0 - %uint_16 = OpConstant %uint 16 -%_arr_uchar_uint_16 = OpTypeArray %uchar %uint_16 -%_ptr_Function__arr_uchar_uint_16 = OpTypePointer Function %_arr_uchar_uint_16 - %40 = OpTypeFunction %void %_ptr_Function_ulong %_ptr_Function__arr_uchar_uint_16 - %uint_16_0 = OpConstant %uint 16 - %42 = OpTypeFunction %void %ulong %ulong - %uint_16_1 = OpConstant %uint 16 -%_ptr_CrossWorkgroup_ulong = OpTypePointer CrossWorkgroup %ulong - %ulong_0 = OpConstant %ulong 0 -%_ptr_Function_uchar = OpTypePointer Function %uchar -%_ptr_Generic_ulong = OpTypePointer Generic %ulong - %1 = OpFunction %void None %40 - %3 = OpFunctionParameter %_ptr_Function_ulong - %2 = OpFunctionParameter %_ptr_Function__arr_uchar_uint_16 - OpFunctionEnd - %4 = OpFunction %void None %42 - %13 = OpFunctionParameter %ulong - %14 = OpFunctionParameter %ulong - %29 = OpLabel - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_ulong Function - %7 = OpVariable %_ptr_Function_ulong Function - %8 = OpVariable %_ptr_Function_ulong Function - %9 = OpVariable %_ptr_Function_ulong Function - %10 = OpVariable %_ptr_Function_ulong Function - %11 = OpVariable %_ptr_Function_ulong Function - %12 = OpVariable %_ptr_Function__arr_uchar_uint_16 Function - OpStore %5 %13 - OpStore %6 %14 - %15 = OpLoad %ulong %5 Aligned 8 - OpStore %7 %15 - %16 = OpLoad %ulong %6 Aligned 8 - OpStore %8 %16 - %18 = OpLoad %ulong %7 - %25 = OpConvertUToPtr %_ptr_CrossWorkgroup_ulong %18 - %17 = OpLoad %ulong %25 Aligned 8 - OpStore %9 %17 - %19 = OpLoad %ulong %9 - %46 = OpBitcast %_ptr_Function_uchar %11 - %47 = OpInBoundsPtrAccessChain %_ptr_Function_uchar %46 %ulong_0 - %24 = OpBitcast %_ptr_Function_ulong %47 - %26 = OpCopyObject %ulong %19 - OpStore %24 %26 Aligned 8 - %48 = OpFunctionCall %void %1 %11 %12 - %27 = OpBitcast %_ptr_Function_ulong %12 - %20 = OpLoad %ulong %27 Aligned 8 - OpStore %10 %20 - %21 = OpLoad %ulong %8 - %22 = OpLoad %ulong %10 - %28 = OpConvertUToPtr %_ptr_Generic_ulong %21 - OpStore %28 %22 Aligned 8 - OpReturn - OpFunctionEnd
\ No newline at end of file diff --git a/ptx/src/test/spirv_run/extern_shared.spvtxt b/ptx/src/test/spirv_run/extern_shared.spvtxt deleted file mode 100644 index 025cd81..0000000 --- a/ptx/src/test/spirv_run/extern_shared.spvtxt +++ /dev/null @@ -1,56 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - OpCapability DenormFlushToZero - OpExtension "SPV_KHR_float_controls" - OpExtension "SPV_KHR_no_integer_wrap_decoration" - %24 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %2 "extern_shared" %1 - OpExecutionMode %2 ContractionOff - %void = OpTypeVoid - %uint = OpTypeInt 32 0 -%_ptr_Workgroup_uint = OpTypePointer Workgroup %uint - %1 = OpVariable %_ptr_Workgroup_uint Workgroup - %ulong = OpTypeInt 64 0 - %29 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong -%_ptr_CrossWorkgroup_ulong = OpTypePointer CrossWorkgroup %ulong -%_ptr_Workgroup_ulong = OpTypePointer Workgroup %ulong - %2 = OpFunction %void None %29 - %8 = OpFunctionParameter %ulong - %9 = OpFunctionParameter %ulong - %22 = OpLabel - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_ulong Function - %7 = OpVariable %_ptr_Function_ulong Function - OpStore %3 %8 - OpStore %4 %9 - %10 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %10 - %11 = OpLoad %ulong %4 Aligned 8 - OpStore %6 %11 - %13 = OpLoad %ulong %5 - %18 = OpConvertUToPtr %_ptr_CrossWorkgroup_ulong %13 - %12 = OpLoad %ulong %18 Aligned 8 - OpStore %7 %12 - %14 = OpLoad %ulong %7 - %19 = OpBitcast %_ptr_Workgroup_ulong %1 - OpStore %19 %14 Aligned 8 - %20 = OpBitcast %_ptr_Workgroup_ulong %1 - %15 = OpLoad %ulong %20 Aligned 8 - OpStore %7 %15 - %16 = OpLoad %ulong %6 - %17 = OpLoad %ulong %7 - %21 = OpConvertUToPtr %_ptr_CrossWorkgroup_ulong %16 - OpStore %21 %17 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/extern_shared_call.spvtxt b/ptx/src/test/spirv_run/extern_shared_call.spvtxt deleted file mode 100644 index bf1dccd..0000000 --- a/ptx/src/test/spirv_run/extern_shared_call.spvtxt +++ /dev/null @@ -1,75 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - OpCapability DenormFlushToZero - OpExtension "SPV_KHR_float_controls" - OpExtension "SPV_KHR_no_integer_wrap_decoration" - %35 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %12 "extern_shared_call" %1 - OpExecutionMode %12 ContractionOff - OpDecorate %1 Alignment 4 - %void = OpTypeVoid - %uint = OpTypeInt 32 0 -%_ptr_Workgroup_uint = OpTypePointer Workgroup %uint - %1 = OpVariable %_ptr_Workgroup_uint Workgroup - %39 = OpTypeFunction %void %_ptr_Workgroup_uint - %ulong = OpTypeInt 64 0 -%_ptr_Function_ulong = OpTypePointer Function %ulong -%_ptr_Workgroup_ulong = OpTypePointer Workgroup %ulong - %ulong_2 = OpConstant %ulong 2 - %43 = OpTypeFunction %void %ulong %ulong -%_ptr_CrossWorkgroup_ulong = OpTypePointer CrossWorkgroup %ulong - %2 = OpFunction %void None %39 - %34 = OpFunctionParameter %_ptr_Workgroup_uint - %11 = OpLabel - %3 = OpVariable %_ptr_Function_ulong Function - %9 = OpBitcast %_ptr_Workgroup_ulong %34 - %4 = OpLoad %ulong %9 Aligned 8 - OpStore %3 %4 - %6 = OpLoad %ulong %3 - %5 = OpIAdd %ulong %6 %ulong_2 - OpStore %3 %5 - %7 = OpLoad %ulong %3 - %10 = OpBitcast %_ptr_Workgroup_ulong %34 - OpStore %10 %7 Aligned 8 - OpReturn - OpFunctionEnd - %12 = OpFunction %void None %43 - %18 = OpFunctionParameter %ulong - %19 = OpFunctionParameter %ulong - %32 = OpLabel - %13 = OpVariable %_ptr_Function_ulong Function - %14 = OpVariable %_ptr_Function_ulong Function - %15 = OpVariable %_ptr_Function_ulong Function - %16 = OpVariable %_ptr_Function_ulong Function - %17 = OpVariable %_ptr_Function_ulong Function - OpStore %13 %18 - OpStore %14 %19 - %20 = OpLoad %ulong %13 Aligned 8 - OpStore %15 %20 - %21 = OpLoad %ulong %14 Aligned 8 - OpStore %16 %21 - %23 = OpLoad %ulong %15 - %28 = OpConvertUToPtr %_ptr_CrossWorkgroup_ulong %23 - %22 = OpLoad %ulong %28 Aligned 8 - OpStore %17 %22 - %24 = OpLoad %ulong %17 - %29 = OpBitcast %_ptr_Workgroup_ulong %1 - OpStore %29 %24 Aligned 8 - %45 = OpFunctionCall %void %2 %1 - %30 = OpBitcast %_ptr_Workgroup_ulong %1 - %25 = OpLoad %ulong %30 Aligned 8 - OpStore %17 %25 - %26 = OpLoad %ulong %16 - %27 = OpLoad %ulong %17 - %31 = OpConvertUToPtr %_ptr_CrossWorkgroup_ulong %26 - OpStore %31 %27 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/fma.spvtxt b/ptx/src/test/spirv_run/fma.spvtxt deleted file mode 100644 index 91a2159..0000000 --- a/ptx/src/test/spirv_run/fma.spvtxt +++ /dev/null @@ -1,69 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %35 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "fma" - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %38 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %float = OpTypeFloat 32 -%_ptr_Function_float = OpTypePointer Function %float -%_ptr_Generic_float = OpTypePointer Generic %float - %ulong_4 = OpConstant %ulong 4 - %uchar = OpTypeInt 8 0 -%_ptr_Generic_uchar = OpTypePointer Generic %uchar - %ulong_8 = OpConstant %ulong 8 - %1 = OpFunction %void None %38 - %9 = OpFunctionParameter %ulong - %10 = OpFunctionParameter %ulong - %33 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_float Function - %7 = OpVariable %_ptr_Function_float Function - %8 = OpVariable %_ptr_Function_float Function - OpStore %2 %9 - OpStore %3 %10 - %11 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %11 - %12 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %12 - %14 = OpLoad %ulong %4 - %29 = OpConvertUToPtr %_ptr_Generic_float %14 - %13 = OpLoad %float %29 Aligned 4 - OpStore %6 %13 - %16 = OpLoad %ulong %4 - %30 = OpConvertUToPtr %_ptr_Generic_float %16 - %45 = OpBitcast %_ptr_Generic_uchar %30 - %46 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %45 %ulong_4 - %26 = OpBitcast %_ptr_Generic_float %46 - %15 = OpLoad %float %26 Aligned 4 - OpStore %7 %15 - %18 = OpLoad %ulong %4 - %31 = OpConvertUToPtr %_ptr_Generic_float %18 - %47 = OpBitcast %_ptr_Generic_uchar %31 - %48 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %47 %ulong_8 - %28 = OpBitcast %_ptr_Generic_float %48 - %17 = OpLoad %float %28 Aligned 4 - OpStore %8 %17 - %20 = OpLoad %float %6 - %21 = OpLoad %float %7 - %22 = OpLoad %float %8 - %19 = OpExtInst %float %35 fma %20 %21 %22 - OpStore %6 %19 - %23 = OpLoad %ulong %5 - %24 = OpLoad %float %6 - %32 = OpConvertUToPtr %_ptr_Generic_float %23 - OpStore %32 %24 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/func_ptr.spvtxt b/ptx/src/test/spirv_run/func_ptr.spvtxt deleted file mode 100644 index 4ff74c6..0000000 --- a/ptx/src/test/spirv_run/func_ptr.spvtxt +++ /dev/null @@ -1,77 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - OpCapability DenormFlushToZero - %39 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %12 "func_ptr" - OpExecutionMode %12 ContractionOff - OpDecorate %12 LinkageAttributes "func_ptr" Export - %void = OpTypeVoid - %float = OpTypeFloat 32 - %42 = OpTypeFunction %float %float %float -%_ptr_Function_float = OpTypePointer Function %float - %ulong = OpTypeInt 64 0 - %45 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong -%_ptr_Generic_ulong = OpTypePointer Generic %ulong - %ulong_1 = OpConstant %ulong 1 - %ulong_0 = OpConstant %ulong 0 - %1 = OpFunction %float None %42 - %5 = OpFunctionParameter %float - %6 = OpFunctionParameter %float - %11 = OpLabel - %3 = OpVariable %_ptr_Function_float Function - %4 = OpVariable %_ptr_Function_float Function - %2 = OpVariable %_ptr_Function_float Function - OpStore %3 %5 - OpStore %4 %6 - %8 = OpLoad %float %3 - %9 = OpLoad %float %4 - %7 = OpFAdd %float %8 %9 - OpStore %2 %7 - %10 = OpLoad %float %2 - OpReturnValue %10 - OpFunctionEnd - %12 = OpFunction %void None %45 - %20 = OpFunctionParameter %ulong - %21 = OpFunctionParameter %ulong - %37 = OpLabel - %13 = OpVariable %_ptr_Function_ulong Function - %14 = OpVariable %_ptr_Function_ulong Function - %15 = OpVariable %_ptr_Function_ulong Function - %16 = OpVariable %_ptr_Function_ulong Function - %17 = OpVariable %_ptr_Function_ulong Function - %18 = OpVariable %_ptr_Function_ulong Function - %19 = OpVariable %_ptr_Function_ulong Function - OpStore %13 %20 - OpStore %14 %21 - %22 = OpLoad %ulong %13 Aligned 8 - OpStore %15 %22 - %23 = OpLoad %ulong %14 Aligned 8 - OpStore %16 %23 - %25 = OpLoad %ulong %15 - %35 = OpConvertUToPtr %_ptr_Generic_ulong %25 - %24 = OpLoad %ulong %35 Aligned 8 - OpStore %17 %24 - %27 = OpLoad %ulong %17 - %26 = OpIAdd %ulong %27 %ulong_1 - OpStore %18 %26 - %28 = OpCopyObject %ulong %ulong_0 - OpStore %19 %28 - %30 = OpLoad %ulong %18 - %31 = OpLoad %ulong %19 - %29 = OpIAdd %ulong %30 %31 - OpStore %18 %29 - %32 = OpLoad %ulong %16 - %33 = OpLoad %ulong %18 - %36 = OpConvertUToPtr %_ptr_Generic_ulong %32 - OpStore %36 %33 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/global_array.spvtxt b/ptx/src/test/spirv_run/global_array.spvtxt deleted file mode 100644 index 4eccb2f..0000000 --- a/ptx/src/test/spirv_run/global_array.spvtxt +++ /dev/null @@ -1,53 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %21 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %2 "global_array" %1 - %void = OpTypeVoid - %uint = OpTypeInt 32 0 - %uint_4 = OpConstant %uint 4 -%_arr_uint_uint_4 = OpTypeArray %uint %uint_4 - %uint_1 = OpConstant %uint 1 - %uint_0 = OpConstant %uint 0 - %28 = OpConstantComposite %_arr_uint_uint_4 %uint_1 %uint_0 %uint_0 %uint_0 - %uint_4_0 = OpConstant %uint 4 -%_ptr_CrossWorkgroup__arr_uint_uint_4 = OpTypePointer CrossWorkgroup %_arr_uint_uint_4 - %1 = OpVariable %_ptr_CrossWorkgroup__arr_uint_uint_4 CrossWorkgroup %28 - %ulong = OpTypeInt 64 0 - %32 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong -%_ptr_Function_uint = OpTypePointer Function %uint -%_ptr_CrossWorkgroup_uint = OpTypePointer CrossWorkgroup %uint - %2 = OpFunction %void None %32 - %8 = OpFunctionParameter %ulong - %9 = OpFunctionParameter %ulong - %19 = OpLabel - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_ulong Function - %7 = OpVariable %_ptr_Function_uint Function - OpStore %3 %8 - OpStore %4 %9 - %16 = OpConvertPtrToU %ulong %1 - %10 = OpCopyObject %ulong %16 - OpStore %5 %10 - %11 = OpLoad %ulong %4 Aligned 8 - OpStore %6 %11 - %13 = OpLoad %ulong %5 - %17 = OpConvertUToPtr %_ptr_CrossWorkgroup_uint %13 - %12 = OpLoad %uint %17 Aligned 4 - OpStore %7 %12 - %14 = OpLoad %ulong %6 - %15 = OpLoad %uint %7 - %18 = OpConvertUToPtr %_ptr_CrossWorkgroup_uint %14 - OpStore %18 %15 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/implicit_param.spvtxt b/ptx/src/test/spirv_run/implicit_param.spvtxt deleted file mode 100644 index 760761a..0000000 --- a/ptx/src/test/spirv_run/implicit_param.spvtxt +++ /dev/null @@ -1,53 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %24 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "implicit_param" - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %27 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %float = OpTypeFloat 32 -%_ptr_Function_float = OpTypePointer Function %float - %uint = OpTypeInt 32 0 -%_ptr_Function_uint = OpTypePointer Function %uint -%_ptr_CrossWorkgroup_float = OpTypePointer CrossWorkgroup %float - %1 = OpFunction %void None %27 - %8 = OpFunctionParameter %ulong - %9 = OpFunctionParameter %ulong - %22 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_float Function - %7 = OpVariable %_ptr_Function_uint Function - OpStore %2 %8 - OpStore %3 %9 - %10 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %18 = OpConvertUToPtr %_ptr_CrossWorkgroup_float %13 - %12 = OpLoad %float %18 Aligned 4 - OpStore %6 %12 - %14 = OpLoad %float %6 - %19 = OpBitcast %_ptr_Function_float %7 - OpStore %19 %14 Aligned 4 - %20 = OpBitcast %_ptr_Function_float %7 - %15 = OpLoad %float %20 Aligned 4 - OpStore %6 %15 - %16 = OpLoad %ulong %5 - %17 = OpLoad %float %6 - %21 = OpConvertUToPtr %_ptr_CrossWorkgroup_float %16 - OpStore %21 %17 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/lanemask_lt.spvtxt b/ptx/src/test/spirv_run/lanemask_lt.spvtxt deleted file mode 100644 index 3de53ce..0000000 --- a/ptx/src/test/spirv_run/lanemask_lt.spvtxt +++ /dev/null @@ -1,70 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %40 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "lanemask_lt" - OpExecutionMode %1 ContractionOff - OpDecorate %11 LinkageAttributes "__zluda_ptx_impl__sreg_lanemask_lt" Import - %void = OpTypeVoid - %uint = OpTypeInt 32 0 - %43 = OpTypeFunction %uint - %ulong = OpTypeInt 64 0 - %45 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong -%_ptr_Function_uint = OpTypePointer Function %uint -%_ptr_Generic_uint = OpTypePointer Generic %uint - %uint_1 = OpConstant %uint 1 - %11 = OpFunction %uint None %43 - OpFunctionEnd - %1 = OpFunction %void None %45 - %13 = OpFunctionParameter %ulong - %14 = OpFunctionParameter %ulong - %38 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_uint Function - %7 = OpVariable %_ptr_Function_uint Function - %8 = OpVariable %_ptr_Function_uint Function - OpStore %2 %13 - OpStore %3 %14 - %15 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %15 - %16 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %16 - %18 = OpLoad %ulong %4 - %29 = OpConvertUToPtr %_ptr_Generic_uint %18 - %28 = OpLoad %uint %29 Aligned 4 - %17 = OpCopyObject %uint %28 - OpStore %6 %17 - %20 = OpLoad %uint %6 - %31 = OpCopyObject %uint %20 - %30 = OpIAdd %uint %31 %uint_1 - %19 = OpCopyObject %uint %30 - OpStore %7 %19 - %10 = OpFunctionCall %uint %11 - %32 = OpCopyObject %uint %10 - %21 = OpCopyObject %uint %32 - OpStore %8 %21 - %23 = OpLoad %uint %7 - %24 = OpLoad %uint %8 - %34 = OpCopyObject %uint %23 - %35 = OpCopyObject %uint %24 - %33 = OpIAdd %uint %34 %35 - %22 = OpCopyObject %uint %33 - OpStore %7 %22 - %25 = OpLoad %ulong %5 - %26 = OpLoad %uint %7 - %36 = OpConvertUToPtr %_ptr_Generic_uint %25 - %37 = OpCopyObject %uint %26 - OpStore %36 %37 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/ld_st.spvtxt b/ptx/src/test/spirv_run/ld_st.spvtxt deleted file mode 100644 index 447b1aa..0000000 --- a/ptx/src/test/spirv_run/ld_st.spvtxt +++ /dev/null @@ -1,42 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %19 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "ld_st" - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %22 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong -%_ptr_Generic_ulong = OpTypePointer Generic %ulong - %1 = OpFunction %void None %22 - %7 = OpFunctionParameter %ulong - %8 = OpFunctionParameter %ulong - %17 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_ulong Function - OpStore %2 %7 - OpStore %3 %8 - %9 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %9 - %10 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %10 - %12 = OpLoad %ulong %4 - %15 = OpConvertUToPtr %_ptr_Generic_ulong %12 - %11 = OpLoad %ulong %15 Aligned 8 - OpStore %6 %11 - %13 = OpLoad %ulong %5 - %14 = OpLoad %ulong %6 - %16 = OpConvertUToPtr %_ptr_Generic_ulong %13 - OpStore %16 %14 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/ld_st_implicit.spvtxt b/ptx/src/test/spirv_run/ld_st_implicit.spvtxt deleted file mode 100644 index 9c0e508..0000000 --- a/ptx/src/test/spirv_run/ld_st_implicit.spvtxt +++ /dev/null @@ -1,56 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - OpCapability DenormFlushToZero - OpExtension "SPV_KHR_float_controls" - OpExtension "SPV_KHR_no_integer_wrap_decoration" - %23 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "ld_st_implicit" - OpExecutionMode %1 ContractionOff - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %26 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong -%ulong_81985529216486895 = OpConstant %ulong 81985529216486895 - %float = OpTypeFloat 32 -%_ptr_CrossWorkgroup_float = OpTypePointer CrossWorkgroup %float - %uint = OpTypeInt 32 0 - %1 = OpFunction %void None %26 - %7 = OpFunctionParameter %ulong - %8 = OpFunctionParameter %ulong - %21 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_ulong Function - OpStore %2 %7 - OpStore %3 %8 - %9 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %9 - %10 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %10 - %11 = OpCopyObject %ulong %ulong_81985529216486895 - OpStore %6 %11 - %13 = OpLoad %ulong %4 - %18 = OpConvertUToPtr %_ptr_CrossWorkgroup_float %13 - %17 = OpLoad %float %18 Aligned 4 - %31 = OpBitcast %uint %17 - %12 = OpUConvert %ulong %31 - OpStore %6 %12 - %14 = OpLoad %ulong %5 - %15 = OpLoad %ulong %6 - %19 = OpConvertUToPtr %_ptr_CrossWorkgroup_float %14 - %32 = OpBitcast %ulong %15 - %33 = OpUConvert %uint %32 - %20 = OpBitcast %float %33 - OpStore %19 %20 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/ld_st_offset.spvtxt b/ptx/src/test/spirv_run/ld_st_offset.spvtxt deleted file mode 100644 index ea97222..0000000 --- a/ptx/src/test/spirv_run/ld_st_offset.spvtxt +++ /dev/null @@ -1,63 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %30 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "ld_st_offset" - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %33 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %uint = OpTypeInt 32 0 -%_ptr_Function_uint = OpTypePointer Function %uint -%_ptr_Generic_uint = OpTypePointer Generic %uint - %ulong_4 = OpConstant %ulong 4 - %uchar = OpTypeInt 8 0 -%_ptr_Generic_uchar = OpTypePointer Generic %uchar - %ulong_4_0 = OpConstant %ulong 4 - %1 = OpFunction %void None %33 - %8 = OpFunctionParameter %ulong - %9 = OpFunctionParameter %ulong - %28 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_uint Function - %7 = OpVariable %_ptr_Function_uint Function - OpStore %2 %8 - OpStore %3 %9 - %10 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %24 = OpConvertUToPtr %_ptr_Generic_uint %13 - %12 = OpLoad %uint %24 Aligned 4 - OpStore %6 %12 - %15 = OpLoad %ulong %4 - %25 = OpConvertUToPtr %_ptr_Generic_uint %15 - %40 = OpBitcast %_ptr_Generic_uchar %25 - %41 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %40 %ulong_4 - %21 = OpBitcast %_ptr_Generic_uint %41 - %14 = OpLoad %uint %21 Aligned 4 - OpStore %7 %14 - %16 = OpLoad %ulong %5 - %17 = OpLoad %uint %7 - %26 = OpConvertUToPtr %_ptr_Generic_uint %16 - OpStore %26 %17 Aligned 4 - %18 = OpLoad %ulong %5 - %19 = OpLoad %uint %6 - %27 = OpConvertUToPtr %_ptr_Generic_uint %18 - %42 = OpBitcast %_ptr_Generic_uchar %27 - %43 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %42 %ulong_4_0 - %23 = OpBitcast %_ptr_Generic_uint %43 - OpStore %23 %19 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/lg2.spvtxt b/ptx/src/test/spirv_run/lg2.spvtxt deleted file mode 100644 index a8175cf..0000000 --- a/ptx/src/test/spirv_run/lg2.spvtxt +++ /dev/null @@ -1,48 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %21 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "lg2" - OpExecutionMode %1 ContractionOff - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %24 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %float = OpTypeFloat 32 -%_ptr_Function_float = OpTypePointer Function %float -%_ptr_Generic_float = OpTypePointer Generic %float - %1 = OpFunction %void None %24 - %7 = OpFunctionParameter %ulong - %8 = OpFunctionParameter %ulong - %19 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_float Function - OpStore %2 %7 - OpStore %3 %8 - %9 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %9 - %10 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %10 - %12 = OpLoad %ulong %4 - %17 = OpConvertUToPtr %_ptr_Generic_float %12 - %11 = OpLoad %float %17 Aligned 4 - OpStore %6 %11 - %14 = OpLoad %float %6 - %13 = OpExtInst %float %21 log2 %14 - OpStore %6 %13 - %15 = OpLoad %ulong %5 - %16 = OpLoad %float %6 - %18 = OpConvertUToPtr %_ptr_Generic_float %15 - OpStore %18 %16 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/local_align.spvtxt b/ptx/src/test/spirv_run/local_align.spvtxt deleted file mode 100644 index a2cfd4c..0000000 --- a/ptx/src/test/spirv_run/local_align.spvtxt +++ /dev/null @@ -1,49 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %20 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "local_align" - OpDecorate %4 Alignment 8 - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %23 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %uint = OpTypeInt 32 0 - %uchar = OpTypeInt 8 0 - %uint_8 = OpConstant %uint 8 -%_arr_uchar_uint_8 = OpTypeArray %uchar %uint_8 -%_ptr_Function__arr_uchar_uint_8 = OpTypePointer Function %_arr_uchar_uint_8 -%_ptr_Generic_ulong = OpTypePointer Generic %ulong - %1 = OpFunction %void None %23 - %8 = OpFunctionParameter %ulong - %9 = OpFunctionParameter %ulong - %18 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function__arr_uchar_uint_8 Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_ulong Function - %7 = OpVariable %_ptr_Function_ulong Function - OpStore %2 %8 - OpStore %3 %9 - %10 = OpLoad %ulong %2 Aligned 8 - OpStore %5 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %6 %11 - %13 = OpLoad %ulong %5 - %16 = OpConvertUToPtr %_ptr_Generic_ulong %13 - %12 = OpLoad %ulong %16 Aligned 8 - OpStore %7 %12 - %14 = OpLoad %ulong %6 - %15 = OpLoad %ulong %7 - %17 = OpConvertUToPtr %_ptr_Generic_ulong %14 - OpStore %17 %15 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/mad_s32.spvtxt b/ptx/src/test/spirv_run/mad_s32.spvtxt deleted file mode 100644 index 0ee3ca7..0000000 --- a/ptx/src/test/spirv_run/mad_s32.spvtxt +++ /dev/null @@ -1,87 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %46 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "mad_s32" - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %49 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %uint = OpTypeInt 32 0 -%_ptr_Function_uint = OpTypePointer Function %uint -%_ptr_Generic_uint = OpTypePointer Generic %uint - %ulong_4 = OpConstant %ulong 4 - %uchar = OpTypeInt 8 0 -%_ptr_Generic_uchar = OpTypePointer Generic %uchar - %ulong_8 = OpConstant %ulong 8 - %ulong_4_0 = OpConstant %ulong 4 - %ulong_8_0 = OpConstant %ulong 8 - %1 = OpFunction %void None %49 - %10 = OpFunctionParameter %ulong - %11 = OpFunctionParameter %ulong - %44 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_uint Function - %7 = OpVariable %_ptr_Function_uint Function - %8 = OpVariable %_ptr_Function_uint Function - %9 = OpVariable %_ptr_Function_uint Function - OpStore %2 %10 - OpStore %3 %11 - %12 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %12 - %13 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %13 - %15 = OpLoad %ulong %4 - %38 = OpConvertUToPtr %_ptr_Generic_uint %15 - %14 = OpLoad %uint %38 Aligned 4 - OpStore %7 %14 - %17 = OpLoad %ulong %4 - %39 = OpConvertUToPtr %_ptr_Generic_uint %17 - %56 = OpBitcast %_ptr_Generic_uchar %39 - %57 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %56 %ulong_4 - %31 = OpBitcast %_ptr_Generic_uint %57 - %16 = OpLoad %uint %31 Aligned 4 - OpStore %8 %16 - %19 = OpLoad %ulong %4 - %40 = OpConvertUToPtr %_ptr_Generic_uint %19 - %58 = OpBitcast %_ptr_Generic_uchar %40 - %59 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %58 %ulong_8 - %33 = OpBitcast %_ptr_Generic_uint %59 - %18 = OpLoad %uint %33 Aligned 4 - OpStore %9 %18 - %21 = OpLoad %uint %7 - %22 = OpLoad %uint %8 - %23 = OpLoad %uint %9 - %60 = OpIMul %uint %21 %22 - %20 = OpIAdd %uint %23 %60 - OpStore %6 %20 - %24 = OpLoad %ulong %5 - %25 = OpLoad %uint %6 - %41 = OpConvertUToPtr %_ptr_Generic_uint %24 - OpStore %41 %25 Aligned 4 - %26 = OpLoad %ulong %5 - %27 = OpLoad %uint %6 - %42 = OpConvertUToPtr %_ptr_Generic_uint %26 - %61 = OpBitcast %_ptr_Generic_uchar %42 - %62 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %61 %ulong_4_0 - %35 = OpBitcast %_ptr_Generic_uint %62 - OpStore %35 %27 Aligned 4 - %28 = OpLoad %ulong %5 - %29 = OpLoad %uint %6 - %43 = OpConvertUToPtr %_ptr_Generic_uint %28 - %63 = OpBitcast %_ptr_Generic_uchar %43 - %64 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %63 %ulong_8_0 - %37 = OpBitcast %_ptr_Generic_uint %64 - OpStore %37 %29 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/max.spvtxt b/ptx/src/test/spirv_run/max.spvtxt deleted file mode 100644 index 86b732a..0000000 --- a/ptx/src/test/spirv_run/max.spvtxt +++ /dev/null @@ -1,59 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %28 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "max" - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %31 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %uint = OpTypeInt 32 0 -%_ptr_Function_uint = OpTypePointer Function %uint -%_ptr_Generic_uint = OpTypePointer Generic %uint - %ulong_4 = OpConstant %ulong 4 - %uchar = OpTypeInt 8 0 -%_ptr_Generic_uchar = OpTypePointer Generic %uchar - %1 = OpFunction %void None %31 - %8 = OpFunctionParameter %ulong - %9 = OpFunctionParameter %ulong - %26 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_uint Function - %7 = OpVariable %_ptr_Function_uint Function - OpStore %2 %8 - OpStore %3 %9 - %10 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %23 = OpConvertUToPtr %_ptr_Generic_uint %13 - %12 = OpLoad %uint %23 Aligned 4 - OpStore %6 %12 - %15 = OpLoad %ulong %4 - %24 = OpConvertUToPtr %_ptr_Generic_uint %15 - %38 = OpBitcast %_ptr_Generic_uchar %24 - %39 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %38 %ulong_4 - %22 = OpBitcast %_ptr_Generic_uint %39 - %14 = OpLoad %uint %22 Aligned 4 - OpStore %7 %14 - %17 = OpLoad %uint %6 - %18 = OpLoad %uint %7 - %16 = OpExtInst %uint %28 s_max %17 %18 - OpStore %6 %16 - %19 = OpLoad %ulong %5 - %20 = OpLoad %uint %6 - %25 = OpConvertUToPtr %_ptr_Generic_uint %19 - OpStore %25 %20 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/membar.spvtxt b/ptx/src/test/spirv_run/membar.spvtxt deleted file mode 100644 index d808cf3..0000000 --- a/ptx/src/test/spirv_run/membar.spvtxt +++ /dev/null @@ -1,49 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %20 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "membar" - OpExecutionMode %1 ContractionOff - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %23 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %uint = OpTypeInt 32 0 -%_ptr_Function_uint = OpTypePointer Function %uint -%_ptr_Generic_uint = OpTypePointer Generic %uint - %uint_0 = OpConstant %uint 0 - %uint_784 = OpConstant %uint 784 - %1 = OpFunction %void None %23 - %7 = OpFunctionParameter %ulong - %8 = OpFunctionParameter %ulong - %18 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_uint Function - OpStore %2 %7 - OpStore %3 %8 - %9 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %9 - %10 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %10 - %12 = OpLoad %ulong %4 - %16 = OpConvertUToPtr %_ptr_Generic_uint %12 - %15 = OpLoad %uint %16 Aligned 4 - %11 = OpCopyObject %uint %15 - OpStore %6 %11 - OpMemoryBarrier %uint_0 %uint_784 - %13 = OpLoad %ulong %5 - %14 = OpLoad %uint %6 - %17 = OpConvertUToPtr %_ptr_Generic_uint %13 - OpStore %17 %14 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/min.spvtxt b/ptx/src/test/spirv_run/min.spvtxt deleted file mode 100644 index a187376..0000000 --- a/ptx/src/test/spirv_run/min.spvtxt +++ /dev/null @@ -1,59 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %28 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "min" - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %31 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %uint = OpTypeInt 32 0 -%_ptr_Function_uint = OpTypePointer Function %uint -%_ptr_Generic_uint = OpTypePointer Generic %uint - %ulong_4 = OpConstant %ulong 4 - %uchar = OpTypeInt 8 0 -%_ptr_Generic_uchar = OpTypePointer Generic %uchar - %1 = OpFunction %void None %31 - %8 = OpFunctionParameter %ulong - %9 = OpFunctionParameter %ulong - %26 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_uint Function - %7 = OpVariable %_ptr_Function_uint Function - OpStore %2 %8 - OpStore %3 %9 - %10 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %23 = OpConvertUToPtr %_ptr_Generic_uint %13 - %12 = OpLoad %uint %23 Aligned 4 - OpStore %6 %12 - %15 = OpLoad %ulong %4 - %24 = OpConvertUToPtr %_ptr_Generic_uint %15 - %38 = OpBitcast %_ptr_Generic_uchar %24 - %39 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %38 %ulong_4 - %22 = OpBitcast %_ptr_Generic_uint %39 - %14 = OpLoad %uint %22 Aligned 4 - OpStore %7 %14 - %17 = OpLoad %uint %6 - %18 = OpLoad %uint %7 - %16 = OpExtInst %uint %28 s_min %17 %18 - OpStore %6 %16 - %19 = OpLoad %ulong %5 - %20 = OpLoad %uint %6 - %25 = OpConvertUToPtr %_ptr_Generic_uint %19 - OpStore %25 %20 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/mod.rs b/ptx/src/test/spirv_run/mod.rs index 60f5052..1b5afee 100644 --- a/ptx/src/test/spirv_run/mod.rs +++ b/ptx/src/test/spirv_run/mod.rs @@ -1,31 +1,11 @@ use crate::pass;
-use crate::ptx;
-use crate::translate;
use hip_runtime_sys::hipError_t;
-use rspirv::{
- binary::{Assemble, Disassemble},
- dr::{Block, Function, Instruction, Loader, Operand},
-};
-use spirv_headers::Word;
-use spirv_tools_sys::{
- spv_binary, spv_endianness_t, spv_parsed_instruction_t, spv_result_t, spv_target_env,
-};
-use std::collections::hash_map::Entry;
use std::error;
-use std::ffi::{c_void, CStr, CString};
+use std::ffi::{CStr, CString};
use std::fmt;
use std::fmt::{Debug, Display, Formatter};
-use std::fs::File;
-use std::hash::Hash;
-use std::io;
-use std::io::Read;
-use std::io::Write;
use std::mem;
-use std::path::Path;
-use std::process::Command;
-use std::slice;
-use std::{borrow::Cow, collections::HashMap, env, fs, path::PathBuf, ptr, str};
-use tempfile::NamedTempFile;
+use std::{ptr, str};
macro_rules! test_ptx {
($fn_name:ident, $input:expr, $output:expr) => {
@@ -236,7 +216,7 @@ fn test_hip_assert< output: &mut [Output],
) -> Result<(), Box<dyn error::Error + 'a>> {
let ast = ptx_parser::parse_module_checked(ptx_text).unwrap();
- let llvm_ir = pass::to_llvm_module2(ast).unwrap();
+ let llvm_ir = pass::to_llvm_module(ast).unwrap();
let name = CString::new(name)?;
let result =
run_hip(name.as_c_str(), llvm_ir, input, output).map_err(|err| DisplayError { err })?;
@@ -382,226 +362,3 @@ fn run_hip<Input: From<u8> + Copy + Debug, Output: From<u8> + Copy + Debug + Def }
Ok(result)
}
-
-struct EqMap<T>
-where
- T: Eq + Copy + Hash,
-{
- m1: HashMap<T, T>,
- m2: HashMap<T, T>,
-}
-
-impl<T: Copy + Eq + Hash> EqMap<T> {
- fn new() -> Self {
- EqMap {
- m1: HashMap::new(),
- m2: HashMap::new(),
- }
- }
-
- fn is_equal(&mut self, t1: T, t2: T) -> bool {
- match (self.m1.entry(t1), self.m2.entry(t2)) {
- (Entry::Occupied(entry1), Entry::Occupied(entry2)) => {
- *entry1.get() == t2 && *entry2.get() == t1
- }
- (Entry::Vacant(entry1), Entry::Vacant(entry2)) => {
- entry1.insert(t2);
- entry2.insert(t1);
- true
- }
- _ => false,
- }
- }
-}
-
-fn is_spirv_fns_equal(fns1: &[Function], fns2: &[Function]) -> bool {
- if fns1.len() != fns2.len() {
- return false;
- }
- for (fn1, fn2) in fns1.iter().zip(fns2.iter()) {
- if !is_spirv_fn_equal(fn1, fn2) {
- return false;
- }
- }
- true
-}
-
-fn is_spirv_fn_equal(fn1: &Function, fn2: &Function) -> bool {
- let mut map = EqMap::new();
- if !is_option_equal(&fn1.def, &fn2.def, &mut map, is_instr_equal) {
- return false;
- }
- if !is_option_equal(&fn1.end, &fn2.end, &mut map, is_instr_equal) {
- return false;
- }
- if fn1.parameters.len() != fn2.parameters.len() {
- return false;
- }
- for (inst1, inst2) in fn1.parameters.iter().zip(fn2.parameters.iter()) {
- if !is_instr_equal(inst1, inst2, &mut map) {
- return false;
- }
- }
- if fn1.blocks.len() != fn2.blocks.len() {
- return false;
- }
- for (b1, b2) in fn1.blocks.iter().zip(fn2.blocks.iter()) {
- if !is_block_equal(b1, b2, &mut map) {
- return false;
- }
- }
- true
-}
-
-fn is_block_equal(b1: &Block, b2: &Block, map: &mut EqMap<Word>) -> bool {
- if !is_option_equal(&b1.label, &b2.label, map, is_instr_equal) {
- return false;
- }
- if b1.instructions.len() != b2.instructions.len() {
- return false;
- }
- for (inst1, inst2) in b1.instructions.iter().zip(b2.instructions.iter()) {
- if !is_instr_equal(inst1, inst2, map) {
- return false;
- }
- }
- true
-}
-
-fn is_instr_equal(instr1: &Instruction, instr2: &Instruction, map: &mut EqMap<Word>) -> bool {
- if instr1.class.opcode != instr2.class.opcode {
- return false;
- }
- if !is_option_equal(&instr1.result_type, &instr2.result_type, map, is_word_equal) {
- return false;
- }
- if !is_option_equal(&instr1.result_id, &instr2.result_id, map, is_word_equal) {
- return false;
- }
- if instr1.operands.len() != instr2.operands.len() {
- return false;
- }
- for (o1, o2) in instr1.operands.iter().zip(instr2.operands.iter()) {
- match (o1, o2) {
- (Operand::IdMemorySemantics(w1), Operand::IdMemorySemantics(w2)) => {
- if !is_word_equal(w1, w2, map) {
- return false;
- }
- }
- (Operand::IdScope(w1), Operand::IdScope(w2)) => {
- if !is_word_equal(w1, w2, map) {
- return false;
- }
- }
- (Operand::IdRef(w1), Operand::IdRef(w2)) => {
- if !is_word_equal(w1, w2, map) {
- return false;
- }
- }
- (o1, o2) => {
- if o1 != o2 {
- return false;
- }
- }
- }
- }
- true
-}
-
-fn is_word_equal(t1: &Word, t2: &Word, map: &mut EqMap<Word>) -> bool {
- map.is_equal(*t1, *t2)
-}
-
-fn is_option_equal<T, F: FnOnce(&T, &T, &mut EqMap<Word>) -> bool>(
- o1: &Option<T>,
- o2: &Option<T>,
- map: &mut EqMap<Word>,
- f: F,
-) -> bool {
- match (o1, o2) {
- (Some(t1), Some(t2)) => f(t1, t2, map),
- (None, None) => true,
- _ => panic!(),
- }
-}
-
-unsafe extern "C" fn parse_header_cb(
- user_data: *mut c_void,
- endian: spv_endianness_t,
- magic: u32,
- version: u32,
- generator: u32,
- id_bound: u32,
- reserved: u32,
-) -> spv_result_t {
- if endian == spv_endianness_t::SPV_ENDIANNESS_BIG {
- return spv_result_t::SPV_UNSUPPORTED;
- }
- let result_vec: &mut Vec<u32> = std::mem::transmute(user_data);
- result_vec.push(magic);
- result_vec.push(version);
- result_vec.push(generator);
- result_vec.push(id_bound);
- result_vec.push(reserved);
- spv_result_t::SPV_SUCCESS
-}
-
-unsafe extern "C" fn parse_instruction_cb(
- user_data: *mut c_void,
- inst: *const spv_parsed_instruction_t,
-) -> spv_result_t {
- let inst = &*inst;
- let result_vec: &mut Vec<u32> = std::mem::transmute(user_data);
- for i in 0..inst.num_words {
- result_vec.push(*(inst.words.add(i as usize)));
- }
- spv_result_t::SPV_SUCCESS
-}
-
-const LLVM_SPIRV: &'static str = "/home/vosen/amd/llvm-project/build/bin/llvm-spirv";
-const AMDGPU: &'static str = "/opt/rocm/";
-const AMDGPU_TARGET: &'static str = "amdgcn-amd-amdhsa";
-const AMDGPU_BITCODE: [&'static str; 8] = [
- "opencl.bc",
- "ocml.bc",
- "ockl.bc",
- "oclc_correctly_rounded_sqrt_off.bc",
- "oclc_daz_opt_on.bc",
- "oclc_finite_only_off.bc",
- "oclc_unsafe_math_off.bc",
- "oclc_wavefrontsize64_off.bc",
-];
-const AMDGPU_BITCODE_DEVICE_PREFIX: &'static str = "oclc_isa_version_";
-
-fn persist_file(path: &Path) -> io::Result<()> {
- let mut persistent = PathBuf::from("/tmp/zluda");
- std::fs::create_dir_all(&persistent)?;
- persistent.push(path.file_name().unwrap());
- std::fs::copy(path, persistent)?;
- Ok(())
-}
-
-fn get_bitcode_paths(device_name: &str) -> impl Iterator<Item = PathBuf> {
- let generic_paths = AMDGPU_BITCODE.iter().map(|x| {
- let mut path = PathBuf::from(AMDGPU);
- path.push("amdgcn");
- path.push("bitcode");
- path.push(x);
- path
- });
- let suffix = if let Some(suffix_idx) = device_name.find(':') {
- suffix_idx
- } else {
- device_name.len()
- };
- let mut additional_path = PathBuf::from(AMDGPU);
- additional_path.push("amdgcn");
- additional_path.push("bitcode");
- additional_path.push(format!(
- "{}{}{}",
- AMDGPU_BITCODE_DEVICE_PREFIX,
- &device_name[3..suffix],
- ".bc"
- ));
- generic_paths.chain(std::iter::once(additional_path))
-}
diff --git a/ptx/src/test/spirv_run/mov.spvtxt b/ptx/src/test/spirv_run/mov.spvtxt deleted file mode 100644 index 13473d9..0000000 --- a/ptx/src/test/spirv_run/mov.spvtxt +++ /dev/null @@ -1,46 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %22 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "mov" - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %25 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong -%_ptr_Generic_ulong = OpTypePointer Generic %ulong - %1 = OpFunction %void None %25 - %8 = OpFunctionParameter %ulong - %9 = OpFunctionParameter %ulong - %20 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_ulong Function - %7 = OpVariable %_ptr_Function_ulong Function - OpStore %2 %8 - OpStore %3 %9 - %10 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %18 = OpConvertUToPtr %_ptr_Generic_ulong %13 - %12 = OpLoad %ulong %18 Aligned 8 - OpStore %6 %12 - %15 = OpLoad %ulong %6 - %14 = OpCopyObject %ulong %15 - OpStore %7 %14 - %16 = OpLoad %ulong %5 - %17 = OpLoad %ulong %7 - %19 = OpConvertUToPtr %_ptr_Generic_ulong %16 - OpStore %19 %17 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/mov_address.spvtxt b/ptx/src/test/spirv_run/mov_address.spvtxt deleted file mode 100644 index 26ae21f..0000000 --- a/ptx/src/test/spirv_run/mov_address.spvtxt +++ /dev/null @@ -1,33 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int64 - OpCapability Int8 - %12 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "mov_address" - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %15 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %uchar = OpTypeInt 8 0 - %uint = OpTypeInt 32 0 - %uint_8 = OpConstant %uint 8 -%_arr_uchar_uint_8 = OpTypeArray %uchar %uint_8 -%_ptr_Function__arr_uchar_uint_8 = OpTypePointer Function %_arr_uchar_uint_8 - %1 = OpFunction %void None %15 - %6 = OpFunctionParameter %ulong - %7 = OpFunctionParameter %ulong - %10 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function__arr_uchar_uint_8 Function - %5 = OpVariable %_ptr_Function_ulong Function - OpStore %2 %6 - OpStore %3 %7 - %9 = OpConvertPtrToU %ulong %4 - %8 = OpCopyObject %ulong %9 - OpStore %5 %8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/mul_ftz.spvtxt b/ptx/src/test/spirv_run/mul_ftz.spvtxt deleted file mode 100644 index e7a4a56..0000000 --- a/ptx/src/test/spirv_run/mul_ftz.spvtxt +++ /dev/null @@ -1,59 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %28 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "mul_ftz" - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %31 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %float = OpTypeFloat 32 -%_ptr_Function_float = OpTypePointer Function %float -%_ptr_Generic_float = OpTypePointer Generic %float - %ulong_4 = OpConstant %ulong 4 - %uchar = OpTypeInt 8 0 -%_ptr_Generic_uchar = OpTypePointer Generic %uchar - %1 = OpFunction %void None %31 - %8 = OpFunctionParameter %ulong - %9 = OpFunctionParameter %ulong - %26 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_float Function - %7 = OpVariable %_ptr_Function_float Function - OpStore %2 %8 - OpStore %3 %9 - %10 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %23 = OpConvertUToPtr %_ptr_Generic_float %13 - %12 = OpLoad %float %23 Aligned 4 - OpStore %6 %12 - %15 = OpLoad %ulong %4 - %24 = OpConvertUToPtr %_ptr_Generic_float %15 - %38 = OpBitcast %_ptr_Generic_uchar %24 - %39 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %38 %ulong_4 - %22 = OpBitcast %_ptr_Generic_float %39 - %14 = OpLoad %float %22 Aligned 4 - OpStore %7 %14 - %17 = OpLoad %float %6 - %18 = OpLoad %float %7 - %16 = OpFMul %float %17 %18 - OpStore %6 %16 - %19 = OpLoad %ulong %5 - %20 = OpLoad %float %6 - %25 = OpConvertUToPtr %_ptr_Generic_float %19 - OpStore %25 %20 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/mul_hi.spvtxt b/ptx/src/test/spirv_run/mul_hi.spvtxt deleted file mode 100644 index 93537b3..0000000 --- a/ptx/src/test/spirv_run/mul_hi.spvtxt +++ /dev/null @@ -1,47 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %23 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "mul_hi" - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %26 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong -%_ptr_Generic_ulong = OpTypePointer Generic %ulong - %ulong_2 = OpConstant %ulong 2 - %1 = OpFunction %void None %26 - %8 = OpFunctionParameter %ulong - %9 = OpFunctionParameter %ulong - %21 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_ulong Function - %7 = OpVariable %_ptr_Function_ulong Function - OpStore %2 %8 - OpStore %3 %9 - %10 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %19 = OpConvertUToPtr %_ptr_Generic_ulong %13 - %12 = OpLoad %ulong %19 Aligned 8 - OpStore %6 %12 - %15 = OpLoad %ulong %6 - %14 = OpExtInst %ulong %23 u_mul_hi %15 %ulong_2 - OpStore %7 %14 - %16 = OpLoad %ulong %5 - %17 = OpLoad %ulong %7 - %20 = OpConvertUToPtr %_ptr_Generic_ulong %16 - OpStore %20 %17 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/mul_lo.spvtxt b/ptx/src/test/spirv_run/mul_lo.spvtxt deleted file mode 100644 index 7d69cfb..0000000 --- a/ptx/src/test/spirv_run/mul_lo.spvtxt +++ /dev/null @@ -1,47 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %23 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "mul_lo" - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %26 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong -%_ptr_Generic_ulong = OpTypePointer Generic %ulong - %ulong_2 = OpConstant %ulong 2 - %1 = OpFunction %void None %26 - %8 = OpFunctionParameter %ulong - %9 = OpFunctionParameter %ulong - %21 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_ulong Function - %7 = OpVariable %_ptr_Function_ulong Function - OpStore %2 %8 - OpStore %3 %9 - %10 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %19 = OpConvertUToPtr %_ptr_Generic_ulong %13 - %12 = OpLoad %ulong %19 Aligned 8 - OpStore %6 %12 - %15 = OpLoad %ulong %6 - %14 = OpIMul %ulong %15 %ulong_2 - OpStore %7 %14 - %16 = OpLoad %ulong %5 - %17 = OpLoad %ulong %7 - %20 = OpConvertUToPtr %_ptr_Generic_ulong %16 - OpStore %20 %17 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/mul_non_ftz.spvtxt b/ptx/src/test/spirv_run/mul_non_ftz.spvtxt deleted file mode 100644 index 5326baa..0000000 --- a/ptx/src/test/spirv_run/mul_non_ftz.spvtxt +++ /dev/null @@ -1,59 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %28 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "mul_non_ftz" - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %31 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %float = OpTypeFloat 32 -%_ptr_Function_float = OpTypePointer Function %float -%_ptr_Generic_float = OpTypePointer Generic %float - %ulong_4 = OpConstant %ulong 4 - %uchar = OpTypeInt 8 0 -%_ptr_Generic_uchar = OpTypePointer Generic %uchar - %1 = OpFunction %void None %31 - %8 = OpFunctionParameter %ulong - %9 = OpFunctionParameter %ulong - %26 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_float Function - %7 = OpVariable %_ptr_Function_float Function - OpStore %2 %8 - OpStore %3 %9 - %10 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %23 = OpConvertUToPtr %_ptr_Generic_float %13 - %12 = OpLoad %float %23 Aligned 4 - OpStore %6 %12 - %15 = OpLoad %ulong %4 - %24 = OpConvertUToPtr %_ptr_Generic_float %15 - %38 = OpBitcast %_ptr_Generic_uchar %24 - %39 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %38 %ulong_4 - %22 = OpBitcast %_ptr_Generic_float %39 - %14 = OpLoad %float %22 Aligned 4 - OpStore %7 %14 - %17 = OpLoad %float %6 - %18 = OpLoad %float %7 - %16 = OpFMul %float %17 %18 - OpStore %6 %16 - %19 = OpLoad %ulong %5 - %20 = OpLoad %float %6 - %25 = OpConvertUToPtr %_ptr_Generic_float %19 - OpStore %25 %20 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/mul_wide.spvtxt b/ptx/src/test/spirv_run/mul_wide.spvtxt deleted file mode 100644 index b8ffac0..0000000 --- a/ptx/src/test/spirv_run/mul_wide.spvtxt +++ /dev/null @@ -1,66 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %30 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "mul_wide" - OpExecutionMode %1 ContractionOff - OpDecorate %17 NoSignedWrap - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %33 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %uint = OpTypeInt 32 0 -%_ptr_Function_uint = OpTypePointer Function %uint -%_ptr_CrossWorkgroup_uint = OpTypePointer CrossWorkgroup %uint - %ulong_4 = OpConstant %ulong 4 - %uchar = OpTypeInt 8 0 -%_ptr_CrossWorkgroup_uchar = OpTypePointer CrossWorkgroup %uchar -%_ptr_Generic_ulong = OpTypePointer Generic %ulong - %1 = OpFunction %void None %33 - %9 = OpFunctionParameter %ulong - %10 = OpFunctionParameter %ulong - %28 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_uint Function - %7 = OpVariable %_ptr_Function_uint Function - %8 = OpVariable %_ptr_Function_ulong Function - OpStore %2 %9 - OpStore %3 %10 - %11 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %11 - %12 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %12 - %14 = OpLoad %ulong %4 - %24 = OpConvertUToPtr %_ptr_CrossWorkgroup_uint %14 - %13 = OpLoad %uint %24 Aligned 4 - OpStore %6 %13 - %16 = OpLoad %ulong %4 - %25 = OpConvertUToPtr %_ptr_CrossWorkgroup_uint %16 - %40 = OpBitcast %_ptr_CrossWorkgroup_uchar %25 - %41 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uchar %40 %ulong_4 - %23 = OpBitcast %_ptr_CrossWorkgroup_uint %41 - %15 = OpLoad %uint %23 Aligned 4 - OpStore %7 %15 - %18 = OpLoad %uint %6 - %19 = OpLoad %uint %7 - %42 = OpSConvert %ulong %18 - %43 = OpSConvert %ulong %19 - %17 = OpIMul %ulong %42 %43 - OpStore %8 %17 - %20 = OpLoad %ulong %5 - %21 = OpLoad %ulong %8 - %26 = OpConvertUToPtr %_ptr_Generic_ulong %20 - %27 = OpCopyObject %ulong %21 - OpStore %26 %27 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/neg.spvtxt b/ptx/src/test/spirv_run/neg.spvtxt deleted file mode 100644 index d5ab925..0000000 --- a/ptx/src/test/spirv_run/neg.spvtxt +++ /dev/null @@ -1,47 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %21 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "neg" - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %24 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %uint = OpTypeInt 32 0 -%_ptr_Function_uint = OpTypePointer Function %uint -%_ptr_Generic_uint = OpTypePointer Generic %uint - %1 = OpFunction %void None %24 - %7 = OpFunctionParameter %ulong - %8 = OpFunctionParameter %ulong - %19 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_uint Function - OpStore %2 %7 - OpStore %3 %8 - %9 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %9 - %10 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %10 - %12 = OpLoad %ulong %4 - %17 = OpConvertUToPtr %_ptr_Generic_uint %12 - %11 = OpLoad %uint %17 Aligned 4 - OpStore %6 %11 - %14 = OpLoad %uint %6 - %13 = OpSNegate %uint %14 - OpStore %6 %13 - %15 = OpLoad %ulong %5 - %16 = OpLoad %uint %6 - %18 = OpConvertUToPtr %_ptr_Generic_uint %15 - OpStore %18 %16 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/non_scalar_ptr_offset.spvtxt b/ptx/src/test/spirv_run/non_scalar_ptr_offset.spvtxt deleted file mode 100644 index 92dc7cc..0000000 --- a/ptx/src/test/spirv_run/non_scalar_ptr_offset.spvtxt +++ /dev/null @@ -1,60 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %27 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "non_scalar_ptr_offset" - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %30 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %uint = OpTypeInt 32 0 -%_ptr_Function_uint = OpTypePointer Function %uint - %ulong_8 = OpConstant %ulong 8 - %v2uint = OpTypeVector %uint 2 -%_ptr_CrossWorkgroup_v2uint = OpTypePointer CrossWorkgroup %v2uint - %uchar = OpTypeInt 8 0 -%_ptr_CrossWorkgroup_uchar = OpTypePointer CrossWorkgroup %uchar -%_ptr_CrossWorkgroup_uint = OpTypePointer CrossWorkgroup %uint - %1 = OpFunction %void None %30 - %9 = OpFunctionParameter %ulong - %10 = OpFunctionParameter %ulong - %25 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_uint Function - %7 = OpVariable %_ptr_Function_uint Function - OpStore %2 %9 - OpStore %3 %10 - %11 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %11 - %12 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %12 - %13 = OpLoad %ulong %4 - %23 = OpConvertUToPtr %_ptr_CrossWorkgroup_v2uint %13 - %38 = OpBitcast %_ptr_CrossWorkgroup_uchar %23 - %39 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uchar %38 %ulong_8 - %22 = OpBitcast %_ptr_CrossWorkgroup_v2uint %39 - %8 = OpLoad %v2uint %22 Aligned 8 - %14 = OpCompositeExtract %uint %8 0 - %15 = OpCompositeExtract %uint %8 1 - OpStore %6 %14 - OpStore %7 %15 - %17 = OpLoad %uint %6 - %18 = OpLoad %uint %7 - %16 = OpIAdd %uint %17 %18 - OpStore %6 %16 - %19 = OpLoad %ulong %5 - %20 = OpLoad %uint %6 - %24 = OpConvertUToPtr %_ptr_CrossWorkgroup_uint %19 - OpStore %24 %20 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/not.spvtxt b/ptx/src/test/spirv_run/not.spvtxt deleted file mode 100644 index 655a892..0000000 --- a/ptx/src/test/spirv_run/not.spvtxt +++ /dev/null @@ -1,48 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %24 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "not" - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %27 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong -%_ptr_Generic_ulong = OpTypePointer Generic %ulong - %1 = OpFunction %void None %27 - %8 = OpFunctionParameter %ulong - %9 = OpFunctionParameter %ulong - %22 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_ulong Function - %7 = OpVariable %_ptr_Function_ulong Function - OpStore %2 %8 - OpStore %3 %9 - %10 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %18 = OpConvertUToPtr %_ptr_Generic_ulong %13 - %12 = OpLoad %ulong %18 Aligned 8 - OpStore %6 %12 - %15 = OpLoad %ulong %6 - %20 = OpCopyObject %ulong %15 - %19 = OpNot %ulong %20 - %14 = OpCopyObject %ulong %19 - OpStore %7 %14 - %16 = OpLoad %ulong %5 - %17 = OpLoad %ulong %7 - %21 = OpConvertUToPtr %_ptr_Generic_ulong %16 - OpStore %21 %17 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/ntid.spvtxt b/ptx/src/test/spirv_run/ntid.spvtxt deleted file mode 100644 index 6754ce4..0000000 --- a/ptx/src/test/spirv_run/ntid.spvtxt +++ /dev/null @@ -1,60 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %30 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "ntid" - OpExecutionMode %1 ContractionOff - OpDecorate %11 LinkageAttributes "__zluda_ptx_impl__sreg_ntid" Import - %void = OpTypeVoid - %uint = OpTypeInt 32 0 - %uchar = OpTypeInt 8 0 - %34 = OpTypeFunction %uint %uchar - %ulong = OpTypeInt 64 0 - %36 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong -%_ptr_Function_uint = OpTypePointer Function %uint -%_ptr_Generic_uint = OpTypePointer Generic %uint - %uchar_0 = OpConstant %uchar 0 - %11 = OpFunction %uint None %34 - %13 = OpFunctionParameter %uchar - OpFunctionEnd - %1 = OpFunction %void None %36 - %14 = OpFunctionParameter %ulong - %15 = OpFunctionParameter %ulong - %28 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_uint Function - %7 = OpVariable %_ptr_Function_uint Function - OpStore %2 %14 - OpStore %3 %15 - %16 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %16 - %17 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %17 - %19 = OpLoad %ulong %4 - %26 = OpConvertUToPtr %_ptr_Generic_uint %19 - %18 = OpLoad %uint %26 Aligned 4 - OpStore %6 %18 - %10 = OpFunctionCall %uint %11 %uchar_0 - %20 = OpCopyObject %uint %10 - OpStore %7 %20 - %22 = OpLoad %uint %6 - %23 = OpLoad %uint %7 - %21 = OpIAdd %uint %22 %23 - OpStore %6 %21 - %24 = OpLoad %ulong %5 - %25 = OpLoad %uint %6 - %27 = OpConvertUToPtr %_ptr_Generic_uint %24 - OpStore %27 %25 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/or.spvtxt b/ptx/src/test/spirv_run/or.spvtxt deleted file mode 100644 index 82db00c..0000000 --- a/ptx/src/test/spirv_run/or.spvtxt +++ /dev/null @@ -1,60 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %31 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "or" - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %34 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong -%_ptr_Generic_ulong = OpTypePointer Generic %ulong - %ulong_8 = OpConstant %ulong 8 - %uchar = OpTypeInt 8 0 -%_ptr_Generic_uchar = OpTypePointer Generic %uchar - %1 = OpFunction %void None %34 - %8 = OpFunctionParameter %ulong - %9 = OpFunctionParameter %ulong - %29 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_ulong Function - %7 = OpVariable %_ptr_Function_ulong Function - OpStore %2 %8 - OpStore %3 %9 - %10 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %23 = OpConvertUToPtr %_ptr_Generic_ulong %13 - %12 = OpLoad %ulong %23 Aligned 8 - OpStore %6 %12 - %15 = OpLoad %ulong %4 - %24 = OpConvertUToPtr %_ptr_Generic_ulong %15 - %39 = OpBitcast %_ptr_Generic_uchar %24 - %40 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %39 %ulong_8 - %22 = OpBitcast %_ptr_Generic_ulong %40 - %14 = OpLoad %ulong %22 Aligned 8 - OpStore %7 %14 - %17 = OpLoad %ulong %6 - %18 = OpLoad %ulong %7 - %26 = OpCopyObject %ulong %17 - %27 = OpCopyObject %ulong %18 - %25 = OpBitwiseOr %ulong %26 %27 - %16 = OpCopyObject %ulong %25 - OpStore %6 %16 - %19 = OpLoad %ulong %5 - %20 = OpLoad %ulong %6 - %28 = OpConvertUToPtr %_ptr_Generic_ulong %19 - OpStore %28 %20 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/popc.spvtxt b/ptx/src/test/spirv_run/popc.spvtxt deleted file mode 100644 index c41e792..0000000 --- a/ptx/src/test/spirv_run/popc.spvtxt +++ /dev/null @@ -1,52 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - OpCapability DenormFlushToZero - OpExtension "SPV_KHR_float_controls" - OpExtension "SPV_KHR_no_integer_wrap_decoration" - %22 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "popc" - OpExecutionMode %1 ContractionOff - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %25 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %uint = OpTypeInt 32 0 -%_ptr_Function_uint = OpTypePointer Function %uint -%_ptr_Generic_uint = OpTypePointer Generic %uint - %1 = OpFunction %void None %25 - %7 = OpFunctionParameter %ulong - %8 = OpFunctionParameter %ulong - %20 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_uint Function - OpStore %2 %7 - OpStore %3 %8 - %9 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %9 - %10 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %10 - %12 = OpLoad %ulong %4 - %17 = OpConvertUToPtr %_ptr_Generic_uint %12 - %11 = OpLoad %uint %17 Aligned 4 - OpStore %6 %11 - %14 = OpLoad %uint %6 - %18 = OpBitCount %uint %14 - %13 = OpCopyObject %uint %18 - OpStore %6 %13 - %15 = OpLoad %ulong %5 - %16 = OpLoad %uint %6 - %19 = OpConvertUToPtr %_ptr_Generic_uint %15 - OpStore %19 %16 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/pred_not.spvtxt b/ptx/src/test/spirv_run/pred_not.spvtxt deleted file mode 100644 index 644731b..0000000 --- a/ptx/src/test/spirv_run/pred_not.spvtxt +++ /dev/null @@ -1,82 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %42 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "pred_not" - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %45 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %bool = OpTypeBool -%_ptr_Function_bool = OpTypePointer Function %bool -%_ptr_Generic_ulong = OpTypePointer Generic %ulong - %ulong_8 = OpConstant %ulong 8 - %uchar = OpTypeInt 8 0 -%_ptr_Generic_uchar = OpTypePointer Generic %uchar - %true = OpConstantTrue %bool - %false = OpConstantFalse %bool - %ulong_1 = OpConstant %ulong 1 - %ulong_2 = OpConstant %ulong 2 - %1 = OpFunction %void None %45 - %14 = OpFunctionParameter %ulong - %15 = OpFunctionParameter %ulong - %40 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_ulong Function - %7 = OpVariable %_ptr_Function_ulong Function - %8 = OpVariable %_ptr_Function_ulong Function - %9 = OpVariable %_ptr_Function_bool Function - OpStore %2 %14 - OpStore %3 %15 - %16 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %16 - %17 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %17 - %19 = OpLoad %ulong %4 - %37 = OpConvertUToPtr %_ptr_Generic_ulong %19 - %18 = OpLoad %ulong %37 Aligned 8 - OpStore %6 %18 - %21 = OpLoad %ulong %4 - %38 = OpConvertUToPtr %_ptr_Generic_ulong %21 - %52 = OpBitcast %_ptr_Generic_uchar %38 - %53 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %52 %ulong_8 - %34 = OpBitcast %_ptr_Generic_ulong %53 - %20 = OpLoad %ulong %34 Aligned 8 - OpStore %7 %20 - %23 = OpLoad %ulong %6 - %24 = OpLoad %ulong %7 - %22 = OpULessThan %bool %23 %24 - OpStore %9 %22 - %26 = OpLoad %bool %9 - %25 = OpSelect %bool %26 %false %true - OpStore %9 %25 - %27 = OpLoad %bool %9 - OpBranchConditional %27 %10 %11 - %10 = OpLabel - %28 = OpCopyObject %ulong %ulong_1 - OpStore %8 %28 - OpBranch %11 - %11 = OpLabel - %29 = OpLoad %bool %9 - OpBranchConditional %29 %13 %12 - %12 = OpLabel - %30 = OpCopyObject %ulong %ulong_2 - OpStore %8 %30 - OpBranch %13 - %13 = OpLabel - %31 = OpLoad %ulong %5 - %32 = OpLoad %ulong %8 - %39 = OpConvertUToPtr %_ptr_Generic_ulong %31 - OpStore %39 %32 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/prmt.spvtxt b/ptx/src/test/spirv_run/prmt.spvtxt deleted file mode 100644 index 060f534..0000000 --- a/ptx/src/test/spirv_run/prmt.spvtxt +++ /dev/null @@ -1,67 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %31 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "prmt" - OpExecutionMode %1 ContractionOff - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %34 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %uint = OpTypeInt 32 0 -%_ptr_Function_uint = OpTypePointer Function %uint -%_ptr_Generic_uint = OpTypePointer Generic %uint - %ulong_4 = OpConstant %ulong 4 - %uchar = OpTypeInt 8 0 -%_ptr_Generic_uchar = OpTypePointer Generic %uchar - %v4uchar = OpTypeVector %uchar 4 - %1 = OpFunction %void None %34 - %8 = OpFunctionParameter %ulong - %9 = OpFunctionParameter %ulong - %29 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_uint Function - %7 = OpVariable %_ptr_Function_uint Function - OpStore %2 %8 - OpStore %3 %9 - %10 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %23 = OpConvertUToPtr %_ptr_Generic_uint %13 - %12 = OpLoad %uint %23 Aligned 4 - OpStore %6 %12 - %15 = OpLoad %ulong %4 - %24 = OpConvertUToPtr %_ptr_Generic_uint %15 - %41 = OpBitcast %_ptr_Generic_uchar %24 - %42 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %41 %ulong_4 - %22 = OpBitcast %_ptr_Generic_uint %42 - %14 = OpLoad %uint %22 Aligned 4 - OpStore %7 %14 - %17 = OpLoad %uint %6 - %18 = OpLoad %uint %7 - %26 = OpCopyObject %uint %17 - %27 = OpCopyObject %uint %18 - %44 = OpBitcast %v4uchar %26 - %45 = OpBitcast %v4uchar %27 - %46 = OpVectorShuffle %v4uchar %44 %45 4 0 6 7 - %25 = OpBitcast %uint %46 - %16 = OpCopyObject %uint %25 - OpStore %7 %16 - %19 = OpLoad %ulong %5 - %20 = OpLoad %uint %7 - %28 = OpConvertUToPtr %_ptr_Generic_uint %19 - OpStore %28 %20 Aligned 4 - OpReturn - OpFunctionEnd
\ No newline at end of file diff --git a/ptx/src/test/spirv_run/rcp.spvtxt b/ptx/src/test/spirv_run/rcp.spvtxt deleted file mode 100644 index 09fa0d9..0000000 --- a/ptx/src/test/spirv_run/rcp.spvtxt +++ /dev/null @@ -1,48 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %21 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "rcp" - OpExecutionMode %1 ContractionOff - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %24 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %float = OpTypeFloat 32 -%_ptr_Function_float = OpTypePointer Function %float -%_ptr_Generic_float = OpTypePointer Generic %float - %1 = OpFunction %void None %24 - %7 = OpFunctionParameter %ulong - %8 = OpFunctionParameter %ulong - %19 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_float Function - OpStore %2 %7 - OpStore %3 %8 - %9 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %9 - %10 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %10 - %12 = OpLoad %ulong %4 - %17 = OpConvertUToPtr %_ptr_Generic_float %12 - %11 = OpLoad %float %17 Aligned 4 - OpStore %6 %11 - %14 = OpLoad %float %6 - %13 = OpExtInst %float %21 native_recip %14 - OpStore %6 %13 - %15 = OpLoad %ulong %5 - %16 = OpLoad %float %6 - %18 = OpConvertUToPtr %_ptr_Generic_float %15 - OpStore %18 %16 Aligned 4 - OpReturn - OpFunctionEnd
\ No newline at end of file diff --git a/ptx/src/test/spirv_run/reg_local.spvtxt b/ptx/src/test/spirv_run/reg_local.spvtxt deleted file mode 100644 index ddb6a9e..0000000 --- a/ptx/src/test/spirv_run/reg_local.spvtxt +++ /dev/null @@ -1,76 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - OpCapability DenormFlushToZero - %34 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "reg_local" - OpExecutionMode %1 ContractionOff - OpDecorate %4 Alignment 8 - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %37 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %uint = OpTypeInt 32 0 - %uchar = OpTypeInt 8 0 - %uint_8 = OpConstant %uint 8 -%_arr_uchar_uint_8 = OpTypeArray %uchar %uint_8 -%_ptr_Function__arr_uchar_uint_8 = OpTypePointer Function %_arr_uchar_uint_8 -%_ptr_CrossWorkgroup_ulong = OpTypePointer CrossWorkgroup %ulong - %ulong_1 = OpConstant %ulong 1 -%_ptr_Generic_ulong = OpTypePointer Generic %ulong - %ulong_0 = OpConstant %ulong 0 -%_ptr_Generic_uchar = OpTypePointer Generic %uchar - %ulong_0_0 = OpConstant %ulong 0 -%_ptr_CrossWorkgroup_uchar = OpTypePointer CrossWorkgroup %uchar - %1 = OpFunction %void None %37 - %8 = OpFunctionParameter %ulong - %9 = OpFunctionParameter %ulong - %32 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function__arr_uchar_uint_8 Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_ulong Function - %7 = OpVariable %_ptr_Function_ulong Function - OpStore %2 %8 - OpStore %3 %9 - %10 = OpLoad %ulong %2 Aligned 8 - OpStore %5 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %6 %11 - %13 = OpLoad %ulong %5 - %25 = OpConvertUToPtr %_ptr_CrossWorkgroup_ulong %13 - %24 = OpLoad %ulong %25 Aligned 8 - %12 = OpCopyObject %ulong %24 - OpStore %7 %12 - %14 = OpLoad %ulong %7 - %19 = OpIAdd %ulong %14 %ulong_1 - %46 = OpBitcast %_ptr_Function_ulong %4 - %26 = OpPtrCastToGeneric %_ptr_Generic_ulong %46 - %27 = OpCopyObject %ulong %19 - OpStore %26 %27 Aligned 8 - %47 = OpBitcast %_ptr_Function_ulong %4 - %28 = OpPtrCastToGeneric %_ptr_Generic_ulong %47 - %49 = OpBitcast %_ptr_Generic_uchar %28 - %50 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %49 %ulong_0 - %21 = OpBitcast %_ptr_Generic_ulong %50 - %29 = OpLoad %ulong %21 Aligned 8 - %15 = OpCopyObject %ulong %29 - OpStore %7 %15 - %16 = OpLoad %ulong %6 - %17 = OpLoad %ulong %7 - %30 = OpConvertUToPtr %_ptr_CrossWorkgroup_ulong %16 - %52 = OpBitcast %_ptr_CrossWorkgroup_uchar %30 - %53 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uchar %52 %ulong_0_0 - %23 = OpBitcast %_ptr_CrossWorkgroup_ulong %53 - %31 = OpCopyObject %ulong %17 - OpStore %23 %31 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/rem.spvtxt b/ptx/src/test/spirv_run/rem.spvtxt deleted file mode 100644 index 2184523..0000000 --- a/ptx/src/test/spirv_run/rem.spvtxt +++ /dev/null @@ -1,59 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %28 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "rem" - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %31 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %uint = OpTypeInt 32 0 -%_ptr_Function_uint = OpTypePointer Function %uint -%_ptr_Generic_uint = OpTypePointer Generic %uint - %ulong_4 = OpConstant %ulong 4 - %uchar = OpTypeInt 8 0 -%_ptr_Generic_uchar = OpTypePointer Generic %uchar - %1 = OpFunction %void None %31 - %8 = OpFunctionParameter %ulong - %9 = OpFunctionParameter %ulong - %26 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_uint Function - %7 = OpVariable %_ptr_Function_uint Function - OpStore %2 %8 - OpStore %3 %9 - %10 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %23 = OpConvertUToPtr %_ptr_Generic_uint %13 - %12 = OpLoad %uint %23 Aligned 4 - OpStore %6 %12 - %15 = OpLoad %ulong %4 - %24 = OpConvertUToPtr %_ptr_Generic_uint %15 - %38 = OpBitcast %_ptr_Generic_uchar %24 - %39 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %38 %ulong_4 - %22 = OpBitcast %_ptr_Generic_uint %39 - %14 = OpLoad %uint %22 Aligned 4 - OpStore %7 %14 - %17 = OpLoad %uint %6 - %18 = OpLoad %uint %7 - %16 = OpSMod %uint %17 %18 - OpStore %6 %16 - %19 = OpLoad %ulong %5 - %20 = OpLoad %uint %6 - %25 = OpConvertUToPtr %_ptr_Generic_uint %19 - OpStore %25 %20 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/rsqrt.spvtxt b/ptx/src/test/spirv_run/rsqrt.spvtxt deleted file mode 100644 index 6c87113..0000000 --- a/ptx/src/test/spirv_run/rsqrt.spvtxt +++ /dev/null @@ -1,48 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %21 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "rsqrt" - OpExecutionMode %1 ContractionOff - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %24 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %double = OpTypeFloat 64 -%_ptr_Function_double = OpTypePointer Function %double -%_ptr_Generic_double = OpTypePointer Generic %double - %1 = OpFunction %void None %24 - %7 = OpFunctionParameter %ulong - %8 = OpFunctionParameter %ulong - %19 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_double Function - OpStore %2 %7 - OpStore %3 %8 - %9 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %9 - %10 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %10 - %12 = OpLoad %ulong %4 - %17 = OpConvertUToPtr %_ptr_Generic_double %12 - %11 = OpLoad %double %17 Aligned 8 - OpStore %6 %11 - %14 = OpLoad %double %6 - %13 = OpExtInst %double %21 rsqrt %14 - OpStore %6 %13 - %15 = OpLoad %ulong %5 - %16 = OpLoad %double %6 - %18 = OpConvertUToPtr %_ptr_Generic_double %15 - OpStore %18 %16 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/selp.spvtxt b/ptx/src/test/spirv_run/selp.spvtxt deleted file mode 100644 index 40c0bce..0000000 --- a/ptx/src/test/spirv_run/selp.spvtxt +++ /dev/null @@ -1,61 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %29 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "selp" - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %32 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %ushort = OpTypeInt 16 0 -%_ptr_Function_ushort = OpTypePointer Function %ushort -%_ptr_Generic_ushort = OpTypePointer Generic %ushort - %ulong_2 = OpConstant %ulong 2 - %uchar = OpTypeInt 8 0 -%_ptr_Generic_uchar = OpTypePointer Generic %uchar - %bool = OpTypeBool - %false = OpConstantFalse %bool - %1 = OpFunction %void None %32 - %8 = OpFunctionParameter %ulong - %9 = OpFunctionParameter %ulong - %27 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_ushort Function - %7 = OpVariable %_ptr_Function_ushort Function - OpStore %2 %8 - OpStore %3 %9 - %10 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %24 = OpConvertUToPtr %_ptr_Generic_ushort %13 - %12 = OpLoad %ushort %24 Aligned 2 - OpStore %6 %12 - %15 = OpLoad %ulong %4 - %25 = OpConvertUToPtr %_ptr_Generic_ushort %15 - %39 = OpBitcast %_ptr_Generic_uchar %25 - %40 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %39 %ulong_2 - %22 = OpBitcast %_ptr_Generic_ushort %40 - %14 = OpLoad %ushort %22 Aligned 2 - OpStore %7 %14 - %17 = OpLoad %ushort %6 - %18 = OpLoad %ushort %7 - %16 = OpSelect %ushort %false %17 %18 - OpStore %6 %16 - %19 = OpLoad %ulong %5 - %20 = OpLoad %ushort %6 - %26 = OpConvertUToPtr %_ptr_Generic_ushort %19 - OpStore %26 %20 Aligned 2 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/selp_true.spvtxt b/ptx/src/test/spirv_run/selp_true.spvtxt deleted file mode 100644 index 81b3b5f..0000000 --- a/ptx/src/test/spirv_run/selp_true.spvtxt +++ /dev/null @@ -1,61 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %29 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "selp_true" - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %32 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %ushort = OpTypeInt 16 0 -%_ptr_Function_ushort = OpTypePointer Function %ushort -%_ptr_Generic_ushort = OpTypePointer Generic %ushort - %ulong_2 = OpConstant %ulong 2 - %uchar = OpTypeInt 8 0 -%_ptr_Generic_uchar = OpTypePointer Generic %uchar - %bool = OpTypeBool - %true = OpConstantTrue %bool - %1 = OpFunction %void None %32 - %8 = OpFunctionParameter %ulong - %9 = OpFunctionParameter %ulong - %27 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_ushort Function - %7 = OpVariable %_ptr_Function_ushort Function - OpStore %2 %8 - OpStore %3 %9 - %10 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %24 = OpConvertUToPtr %_ptr_Generic_ushort %13 - %12 = OpLoad %ushort %24 Aligned 2 - OpStore %6 %12 - %15 = OpLoad %ulong %4 - %25 = OpConvertUToPtr %_ptr_Generic_ushort %15 - %39 = OpBitcast %_ptr_Generic_uchar %25 - %40 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %39 %ulong_2 - %22 = OpBitcast %_ptr_Generic_ushort %40 - %14 = OpLoad %ushort %22 Aligned 2 - OpStore %7 %14 - %17 = OpLoad %ushort %6 - %18 = OpLoad %ushort %7 - %16 = OpSelect %ushort %true %17 %18 - OpStore %6 %16 - %19 = OpLoad %ulong %5 - %20 = OpLoad %ushort %6 - %26 = OpConvertUToPtr %_ptr_Generic_ushort %19 - OpStore %26 %20 Aligned 2 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/setp.spvtxt b/ptx/src/test/spirv_run/setp.spvtxt deleted file mode 100644 index 5868881..0000000 --- a/ptx/src/test/spirv_run/setp.spvtxt +++ /dev/null @@ -1,77 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %40 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "setp" - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %43 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %bool = OpTypeBool -%_ptr_Function_bool = OpTypePointer Function %bool -%_ptr_Generic_ulong = OpTypePointer Generic %ulong - %ulong_8 = OpConstant %ulong 8 - %uchar = OpTypeInt 8 0 -%_ptr_Generic_uchar = OpTypePointer Generic %uchar - %ulong_1 = OpConstant %ulong 1 - %ulong_2 = OpConstant %ulong 2 - %1 = OpFunction %void None %43 - %14 = OpFunctionParameter %ulong - %15 = OpFunctionParameter %ulong - %38 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_ulong Function - %7 = OpVariable %_ptr_Function_ulong Function - %8 = OpVariable %_ptr_Function_ulong Function - %9 = OpVariable %_ptr_Function_bool Function - OpStore %2 %14 - OpStore %3 %15 - %16 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %16 - %17 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %17 - %19 = OpLoad %ulong %4 - %35 = OpConvertUToPtr %_ptr_Generic_ulong %19 - %18 = OpLoad %ulong %35 Aligned 8 - OpStore %6 %18 - %21 = OpLoad %ulong %4 - %36 = OpConvertUToPtr %_ptr_Generic_ulong %21 - %50 = OpBitcast %_ptr_Generic_uchar %36 - %51 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %50 %ulong_8 - %32 = OpBitcast %_ptr_Generic_ulong %51 - %20 = OpLoad %ulong %32 Aligned 8 - OpStore %7 %20 - %23 = OpLoad %ulong %6 - %24 = OpLoad %ulong %7 - %22 = OpULessThan %bool %23 %24 - OpStore %9 %22 - %25 = OpLoad %bool %9 - OpBranchConditional %25 %10 %11 - %10 = OpLabel - %26 = OpCopyObject %ulong %ulong_1 - OpStore %8 %26 - OpBranch %11 - %11 = OpLabel - %27 = OpLoad %bool %9 - OpBranchConditional %27 %13 %12 - %12 = OpLabel - %28 = OpCopyObject %ulong %ulong_2 - OpStore %8 %28 - OpBranch %13 - %13 = OpLabel - %29 = OpLoad %ulong %5 - %30 = OpLoad %ulong %8 - %37 = OpConvertUToPtr %_ptr_Generic_ulong %29 - OpStore %37 %30 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/setp_gt.spvtxt b/ptx/src/test/spirv_run/setp_gt.spvtxt deleted file mode 100644 index e9783f5..0000000 --- a/ptx/src/test/spirv_run/setp_gt.spvtxt +++ /dev/null @@ -1,79 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %40 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "setp_gt" - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %43 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %float = OpTypeFloat 32 -%_ptr_Function_float = OpTypePointer Function %float - %bool = OpTypeBool -%_ptr_Function_bool = OpTypePointer Function %bool -%_ptr_Generic_float = OpTypePointer Generic %float - %ulong_4 = OpConstant %ulong 4 - %uchar = OpTypeInt 8 0 -%_ptr_Generic_uchar = OpTypePointer Generic %uchar - %1 = OpFunction %void None %43 - %14 = OpFunctionParameter %ulong - %15 = OpFunctionParameter %ulong - %38 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_float Function - %7 = OpVariable %_ptr_Function_float Function - %8 = OpVariable %_ptr_Function_float Function - %9 = OpVariable %_ptr_Function_bool Function - OpStore %2 %14 - OpStore %3 %15 - %16 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %16 - %17 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %17 - %19 = OpLoad %ulong %4 - %35 = OpConvertUToPtr %_ptr_Generic_float %19 - %18 = OpLoad %float %35 Aligned 4 - OpStore %6 %18 - %21 = OpLoad %ulong %4 - %36 = OpConvertUToPtr %_ptr_Generic_float %21 - %52 = OpBitcast %_ptr_Generic_uchar %36 - %53 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %52 %ulong_4 - %34 = OpBitcast %_ptr_Generic_float %53 - %20 = OpLoad %float %34 Aligned 4 - OpStore %7 %20 - %23 = OpLoad %float %6 - %24 = OpLoad %float %7 - %22 = OpFOrdGreaterThan %bool %23 %24 - OpStore %9 %22 - %25 = OpLoad %bool %9 - OpBranchConditional %25 %10 %11 - %10 = OpLabel - %27 = OpLoad %float %6 - %26 = OpCopyObject %float %27 - OpStore %8 %26 - OpBranch %11 - %11 = OpLabel - %28 = OpLoad %bool %9 - OpBranchConditional %28 %13 %12 - %12 = OpLabel - %30 = OpLoad %float %7 - %29 = OpCopyObject %float %30 - OpStore %8 %29 - OpBranch %13 - %13 = OpLabel - %31 = OpLoad %ulong %5 - %32 = OpLoad %float %8 - %37 = OpConvertUToPtr %_ptr_Generic_float %31 - OpStore %37 %32 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/setp_leu.spvtxt b/ptx/src/test/spirv_run/setp_leu.spvtxt deleted file mode 100644 index 1d2d781..0000000 --- a/ptx/src/test/spirv_run/setp_leu.spvtxt +++ /dev/null @@ -1,79 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %40 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "setp_leu" - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %43 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %float = OpTypeFloat 32 -%_ptr_Function_float = OpTypePointer Function %float - %bool = OpTypeBool -%_ptr_Function_bool = OpTypePointer Function %bool -%_ptr_Generic_float = OpTypePointer Generic %float - %ulong_4 = OpConstant %ulong 4 - %uchar = OpTypeInt 8 0 -%_ptr_Generic_uchar = OpTypePointer Generic %uchar - %1 = OpFunction %void None %43 - %14 = OpFunctionParameter %ulong - %15 = OpFunctionParameter %ulong - %38 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_float Function - %7 = OpVariable %_ptr_Function_float Function - %8 = OpVariable %_ptr_Function_float Function - %9 = OpVariable %_ptr_Function_bool Function - OpStore %2 %14 - OpStore %3 %15 - %16 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %16 - %17 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %17 - %19 = OpLoad %ulong %4 - %35 = OpConvertUToPtr %_ptr_Generic_float %19 - %18 = OpLoad %float %35 Aligned 4 - OpStore %6 %18 - %21 = OpLoad %ulong %4 - %36 = OpConvertUToPtr %_ptr_Generic_float %21 - %52 = OpBitcast %_ptr_Generic_uchar %36 - %53 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %52 %ulong_4 - %34 = OpBitcast %_ptr_Generic_float %53 - %20 = OpLoad %float %34 Aligned 4 - OpStore %7 %20 - %23 = OpLoad %float %6 - %24 = OpLoad %float %7 - %22 = OpFUnordLessThanEqual %bool %23 %24 - OpStore %9 %22 - %25 = OpLoad %bool %9 - OpBranchConditional %25 %10 %11 - %10 = OpLabel - %27 = OpLoad %float %6 - %26 = OpCopyObject %float %27 - OpStore %8 %26 - OpBranch %11 - %11 = OpLabel - %28 = OpLoad %bool %9 - OpBranchConditional %28 %13 %12 - %12 = OpLabel - %30 = OpLoad %float %7 - %29 = OpCopyObject %float %30 - OpStore %8 %29 - OpBranch %13 - %13 = OpLabel - %31 = OpLoad %ulong %5 - %32 = OpLoad %float %8 - %37 = OpConvertUToPtr %_ptr_Generic_float %31 - OpStore %37 %32 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/setp_nan.spvtxt b/ptx/src/test/spirv_run/setp_nan.spvtxt deleted file mode 100644 index 2ee333a..0000000 --- a/ptx/src/test/spirv_run/setp_nan.spvtxt +++ /dev/null @@ -1,228 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %130 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "setp_nan" - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %133 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %float = OpTypeFloat 32 -%_ptr_Function_float = OpTypePointer Function %float - %uint = OpTypeInt 32 0 -%_ptr_Function_uint = OpTypePointer Function %uint - %bool = OpTypeBool -%_ptr_Function_bool = OpTypePointer Function %bool -%_ptr_Generic_float = OpTypePointer Generic %float - %ulong_4 = OpConstant %ulong 4 - %uchar = OpTypeInt 8 0 -%_ptr_Generic_uchar = OpTypePointer Generic %uchar - %ulong_8 = OpConstant %ulong 8 - %ulong_12 = OpConstant %ulong 12 - %ulong_16 = OpConstant %ulong 16 - %ulong_20 = OpConstant %ulong 20 - %ulong_24 = OpConstant %ulong 24 - %ulong_28 = OpConstant %ulong 28 - %uint_1 = OpConstant %uint 1 - %uint_0 = OpConstant %uint 0 -%_ptr_Generic_uint = OpTypePointer Generic %uint - %uint_1_0 = OpConstant %uint 1 - %uint_0_0 = OpConstant %uint 0 - %ulong_4_0 = OpConstant %ulong 4 - %uint_1_1 = OpConstant %uint 1 - %uint_0_1 = OpConstant %uint 0 - %ulong_8_0 = OpConstant %ulong 8 - %uint_1_2 = OpConstant %uint 1 - %uint_0_2 = OpConstant %uint 0 - %ulong_12_0 = OpConstant %ulong 12 - %1 = OpFunction %void None %133 - %32 = OpFunctionParameter %ulong - %33 = OpFunctionParameter %ulong - %128 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_float Function - %7 = OpVariable %_ptr_Function_float Function - %8 = OpVariable %_ptr_Function_float Function - %9 = OpVariable %_ptr_Function_float Function - %10 = OpVariable %_ptr_Function_float Function - %11 = OpVariable %_ptr_Function_float Function - %12 = OpVariable %_ptr_Function_float Function - %13 = OpVariable %_ptr_Function_float Function - %14 = OpVariable %_ptr_Function_uint Function - %15 = OpVariable %_ptr_Function_bool Function - OpStore %2 %32 - OpStore %3 %33 - %34 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %34 - %35 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %35 - %37 = OpLoad %ulong %4 - %116 = OpConvertUToPtr %_ptr_Generic_float %37 - %36 = OpLoad %float %116 Aligned 4 - OpStore %6 %36 - %39 = OpLoad %ulong %4 - %117 = OpConvertUToPtr %_ptr_Generic_float %39 - %144 = OpBitcast %_ptr_Generic_uchar %117 - %145 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %144 %ulong_4 - %89 = OpBitcast %_ptr_Generic_float %145 - %38 = OpLoad %float %89 Aligned 4 - OpStore %7 %38 - %41 = OpLoad %ulong %4 - %118 = OpConvertUToPtr %_ptr_Generic_float %41 - %146 = OpBitcast %_ptr_Generic_uchar %118 - %147 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %146 %ulong_8 - %91 = OpBitcast %_ptr_Generic_float %147 - %40 = OpLoad %float %91 Aligned 4 - OpStore %8 %40 - %43 = OpLoad %ulong %4 - %119 = OpConvertUToPtr %_ptr_Generic_float %43 - %148 = OpBitcast %_ptr_Generic_uchar %119 - %149 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %148 %ulong_12 - %93 = OpBitcast %_ptr_Generic_float %149 - %42 = OpLoad %float %93 Aligned 4 - OpStore %9 %42 - %45 = OpLoad %ulong %4 - %120 = OpConvertUToPtr %_ptr_Generic_float %45 - %150 = OpBitcast %_ptr_Generic_uchar %120 - %151 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %150 %ulong_16 - %95 = OpBitcast %_ptr_Generic_float %151 - %44 = OpLoad %float %95 Aligned 4 - OpStore %10 %44 - %47 = OpLoad %ulong %4 - %121 = OpConvertUToPtr %_ptr_Generic_float %47 - %152 = OpBitcast %_ptr_Generic_uchar %121 - %153 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %152 %ulong_20 - %97 = OpBitcast %_ptr_Generic_float %153 - %46 = OpLoad %float %97 Aligned 4 - OpStore %11 %46 - %49 = OpLoad %ulong %4 - %122 = OpConvertUToPtr %_ptr_Generic_float %49 - %154 = OpBitcast %_ptr_Generic_uchar %122 - %155 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %154 %ulong_24 - %99 = OpBitcast %_ptr_Generic_float %155 - %48 = OpLoad %float %99 Aligned 4 - OpStore %12 %48 - %51 = OpLoad %ulong %4 - %123 = OpConvertUToPtr %_ptr_Generic_float %51 - %156 = OpBitcast %_ptr_Generic_uchar %123 - %157 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %156 %ulong_28 - %101 = OpBitcast %_ptr_Generic_float %157 - %50 = OpLoad %float %101 Aligned 4 - OpStore %13 %50 - %53 = OpLoad %float %6 - %54 = OpLoad %float %7 - %158 = OpIsNan %bool %53 - %159 = OpIsNan %bool %54 - %52 = OpLogicalOr %bool %158 %159 - OpStore %15 %52 - %55 = OpLoad %bool %15 - OpBranchConditional %55 %16 %17 - %16 = OpLabel - %56 = OpCopyObject %uint %uint_1 - OpStore %14 %56 - OpBranch %17 - %17 = OpLabel - %57 = OpLoad %bool %15 - OpBranchConditional %57 %19 %18 - %18 = OpLabel - %58 = OpCopyObject %uint %uint_0 - OpStore %14 %58 - OpBranch %19 - %19 = OpLabel - %59 = OpLoad %ulong %5 - %60 = OpLoad %uint %14 - %124 = OpConvertUToPtr %_ptr_Generic_uint %59 - OpStore %124 %60 Aligned 4 - %62 = OpLoad %float %8 - %63 = OpLoad %float %9 - %161 = OpIsNan %bool %62 - %162 = OpIsNan %bool %63 - %61 = OpLogicalOr %bool %161 %162 - OpStore %15 %61 - %64 = OpLoad %bool %15 - OpBranchConditional %64 %20 %21 - %20 = OpLabel - %65 = OpCopyObject %uint %uint_1_0 - OpStore %14 %65 - OpBranch %21 - %21 = OpLabel - %66 = OpLoad %bool %15 - OpBranchConditional %66 %23 %22 - %22 = OpLabel - %67 = OpCopyObject %uint %uint_0_0 - OpStore %14 %67 - OpBranch %23 - %23 = OpLabel - %68 = OpLoad %ulong %5 - %69 = OpLoad %uint %14 - %125 = OpConvertUToPtr %_ptr_Generic_uint %68 - %163 = OpBitcast %_ptr_Generic_uchar %125 - %164 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %163 %ulong_4_0 - %107 = OpBitcast %_ptr_Generic_uint %164 - OpStore %107 %69 Aligned 4 - %71 = OpLoad %float %10 - %72 = OpLoad %float %11 - %165 = OpIsNan %bool %71 - %166 = OpIsNan %bool %72 - %70 = OpLogicalOr %bool %165 %166 - OpStore %15 %70 - %73 = OpLoad %bool %15 - OpBranchConditional %73 %24 %25 - %24 = OpLabel - %74 = OpCopyObject %uint %uint_1_1 - OpStore %14 %74 - OpBranch %25 - %25 = OpLabel - %75 = OpLoad %bool %15 - OpBranchConditional %75 %27 %26 - %26 = OpLabel - %76 = OpCopyObject %uint %uint_0_1 - OpStore %14 %76 - OpBranch %27 - %27 = OpLabel - %77 = OpLoad %ulong %5 - %78 = OpLoad %uint %14 - %126 = OpConvertUToPtr %_ptr_Generic_uint %77 - %167 = OpBitcast %_ptr_Generic_uchar %126 - %168 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %167 %ulong_8_0 - %111 = OpBitcast %_ptr_Generic_uint %168 - OpStore %111 %78 Aligned 4 - %80 = OpLoad %float %12 - %81 = OpLoad %float %13 - %169 = OpIsNan %bool %80 - %170 = OpIsNan %bool %81 - %79 = OpLogicalOr %bool %169 %170 - OpStore %15 %79 - %82 = OpLoad %bool %15 - OpBranchConditional %82 %28 %29 - %28 = OpLabel - %83 = OpCopyObject %uint %uint_1_2 - OpStore %14 %83 - OpBranch %29 - %29 = OpLabel - %84 = OpLoad %bool %15 - OpBranchConditional %84 %31 %30 - %30 = OpLabel - %85 = OpCopyObject %uint %uint_0_2 - OpStore %14 %85 - OpBranch %31 - %31 = OpLabel - %86 = OpLoad %ulong %5 - %87 = OpLoad %uint %14 - %127 = OpConvertUToPtr %_ptr_Generic_uint %86 - %171 = OpBitcast %_ptr_Generic_uchar %127 - %172 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %171 %ulong_12_0 - %115 = OpBitcast %_ptr_Generic_uint %172 - OpStore %115 %87 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/setp_num.spvtxt b/ptx/src/test/spirv_run/setp_num.spvtxt deleted file mode 100644 index c576a50..0000000 --- a/ptx/src/test/spirv_run/setp_num.spvtxt +++ /dev/null @@ -1,240 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %130 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "setp_num" - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %133 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %float = OpTypeFloat 32 -%_ptr_Function_float = OpTypePointer Function %float - %uint = OpTypeInt 32 0 -%_ptr_Function_uint = OpTypePointer Function %uint - %bool = OpTypeBool -%_ptr_Function_bool = OpTypePointer Function %bool -%_ptr_Generic_float = OpTypePointer Generic %float - %ulong_4 = OpConstant %ulong 4 - %uchar = OpTypeInt 8 0 -%_ptr_Generic_uchar = OpTypePointer Generic %uchar - %ulong_8 = OpConstant %ulong 8 - %ulong_12 = OpConstant %ulong 12 - %ulong_16 = OpConstant %ulong 16 - %ulong_20 = OpConstant %ulong 20 - %ulong_24 = OpConstant %ulong 24 - %ulong_28 = OpConstant %ulong 28 - %true = OpConstantTrue %bool - %false = OpConstantFalse %bool - %uint_2 = OpConstant %uint 2 - %uint_0 = OpConstant %uint 0 -%_ptr_Generic_uint = OpTypePointer Generic %uint - %true_0 = OpConstantTrue %bool - %false_0 = OpConstantFalse %bool - %uint_2_0 = OpConstant %uint 2 - %uint_0_0 = OpConstant %uint 0 - %ulong_4_0 = OpConstant %ulong 4 - %true_1 = OpConstantTrue %bool - %false_1 = OpConstantFalse %bool - %uint_2_1 = OpConstant %uint 2 - %uint_0_1 = OpConstant %uint 0 - %ulong_8_0 = OpConstant %ulong 8 - %true_2 = OpConstantTrue %bool - %false_2 = OpConstantFalse %bool - %uint_2_2 = OpConstant %uint 2 - %uint_0_2 = OpConstant %uint 0 - %ulong_12_0 = OpConstant %ulong 12 - %1 = OpFunction %void None %133 - %32 = OpFunctionParameter %ulong - %33 = OpFunctionParameter %ulong - %128 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_float Function - %7 = OpVariable %_ptr_Function_float Function - %8 = OpVariable %_ptr_Function_float Function - %9 = OpVariable %_ptr_Function_float Function - %10 = OpVariable %_ptr_Function_float Function - %11 = OpVariable %_ptr_Function_float Function - %12 = OpVariable %_ptr_Function_float Function - %13 = OpVariable %_ptr_Function_float Function - %14 = OpVariable %_ptr_Function_uint Function - %15 = OpVariable %_ptr_Function_bool Function - OpStore %2 %32 - OpStore %3 %33 - %34 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %34 - %35 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %35 - %37 = OpLoad %ulong %4 - %116 = OpConvertUToPtr %_ptr_Generic_float %37 - %36 = OpLoad %float %116 Aligned 4 - OpStore %6 %36 - %39 = OpLoad %ulong %4 - %117 = OpConvertUToPtr %_ptr_Generic_float %39 - %144 = OpBitcast %_ptr_Generic_uchar %117 - %145 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %144 %ulong_4 - %89 = OpBitcast %_ptr_Generic_float %145 - %38 = OpLoad %float %89 Aligned 4 - OpStore %7 %38 - %41 = OpLoad %ulong %4 - %118 = OpConvertUToPtr %_ptr_Generic_float %41 - %146 = OpBitcast %_ptr_Generic_uchar %118 - %147 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %146 %ulong_8 - %91 = OpBitcast %_ptr_Generic_float %147 - %40 = OpLoad %float %91 Aligned 4 - OpStore %8 %40 - %43 = OpLoad %ulong %4 - %119 = OpConvertUToPtr %_ptr_Generic_float %43 - %148 = OpBitcast %_ptr_Generic_uchar %119 - %149 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %148 %ulong_12 - %93 = OpBitcast %_ptr_Generic_float %149 - %42 = OpLoad %float %93 Aligned 4 - OpStore %9 %42 - %45 = OpLoad %ulong %4 - %120 = OpConvertUToPtr %_ptr_Generic_float %45 - %150 = OpBitcast %_ptr_Generic_uchar %120 - %151 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %150 %ulong_16 - %95 = OpBitcast %_ptr_Generic_float %151 - %44 = OpLoad %float %95 Aligned 4 - OpStore %10 %44 - %47 = OpLoad %ulong %4 - %121 = OpConvertUToPtr %_ptr_Generic_float %47 - %152 = OpBitcast %_ptr_Generic_uchar %121 - %153 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %152 %ulong_20 - %97 = OpBitcast %_ptr_Generic_float %153 - %46 = OpLoad %float %97 Aligned 4 - OpStore %11 %46 - %49 = OpLoad %ulong %4 - %122 = OpConvertUToPtr %_ptr_Generic_float %49 - %154 = OpBitcast %_ptr_Generic_uchar %122 - %155 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %154 %ulong_24 - %99 = OpBitcast %_ptr_Generic_float %155 - %48 = OpLoad %float %99 Aligned 4 - OpStore %12 %48 - %51 = OpLoad %ulong %4 - %123 = OpConvertUToPtr %_ptr_Generic_float %51 - %156 = OpBitcast %_ptr_Generic_uchar %123 - %157 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %156 %ulong_28 - %101 = OpBitcast %_ptr_Generic_float %157 - %50 = OpLoad %float %101 Aligned 4 - OpStore %13 %50 - %53 = OpLoad %float %6 - %54 = OpLoad %float %7 - %158 = OpIsNan %bool %53 - %159 = OpIsNan %bool %54 - %160 = OpLogicalOr %bool %158 %159 - %52 = OpSelect %bool %160 %false %true - OpStore %15 %52 - %55 = OpLoad %bool %15 - OpBranchConditional %55 %16 %17 - %16 = OpLabel - %56 = OpCopyObject %uint %uint_2 - OpStore %14 %56 - OpBranch %17 - %17 = OpLabel - %57 = OpLoad %bool %15 - OpBranchConditional %57 %19 %18 - %18 = OpLabel - %58 = OpCopyObject %uint %uint_0 - OpStore %14 %58 - OpBranch %19 - %19 = OpLabel - %59 = OpLoad %ulong %5 - %60 = OpLoad %uint %14 - %124 = OpConvertUToPtr %_ptr_Generic_uint %59 - OpStore %124 %60 Aligned 4 - %62 = OpLoad %float %8 - %63 = OpLoad %float %9 - %164 = OpIsNan %bool %62 - %165 = OpIsNan %bool %63 - %166 = OpLogicalOr %bool %164 %165 - %61 = OpSelect %bool %166 %false_0 %true_0 - OpStore %15 %61 - %64 = OpLoad %bool %15 - OpBranchConditional %64 %20 %21 - %20 = OpLabel - %65 = OpCopyObject %uint %uint_2_0 - OpStore %14 %65 - OpBranch %21 - %21 = OpLabel - %66 = OpLoad %bool %15 - OpBranchConditional %66 %23 %22 - %22 = OpLabel - %67 = OpCopyObject %uint %uint_0_0 - OpStore %14 %67 - OpBranch %23 - %23 = OpLabel - %68 = OpLoad %ulong %5 - %69 = OpLoad %uint %14 - %125 = OpConvertUToPtr %_ptr_Generic_uint %68 - %169 = OpBitcast %_ptr_Generic_uchar %125 - %170 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %169 %ulong_4_0 - %107 = OpBitcast %_ptr_Generic_uint %170 - OpStore %107 %69 Aligned 4 - %71 = OpLoad %float %10 - %72 = OpLoad %float %11 - %171 = OpIsNan %bool %71 - %172 = OpIsNan %bool %72 - %173 = OpLogicalOr %bool %171 %172 - %70 = OpSelect %bool %173 %false_1 %true_1 - OpStore %15 %70 - %73 = OpLoad %bool %15 - OpBranchConditional %73 %24 %25 - %24 = OpLabel - %74 = OpCopyObject %uint %uint_2_1 - OpStore %14 %74 - OpBranch %25 - %25 = OpLabel - %75 = OpLoad %bool %15 - OpBranchConditional %75 %27 %26 - %26 = OpLabel - %76 = OpCopyObject %uint %uint_0_1 - OpStore %14 %76 - OpBranch %27 - %27 = OpLabel - %77 = OpLoad %ulong %5 - %78 = OpLoad %uint %14 - %126 = OpConvertUToPtr %_ptr_Generic_uint %77 - %176 = OpBitcast %_ptr_Generic_uchar %126 - %177 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %176 %ulong_8_0 - %111 = OpBitcast %_ptr_Generic_uint %177 - OpStore %111 %78 Aligned 4 - %80 = OpLoad %float %12 - %81 = OpLoad %float %13 - %178 = OpIsNan %bool %80 - %179 = OpIsNan %bool %81 - %180 = OpLogicalOr %bool %178 %179 - %79 = OpSelect %bool %180 %false_2 %true_2 - OpStore %15 %79 - %82 = OpLoad %bool %15 - OpBranchConditional %82 %28 %29 - %28 = OpLabel - %83 = OpCopyObject %uint %uint_2_2 - OpStore %14 %83 - OpBranch %29 - %29 = OpLabel - %84 = OpLoad %bool %15 - OpBranchConditional %84 %31 %30 - %30 = OpLabel - %85 = OpCopyObject %uint %uint_0_2 - OpStore %14 %85 - OpBranch %31 - %31 = OpLabel - %86 = OpLoad %ulong %5 - %87 = OpLoad %uint %14 - %127 = OpConvertUToPtr %_ptr_Generic_uint %86 - %183 = OpBitcast %_ptr_Generic_uchar %127 - %184 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %183 %ulong_12_0 - %115 = OpBitcast %_ptr_Generic_uint %184 - OpStore %115 %87 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/shared_ptr_32.spvtxt b/ptx/src/test/spirv_run/shared_ptr_32.spvtxt deleted file mode 100644 index 787a71c..0000000 --- a/ptx/src/test/spirv_run/shared_ptr_32.spvtxt +++ /dev/null @@ -1,73 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - OpCapability DenormFlushToZero - OpExtension "SPV_KHR_float_controls" - OpExtension "SPV_KHR_no_integer_wrap_decoration" - %32 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "shared_ptr_32" %4 - OpExecutionMode %1 ContractionOff - OpDecorate %4 Alignment 4 - %void = OpTypeVoid - %uint = OpTypeInt 32 0 - %uchar = OpTypeInt 8 0 - %uint_128 = OpConstant %uint 128 -%_arr_uchar_uint_128 = OpTypeArray %uchar %uint_128 -%_ptr_Workgroup__arr_uchar_uint_128 = OpTypePointer Workgroup %_arr_uchar_uint_128 - %4 = OpVariable %_ptr_Workgroup__arr_uchar_uint_128 Workgroup - %ulong = OpTypeInt 64 0 - %40 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong -%_ptr_Function_uint = OpTypePointer Function %uint -%_ptr_CrossWorkgroup_ulong = OpTypePointer CrossWorkgroup %ulong -%_ptr_Workgroup_ulong = OpTypePointer Workgroup %ulong - %ulong_0 = OpConstant %ulong 0 -%_ptr_Workgroup_uchar = OpTypePointer Workgroup %uchar - %1 = OpFunction %void None %40 - %10 = OpFunctionParameter %ulong - %11 = OpFunctionParameter %ulong - %30 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_ulong Function - %7 = OpVariable %_ptr_Function_uint Function - %8 = OpVariable %_ptr_Function_ulong Function - %9 = OpVariable %_ptr_Function_ulong Function - OpStore %2 %10 - OpStore %3 %11 - %12 = OpLoad %ulong %2 Aligned 8 - OpStore %5 %12 - %13 = OpLoad %ulong %3 Aligned 8 - OpStore %6 %13 - %25 = OpConvertPtrToU %uint %4 - %14 = OpCopyObject %uint %25 - OpStore %7 %14 - %16 = OpLoad %ulong %5 - %26 = OpConvertUToPtr %_ptr_CrossWorkgroup_ulong %16 - %15 = OpLoad %ulong %26 Aligned 8 - OpStore %8 %15 - %17 = OpLoad %uint %7 - %18 = OpLoad %ulong %8 - %27 = OpConvertUToPtr %_ptr_Workgroup_ulong %17 - OpStore %27 %18 Aligned 8 - %20 = OpLoad %uint %7 - %28 = OpConvertUToPtr %_ptr_Workgroup_ulong %20 - %46 = OpBitcast %_ptr_Workgroup_uchar %28 - %47 = OpInBoundsPtrAccessChain %_ptr_Workgroup_uchar %46 %ulong_0 - %24 = OpBitcast %_ptr_Workgroup_ulong %47 - %19 = OpLoad %ulong %24 Aligned 8 - OpStore %9 %19 - %21 = OpLoad %ulong %6 - %22 = OpLoad %ulong %9 - %29 = OpConvertUToPtr %_ptr_CrossWorkgroup_ulong %21 - OpStore %29 %22 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/shared_ptr_take_address.spvtxt b/ptx/src/test/spirv_run/shared_ptr_take_address.spvtxt deleted file mode 100644 index 14926ef..0000000 --- a/ptx/src/test/spirv_run/shared_ptr_take_address.spvtxt +++ /dev/null @@ -1,64 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - OpCapability DenormFlushToZero - OpExtension "SPV_KHR_float_controls" - OpExtension "SPV_KHR_no_integer_wrap_decoration" - %30 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %2 "shared_ptr_take_address" %1 - OpExecutionMode %2 ContractionOff - OpDecorate %1 Alignment 4 - %void = OpTypeVoid - %uchar = OpTypeInt 8 0 -%_ptr_Workgroup_uchar = OpTypePointer Workgroup %uchar - %1 = OpVariable %_ptr_Workgroup_uchar Workgroup - %ulong = OpTypeInt 64 0 - %35 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong -%_ptr_CrossWorkgroup_ulong = OpTypePointer CrossWorkgroup %ulong -%_ptr_Workgroup_ulong = OpTypePointer Workgroup %ulong - %2 = OpFunction %void None %35 - %10 = OpFunctionParameter %ulong - %11 = OpFunctionParameter %ulong - %28 = OpLabel - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_ulong Function - %7 = OpVariable %_ptr_Function_ulong Function - %8 = OpVariable %_ptr_Function_ulong Function - %9 = OpVariable %_ptr_Function_ulong Function - OpStore %3 %10 - OpStore %4 %11 - %12 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %12 - %13 = OpLoad %ulong %4 Aligned 8 - OpStore %6 %13 - %23 = OpConvertPtrToU %ulong %1 - %14 = OpCopyObject %ulong %23 - OpStore %7 %14 - %16 = OpLoad %ulong %5 - %24 = OpConvertUToPtr %_ptr_CrossWorkgroup_ulong %16 - %15 = OpLoad %ulong %24 Aligned 8 - OpStore %8 %15 - %17 = OpLoad %ulong %7 - %18 = OpLoad %ulong %8 - %25 = OpConvertUToPtr %_ptr_Workgroup_ulong %17 - OpStore %25 %18 Aligned 8 - %20 = OpLoad %ulong %7 - %26 = OpConvertUToPtr %_ptr_Workgroup_ulong %20 - %19 = OpLoad %ulong %26 Aligned 8 - OpStore %9 %19 - %21 = OpLoad %ulong %6 - %22 = OpLoad %ulong %9 - %27 = OpConvertUToPtr %_ptr_CrossWorkgroup_ulong %21 - OpStore %27 %22 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/shared_unify_extern.spvtxt b/ptx/src/test/spirv_run/shared_unify_extern.spvtxt deleted file mode 100644 index 90fc156..0000000 --- a/ptx/src/test/spirv_run/shared_unify_extern.spvtxt +++ /dev/null @@ -1,118 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - OpCapability DenormFlushToZero - OpExtension "SPV_KHR_float_controls" - OpExtension "SPV_KHR_no_integer_wrap_decoration" - %61 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %27 "shared_unify_extern" %1 %2 - OpExecutionMode %27 ContractionOff - %void = OpTypeVoid - %uint = OpTypeInt 32 0 -%_ptr_Workgroup_uint = OpTypePointer Workgroup %uint - %1 = OpVariable %_ptr_Workgroup_uint Workgroup - %uint_4 = OpConstant %uint 4 -%_arr_uint_uint_4 = OpTypeArray %uint %uint_4 -%_ptr_Workgroup__arr_uint_uint_4 = OpTypePointer Workgroup %_arr_uint_uint_4 - %2 = OpVariable %_ptr_Workgroup__arr_uint_uint_4 Workgroup - %ulong = OpTypeInt 64 0 - %uint_4_0 = OpConstant %uint 4 - %70 = OpTypeFunction %ulong %_ptr_Workgroup_uint %_ptr_Workgroup__arr_uint_uint_4 - %uint_4_1 = OpConstant %uint 4 -%_ptr_Function_ulong = OpTypePointer Function %ulong -%_ptr_Workgroup_ulong = OpTypePointer Workgroup %ulong - %uint_4_2 = OpConstant %uint 4 - %75 = OpTypeFunction %ulong %ulong %_ptr_Workgroup_uint %_ptr_Workgroup__arr_uint_uint_4 - %uint_4_3 = OpConstant %uint 4 - %77 = OpTypeFunction %void %ulong %ulong -%_ptr_CrossWorkgroup_ulong = OpTypePointer CrossWorkgroup %ulong - %ulong_8 = OpConstant %ulong 8 - %uchar = OpTypeInt 8 0 -%_ptr_CrossWorkgroup_uchar = OpTypePointer CrossWorkgroup %uchar -%_ptr_Generic_ulong = OpTypePointer Generic %ulong - %3 = OpFunction %ulong None %70 - %57 = OpFunctionParameter %_ptr_Workgroup_uint - %58 = OpFunctionParameter %_ptr_Workgroup__arr_uint_uint_4 - %16 = OpLabel - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_ulong Function - %13 = OpBitcast %_ptr_Workgroup_ulong %58 - %7 = OpLoad %ulong %13 Aligned 8 - OpStore %5 %7 - %14 = OpBitcast %_ptr_Workgroup_ulong %57 - %8 = OpLoad %ulong %14 Aligned 8 - OpStore %6 %8 - %10 = OpLoad %ulong %6 - %11 = OpLoad %ulong %5 - %15 = OpIAdd %ulong %10 %11 - %9 = OpCopyObject %ulong %15 - OpStore %4 %9 - %12 = OpLoad %ulong %4 - OpReturnValue %12 - OpFunctionEnd - %17 = OpFunction %ulong None %75 - %20 = OpFunctionParameter %ulong - %59 = OpFunctionParameter %_ptr_Workgroup_uint - %60 = OpFunctionParameter %_ptr_Workgroup__arr_uint_uint_4 - %26 = OpLabel - %19 = OpVariable %_ptr_Function_ulong Function - %18 = OpVariable %_ptr_Function_ulong Function - OpStore %19 %20 - %21 = OpLoad %ulong %19 - %24 = OpBitcast %_ptr_Workgroup_ulong %59 - %25 = OpCopyObject %ulong %21 - OpStore %24 %25 Aligned 8 - %22 = OpFunctionCall %ulong %3 %59 %60 - OpStore %18 %22 - %23 = OpLoad %ulong %18 - OpReturnValue %23 - OpFunctionEnd - %27 = OpFunction %void None %77 - %34 = OpFunctionParameter %ulong - %35 = OpFunctionParameter %ulong - %55 = OpLabel - %28 = OpVariable %_ptr_Function_ulong Function - %29 = OpVariable %_ptr_Function_ulong Function - %30 = OpVariable %_ptr_Function_ulong Function - %31 = OpVariable %_ptr_Function_ulong Function - %32 = OpVariable %_ptr_Function_ulong Function - %33 = OpVariable %_ptr_Function_ulong Function - OpStore %28 %34 - OpStore %29 %35 - %36 = OpLoad %ulong %28 Aligned 8 - OpStore %30 %36 - %37 = OpLoad %ulong %29 Aligned 8 - OpStore %31 %37 - %39 = OpLoad %ulong %30 - %49 = OpConvertUToPtr %_ptr_CrossWorkgroup_ulong %39 - %38 = OpLoad %ulong %49 Aligned 8 - OpStore %32 %38 - %41 = OpLoad %ulong %30 - %50 = OpConvertUToPtr %_ptr_CrossWorkgroup_ulong %41 - %81 = OpBitcast %_ptr_CrossWorkgroup_uchar %50 - %82 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uchar %81 %ulong_8 - %48 = OpBitcast %_ptr_CrossWorkgroup_ulong %82 - %40 = OpLoad %ulong %48 Aligned 8 - OpStore %33 %40 - %42 = OpLoad %ulong %33 - %51 = OpBitcast %_ptr_Workgroup_ulong %2 - OpStore %51 %42 Aligned 8 - %44 = OpLoad %ulong %32 - %53 = OpCopyObject %ulong %44 - %52 = OpFunctionCall %ulong %17 %53 %1 %2 - %43 = OpCopyObject %ulong %52 - OpStore %33 %43 - %45 = OpLoad %ulong %31 - %46 = OpLoad %ulong %33 - %54 = OpConvertUToPtr %_ptr_Generic_ulong %45 - OpStore %54 %46 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/shared_unify_local.spvtxt b/ptx/src/test/spirv_run/shared_unify_local.spvtxt deleted file mode 100644 index dc00c2f..0000000 --- a/ptx/src/test/spirv_run/shared_unify_local.spvtxt +++ /dev/null @@ -1,117 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - OpCapability DenormFlushToZero - OpExtension "SPV_KHR_float_controls" - OpExtension "SPV_KHR_no_integer_wrap_decoration" - %64 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %31 "shared_unify_local" %1 %5 - OpExecutionMode %31 ContractionOff - OpDecorate %5 Alignment 4 - %void = OpTypeVoid - %uint = OpTypeInt 32 0 -%_ptr_Workgroup_uint = OpTypePointer Workgroup %uint - %1 = OpVariable %_ptr_Workgroup_uint Workgroup - %ulong = OpTypeInt 64 0 -%_ptr_Workgroup_ulong = OpTypePointer Workgroup %ulong - %5 = OpVariable %_ptr_Workgroup_ulong Workgroup - %70 = OpTypeFunction %ulong %ulong %_ptr_Workgroup_uint %_ptr_Workgroup_ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %72 = OpTypeFunction %ulong %ulong %ulong %_ptr_Workgroup_uint %_ptr_Workgroup_ulong - %73 = OpTypeFunction %void %ulong %ulong -%_ptr_CrossWorkgroup_ulong = OpTypePointer CrossWorkgroup %ulong - %ulong_8 = OpConstant %ulong 8 - %uchar = OpTypeInt 8 0 -%_ptr_CrossWorkgroup_uchar = OpTypePointer CrossWorkgroup %uchar -%_ptr_Generic_ulong = OpTypePointer Generic %ulong - %2 = OpFunction %ulong None %70 - %7 = OpFunctionParameter %ulong - %60 = OpFunctionParameter %_ptr_Workgroup_uint - %61 = OpFunctionParameter %_ptr_Workgroup_ulong - %17 = OpLabel - %4 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_ulong Function - OpStore %4 %7 - %8 = OpLoad %ulong %4 - OpStore %61 %8 Aligned 8 - %9 = OpLoad %ulong %61 Aligned 8 - OpStore %6 %9 - %15 = OpBitcast %_ptr_Workgroup_ulong %60 - %10 = OpLoad %ulong %15 Aligned 8 - OpStore %4 %10 - %12 = OpLoad %ulong %4 - %13 = OpLoad %ulong %6 - %16 = OpIAdd %ulong %12 %13 - %11 = OpCopyObject %ulong %16 - OpStore %3 %11 - %14 = OpLoad %ulong %3 - OpReturnValue %14 - OpFunctionEnd - %18 = OpFunction %ulong None %72 - %22 = OpFunctionParameter %ulong - %23 = OpFunctionParameter %ulong - %62 = OpFunctionParameter %_ptr_Workgroup_uint - %63 = OpFunctionParameter %_ptr_Workgroup_ulong - %30 = OpLabel - %20 = OpVariable %_ptr_Function_ulong Function - %21 = OpVariable %_ptr_Function_ulong Function - %19 = OpVariable %_ptr_Function_ulong Function - OpStore %20 %22 - OpStore %21 %23 - %24 = OpLoad %ulong %20 - %28 = OpBitcast %_ptr_Workgroup_ulong %62 - %29 = OpCopyObject %ulong %24 - OpStore %28 %29 Aligned 8 - %26 = OpLoad %ulong %21 - %25 = OpFunctionCall %ulong %2 %26 %62 %63 - OpStore %19 %25 - %27 = OpLoad %ulong %19 - OpReturnValue %27 - OpFunctionEnd - %31 = OpFunction %void None %73 - %38 = OpFunctionParameter %ulong - %39 = OpFunctionParameter %ulong - %58 = OpLabel - %32 = OpVariable %_ptr_Function_ulong Function - %33 = OpVariable %_ptr_Function_ulong Function - %34 = OpVariable %_ptr_Function_ulong Function - %35 = OpVariable %_ptr_Function_ulong Function - %36 = OpVariable %_ptr_Function_ulong Function - %37 = OpVariable %_ptr_Function_ulong Function - OpStore %32 %38 - OpStore %33 %39 - %40 = OpLoad %ulong %32 Aligned 8 - OpStore %34 %40 - %41 = OpLoad %ulong %33 Aligned 8 - OpStore %35 %41 - %43 = OpLoad %ulong %34 - %53 = OpConvertUToPtr %_ptr_CrossWorkgroup_ulong %43 - %42 = OpLoad %ulong %53 Aligned 8 - OpStore %36 %42 - %45 = OpLoad %ulong %34 - %54 = OpConvertUToPtr %_ptr_CrossWorkgroup_ulong %45 - %77 = OpBitcast %_ptr_CrossWorkgroup_uchar %54 - %78 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uchar %77 %ulong_8 - %52 = OpBitcast %_ptr_CrossWorkgroup_ulong %78 - %44 = OpLoad %ulong %52 Aligned 8 - OpStore %37 %44 - %47 = OpLoad %ulong %36 - %48 = OpLoad %ulong %37 - %56 = OpCopyObject %ulong %47 - %55 = OpFunctionCall %ulong %18 %56 %48 %1 %5 - %46 = OpCopyObject %ulong %55 - OpStore %37 %46 - %49 = OpLoad %ulong %35 - %50 = OpLoad %ulong %37 - %57 = OpConvertUToPtr %_ptr_Generic_ulong %49 - OpStore %57 %50 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/shared_variable.spvtxt b/ptx/src/test/spirv_run/shared_variable.spvtxt deleted file mode 100644 index fbbfe4a..0000000 --- a/ptx/src/test/spirv_run/shared_variable.spvtxt +++ /dev/null @@ -1,61 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - OpCapability DenormFlushToZero - OpExtension "SPV_KHR_float_controls" - OpExtension "SPV_KHR_no_integer_wrap_decoration" - %25 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "shared_variable" %4 - OpExecutionMode %1 ContractionOff - OpDecorate %4 Alignment 4 - %void = OpTypeVoid - %uint = OpTypeInt 32 0 - %uchar = OpTypeInt 8 0 - %uint_128 = OpConstant %uint 128 -%_arr_uchar_uint_128 = OpTypeArray %uchar %uint_128 -%_ptr_Workgroup__arr_uchar_uint_128 = OpTypePointer Workgroup %_arr_uchar_uint_128 - %4 = OpVariable %_ptr_Workgroup__arr_uchar_uint_128 Workgroup - %ulong = OpTypeInt 64 0 - %33 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong -%_ptr_CrossWorkgroup_ulong = OpTypePointer CrossWorkgroup %ulong -%_ptr_Workgroup_ulong = OpTypePointer Workgroup %ulong - %1 = OpFunction %void None %33 - %9 = OpFunctionParameter %ulong - %10 = OpFunctionParameter %ulong - %23 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_ulong Function - %7 = OpVariable %_ptr_Function_ulong Function - %8 = OpVariable %_ptr_Function_ulong Function - OpStore %2 %9 - OpStore %3 %10 - %11 = OpLoad %ulong %2 Aligned 8 - OpStore %5 %11 - %12 = OpLoad %ulong %3 Aligned 8 - OpStore %6 %12 - %14 = OpLoad %ulong %5 - %19 = OpConvertUToPtr %_ptr_CrossWorkgroup_ulong %14 - %13 = OpLoad %ulong %19 Aligned 8 - OpStore %7 %13 - %15 = OpLoad %ulong %7 - %20 = OpBitcast %_ptr_Workgroup_ulong %4 - OpStore %20 %15 Aligned 8 - %21 = OpBitcast %_ptr_Workgroup_ulong %4 - %16 = OpLoad %ulong %21 Aligned 8 - OpStore %8 %16 - %17 = OpLoad %ulong %6 - %18 = OpLoad %ulong %8 - %22 = OpConvertUToPtr %_ptr_CrossWorkgroup_ulong %17 - OpStore %22 %18 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/shl.spvtxt b/ptx/src/test/spirv_run/shl.spvtxt deleted file mode 100644 index 2a1249e..0000000 --- a/ptx/src/test/spirv_run/shl.spvtxt +++ /dev/null @@ -1,51 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %25 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "shl" - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %28 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong -%_ptr_Generic_ulong = OpTypePointer Generic %ulong - %uint = OpTypeInt 32 0 - %uint_2 = OpConstant %uint 2 - %1 = OpFunction %void None %28 - %8 = OpFunctionParameter %ulong - %9 = OpFunctionParameter %ulong - %23 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_ulong Function - %7 = OpVariable %_ptr_Function_ulong Function - OpStore %2 %8 - OpStore %3 %9 - %10 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %19 = OpConvertUToPtr %_ptr_Generic_ulong %13 - %12 = OpLoad %ulong %19 Aligned 8 - OpStore %6 %12 - %15 = OpLoad %ulong %6 - %21 = OpCopyObject %ulong %15 - %32 = OpUConvert %ulong %uint_2 - %20 = OpShiftLeftLogical %ulong %21 %32 - %14 = OpCopyObject %ulong %20 - OpStore %7 %14 - %16 = OpLoad %ulong %5 - %17 = OpLoad %ulong %7 - %22 = OpConvertUToPtr %_ptr_Generic_ulong %16 - OpStore %22 %17 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/shl_link_hack.spvtxt b/ptx/src/test/spirv_run/shl_link_hack.spvtxt deleted file mode 100644 index 7e53af8..0000000 --- a/ptx/src/test/spirv_run/shl_link_hack.spvtxt +++ /dev/null @@ -1,65 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %34 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "shl_link_hack" - OpDecorate %29 LinkageAttributes "__zluda_ptx_impl__atom_relaxed_gpu_generic_inc" Import - %void = OpTypeVoid - %uint = OpTypeInt 32 0 -%_ptr_Generic_uint = OpTypePointer Generic %uint - %38 = OpTypeFunction %uint %_ptr_Generic_uint %uint - %ulong = OpTypeInt 64 0 - %40 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong -%_ptr_Function_uint = OpTypePointer Function %uint -%uint_2000000 = OpConstant %uint 2000000 -%_ptr_Generic_ulong = OpTypePointer Generic %ulong - %uint_2 = OpConstant %uint 2 - %29 = OpFunction %uint None %38 - %31 = OpFunctionParameter %_ptr_Generic_uint - %32 = OpFunctionParameter %uint - OpFunctionEnd - %1 = OpFunction %void None %40 - %9 = OpFunctionParameter %ulong - %10 = OpFunctionParameter %ulong - %28 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_ulong Function - %7 = OpVariable %_ptr_Function_ulong Function - %8 = OpVariable %_ptr_Function_uint Function - OpStore %2 %9 - OpStore %3 %10 - %11 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %11 - %12 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %12 - %14 = OpLoad %ulong %5 - %23 = OpConvertUToPtr %_ptr_Generic_uint %14 - %13 = OpFunctionCall %uint %29 %23 %uint_2000000 - OpStore %8 %13 - %16 = OpLoad %ulong %4 - %24 = OpConvertUToPtr %_ptr_Generic_ulong %16 - %15 = OpLoad %ulong %24 Aligned 8 - OpStore %6 %15 - %18 = OpLoad %ulong %6 - %26 = OpCopyObject %ulong %18 - %44 = OpUConvert %ulong %uint_2 - %25 = OpShiftLeftLogical %ulong %26 %44 - %17 = OpCopyObject %ulong %25 - OpStore %7 %17 - %19 = OpLoad %ulong %5 - %20 = OpLoad %ulong %7 - %27 = OpConvertUToPtr %_ptr_Generic_ulong %19 - OpStore %27 %20 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/shr.spvtxt b/ptx/src/test/spirv_run/shr.spvtxt deleted file mode 100644 index 249e71a..0000000 --- a/ptx/src/test/spirv_run/shr.spvtxt +++ /dev/null @@ -1,48 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %22 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "shr" - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %25 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %uint = OpTypeInt 32 0 -%_ptr_Function_uint = OpTypePointer Function %uint -%_ptr_Generic_uint = OpTypePointer Generic %uint - %uint_1 = OpConstant %uint 1 - %1 = OpFunction %void None %25 - %7 = OpFunctionParameter %ulong - %8 = OpFunctionParameter %ulong - %20 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_uint Function - OpStore %2 %7 - OpStore %3 %8 - %9 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %9 - %10 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %10 - %12 = OpLoad %ulong %4 - %18 = OpConvertUToPtr %_ptr_Generic_uint %12 - %11 = OpLoad %uint %18 Aligned 4 - OpStore %6 %11 - %14 = OpLoad %uint %6 - %13 = OpShiftRightArithmetic %uint %14 %uint_1 - OpStore %6 %13 - %15 = OpLoad %ulong %5 - %16 = OpLoad %uint %6 - %19 = OpConvertUToPtr %_ptr_Generic_uint %15 - OpStore %19 %16 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/sign_extend.spvtxt b/ptx/src/test/spirv_run/sign_extend.spvtxt deleted file mode 100644 index 5ceffed..0000000 --- a/ptx/src/test/spirv_run/sign_extend.spvtxt +++ /dev/null @@ -1,47 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %20 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "sign_extend" - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %23 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %uint = OpTypeInt 32 0 -%_ptr_Function_uint = OpTypePointer Function %uint - %ushort = OpTypeInt 16 0 -%_ptr_Generic_ushort = OpTypePointer Generic %ushort -%_ptr_Generic_uint = OpTypePointer Generic %uint - %1 = OpFunction %void None %23 - %7 = OpFunctionParameter %ulong - %8 = OpFunctionParameter %ulong - %18 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_uint Function - OpStore %2 %7 - OpStore %3 %8 - %9 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %9 - %10 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %10 - %12 = OpLoad %ulong %4 - %16 = OpConvertUToPtr %_ptr_Generic_ushort %12 - %15 = OpLoad %ushort %16 Aligned 2 - %11 = OpSConvert %uint %15 - OpStore %6 %11 - %13 = OpLoad %ulong %5 - %14 = OpLoad %uint %6 - %17 = OpConvertUToPtr %_ptr_Generic_uint %13 - OpStore %17 %14 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/sin.spvtxt b/ptx/src/test/spirv_run/sin.spvtxt deleted file mode 100644 index 6dd3e53..0000000 --- a/ptx/src/test/spirv_run/sin.spvtxt +++ /dev/null @@ -1,48 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %21 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "sin" - OpExecutionMode %1 ContractionOff - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %24 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %float = OpTypeFloat 32 -%_ptr_Function_float = OpTypePointer Function %float -%_ptr_Generic_float = OpTypePointer Generic %float - %1 = OpFunction %void None %24 - %7 = OpFunctionParameter %ulong - %8 = OpFunctionParameter %ulong - %19 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_float Function - OpStore %2 %7 - OpStore %3 %8 - %9 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %9 - %10 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %10 - %12 = OpLoad %ulong %4 - %17 = OpConvertUToPtr %_ptr_Generic_float %12 - %11 = OpLoad %float %17 Aligned 4 - OpStore %6 %11 - %14 = OpLoad %float %6 - %13 = OpExtInst %float %21 sin %14 - OpStore %6 %13 - %15 = OpLoad %ulong %5 - %16 = OpLoad %float %6 - %18 = OpConvertUToPtr %_ptr_Generic_float %15 - OpStore %18 %16 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/sqrt.spvtxt b/ptx/src/test/spirv_run/sqrt.spvtxt deleted file mode 100644 index 1c65aa3..0000000 --- a/ptx/src/test/spirv_run/sqrt.spvtxt +++ /dev/null @@ -1,48 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %21 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "sqrt" - OpExecutionMode %1 ContractionOff - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %24 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %float = OpTypeFloat 32 -%_ptr_Function_float = OpTypePointer Function %float -%_ptr_Generic_float = OpTypePointer Generic %float - %1 = OpFunction %void None %24 - %7 = OpFunctionParameter %ulong - %8 = OpFunctionParameter %ulong - %19 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_float Function - OpStore %2 %7 - OpStore %3 %8 - %9 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %9 - %10 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %10 - %12 = OpLoad %ulong %4 - %17 = OpConvertUToPtr %_ptr_Generic_float %12 - %11 = OpLoad %float %17 Aligned 4 - OpStore %6 %11 - %14 = OpLoad %float %6 - %13 = OpExtInst %float %21 sqrt %14 - OpStore %6 %13 - %15 = OpLoad %ulong %5 - %16 = OpLoad %float %6 - %18 = OpConvertUToPtr %_ptr_Generic_float %15 - OpStore %18 %16 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/stateful_ld_st_ntid.spvtxt b/ptx/src/test/spirv_run/stateful_ld_st_ntid.spvtxt deleted file mode 100644 index e2d4db6..0000000 --- a/ptx/src/test/spirv_run/stateful_ld_st_ntid.spvtxt +++ /dev/null @@ -1,93 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %56 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "stateful_ld_st_ntid" - OpExecutionMode %1 ContractionOff - OpDecorate %12 LinkageAttributes "__zluda_ptx_impl__sreg_tid" Import - %void = OpTypeVoid - %uint = OpTypeInt 32 0 - %uchar = OpTypeInt 8 0 - %60 = OpTypeFunction %uint %uchar -%_ptr_CrossWorkgroup_uchar = OpTypePointer CrossWorkgroup %uchar - %62 = OpTypeFunction %void %_ptr_CrossWorkgroup_uchar %_ptr_CrossWorkgroup_uchar -%_ptr_Function__ptr_CrossWorkgroup_uchar = OpTypePointer Function %_ptr_CrossWorkgroup_uchar -%_ptr_Function_uint = OpTypePointer Function %uint - %ulong = OpTypeInt 64 0 -%_ptr_Function_ulong = OpTypePointer Function %ulong - %uchar_0 = OpConstant %uchar 0 -%_ptr_CrossWorkgroup_ulong = OpTypePointer CrossWorkgroup %ulong - %12 = OpFunction %uint None %60 - %14 = OpFunctionParameter %uchar - OpFunctionEnd - %1 = OpFunction %void None %62 - %25 = OpFunctionParameter %_ptr_CrossWorkgroup_uchar - %26 = OpFunctionParameter %_ptr_CrossWorkgroup_uchar - %54 = OpLabel - %17 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function - %18 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function - %15 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function - %16 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function - %6 = OpVariable %_ptr_Function_uint Function - %7 = OpVariable %_ptr_Function_ulong Function - %8 = OpVariable %_ptr_Function_ulong Function - OpStore %17 %25 - OpStore %18 %26 - %47 = OpBitcast %_ptr_Function_ulong %17 - %46 = OpLoad %ulong %47 Aligned 8 - %19 = OpCopyObject %ulong %46 - %27 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %19 - OpStore %15 %27 - %49 = OpBitcast %_ptr_Function_ulong %18 - %48 = OpLoad %ulong %49 Aligned 8 - %20 = OpCopyObject %ulong %48 - %28 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %20 - OpStore %16 %28 - %29 = OpLoad %_ptr_CrossWorkgroup_uchar %15 - %22 = OpConvertPtrToU %ulong %29 - %21 = OpCopyObject %ulong %22 - %30 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %21 - OpStore %15 %30 - %31 = OpLoad %_ptr_CrossWorkgroup_uchar %16 - %24 = OpConvertPtrToU %ulong %31 - %23 = OpCopyObject %ulong %24 - %32 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %23 - OpStore %16 %32 - %11 = OpFunctionCall %uint %12 %uchar_0 - %33 = OpCopyObject %uint %11 - OpStore %6 %33 - %35 = OpLoad %uint %6 - %67 = OpBitcast %uint %35 - %34 = OpUConvert %ulong %67 - OpStore %7 %34 - %37 = OpLoad %_ptr_CrossWorkgroup_uchar %15 - %38 = OpLoad %ulong %7 - %50 = OpCopyObject %ulong %38 - %68 = OpBitcast %_ptr_CrossWorkgroup_uchar %37 - %69 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uchar %68 %50 - %36 = OpBitcast %_ptr_CrossWorkgroup_uchar %69 - OpStore %15 %36 - %40 = OpLoad %_ptr_CrossWorkgroup_uchar %16 - %41 = OpLoad %ulong %7 - %51 = OpCopyObject %ulong %41 - %70 = OpBitcast %_ptr_CrossWorkgroup_uchar %40 - %71 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uchar %70 %51 - %39 = OpBitcast %_ptr_CrossWorkgroup_uchar %71 - OpStore %16 %39 - %43 = OpLoad %_ptr_CrossWorkgroup_uchar %15 - %52 = OpBitcast %_ptr_CrossWorkgroup_ulong %43 - %42 = OpLoad %ulong %52 Aligned 8 - OpStore %8 %42 - %44 = OpLoad %_ptr_CrossWorkgroup_uchar %16 - %45 = OpLoad %ulong %8 - %53 = OpBitcast %_ptr_CrossWorkgroup_ulong %44 - OpStore %53 %45 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/stateful_ld_st_ntid_chain.spvtxt b/ptx/src/test/spirv_run/stateful_ld_st_ntid_chain.spvtxt deleted file mode 100644 index 5da0ef3..0000000 --- a/ptx/src/test/spirv_run/stateful_ld_st_ntid_chain.spvtxt +++ /dev/null @@ -1,97 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %64 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "stateful_ld_st_ntid_chain" - OpExecutionMode %1 ContractionOff - OpDecorate %16 LinkageAttributes "__zluda_ptx_impl__sreg_tid" Import - %void = OpTypeVoid - %uint = OpTypeInt 32 0 - %uchar = OpTypeInt 8 0 - %68 = OpTypeFunction %uint %uchar -%_ptr_CrossWorkgroup_uchar = OpTypePointer CrossWorkgroup %uchar - %70 = OpTypeFunction %void %_ptr_CrossWorkgroup_uchar %_ptr_CrossWorkgroup_uchar -%_ptr_Function__ptr_CrossWorkgroup_uchar = OpTypePointer Function %_ptr_CrossWorkgroup_uchar -%_ptr_Function_uint = OpTypePointer Function %uint - %ulong = OpTypeInt 64 0 -%_ptr_Function_ulong = OpTypePointer Function %ulong - %uchar_0 = OpConstant %uchar 0 -%_ptr_CrossWorkgroup_ulong = OpTypePointer CrossWorkgroup %ulong - %16 = OpFunction %uint None %68 - %18 = OpFunctionParameter %uchar - OpFunctionEnd - %1 = OpFunction %void None %70 - %33 = OpFunctionParameter %_ptr_CrossWorkgroup_uchar - %34 = OpFunctionParameter %_ptr_CrossWorkgroup_uchar - %62 = OpLabel - %25 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function - %26 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function - %19 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function - %20 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function - %21 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function - %22 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function - %23 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function - %24 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function - %10 = OpVariable %_ptr_Function_uint Function - %11 = OpVariable %_ptr_Function_ulong Function - %12 = OpVariable %_ptr_Function_ulong Function - OpStore %25 %33 - OpStore %26 %34 - %55 = OpBitcast %_ptr_Function_ulong %25 - %54 = OpLoad %ulong %55 Aligned 8 - %27 = OpCopyObject %ulong %54 - %35 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %27 - OpStore %19 %35 - %57 = OpBitcast %_ptr_Function_ulong %26 - %56 = OpLoad %ulong %57 Aligned 8 - %28 = OpCopyObject %ulong %56 - %36 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %28 - OpStore %22 %36 - %37 = OpLoad %_ptr_CrossWorkgroup_uchar %19 - %30 = OpConvertPtrToU %ulong %37 - %29 = OpCopyObject %ulong %30 - %38 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %29 - OpStore %20 %38 - %39 = OpLoad %_ptr_CrossWorkgroup_uchar %22 - %32 = OpConvertPtrToU %ulong %39 - %31 = OpCopyObject %ulong %32 - %40 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %31 - OpStore %23 %40 - %15 = OpFunctionCall %uint %16 %uchar_0 - %41 = OpCopyObject %uint %15 - OpStore %10 %41 - %43 = OpLoad %uint %10 - %75 = OpBitcast %uint %43 - %42 = OpUConvert %ulong %75 - OpStore %11 %42 - %45 = OpLoad %_ptr_CrossWorkgroup_uchar %20 - %46 = OpLoad %ulong %11 - %58 = OpCopyObject %ulong %46 - %76 = OpBitcast %_ptr_CrossWorkgroup_uchar %45 - %77 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uchar %76 %58 - %44 = OpBitcast %_ptr_CrossWorkgroup_uchar %77 - OpStore %21 %44 - %48 = OpLoad %_ptr_CrossWorkgroup_uchar %23 - %49 = OpLoad %ulong %11 - %59 = OpCopyObject %ulong %49 - %78 = OpBitcast %_ptr_CrossWorkgroup_uchar %48 - %79 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uchar %78 %59 - %47 = OpBitcast %_ptr_CrossWorkgroup_uchar %79 - OpStore %24 %47 - %51 = OpLoad %_ptr_CrossWorkgroup_uchar %21 - %60 = OpBitcast %_ptr_CrossWorkgroup_ulong %51 - %50 = OpLoad %ulong %60 Aligned 8 - OpStore %12 %50 - %52 = OpLoad %_ptr_CrossWorkgroup_uchar %24 - %53 = OpLoad %ulong %12 - %61 = OpBitcast %_ptr_CrossWorkgroup_ulong %52 - OpStore %61 %53 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/stateful_ld_st_ntid_sub.spvtxt b/ptx/src/test/spirv_run/stateful_ld_st_ntid_sub.spvtxt deleted file mode 100644 index 0ef5d28..0000000 --- a/ptx/src/test/spirv_run/stateful_ld_st_ntid_sub.spvtxt +++ /dev/null @@ -1,107 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %70 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "stateful_ld_st_ntid_sub" - OpExecutionMode %1 ContractionOff - OpDecorate %16 LinkageAttributes "__zluda_ptx_impl__sreg_tid" Import - %void = OpTypeVoid - %uint = OpTypeInt 32 0 - %uchar = OpTypeInt 8 0 - %74 = OpTypeFunction %uint %uchar -%_ptr_CrossWorkgroup_uchar = OpTypePointer CrossWorkgroup %uchar - %76 = OpTypeFunction %void %_ptr_CrossWorkgroup_uchar %_ptr_CrossWorkgroup_uchar -%_ptr_Function__ptr_CrossWorkgroup_uchar = OpTypePointer Function %_ptr_CrossWorkgroup_uchar -%_ptr_Function_uint = OpTypePointer Function %uint - %ulong = OpTypeInt 64 0 -%_ptr_Function_ulong = OpTypePointer Function %ulong - %uchar_0 = OpConstant %uchar 0 - %ulong_0 = OpConstant %ulong 0 -%_ptr_CrossWorkgroup_ulong = OpTypePointer CrossWorkgroup %ulong - %ulong_0_0 = OpConstant %ulong 0 - %16 = OpFunction %uint None %74 - %18 = OpFunctionParameter %uchar - OpFunctionEnd - %1 = OpFunction %void None %76 - %35 = OpFunctionParameter %_ptr_CrossWorkgroup_uchar - %36 = OpFunctionParameter %_ptr_CrossWorkgroup_uchar - %68 = OpLabel - %25 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function - %26 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function - %19 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function - %20 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function - %21 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function - %22 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function - %23 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function - %24 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function - %10 = OpVariable %_ptr_Function_uint Function - %11 = OpVariable %_ptr_Function_ulong Function - %12 = OpVariable %_ptr_Function_ulong Function - OpStore %25 %35 - OpStore %26 %36 - %61 = OpBitcast %_ptr_Function_ulong %25 - %60 = OpLoad %ulong %61 Aligned 8 - %27 = OpCopyObject %ulong %60 - %37 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %27 - OpStore %19 %37 - %63 = OpBitcast %_ptr_Function_ulong %26 - %62 = OpLoad %ulong %63 Aligned 8 - %28 = OpCopyObject %ulong %62 - %38 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %28 - OpStore %22 %38 - %39 = OpLoad %_ptr_CrossWorkgroup_uchar %19 - %30 = OpConvertPtrToU %ulong %39 - %29 = OpCopyObject %ulong %30 - %40 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %29 - OpStore %20 %40 - %41 = OpLoad %_ptr_CrossWorkgroup_uchar %22 - %32 = OpConvertPtrToU %ulong %41 - %31 = OpCopyObject %ulong %32 - %42 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %31 - OpStore %23 %42 - %15 = OpFunctionCall %uint %16 %uchar_0 - %43 = OpCopyObject %uint %15 - OpStore %10 %43 - %45 = OpLoad %uint %10 - %81 = OpBitcast %uint %45 - %44 = OpUConvert %ulong %81 - OpStore %11 %44 - %46 = OpLoad %ulong %11 - %64 = OpCopyObject %ulong %46 - %33 = OpSNegate %ulong %64 - %48 = OpLoad %_ptr_CrossWorkgroup_uchar %20 - %82 = OpBitcast %_ptr_CrossWorkgroup_uchar %48 - %83 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uchar %82 %33 - %47 = OpBitcast %_ptr_CrossWorkgroup_uchar %83 - OpStore %21 %47 - %49 = OpLoad %ulong %11 - %65 = OpCopyObject %ulong %49 - %34 = OpSNegate %ulong %65 - %51 = OpLoad %_ptr_CrossWorkgroup_uchar %23 - %84 = OpBitcast %_ptr_CrossWorkgroup_uchar %51 - %85 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uchar %84 %34 - %50 = OpBitcast %_ptr_CrossWorkgroup_uchar %85 - OpStore %24 %50 - %53 = OpLoad %_ptr_CrossWorkgroup_uchar %21 - %66 = OpBitcast %_ptr_CrossWorkgroup_ulong %53 - %87 = OpBitcast %_ptr_CrossWorkgroup_uchar %66 - %88 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uchar %87 %ulong_0 - %57 = OpBitcast %_ptr_CrossWorkgroup_ulong %88 - %52 = OpLoad %ulong %57 Aligned 8 - OpStore %12 %52 - %54 = OpLoad %_ptr_CrossWorkgroup_uchar %24 - %55 = OpLoad %ulong %12 - %67 = OpBitcast %_ptr_CrossWorkgroup_ulong %54 - %89 = OpBitcast %_ptr_CrossWorkgroup_uchar %67 - %90 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uchar %89 %ulong_0_0 - %59 = OpBitcast %_ptr_CrossWorkgroup_ulong %90 - OpStore %59 %55 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/stateful_ld_st_simple.spvtxt b/ptx/src/test/spirv_run/stateful_ld_st_simple.spvtxt deleted file mode 100644 index 7a142b7..0000000 --- a/ptx/src/test/spirv_run/stateful_ld_st_simple.spvtxt +++ /dev/null @@ -1,65 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %41 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "stateful_ld_st_simple" - %void = OpTypeVoid - %uchar = OpTypeInt 8 0 -%_ptr_CrossWorkgroup_uchar = OpTypePointer CrossWorkgroup %uchar - %45 = OpTypeFunction %void %_ptr_CrossWorkgroup_uchar %_ptr_CrossWorkgroup_uchar -%_ptr_Function__ptr_CrossWorkgroup_uchar = OpTypePointer Function %_ptr_CrossWorkgroup_uchar - %ulong = OpTypeInt 64 0 -%_ptr_Function_ulong = OpTypePointer Function %ulong -%_ptr_CrossWorkgroup_ulong = OpTypePointer CrossWorkgroup %ulong - %1 = OpFunction %void None %45 - %21 = OpFunctionParameter %_ptr_CrossWorkgroup_uchar - %22 = OpFunctionParameter %_ptr_CrossWorkgroup_uchar - %39 = OpLabel - %2 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function - %3 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function - %9 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function - %10 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function - %11 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function - %12 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function - %8 = OpVariable %_ptr_Function_ulong Function - OpStore %2 %21 - OpStore %3 %22 - %14 = OpBitcast %_ptr_Function_ulong %2 - %13 = OpLoad %ulong %14 Aligned 8 - %23 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %13 - OpStore %9 %23 - %16 = OpBitcast %_ptr_Function_ulong %3 - %15 = OpLoad %ulong %16 Aligned 8 - %24 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %15 - OpStore %10 %24 - %25 = OpLoad %_ptr_CrossWorkgroup_uchar %9 - %18 = OpConvertPtrToU %ulong %25 - %34 = OpCopyObject %ulong %18 - %33 = OpCopyObject %ulong %34 - %17 = OpCopyObject %ulong %33 - %26 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %17 - OpStore %11 %26 - %27 = OpLoad %_ptr_CrossWorkgroup_uchar %10 - %20 = OpConvertPtrToU %ulong %27 - %36 = OpCopyObject %ulong %20 - %35 = OpCopyObject %ulong %36 - %19 = OpCopyObject %ulong %35 - %28 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %19 - OpStore %12 %28 - %30 = OpLoad %_ptr_CrossWorkgroup_uchar %11 - %37 = OpBitcast %_ptr_CrossWorkgroup_ulong %30 - %29 = OpLoad %ulong %37 Aligned 8 - OpStore %8 %29 - %31 = OpLoad %_ptr_CrossWorkgroup_uchar %12 - %32 = OpLoad %ulong %8 - %38 = OpBitcast %_ptr_CrossWorkgroup_ulong %31 - OpStore %38 %32 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/stateful_neg_offset.spvtxt b/ptx/src/test/spirv_run/stateful_neg_offset.spvtxt deleted file mode 100644 index 62843ca..0000000 --- a/ptx/src/test/spirv_run/stateful_neg_offset.spvtxt +++ /dev/null @@ -1,80 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %57 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "stateful_neg_offset" - %void = OpTypeVoid - %uchar = OpTypeInt 8 0 -%_ptr_CrossWorkgroup_uchar = OpTypePointer CrossWorkgroup %uchar - %61 = OpTypeFunction %void %_ptr_CrossWorkgroup_uchar %_ptr_CrossWorkgroup_uchar -%_ptr_Function__ptr_CrossWorkgroup_uchar = OpTypePointer Function %_ptr_CrossWorkgroup_uchar - %ulong = OpTypeInt 64 0 -%_ptr_Function_ulong = OpTypePointer Function %ulong -%_ptr_CrossWorkgroup_ulong = OpTypePointer CrossWorkgroup %ulong - %1 = OpFunction %void None %61 - %29 = OpFunctionParameter %_ptr_CrossWorkgroup_uchar - %30 = OpFunctionParameter %_ptr_CrossWorkgroup_uchar - %55 = OpLabel - %15 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function - %16 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function - %10 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function - %11 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function - %12 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function - %13 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function - %14 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function - %9 = OpVariable %_ptr_Function_ulong Function - OpStore %15 %29 - OpStore %16 %30 - %47 = OpBitcast %_ptr_Function_ulong %15 - %17 = OpLoad %ulong %47 Aligned 8 - %31 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %17 - OpStore %10 %31 - %48 = OpBitcast %_ptr_Function_ulong %16 - %18 = OpLoad %ulong %48 Aligned 8 - %32 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %18 - OpStore %11 %32 - %33 = OpLoad %_ptr_CrossWorkgroup_uchar %10 - %20 = OpConvertPtrToU %ulong %33 - %50 = OpCopyObject %ulong %20 - %49 = OpCopyObject %ulong %50 - %19 = OpCopyObject %ulong %49 - %34 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %19 - OpStore %12 %34 - %35 = OpLoad %_ptr_CrossWorkgroup_uchar %11 - %22 = OpConvertPtrToU %ulong %35 - %52 = OpCopyObject %ulong %22 - %51 = OpCopyObject %ulong %52 - %21 = OpCopyObject %ulong %51 - %36 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %21 - OpStore %13 %36 - %37 = OpLoad %_ptr_CrossWorkgroup_uchar %12 - %24 = OpConvertPtrToU %ulong %37 - %38 = OpLoad %_ptr_CrossWorkgroup_uchar %13 - %25 = OpConvertPtrToU %ulong %38 - %23 = OpIAdd %ulong %24 %25 - %39 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %23 - OpStore %14 %39 - %40 = OpLoad %_ptr_CrossWorkgroup_uchar %12 - %27 = OpConvertPtrToU %ulong %40 - %41 = OpLoad %_ptr_CrossWorkgroup_uchar %13 - %28 = OpConvertPtrToU %ulong %41 - %26 = OpISub %ulong %27 %28 - %42 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %26 - OpStore %14 %42 - %44 = OpLoad %_ptr_CrossWorkgroup_uchar %12 - %53 = OpBitcast %_ptr_CrossWorkgroup_ulong %44 - %43 = OpLoad %ulong %53 Aligned 8 - OpStore %9 %43 - %45 = OpLoad %_ptr_CrossWorkgroup_uchar %13 - %46 = OpLoad %ulong %9 - %54 = OpBitcast %_ptr_CrossWorkgroup_ulong %45 - OpStore %54 %46 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/sub.spvtxt b/ptx/src/test/spirv_run/sub.spvtxt deleted file mode 100644 index 05656dd..0000000 --- a/ptx/src/test/spirv_run/sub.spvtxt +++ /dev/null @@ -1,47 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %23 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "sub" - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %26 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong -%_ptr_Generic_ulong = OpTypePointer Generic %ulong - %ulong_1 = OpConstant %ulong 1 - %1 = OpFunction %void None %26 - %8 = OpFunctionParameter %ulong - %9 = OpFunctionParameter %ulong - %21 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_ulong Function - %7 = OpVariable %_ptr_Function_ulong Function - OpStore %2 %8 - OpStore %3 %9 - %10 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %19 = OpConvertUToPtr %_ptr_Generic_ulong %13 - %12 = OpLoad %ulong %19 Aligned 8 - OpStore %6 %12 - %15 = OpLoad %ulong %6 - %14 = OpISub %ulong %15 %ulong_1 - OpStore %7 %14 - %16 = OpLoad %ulong %5 - %17 = OpLoad %ulong %7 - %20 = OpConvertUToPtr %_ptr_Generic_ulong %16 - OpStore %20 %17 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/vector.spvtxt b/ptx/src/test/spirv_run/vector.spvtxt deleted file mode 100644 index 8253bf9..0000000 --- a/ptx/src/test/spirv_run/vector.spvtxt +++ /dev/null @@ -1,99 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %51 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %25 "vector" - %void = OpTypeVoid - %uint = OpTypeInt 32 0 - %v2uint = OpTypeVector %uint 2 - %55 = OpTypeFunction %v2uint %v2uint -%_ptr_Function_v2uint = OpTypePointer Function %v2uint -%_ptr_Function_uint = OpTypePointer Function %uint - %uint_0 = OpConstant %uint 0 - %uint_1 = OpConstant %uint 1 - %ulong = OpTypeInt 64 0 - %67 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong -%_ptr_Generic_v2uint = OpTypePointer Generic %v2uint - %1 = OpFunction %v2uint None %55 - %7 = OpFunctionParameter %v2uint - %24 = OpLabel - %3 = OpVariable %_ptr_Function_v2uint Function - %2 = OpVariable %_ptr_Function_v2uint Function - %4 = OpVariable %_ptr_Function_v2uint Function - %5 = OpVariable %_ptr_Function_uint Function - %6 = OpVariable %_ptr_Function_uint Function - OpStore %3 %7 - %59 = OpInBoundsAccessChain %_ptr_Function_uint %3 %uint_0 - %9 = OpLoad %uint %59 - %8 = OpCopyObject %uint %9 - OpStore %5 %8 - %61 = OpInBoundsAccessChain %_ptr_Function_uint %3 %uint_1 - %11 = OpLoad %uint %61 - %10 = OpCopyObject %uint %11 - OpStore %6 %10 - %13 = OpLoad %uint %5 - %14 = OpLoad %uint %6 - %12 = OpIAdd %uint %13 %14 - OpStore %6 %12 - %16 = OpLoad %uint %6 - %15 = OpCopyObject %uint %16 - %62 = OpInBoundsAccessChain %_ptr_Function_uint %4 %uint_0 - OpStore %62 %15 - %18 = OpLoad %uint %6 - %17 = OpCopyObject %uint %18 - %63 = OpInBoundsAccessChain %_ptr_Function_uint %4 %uint_1 - OpStore %63 %17 - %64 = OpInBoundsAccessChain %_ptr_Function_uint %4 %uint_1 - %20 = OpLoad %uint %64 - %19 = OpCopyObject %uint %20 - %65 = OpInBoundsAccessChain %_ptr_Function_uint %4 %uint_0 - OpStore %65 %19 - %22 = OpLoad %v2uint %4 - %21 = OpCopyObject %v2uint %22 - OpStore %2 %21 - %23 = OpLoad %v2uint %2 - OpReturnValue %23 - OpFunctionEnd - %25 = OpFunction %void None %67 - %34 = OpFunctionParameter %ulong - %35 = OpFunctionParameter %ulong - %49 = OpLabel - %26 = OpVariable %_ptr_Function_ulong Function - %27 = OpVariable %_ptr_Function_ulong Function - %28 = OpVariable %_ptr_Function_ulong Function - %29 = OpVariable %_ptr_Function_ulong Function - %30 = OpVariable %_ptr_Function_v2uint Function - %31 = OpVariable %_ptr_Function_uint Function - %32 = OpVariable %_ptr_Function_uint Function - %33 = OpVariable %_ptr_Function_ulong Function - OpStore %26 %34 - OpStore %27 %35 - %36 = OpLoad %ulong %26 Aligned 8 - OpStore %28 %36 - %37 = OpLoad %ulong %27 Aligned 8 - OpStore %29 %37 - %39 = OpLoad %ulong %28 - %46 = OpConvertUToPtr %_ptr_Generic_v2uint %39 - %38 = OpLoad %v2uint %46 Aligned 8 - OpStore %30 %38 - %41 = OpLoad %v2uint %30 - %40 = OpFunctionCall %v2uint %1 %41 - OpStore %30 %40 - %43 = OpLoad %v2uint %30 - %47 = OpBitcast %ulong %43 - %42 = OpCopyObject %ulong %47 - OpStore %33 %42 - %44 = OpLoad %ulong %29 - %45 = OpLoad %v2uint %30 - %48 = OpConvertUToPtr %_ptr_Generic_v2uint %44 - OpStore %48 %45 Aligned 8 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/vector4.spvtxt b/ptx/src/test/spirv_run/vector4.spvtxt deleted file mode 100644 index 9b6349b..0000000 --- a/ptx/src/test/spirv_run/vector4.spvtxt +++ /dev/null @@ -1,56 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %24 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "vector4" - OpExecutionMode %1 ContractionOff - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %27 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %uint = OpTypeInt 32 0 - %v4uint = OpTypeVector %uint 4 -%_ptr_Function_v4uint = OpTypePointer Function %v4uint -%_ptr_Function_uint = OpTypePointer Function %uint -%_ptr_Generic_v4uint = OpTypePointer Generic %v4uint - %uint_3 = OpConstant %uint 3 -%_ptr_Generic_uint = OpTypePointer Generic %uint - %1 = OpFunction %void None %27 - %8 = OpFunctionParameter %ulong - %9 = OpFunctionParameter %ulong - %22 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_v4uint Function - %7 = OpVariable %_ptr_Function_uint Function - OpStore %2 %8 - OpStore %3 %9 - %10 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %18 = OpConvertUToPtr %_ptr_Generic_v4uint %13 - %12 = OpLoad %v4uint %18 Aligned 16 - OpStore %6 %12 - %35 = OpInBoundsAccessChain %_ptr_Function_uint %6 %uint_3 - %15 = OpLoad %uint %35 - %20 = OpCopyObject %uint %15 - %19 = OpCopyObject %uint %20 - %14 = OpCopyObject %uint %19 - OpStore %7 %14 - %16 = OpLoad %ulong %5 - %17 = OpLoad %uint %7 - %21 = OpConvertUToPtr %_ptr_Generic_uint %16 - OpStore %21 %17 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/vector_extract.spvtxt b/ptx/src/test/spirv_run/vector_extract.spvtxt deleted file mode 100644 index 802c69b..0000000 --- a/ptx/src/test/spirv_run/vector_extract.spvtxt +++ /dev/null @@ -1,125 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %61 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "vector_extract" - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %64 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %ushort = OpTypeInt 16 0 -%_ptr_Function_ushort = OpTypePointer Function %ushort - %v4ushort = OpTypeVector %ushort 4 -%_ptr_Function_v4ushort = OpTypePointer Function %v4ushort - %uchar = OpTypeInt 8 0 - %v4uchar = OpTypeVector %uchar 4 -%_ptr_CrossWorkgroup_v4uchar = OpTypePointer CrossWorkgroup %v4uchar - %1 = OpFunction %void None %64 - %17 = OpFunctionParameter %ulong - %18 = OpFunctionParameter %ulong - %59 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_ushort Function - %7 = OpVariable %_ptr_Function_ushort Function - %8 = OpVariable %_ptr_Function_ushort Function - %9 = OpVariable %_ptr_Function_ushort Function - %10 = OpVariable %_ptr_Function_v4ushort Function - OpStore %2 %17 - OpStore %3 %18 - %19 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %19 - %20 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %20 - %21 = OpLoad %ulong %4 - %49 = OpConvertUToPtr %_ptr_CrossWorkgroup_v4uchar %21 - %11 = OpLoad %v4uchar %49 Aligned 4 - %50 = OpCompositeExtract %uchar %11 0 - %51 = OpCompositeExtract %uchar %11 1 - %52 = OpCompositeExtract %uchar %11 2 - %53 = OpCompositeExtract %uchar %11 3 - %73 = OpBitcast %uchar %50 - %22 = OpUConvert %ushort %73 - %74 = OpBitcast %uchar %51 - %23 = OpUConvert %ushort %74 - %75 = OpBitcast %uchar %52 - %24 = OpUConvert %ushort %75 - %76 = OpBitcast %uchar %53 - %25 = OpUConvert %ushort %76 - OpStore %6 %22 - OpStore %7 %23 - OpStore %8 %24 - OpStore %9 %25 - %26 = OpLoad %ushort %7 - %27 = OpLoad %ushort %8 - %28 = OpLoad %ushort %9 - %29 = OpLoad %ushort %6 - %77 = OpUndef %v4ushort - %78 = OpCompositeInsert %v4ushort %26 %77 0 - %79 = OpCompositeInsert %v4ushort %27 %78 1 - %80 = OpCompositeInsert %v4ushort %28 %79 2 - %81 = OpCompositeInsert %v4ushort %29 %80 3 - %12 = OpCopyObject %v4ushort %81 - %30 = OpCopyObject %v4ushort %12 - OpStore %10 %30 - %31 = OpLoad %v4ushort %10 - %13 = OpCopyObject %v4ushort %31 - %32 = OpCompositeExtract %ushort %13 0 - %33 = OpCompositeExtract %ushort %13 1 - %34 = OpCompositeExtract %ushort %13 2 - %35 = OpCompositeExtract %ushort %13 3 - OpStore %8 %32 - OpStore %9 %33 - OpStore %6 %34 - OpStore %7 %35 - %36 = OpLoad %ushort %8 - %37 = OpLoad %ushort %9 - %38 = OpLoad %ushort %6 - %39 = OpLoad %ushort %7 - %82 = OpUndef %v4ushort - %83 = OpCompositeInsert %v4ushort %36 %82 0 - %84 = OpCompositeInsert %v4ushort %37 %83 1 - %85 = OpCompositeInsert %v4ushort %38 %84 2 - %86 = OpCompositeInsert %v4ushort %39 %85 3 - %15 = OpCopyObject %v4ushort %86 - %14 = OpCopyObject %v4ushort %15 - %40 = OpCompositeExtract %ushort %14 0 - %41 = OpCompositeExtract %ushort %14 1 - %42 = OpCompositeExtract %ushort %14 2 - %43 = OpCompositeExtract %ushort %14 3 - OpStore %9 %40 - OpStore %6 %41 - OpStore %7 %42 - OpStore %8 %43 - %44 = OpLoad %ushort %6 - %45 = OpLoad %ushort %7 - %46 = OpLoad %ushort %8 - %47 = OpLoad %ushort %9 - %87 = OpBitcast %ushort %44 - %54 = OpUConvert %uchar %87 - %88 = OpBitcast %ushort %45 - %55 = OpUConvert %uchar %88 - %89 = OpBitcast %ushort %46 - %56 = OpUConvert %uchar %89 - %90 = OpBitcast %ushort %47 - %57 = OpUConvert %uchar %90 - %91 = OpUndef %v4uchar - %92 = OpCompositeInsert %v4uchar %54 %91 0 - %93 = OpCompositeInsert %v4uchar %55 %92 1 - %94 = OpCompositeInsert %v4uchar %56 %93 2 - %95 = OpCompositeInsert %v4uchar %57 %94 3 - %16 = OpCopyObject %v4uchar %95 - %48 = OpLoad %ulong %5 - %58 = OpConvertUToPtr %_ptr_CrossWorkgroup_v4uchar %48 - OpStore %58 %16 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/test/spirv_run/xor.spvtxt b/ptx/src/test/spirv_run/xor.spvtxt deleted file mode 100644 index c3a1f6f..0000000 --- a/ptx/src/test/spirv_run/xor.spvtxt +++ /dev/null @@ -1,59 +0,0 @@ - OpCapability GenericPointer - OpCapability Linkage - OpCapability Addresses - OpCapability Kernel - OpCapability Int8 - OpCapability Int16 - OpCapability Int64 - OpCapability Float16 - OpCapability Float64 - %28 = OpExtInstImport "OpenCL.std" - OpMemoryModel Physical64 OpenCL - OpEntryPoint Kernel %1 "xor" - %void = OpTypeVoid - %ulong = OpTypeInt 64 0 - %31 = OpTypeFunction %void %ulong %ulong -%_ptr_Function_ulong = OpTypePointer Function %ulong - %uint = OpTypeInt 32 0 -%_ptr_Function_uint = OpTypePointer Function %uint -%_ptr_Generic_uint = OpTypePointer Generic %uint - %ulong_4 = OpConstant %ulong 4 - %uchar = OpTypeInt 8 0 -%_ptr_Generic_uchar = OpTypePointer Generic %uchar - %1 = OpFunction %void None %31 - %8 = OpFunctionParameter %ulong - %9 = OpFunctionParameter %ulong - %26 = OpLabel - %2 = OpVariable %_ptr_Function_ulong Function - %3 = OpVariable %_ptr_Function_ulong Function - %4 = OpVariable %_ptr_Function_ulong Function - %5 = OpVariable %_ptr_Function_ulong Function - %6 = OpVariable %_ptr_Function_uint Function - %7 = OpVariable %_ptr_Function_uint Function - OpStore %2 %8 - OpStore %3 %9 - %10 = OpLoad %ulong %2 Aligned 8 - OpStore %4 %10 - %11 = OpLoad %ulong %3 Aligned 8 - OpStore %5 %11 - %13 = OpLoad %ulong %4 - %23 = OpConvertUToPtr %_ptr_Generic_uint %13 - %12 = OpLoad %uint %23 Aligned 4 - OpStore %6 %12 - %15 = OpLoad %ulong %4 - %24 = OpConvertUToPtr %_ptr_Generic_uint %15 - %38 = OpBitcast %_ptr_Generic_uchar %24 - %39 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %38 %ulong_4 - %22 = OpBitcast %_ptr_Generic_uint %39 - %14 = OpLoad %uint %22 Aligned 4 - OpStore %7 %14 - %17 = OpLoad %uint %6 - %18 = OpLoad %uint %7 - %16 = OpBitwiseXor %uint %17 %18 - OpStore %6 %16 - %19 = OpLoad %ulong %5 - %20 = OpLoad %uint %6 - %25 = OpConvertUToPtr %_ptr_Generic_uint %19 - OpStore %25 %20 Aligned 4 - OpReturn - OpFunctionEnd diff --git a/ptx/src/translate.rs b/ptx/src/translate.rs deleted file mode 100644 index 9b422fd..0000000 --- a/ptx/src/translate.rs +++ /dev/null @@ -1,8181 +0,0 @@ -use crate::ast;
-use half::f16;
-use rspirv::dr;
-use std::cell::RefCell;
-use std::collections::{hash_map, BTreeMap, HashMap, HashSet};
-use std::{borrow::Cow, collections::BTreeSet, ffi::CString, hash::Hash, iter, mem, rc::Rc};
-
-use rspirv::binary::{Assemble, Disassemble};
-
-static ZLUDA_PTX_IMPL_INTEL: &'static [u8] = include_bytes!("../lib/zluda_ptx_impl.spv");
-static ZLUDA_PTX_IMPL_AMD: &'static [u8] = include_bytes!("../lib/zluda_ptx_impl.bc");
-const ZLUDA_PTX_PREFIX: &'static str = "__zluda_ptx_impl__";
-
-quick_error! {
- #[derive(Debug)]
- pub enum TranslateError {
- UnknownSymbol {}
- UntypedSymbol {}
- MismatchedType {}
- Spirv(err: rspirv::dr::Error) {
- from()
- display("{}", err)
- cause(err)
- }
- Unreachable {}
- Todo {}
- }
-}
-
-#[cfg(debug_assertions)]
-fn error_unreachable() -> TranslateError {
- unreachable!()
-}
-
-#[cfg(not(debug_assertions))]
-fn error_unreachable() -> TranslateError {
- TranslateError::Unreachable
-}
-
-fn error_unknown_symbol() -> TranslateError {
- TranslateError::UnknownSymbol
-}
-
-#[derive(PartialEq, Eq, Hash, Clone)]
-enum SpirvType {
- Base(SpirvScalarKey),
- Vector(SpirvScalarKey, u8),
- Array(SpirvScalarKey, Vec<u32>),
- Pointer(Box<SpirvType>, spirv::StorageClass),
- Func(Option<Box<SpirvType>>, Vec<SpirvType>),
- Struct(Vec<SpirvScalarKey>),
-}
-
-impl SpirvType {
- fn new(t: ast::Type) -> Self {
- match t {
- ast::Type::Scalar(t) => SpirvType::Base(t.into()),
- ast::Type::Vector(typ, len) => SpirvType::Vector(typ.into(), len),
- ast::Type::Array(t, len) => SpirvType::Array(t.into(), len),
- ast::Type::Pointer(pointer_t, space) => SpirvType::Pointer(
- Box::new(SpirvType::Base(pointer_t.into())),
- space.to_spirv(),
- ),
- }
- }
-
- fn pointer_to(t: ast::Type, outer_space: spirv::StorageClass) -> Self {
- let key = Self::new(t);
- SpirvType::Pointer(Box::new(key), outer_space)
- }
-}
-
-impl From<ast::ScalarType> for SpirvType {
- fn from(t: ast::ScalarType) -> Self {
- SpirvType::Base(t.into())
- }
-}
-
-struct TypeWordMap {
- void: spirv::Word,
- complex: HashMap<SpirvType, spirv::Word>,
- constants: HashMap<(SpirvType, u64), spirv::Word>,
-}
-
-// SPIR-V integer type definitions are signless, more below:
-// https://www.khronos.org/registry/spir-v/specs/unified1/SPIRV.html#_a_id_unsignedsigned_a_unsigned_versus_signed_integers
-// https://www.khronos.org/registry/spir-v/specs/unified1/SPIRV.html#_validation_rules_for_kernel_a_href_capability_capabilities_a
-#[derive(PartialEq, Eq, Hash, Clone, Copy)]
-enum SpirvScalarKey {
- B8,
- B16,
- B32,
- B64,
- F16,
- F32,
- F64,
- Pred,
- F16x2,
-}
-
-impl From<ast::ScalarType> for SpirvScalarKey {
- fn from(t: ast::ScalarType) -> Self {
- match t {
- ast::ScalarType::B8 | ast::ScalarType::U8 | ast::ScalarType::S8 => SpirvScalarKey::B8,
- ast::ScalarType::B16 | ast::ScalarType::U16 | ast::ScalarType::S16 => {
- SpirvScalarKey::B16
- }
- ast::ScalarType::B32 | ast::ScalarType::U32 | ast::ScalarType::S32 => {
- SpirvScalarKey::B32
- }
- ast::ScalarType::B64 | ast::ScalarType::U64 | ast::ScalarType::S64 => {
- SpirvScalarKey::B64
- }
- ast::ScalarType::F16 => SpirvScalarKey::F16,
- ast::ScalarType::F32 => SpirvScalarKey::F32,
- ast::ScalarType::F64 => SpirvScalarKey::F64,
- ast::ScalarType::F16x2 => SpirvScalarKey::F16x2,
- ast::ScalarType::Pred => SpirvScalarKey::Pred,
- }
- }
-}
-
-impl TypeWordMap {
- fn new(b: &mut dr::Builder) -> TypeWordMap {
- let void = b.type_void(None);
- TypeWordMap {
- void: void,
- complex: HashMap::<SpirvType, spirv::Word>::new(),
- constants: HashMap::new(),
- }
- }
-
- fn void(&self) -> spirv::Word {
- self.void
- }
-
- fn get_or_add_scalar(&mut self, b: &mut dr::Builder, t: ast::ScalarType) -> spirv::Word {
- let key: SpirvScalarKey = t.into();
- self.get_or_add_spirv_scalar(b, key)
- }
-
- fn get_or_add_spirv_scalar(&mut self, b: &mut dr::Builder, key: SpirvScalarKey) -> spirv::Word {
- *self
- .complex
- .entry(SpirvType::Base(key))
- .or_insert_with(|| match key {
- SpirvScalarKey::B8 => b.type_int(None, 8, 0),
- SpirvScalarKey::B16 => b.type_int(None, 16, 0),
- SpirvScalarKey::B32 => b.type_int(None, 32, 0),
- SpirvScalarKey::B64 => b.type_int(None, 64, 0),
- SpirvScalarKey::F16 => b.type_float(None, 16),
- SpirvScalarKey::F32 => b.type_float(None, 32),
- SpirvScalarKey::F64 => b.type_float(None, 64),
- SpirvScalarKey::Pred => b.type_bool(None),
- SpirvScalarKey::F16x2 => todo!(),
- })
- }
-
- fn get_or_add(&mut self, b: &mut dr::Builder, t: SpirvType) -> spirv::Word {
- match t {
- SpirvType::Base(key) => self.get_or_add_spirv_scalar(b, key),
- SpirvType::Pointer(ref typ, storage) => {
- let base = self.get_or_add(b, *typ.clone());
- *self
- .complex
- .entry(t)
- .or_insert_with(|| b.type_pointer(None, storage, base))
- }
- SpirvType::Vector(typ, len) => {
- let base = self.get_or_add_spirv_scalar(b, typ);
- *self
- .complex
- .entry(t)
- .or_insert_with(|| b.type_vector(None, base, len as u32))
- }
- SpirvType::Array(typ, array_dimensions) => {
- let (base_type, length) = match &*array_dimensions {
- &[] => {
- return self.get_or_add(b, SpirvType::Base(typ));
- }
- &[len] => {
- let u32_type = self.get_or_add_scalar(b, ast::ScalarType::U32);
- let base = self.get_or_add_spirv_scalar(b, typ);
- let len_const = b.constant_u32(u32_type, None, len);
- (base, len_const)
- }
- array_dimensions => {
- let u32_type = self.get_or_add_scalar(b, ast::ScalarType::U32);
- let base = self
- .get_or_add(b, SpirvType::Array(typ, array_dimensions[1..].to_vec()));
- let len_const = b.constant_u32(u32_type, None, array_dimensions[0]);
- (base, len_const)
- }
- };
- *self
- .complex
- .entry(SpirvType::Array(typ, array_dimensions))
- .or_insert_with(|| b.type_array(None, base_type, length))
- }
- SpirvType::Func(ref out_params, ref in_params) => {
- let out_t = match out_params {
- Some(p) => self.get_or_add(b, *p.clone()),
- None => self.void(),
- };
- let in_t = in_params
- .iter()
- .map(|t| self.get_or_add(b, t.clone()))
- .collect::<Vec<_>>();
- *self
- .complex
- .entry(t)
- .or_insert_with(|| b.type_function(None, out_t, in_t))
- }
- SpirvType::Struct(ref underlying) => {
- let underlying_ids = underlying
- .iter()
- .map(|t| self.get_or_add_spirv_scalar(b, *t))
- .collect::<Vec<_>>();
- *self
- .complex
- .entry(t)
- .or_insert_with(|| b.type_struct(None, underlying_ids))
- }
- }
- }
-
- fn get_or_add_fn(
- &mut self,
- b: &mut dr::Builder,
- in_params: impl Iterator<Item = SpirvType>,
- mut out_params: impl ExactSizeIterator<Item = SpirvType>,
- ) -> (spirv::Word, spirv::Word) {
- let (out_args, out_spirv_type) = if out_params.len() == 0 {
- (None, self.void())
- } else if out_params.len() == 1 {
- let arg_as_key = out_params.next().unwrap();
- (
- Some(Box::new(arg_as_key.clone())),
- self.get_or_add(b, arg_as_key),
- )
- } else {
- // TODO: support multiple return values
- todo!()
- };
- (
- out_spirv_type,
- self.get_or_add(b, SpirvType::Func(out_args, in_params.collect::<Vec<_>>())),
- )
- }
-
- fn get_or_add_constant(
- &mut self,
- b: &mut dr::Builder,
- typ: &ast::Type,
- init: &[u8],
- ) -> Result<spirv::Word, TranslateError> {
- Ok(match typ {
- ast::Type::Scalar(t) => match t {
- ast::ScalarType::B8 | ast::ScalarType::U8 | ast::ScalarType::S8 => self
- .get_or_add_constant_single::<u8, _, _>(
- b,
- *t,
- init,
- |v| v as u64,
- |b, result_type, v| b.constant_u32(result_type, None, v as u32),
- ),
- ast::ScalarType::B16 | ast::ScalarType::U16 | ast::ScalarType::S16 => self
- .get_or_add_constant_single::<u16, _, _>(
- b,
- *t,
- init,
- |v| v as u64,
- |b, result_type, v| b.constant_u32(result_type, None, v as u32),
- ),
- ast::ScalarType::B32 | ast::ScalarType::U32 | ast::ScalarType::S32 => self
- .get_or_add_constant_single::<u32, _, _>(
- b,
- *t,
- init,
- |v| v as u64,
- |b, result_type, v| b.constant_u32(result_type, None, v),
- ),
- ast::ScalarType::B64 | ast::ScalarType::U64 | ast::ScalarType::S64 => self
- .get_or_add_constant_single::<u64, _, _>(
- b,
- *t,
- init,
- |v| v,
- |b, result_type, v| b.constant_u64(result_type, None, v),
- ),
- ast::ScalarType::F16 => self.get_or_add_constant_single::<f16, _, _>(
- b,
- *t,
- init,
- |v| unsafe { mem::transmute::<_, u16>(v) } as u64,
- |b, result_type, v| b.constant_f32(result_type, None, v.to_f32()),
- ),
- ast::ScalarType::F32 => self.get_or_add_constant_single::<f32, _, _>(
- b,
- *t,
- init,
- |v| unsafe { mem::transmute::<_, u32>(v) } as u64,
- |b, result_type, v| b.constant_f32(result_type, None, v),
- ),
- ast::ScalarType::F64 => self.get_or_add_constant_single::<f64, _, _>(
- b,
- *t,
- init,
- |v| unsafe { mem::transmute::<_, u64>(v) },
- |b, result_type, v| b.constant_f64(result_type, None, v),
- ),
- ast::ScalarType::F16x2 => return Err(TranslateError::Todo),
- ast::ScalarType::Pred => self.get_or_add_constant_single::<u8, _, _>(
- b,
- *t,
- init,
- |v| v as u64,
- |b, result_type, v| {
- if v == 0 {
- b.constant_false(result_type, None)
- } else {
- b.constant_true(result_type, None)
- }
- },
- ),
- },
- ast::Type::Vector(typ, len) => {
- let result_type =
- self.get_or_add(b, SpirvType::Vector(SpirvScalarKey::from(*typ), *len));
- let size_of_t = typ.size_of();
- let components = (0..*len)
- .map(|x| {
- self.get_or_add_constant(
- b,
- &ast::Type::Scalar(*typ),
- &init[((size_of_t as usize) * (x as usize))..],
- )
- })
- .collect::<Result<Vec<_>, _>>()?;
- b.constant_composite(result_type, None, components.into_iter())
- }
- ast::Type::Array(typ, dims) => match dims.as_slice() {
- [] => return Err(error_unreachable()),
- [dim] => {
- let result_type = self
- .get_or_add(b, SpirvType::Array(SpirvScalarKey::from(*typ), vec![*dim]));
- let size_of_t = typ.size_of();
- let components = (0..*dim)
- .map(|x| {
- self.get_or_add_constant(
- b,
- &ast::Type::Scalar(*typ),
- &init[((size_of_t as usize) * (x as usize))..],
- )
- })
- .collect::<Result<Vec<_>, _>>()?;
- b.constant_composite(result_type, None, components.into_iter())
- }
- [first_dim, rest @ ..] => {
- let result_type = self.get_or_add(
- b,
- SpirvType::Array(SpirvScalarKey::from(*typ), rest.to_vec()),
- );
- let size_of_t = rest
- .iter()
- .fold(typ.size_of() as u32, |x, y| (x as u32) * (*y));
- let components = (0..*first_dim)
- .map(|x| {
- self.get_or_add_constant(
- b,
- &ast::Type::Array(*typ, rest.to_vec()),
- &init[((size_of_t as usize) * (x as usize))..],
- )
- })
- .collect::<Result<Vec<_>, _>>()?;
- b.constant_composite(result_type, None, components.into_iter())
- }
- },
- ast::Type::Pointer(..) => return Err(error_unreachable()),
- })
- }
-
- fn get_or_add_constant_single<
- T: Copy,
- CastAsU64: FnOnce(T) -> u64,
- InsertConstant: FnOnce(&mut dr::Builder, spirv::Word, T) -> spirv::Word,
- >(
- &mut self,
- b: &mut dr::Builder,
- key: ast::ScalarType,
- init: &[u8],
- cast: CastAsU64,
- f: InsertConstant,
- ) -> spirv::Word {
- let value = unsafe { *(init.as_ptr() as *const T) };
- let value_64 = cast(value);
- let ht_key = (SpirvType::Base(SpirvScalarKey::from(key)), value_64);
- match self.constants.get(&ht_key) {
- Some(value) => *value,
- None => {
- let spirv_type = self.get_or_add_scalar(b, key);
- let result = f(b, spirv_type, value);
- self.constants.insert(ht_key, result);
- result
- }
- }
- }
-}
-
-pub struct Module {
- pub spirv: dr::Module,
- pub kernel_info: HashMap<String, KernelInfo>,
- pub should_link_ptx_impl: Option<(&'static [u8], &'static [u8])>,
- pub build_options: CString,
-}
-impl Module {
- pub fn assemble(&self) -> Vec<u32> {
- self.spirv.assemble()
- }
-}
-
-pub struct KernelInfo {
- pub arguments_sizes: Vec<(usize, bool)>,
- pub uses_shared_mem: bool,
-}
-
-pub fn to_spirv_module<'input>(ast: ast::Module<'input>) -> Result<Module, TranslateError> {
- let mut id_defs = GlobalStringIdResolver::<'input>::new(1);
- let mut ptx_impl_imports = HashMap::new();
- let directives = ast
- .directives
- .into_iter()
- .filter_map(|directive| {
- translate_directive(&mut id_defs, &mut ptx_impl_imports, directive).transpose()
- })
- .collect::<Result<Vec<_>, _>>()?;
- let directives = hoist_function_globals(directives);
- let must_link_ptx_impl = ptx_impl_imports.len() > 0;
- let mut directives = ptx_impl_imports
- .into_iter()
- .map(|(_, v)| v)
- .chain(directives.into_iter())
- .collect::<Vec<_>>();
- let mut builder = dr::Builder::new();
- builder.reserve_ids(id_defs.current_id());
- let call_map = MethodsCallMap::new(&directives);
- let mut directives =
- convert_dynamic_shared_memory_usage(directives, &call_map, &mut || builder.id());
- normalize_variable_decls(&mut directives);
- let denorm_information = compute_denorm_information(&directives);
- // https://www.khronos.org/registry/spir-v/specs/unified1/SPIRV.html#_a_id_logicallayout_a_logical_layout_of_a_module
- builder.set_version(1, 3);
- emit_capabilities(&mut builder);
- emit_extensions(&mut builder);
- let opencl_id = emit_opencl_import(&mut builder);
- emit_memory_model(&mut builder);
- let mut map = TypeWordMap::new(&mut builder);
- //emit_builtins(&mut builder, &mut map, &id_defs);
- let mut kernel_info = HashMap::new();
- let (build_options, should_flush_denorms) =
- emit_denorm_build_string(&call_map, &denorm_information);
- let (directives, globals_use_map) = get_globals_use_map(directives);
- emit_directives(
- &mut builder,
- &mut map,
- &id_defs,
- opencl_id,
- should_flush_denorms,
- &call_map,
- globals_use_map,
- directives,
- &mut kernel_info,
- )?;
- let spirv = builder.module();
- Ok(Module {
- spirv,
- kernel_info,
- should_link_ptx_impl: if must_link_ptx_impl {
- Some((ZLUDA_PTX_IMPL_INTEL, ZLUDA_PTX_IMPL_AMD))
- } else {
- None
- },
- build_options,
- })
-}
-
-fn get_globals_use_map<'input>(
- directives: Vec<Directive<'input>>,
-) -> (
- Vec<Directive<'input>>,
- HashMap<ast::MethodName<'input, spirv::Word>, HashSet<spirv::Word>>,
-) {
- let mut known_globals = HashSet::new();
- for directive in directives.iter() {
- match directive {
- Directive::Variable(_, ast::Variable { name, .. }) => {
- known_globals.insert(*name);
- }
- Directive::Method(..) => {}
- }
- }
- let mut symbol_uses_map = HashMap::new();
- let directives = directives
- .into_iter()
- .map(|directive| match directive {
- Directive::Variable(..) | Directive::Method(Function { body: None, .. }) => directive,
- Directive::Method(Function {
- func_decl,
- body: Some(mut statements),
- globals,
- import_as,
- tuning,
- linkage,
- }) => {
- let method_name = func_decl.borrow().name;
- statements = statements
- .into_iter()
- .map(|statement| {
- statement.map_id(&mut |symbol, _| {
- if known_globals.contains(&symbol) {
- multi_hash_map_append(&mut symbol_uses_map, method_name, symbol);
- }
- symbol
- })
- })
- .collect::<Vec<_>>();
- Directive::Method(Function {
- func_decl,
- body: Some(statements),
- globals,
- import_as,
- tuning,
- linkage,
- })
- }
- })
- .collect::<Vec<_>>();
- (directives, symbol_uses_map)
-}
-
-fn hoist_function_globals(directives: Vec<Directive>) -> Vec<Directive> {
- let mut result = Vec::with_capacity(directives.len());
- for directive in directives {
- match directive {
- Directive::Method(method) => {
- for variable in method.globals {
- result.push(Directive::Variable(ast::LinkingDirective::NONE, variable));
- }
- result.push(Directive::Method(Function {
- globals: Vec::new(),
- ..method
- }))
- }
- _ => result.push(directive),
- }
- }
- result
-}
-
-// TODO: remove this once we have pef-function support for denorms
-fn emit_denorm_build_string<'input>(
- call_map: &MethodsCallMap,
- denorm_information: &HashMap<
- ast::MethodName<'input, spirv::Word>,
- HashMap<u8, (spirv::FPDenormMode, isize)>,
- >,
-) -> (CString, bool) {
- let denorm_counts = denorm_information
- .iter()
- .map(|(method, meth_denorm)| {
- let f16_count = meth_denorm
- .get(&(mem::size_of::<f16>() as u8))
- .unwrap_or(&(spirv::FPDenormMode::FlushToZero, 0))
- .1;
- let f32_count = meth_denorm
- .get(&(mem::size_of::<f32>() as u8))
- .unwrap_or(&(spirv::FPDenormMode::FlushToZero, 0))
- .1;
- (method, (f16_count + f32_count))
- })
- .collect::<HashMap<_, _>>();
- let mut flush_over_preserve = 0;
- for (kernel, children) in call_map.kernels() {
- flush_over_preserve += *denorm_counts
- .get(&ast::MethodName::Kernel(kernel))
- .unwrap_or(&0);
- for child_fn in children {
- flush_over_preserve += *denorm_counts
- .get(&ast::MethodName::Func(*child_fn))
- .unwrap_or(&0);
- }
- }
- if flush_over_preserve > 0 {
- (
- CString::new("-ze-take-global-address -ze-denorms-are-zero").unwrap(),
- true,
- )
- } else {
- (CString::new("-ze-take-global-address").unwrap(), false)
- }
-}
-
-fn emit_directives<'input>(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- id_defs: &GlobalStringIdResolver<'input>,
- opencl_id: spirv::Word,
- should_flush_denorms: bool,
- call_map: &MethodsCallMap<'input>,
- globals_use_map: HashMap<ast::MethodName<'input, spirv::Word>, HashSet<spirv::Word>>,
- directives: Vec<Directive<'input>>,
- kernel_info: &mut HashMap<String, KernelInfo>,
-) -> Result<(), TranslateError> {
- let empty_body = Vec::new();
- for d in directives.iter() {
- match d {
- Directive::Variable(linking, var) => {
- emit_variable(builder, map, id_defs, *linking, &var)?;
- }
- Directive::Method(f) => {
- let f_body = match &f.body {
- Some(f) => f,
- None => {
- if f.linkage.contains(ast::LinkingDirective::EXTERN) {
- &empty_body
- } else {
- continue;
- }
- }
- };
- for var in f.globals.iter() {
- emit_variable(builder, map, id_defs, ast::LinkingDirective::NONE, var)?;
- }
- let func_decl = (*f.func_decl).borrow();
- let fn_id = emit_function_header(
- builder,
- map,
- &id_defs,
- &*func_decl,
- call_map,
- &globals_use_map,
- kernel_info,
- )?;
- if func_decl.name.is_kernel() {
- if should_flush_denorms {
- builder.execution_mode(
- fn_id,
- spirv_headers::ExecutionMode::DenormFlushToZero,
- [16],
- );
- builder.execution_mode(
- fn_id,
- spirv_headers::ExecutionMode::DenormFlushToZero,
- [32],
- );
- builder.execution_mode(
- fn_id,
- spirv_headers::ExecutionMode::DenormFlushToZero,
- [64],
- );
- }
- // FP contraction happens when compiling source -> PTX and is illegal at this stage (unless you force it in cuModuleLoadDataEx)
- builder.execution_mode(fn_id, spirv_headers::ExecutionMode::ContractionOff, []);
- for t in f.tuning.iter() {
- match *t {
- ast::TuningDirective::MaxNtid(nx, ny, nz) => {
- builder.execution_mode(
- fn_id,
- spirv_headers::ExecutionMode::MaxWorkgroupSizeINTEL,
- [nx, ny, nz],
- );
- }
- ast::TuningDirective::ReqNtid(nx, ny, nz) => {
- builder.execution_mode(
- fn_id,
- spirv_headers::ExecutionMode::LocalSize,
- [nx, ny, nz],
- );
- }
- // Too architecture specific
- ast::TuningDirective::MaxNReg(..)
- | ast::TuningDirective::MinNCtaPerSm(..) => {}
- }
- }
- }
- emit_function_body_ops(builder, map, id_defs, opencl_id, &f_body)?;
- emit_function_linkage(builder, id_defs, f, fn_id)?;
- builder.select_block(None)?;
- builder.end_function()?;
- }
- }
- }
- Ok(())
-}
-
-fn emit_function_linkage<'input>(
- builder: &mut dr::Builder,
- id_defs: &GlobalStringIdResolver<'input>,
- f: &Function,
- fn_name: spirv::Word,
-) -> Result<(), TranslateError> {
- if f.linkage == ast::LinkingDirective::NONE {
- return Ok(());
- };
- let linking_name = match f.func_decl.borrow().name {
- // According to SPIR-V rules linkage attributes are invalid on kernels
- ast::MethodName::Kernel(..) => return Ok(()),
- ast::MethodName::Func(fn_id) => f.import_as.as_deref().map_or_else(
- || match id_defs.reverse_variables.get(&fn_id) {
- Some(fn_name) => Ok(fn_name),
- None => Err(error_unknown_symbol()),
- },
- Result::Ok,
- )?,
- };
- emit_linking_decoration(builder, id_defs, Some(linking_name), fn_name, f.linkage);
- Ok(())
-}
-
-struct MethodsCallMap<'input> {
- map: HashMap<ast::MethodName<'input, spirv::Word>, HashSet<spirv::Word>>,
-}
-
-impl<'input> MethodsCallMap<'input> {
- fn new(module: &[Directive<'input>]) -> Self {
- let mut directly_called_by = HashMap::new();
- for directive in module {
- match directive {
- Directive::Method(Function {
- func_decl,
- body: Some(statements),
- ..
- }) => {
- let call_key: ast::MethodName<_> = (**func_decl).borrow().name;
- if let hash_map::Entry::Vacant(entry) = directly_called_by.entry(call_key) {
- entry.insert(Vec::new());
- }
- for statement in statements {
- match statement {
- Statement::Call(call) => {
- multi_hash_map_append(&mut directly_called_by, call_key, call.name);
- }
- _ => {}
- }
- }
- }
- _ => {}
- }
- }
- let mut result = HashMap::new();
- for (&method_key, children) in directly_called_by.iter() {
- let mut visited = HashSet::new();
- for child in children {
- Self::add_call_map_single(&directly_called_by, &mut visited, *child);
- }
- result.insert(method_key, visited);
- }
- MethodsCallMap { map: result }
- }
-
- fn add_call_map_single(
- directly_called_by: &HashMap<ast::MethodName<'input, spirv::Word>, Vec<spirv::Word>>,
- visited: &mut HashSet<spirv::Word>,
- current: spirv::Word,
- ) {
- if !visited.insert(current) {
- return;
- }
- if let Some(children) = directly_called_by.get(&ast::MethodName::Func(current)) {
- for child in children {
- Self::add_call_map_single(directly_called_by, visited, *child);
- }
- }
- }
-
- fn get_kernel_children(&self, name: &'input str) -> impl Iterator<Item = &spirv::Word> {
- self.map
- .get(&ast::MethodName::Kernel(name))
- .into_iter()
- .flatten()
- }
-
- fn kernels(&self) -> impl Iterator<Item = (&'input str, &HashSet<spirv::Word>)> {
- self.map
- .iter()
- .filter_map(|(method, children)| match method {
- ast::MethodName::Kernel(kernel) => Some((*kernel, children)),
- ast::MethodName::Func(..) => None,
- })
- }
-
- fn methods(
- &self,
- ) -> impl Iterator<Item = (ast::MethodName<'input, spirv::Word>, &HashSet<spirv::Word>)> {
- self.map
- .iter()
- .map(|(method, children)| (*method, children))
- }
-
- fn visit_callees(
- &self,
- method: ast::MethodName<'input, spirv::Word>,
- f: impl FnMut(spirv::Word),
- ) {
- self.map
- .get(&method)
- .into_iter()
- .flatten()
- .copied()
- .for_each(f);
- }
-}
-
-fn multi_hash_map_append<
- K: Eq + std::hash::Hash,
- V,
- Collection: std::iter::Extend<V> + std::default::Default,
->(
- m: &mut HashMap<K, Collection>,
- key: K,
- value: V,
-) {
- match m.entry(key) {
- hash_map::Entry::Occupied(mut entry) => {
- entry.get_mut().extend(iter::once(value));
- }
- hash_map::Entry::Vacant(entry) => {
- entry.insert(Default::default()).extend(iter::once(value));
- }
- }
-}
-
-/*
- PTX represents dynamically allocated shared local memory as
- .extern .shared .b32 shared_mem[];
- In SPIRV/OpenCL world this is expressed as an additional argument to the kernel
- And in AMD compilation
- This pass looks for all uses of .extern .shared and converts them to
- an additional method argument
- The question is how this artificial argument should be expressed. There are
- several options:
- * Straight conversion:
- .shared .b32 shared_mem[]
- * Introduce .param_shared statespace:
- .param_shared .b32 shared_mem
- or
- .param_shared .b32 shared_mem[]
- * Introduce .shared_ptr <SCALAR> type:
- .param .shared_ptr .b32 shared_mem
- * Reuse .ptr hint:
- .param .u64 .ptr shared_mem
- This is the most tempting, but also the most nonsensical, .ptr is just a
- hint, which has no semantical meaning (and the output of our
- transformation has a semantical meaning - we emit additional
- "OpFunctionParameter ..." with type "OpTypePointer Workgroup ...")
-*/
-fn convert_dynamic_shared_memory_usage<'input>(
- module: Vec<Directive<'input>>,
- kernels_methods_call_map: &MethodsCallMap<'input>,
- new_id: &mut impl FnMut() -> spirv::Word,
-) -> Vec<Directive<'input>> {
- let mut globals_shared = HashMap::new();
- for dir in module.iter() {
- match dir {
- Directive::Variable(
- _,
- ast::Variable {
- state_space: ast::StateSpace::Shared,
- name,
- v_type,
- ..
- },
- ) => {
- globals_shared.insert(*name, v_type.clone());
- }
- _ => {}
- }
- }
- if globals_shared.len() == 0 {
- return module;
- }
- let mut methods_to_directly_used_shared_globals = HashMap::<_, HashSet<spirv::Word>>::new();
- let module = module
- .into_iter()
- .map(|directive| match directive {
- Directive::Method(Function {
- func_decl,
- globals,
- body: Some(statements),
- import_as,
- tuning,
- linkage,
- }) => {
- let call_key = (*func_decl).borrow().name;
- let statements = statements
- .into_iter()
- .map(|statement| {
- statement.map_id(&mut |id, _| {
- if let Some(type_) = globals_shared.get(&id) {
- methods_to_directly_used_shared_globals
- .entry(call_key)
- .or_insert_with(HashSet::new)
- .insert(id);
- }
- id
- })
- })
- .collect();
- Directive::Method(Function {
- func_decl,
- globals,
- body: Some(statements),
- import_as,
- tuning,
- linkage,
- })
- }
- directive => directive,
- })
- .collect::<Vec<_>>();
- // If there's a chain `kernel` -> `fn1` -> `fn2`, where only `fn2` uses extern shared,
- // make sure it gets propagated to `fn1` and `kernel`
- let methods_to_indirectly_used_shared_globals = resolve_indirect_uses_of_globals_shared(
- methods_to_directly_used_shared_globals,
- kernels_methods_call_map,
- );
- // now visit every method declaration and inject those additional arguments
- let mut directives = Vec::with_capacity(module.len());
- for directive in module.into_iter() {
- match directive {
- Directive::Method(Function {
- func_decl,
- globals,
- body: Some(statements),
- import_as,
- tuning,
- linkage,
- }) => {
- let statements = {
- let func_decl_ref = &mut (*func_decl).borrow_mut();
- let method_name = func_decl_ref.name;
- insert_arguments_remap_statements(
- new_id,
- kernels_methods_call_map,
- &globals_shared,
- &methods_to_indirectly_used_shared_globals,
- method_name,
- &mut directives,
- func_decl_ref,
- statements,
- )
- };
- directives.push(Directive::Method(Function {
- func_decl,
- globals,
- body: Some(statements),
- import_as,
- tuning,
- linkage,
- }));
- }
- directive => directives.push(directive),
- }
- }
- directives
-}
-
-fn insert_arguments_remap_statements<'input>(
- new_id: &mut impl FnMut() -> u32,
- kernels_methods_call_map: &MethodsCallMap<'input>,
- globals_shared: &HashMap<u32, ast::Type>,
- methods_to_indirectly_used_shared_globals: &HashMap<
- ast::MethodName<'input, spirv::Word>,
- BTreeSet<spirv::Word>,
- >,
- method_name: ast::MethodName<u32>,
- result: &mut Vec<Directive>,
- func_decl_ref: &mut std::cell::RefMut<ast::MethodDeclaration<u32>>,
- statements: Vec<Statement<ast::Instruction<ExpandedArgParams>, ExpandedArgParams>>,
-) -> Vec<Statement<ast::Instruction<ExpandedArgParams>, ExpandedArgParams>> {
- let remapped_globals_in_method =
- if let Some(method_globals) = methods_to_indirectly_used_shared_globals.get(&method_name) {
- match method_name {
- ast::MethodName::Func(..) => {
- let remapped_globals = method_globals
- .iter()
- .map(|global| {
- (
- *global,
- (
- new_id(),
- globals_shared
- .get(&global)
- .unwrap_or_else(|| todo!())
- .clone(),
- ),
- )
- })
- .collect::<BTreeMap<_, _>>();
- for (_, (new_shared_global_id, shared_global_type)) in remapped_globals.iter() {
- func_decl_ref.input_arguments.push(ast::Variable {
- align: None,
- v_type: shared_global_type.clone(),
- state_space: ast::StateSpace::Shared,
- name: *new_shared_global_id,
- array_init: Vec::new(),
- });
- }
- remapped_globals
- }
- ast::MethodName::Kernel(..) => method_globals
- .iter()
- .map(|global| {
- (
- *global,
- (
- *global,
- globals_shared
- .get(&global)
- .unwrap_or_else(|| todo!())
- .clone(),
- ),
- )
- })
- .collect::<BTreeMap<_, _>>(),
- }
- } else {
- return statements;
- };
- replace_uses_of_shared_memory(
- new_id,
- methods_to_indirectly_used_shared_globals,
- statements,
- remapped_globals_in_method,
- )
-}
-
-#[derive(Clone, Copy, PartialEq, Eq, Hash)]
-enum GlobalSharedSize {
- ExternUnsized,
- Sized(usize),
-}
-
-impl GlobalSharedSize {
- fn fold(self, other: GlobalSharedSize) -> GlobalSharedSize {
- match (self, other) {
- (GlobalSharedSize::Sized(s1), GlobalSharedSize::Sized(s2)) => {
- GlobalSharedSize::Sized(usize::max(s1, s2))
- }
- _ => GlobalSharedSize::ExternUnsized,
- }
- }
-}
-
-fn replace_uses_of_shared_memory<'input>(
- new_id: &mut impl FnMut() -> spirv::Word,
- methods_to_indirectly_used_shared_globals: &HashMap<
- ast::MethodName<'input, spirv::Word>,
- BTreeSet<spirv::Word>,
- >,
- statements: Vec<ExpandedStatement>,
- remapped_globals_in_method: BTreeMap<spirv::Word, (spirv::Word, ast::Type)>,
-) -> Vec<ExpandedStatement> {
- let mut result = Vec::with_capacity(statements.len());
- for statement in statements {
- match statement {
- Statement::Call(mut call) => {
- // We can safely skip checking call arguments,
- // because there's simply no way to pass shared ptr
- // without converting it to .b64 first
- if let Some(shared_globals_used_by_callee) =
- methods_to_indirectly_used_shared_globals.get(&ast::MethodName::Func(call.name))
- {
- for &shared_global_used_by_callee in shared_globals_used_by_callee {
- let (remapped_shared_id, type_) = remapped_globals_in_method
- .get(&shared_global_used_by_callee)
- .unwrap_or_else(|| todo!());
- call.input_arguments.push((
- *remapped_shared_id,
- type_.clone(),
- ast::StateSpace::Shared,
- ));
- }
- }
- result.push(Statement::Call(call))
- }
- statement => {
- let new_statement = statement.map_id(&mut |id, _| {
- if let Some((remapped_shared_id, _)) = remapped_globals_in_method.get(&id) {
- *remapped_shared_id
- } else {
- id
- }
- });
- result.push(new_statement);
- }
- }
- }
- result
-}
-
-// We need to compute two kinds of information:
-// * If it's a kernel -> size of .shared globals in use (direct or indirect)
-// * If it's a function -> does it use .shared global (directly or indirectly)
-fn resolve_indirect_uses_of_globals_shared<'input>(
- methods_use_of_globals_shared: HashMap<
- ast::MethodName<'input, spirv::Word>,
- HashSet<spirv::Word>,
- >,
- kernels_methods_call_map: &MethodsCallMap<'input>,
-) -> HashMap<ast::MethodName<'input, spirv::Word>, BTreeSet<spirv::Word>> {
- let mut result = HashMap::new();
- for (method, callees) in kernels_methods_call_map.methods() {
- let mut indirect_globals = methods_use_of_globals_shared
- .get(&method)
- .into_iter()
- .flatten()
- .copied()
- .collect::<BTreeSet<_>>();
- for &callee in callees {
- indirect_globals.extend(
- methods_use_of_globals_shared
- .get(&ast::MethodName::Func(callee))
- .into_iter()
- .flatten()
- .copied(),
- );
- }
- result.insert(method, indirect_globals);
- }
- result
-}
-
-type DenormCountMap<T> = HashMap<T, isize>;
-
-fn denorm_count_map_update<T: Eq + Hash>(map: &mut DenormCountMap<T>, key: T, value: bool) {
- let num_value = if value { 1 } else { -1 };
- denorm_count_map_update_impl(map, key, num_value);
-}
-
-fn denorm_count_map_update_impl<T: Eq + Hash>(
- map: &mut DenormCountMap<T>,
- key: T,
- num_value: isize,
-) {
- match map.entry(key) {
- hash_map::Entry::Occupied(mut counter) => {
- *(counter.get_mut()) += num_value;
- }
- hash_map::Entry::Vacant(entry) => {
- entry.insert(num_value);
- }
- }
-}
-
-// HACK ALERT!
-// This function is a "good enough" heuristic of whetever to mark f16/f32 operations
-// in the kernel as flushing denorms to zero or preserving them
-// PTX support per-instruction ftz information. Unfortunately SPIR-V has no
-// such capability, so instead we guesstimate which use is more common in the kernel
-// and emit suitable execution mode
-fn compute_denorm_information<'input>(
- module: &[Directive<'input>],
-) -> HashMap<ast::MethodName<'input, spirv::Word>, HashMap<u8, (spirv::FPDenormMode, isize)>> {
- let mut denorm_methods = HashMap::new();
- for directive in module {
- match directive {
- Directive::Variable(..) | Directive::Method(Function { body: None, .. }) => {}
- Directive::Method(Function {
- func_decl,
- body: Some(statements),
- ..
- }) => {
- let mut flush_counter = DenormCountMap::new();
- let method_key = (**func_decl).borrow().name;
- for statement in statements {
- match statement {
- Statement::Instruction(inst) => {
- if let Some((flush, width)) = inst.flush_to_zero() {
- denorm_count_map_update(&mut flush_counter, width, flush);
- }
- }
- Statement::LoadVar(..) => {}
- Statement::StoreVar(..) => {}
- Statement::Call(_) => {}
- Statement::Conditional(_) => {}
- Statement::Conversion(_) => {}
- Statement::Constant(_) => {}
- Statement::RetValue(_, _) => {}
- Statement::Label(_) => {}
- Statement::Variable(_) => {}
- Statement::PtrAccess { .. } => {}
- Statement::RepackVector(_) => {}
- Statement::FunctionPointer(_) => {}
- }
- }
- denorm_methods.insert(method_key, flush_counter);
- }
- }
- }
- denorm_methods
- .into_iter()
- .map(|(name, v)| {
- let width_to_denorm = v
- .into_iter()
- .map(|(k, flush_over_preserve)| {
- let mode = if flush_over_preserve > 0 {
- spirv::FPDenormMode::FlushToZero
- } else {
- spirv::FPDenormMode::Preserve
- };
- (k, (mode, flush_over_preserve))
- })
- .collect();
- (name, width_to_denorm)
- })
- .collect()
-}
-
-fn emit_function_header<'input>(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- defined_globals: &GlobalStringIdResolver<'input>,
- func_decl: &ast::MethodDeclaration<'input, spirv::Word>,
- call_map: &MethodsCallMap<'input>,
- globals_use_map: &HashMap<ast::MethodName<'input, spirv::Word>, HashSet<spirv::Word>>,
- kernel_info: &mut HashMap<String, KernelInfo>,
-) -> Result<spirv::Word, TranslateError> {
- if let ast::MethodName::Kernel(name) = func_decl.name {
- let args_lens = func_decl
- .input_arguments
- .iter()
- .map(|param| {
- (
- param.v_type.size_of(),
- matches!(param.v_type, ast::Type::Pointer(..)),
- )
- })
- .collect();
- kernel_info.insert(
- name.to_string(),
- KernelInfo {
- arguments_sizes: args_lens,
- uses_shared_mem: func_decl.shared_mem.is_some(),
- },
- );
- }
- let (ret_type, func_type) = get_function_type(
- builder,
- map,
- func_decl.effective_input_arguments().map(|(_, typ)| typ),
- &func_decl.return_arguments,
- );
- let fn_id = match func_decl.name {
- ast::MethodName::Kernel(name) => {
- let fn_id = defined_globals.get_id(name)?;
- let interface = globals_use_map
- .get(&ast::MethodName::Kernel(name))
- .into_iter()
- .flatten()
- .copied()
- .chain({
- call_map
- .get_kernel_children(name)
- .copied()
- .flat_map(|subfunction| {
- globals_use_map
- .get(&ast::MethodName::Func(subfunction))
- .into_iter()
- .flatten()
- .copied()
- })
- .into_iter()
- })
- .collect::<Vec<spirv::Word>>();
- builder.entry_point(spirv::ExecutionModel::Kernel, fn_id, name, interface);
- fn_id
- }
- ast::MethodName::Func(name) => name,
- };
- builder.begin_function(
- ret_type,
- Some(fn_id),
- spirv::FunctionControl::NONE,
- func_type,
- )?;
- for (name, typ) in func_decl.effective_input_arguments() {
- let result_type = map.get_or_add(builder, typ);
- builder.function_parameter(Some(name), result_type)?;
- }
- Ok(fn_id)
-}
-
-fn emit_capabilities(builder: &mut dr::Builder) {
- builder.capability(spirv::Capability::GenericPointer);
- builder.capability(spirv::Capability::Linkage);
- builder.capability(spirv::Capability::Addresses);
- builder.capability(spirv::Capability::Kernel);
- builder.capability(spirv::Capability::Int8);
- builder.capability(spirv::Capability::Int16);
- builder.capability(spirv::Capability::Int64);
- builder.capability(spirv::Capability::Float16);
- builder.capability(spirv::Capability::Float64);
- builder.capability(spirv::Capability::DenormFlushToZero);
- // TODO: re-enable when Intel float control extension works
- //builder.capability(spirv::Capability::FunctionFloatControlINTEL);
-}
-
-// http://htmlpreview.github.io/?https://github.com/KhronosGroup/SPIRV-Registry/blob/master/extensions/KHR/SPV_KHR_float_controls.html
-fn emit_extensions(builder: &mut dr::Builder) {
- // TODO: re-enable when Intel float control extension works
- //builder.extension("SPV_INTEL_float_controls2");
- builder.extension("SPV_KHR_float_controls");
- builder.extension("SPV_KHR_no_integer_wrap_decoration");
-}
-
-fn emit_opencl_import(builder: &mut dr::Builder) -> spirv::Word {
- builder.ext_inst_import("OpenCL.std")
-}
-
-fn emit_memory_model(builder: &mut dr::Builder) {
- builder.memory_model(
- spirv::AddressingModel::Physical64,
- spirv::MemoryModel::OpenCL,
- );
-}
-
-fn translate_directive<'input, 'a>(
- id_defs: &'a mut GlobalStringIdResolver<'input>,
- ptx_impl_imports: &'a mut HashMap<String, Directive<'input>>,
- d: ast::Directive<'input, ast::ParsedArgParams<'input>>,
-) -> Result<Option<Directive<'input>>, TranslateError> {
- Ok(match d {
- ast::Directive::Variable(linking, var) => Some(Directive::Variable(
- linking,
- ast::Variable {
- align: var.align,
- v_type: var.v_type.clone(),
- state_space: var.state_space,
- name: id_defs.get_or_add_def_typed(var.name, var.v_type, var.state_space, true),
- array_init: var.array_init,
- },
- )),
- ast::Directive::Method(linkage, f) => {
- translate_function(id_defs, ptx_impl_imports, linkage, f)?.map(Directive::Method)
- }
- })
-}
-
-fn translate_function<'input, 'a>(
- id_defs: &'a mut GlobalStringIdResolver<'input>,
- ptx_impl_imports: &'a mut HashMap<String, Directive<'input>>,
- linkage: ast::LinkingDirective,
- f: ast::ParsedFunction<'input>,
-) -> Result<Option<Function<'input>>, TranslateError> {
- let import_as = match &f.func_directive {
- ast::MethodDeclaration {
- name: ast::MethodName::Func(func_name),
- ..
- } if *func_name == "__assertfail" || *func_name == "vprintf" => {
- Some([ZLUDA_PTX_PREFIX, func_name].concat())
- }
- _ => None,
- };
- let (str_resolver, fn_resolver, fn_decl) = id_defs.start_fn(&f.func_directive)?;
- let mut func = to_ssa(
- ptx_impl_imports,
- str_resolver,
- fn_resolver,
- fn_decl,
- f.body,
- f.tuning,
- linkage,
- )?;
- func.import_as = import_as;
- if func.import_as.is_some() {
- ptx_impl_imports.insert(
- func.import_as.as_ref().unwrap().clone(),
- Directive::Method(func),
- );
- Ok(None)
- } else {
- Ok(Some(func))
- }
-}
-
-fn rename_fn_params<'a, 'b>(
- fn_resolver: &mut FnStringIdResolver<'a, 'b>,
- args: &'b [ast::Variable<&'a str>],
-) -> Vec<ast::Variable<spirv::Word>> {
- args.iter()
- .map(|a| ast::Variable {
- name: fn_resolver.add_def(a.name, Some((a.v_type.clone(), a.state_space)), true),
- v_type: a.v_type.clone(),
- state_space: a.state_space,
- align: a.align,
- array_init: a.array_init.clone(),
- })
- .collect()
-}
-
-fn to_ssa<'input, 'b>(
- ptx_impl_imports: &'b mut HashMap<String, Directive<'input>>,
- mut id_defs: FnStringIdResolver<'input, 'b>,
- fn_defs: GlobalFnDeclResolver<'input, 'b>,
- func_decl: Rc<RefCell<ast::MethodDeclaration<'input, spirv::Word>>>,
- f_body: Option<Vec<ast::Statement<ast::ParsedArgParams<'input>>>>,
- tuning: Vec<ast::TuningDirective>,
- linkage: ast::LinkingDirective,
-) -> Result<Function<'input>, TranslateError> {
- //deparamize_function_decl(&func_decl)?;
- let f_body = match f_body {
- Some(vec) => vec,
- None => {
- return Ok(Function {
- func_decl: func_decl,
- body: None,
- globals: Vec::new(),
- import_as: None,
- tuning,
- linkage,
- })
- }
- };
- let normalized_ids = normalize_identifiers(&mut id_defs, &fn_defs, f_body)?;
- let mut numeric_id_defs = id_defs.finish();
- let unadorned_statements = normalize_predicates(normalized_ids, &mut numeric_id_defs)?;
- let typed_statements =
- convert_to_typed_statements(unadorned_statements, &fn_defs, &mut numeric_id_defs)?;
- let typed_statements =
- fix_special_registers2(ptx_impl_imports, typed_statements, &mut numeric_id_defs)?;
- let (func_decl, typed_statements) =
- convert_to_stateful_memory_access(func_decl, typed_statements, &mut numeric_id_defs)?;
- let ssa_statements = insert_mem_ssa_statements(
- typed_statements,
- &mut numeric_id_defs,
- &mut (*func_decl).borrow_mut(),
- )?;
- let mut numeric_id_defs = numeric_id_defs.finish();
- let expanded_statements = expand_arguments(ssa_statements, &mut numeric_id_defs)?;
- let expanded_statements =
- insert_implicit_conversions(expanded_statements, &mut numeric_id_defs)?;
- let mut numeric_id_defs = numeric_id_defs.unmut();
- let labeled_statements = normalize_labels(expanded_statements, &mut numeric_id_defs);
- let (f_body, globals) =
- extract_globals(labeled_statements, ptx_impl_imports, &mut numeric_id_defs)?;
- Ok(Function {
- func_decl: func_decl,
- globals: globals,
- body: Some(f_body),
- import_as: None,
- tuning,
- linkage,
- })
-}
-
-fn fix_special_registers2<'a, 'b, 'input>(
- ptx_impl_imports: &'a mut HashMap<String, Directive<'input>>,
- typed_statements: Vec<TypedStatement>,
- numeric_id_defs: &'a mut NumericIdResolver<'b>,
-) -> Result<Vec<TypedStatement>, TranslateError> {
- let result = Vec::with_capacity(typed_statements.len());
- let mut sreg_sresolver = SpecialRegisterResolver {
- ptx_impl_imports,
- numeric_id_defs,
- result,
- };
- for s in typed_statements {
- match s {
- Statement::Call(details) => {
- let new_statement = details.visit(&mut sreg_sresolver)?;
- sreg_sresolver.result.push(new_statement);
- }
- Statement::Instruction(details) => {
- let new_statement = details.visit(&mut sreg_sresolver)?;
- sreg_sresolver.result.push(new_statement);
- }
- Statement::Conditional(details) => {
- let new_statement = details.visit(&mut sreg_sresolver)?;
- sreg_sresolver.result.push(new_statement);
- }
- Statement::Conversion(details) => {
- let new_statement = details.visit(&mut sreg_sresolver)?;
- sreg_sresolver.result.push(new_statement);
- }
- Statement::PtrAccess(details) => {
- let new_statement = details.visit(&mut sreg_sresolver)?;
- sreg_sresolver.result.push(new_statement);
- }
- Statement::RepackVector(details) => {
- let new_statement = details.visit(&mut sreg_sresolver)?;
- sreg_sresolver.result.push(new_statement);
- }
- s @ Statement::Variable(_)
- | s @ Statement::Label(_)
- | s @ Statement::FunctionPointer(_) => sreg_sresolver.result.push(s),
- _ => return Err(error_unreachable()),
- }
- }
- Ok(sreg_sresolver.result)
-}
-
-struct SpecialRegisterResolver<'a, 'b, 'input> {
- ptx_impl_imports: &'a mut HashMap<String, Directive<'input>>,
- numeric_id_defs: &'a mut NumericIdResolver<'b>,
- result: Vec<TypedStatement>,
-}
-
-impl<'a, 'b, 'input> SpecialRegisterResolver<'a, 'b, 'input> {
- fn replace_sreg(
- &mut self,
- desc: ArgumentDescriptor<spirv::Word>,
- vector_index: Option<u8>,
- ) -> Result<spirv::Word, TranslateError> {
- if let Some(sreg) = self.numeric_id_defs.special_registers.get(desc.op) {
- if desc.is_dst {
- return Err(TranslateError::MismatchedType);
- }
- let input_arguments = match (vector_index, sreg.get_function_input_type()) {
- (Some(idx), Some(inp_type)) => {
- if inp_type != ast::ScalarType::U8 {
- return Err(TranslateError::Unreachable);
- }
- let constant = self.numeric_id_defs.register_intermediate(Some((
- ast::Type::Scalar(inp_type),
- ast::StateSpace::Reg,
- )));
- self.result.push(Statement::Constant(ConstantDefinition {
- dst: constant,
- typ: inp_type,
- value: ast::ImmediateValue::U64(idx as u64),
- }));
- vec![(
- TypedOperand::Reg(constant),
- ast::Type::Scalar(inp_type),
- ast::StateSpace::Reg,
- )]
- }
- (None, None) => Vec::new(),
- _ => return Err(TranslateError::MismatchedType),
- };
- let ocl_fn_name = [ZLUDA_PTX_PREFIX, sreg.get_unprefixed_function_name()].concat();
- let return_type = sreg.get_function_return_type();
- let fn_result = self.numeric_id_defs.register_intermediate(Some((
- ast::Type::Scalar(return_type),
- ast::StateSpace::Reg,
- )));
- let return_arguments = vec![(
- fn_result,
- ast::Type::Scalar(return_type),
- ast::StateSpace::Reg,
- )];
- let fn_call = register_external_fn_call(
- self.numeric_id_defs,
- self.ptx_impl_imports,
- ocl_fn_name.to_string(),
- return_arguments.iter().map(|(_, typ, space)| (typ, *space)),
- input_arguments.iter().map(|(_, typ, space)| (typ, *space)),
- )?;
- self.result.push(Statement::Call(ResolvedCall {
- uniform: false,
- return_arguments,
- name: fn_call,
- input_arguments,
- }));
- Ok(fn_result)
- } else {
- Ok(desc.op)
- }
- }
-}
-
-impl<'a, 'b, 'input> ArgumentMapVisitor<TypedArgParams, TypedArgParams>
- for SpecialRegisterResolver<'a, 'b, 'input>
-{
- fn id(
- &mut self,
- desc: ArgumentDescriptor<spirv::Word>,
- _: Option<(&ast::Type, ast::StateSpace)>,
- ) -> Result<spirv::Word, TranslateError> {
- self.replace_sreg(desc, None)
- }
-
- fn operand(
- &mut self,
- desc: ArgumentDescriptor<TypedOperand>,
- typ: &ast::Type,
- state_space: ast::StateSpace,
- ) -> Result<TypedOperand, TranslateError> {
- Ok(match desc.op {
- TypedOperand::Reg(reg) => TypedOperand::Reg(self.replace_sreg(desc.new_op(reg), None)?),
- op @ TypedOperand::RegOffset(_, _) => op,
- op @ TypedOperand::Imm(_) => op,
- TypedOperand::VecMember(reg, idx) => {
- TypedOperand::VecMember(self.replace_sreg(desc.new_op(reg), Some(idx))?, idx)
- }
- })
- }
-}
-
-fn extract_globals<'input, 'b>(
- sorted_statements: Vec<ExpandedStatement>,
- ptx_impl_imports: &mut HashMap<String, Directive>,
- id_def: &mut NumericIdResolver,
-) -> Result<(Vec<ExpandedStatement>, Vec<ast::Variable<spirv::Word>>), TranslateError> {
- let mut local = Vec::with_capacity(sorted_statements.len());
- let mut global = Vec::new();
- for statement in sorted_statements {
- match statement {
- Statement::Variable(
- var @ ast::Variable {
- state_space: ast::StateSpace::Shared,
- ..
- },
- )
- | Statement::Variable(
- var @ ast::Variable {
- state_space: ast::StateSpace::Global,
- ..
- },
- ) => global.push(var),
- Statement::Instruction(ast::Instruction::Bfe { typ, arg }) => {
- let fn_name = [ZLUDA_PTX_PREFIX, "bfe_", typ.to_ptx_name()].concat();
- local.push(instruction_to_fn_call(
- id_def,
- ptx_impl_imports,
- ast::Instruction::Bfe { typ, arg },
- fn_name,
- )?);
- }
- Statement::Instruction(ast::Instruction::Bfi { typ, arg }) => {
- let fn_name = [ZLUDA_PTX_PREFIX, "bfi_", typ.to_ptx_name()].concat();
- local.push(instruction_to_fn_call(
- id_def,
- ptx_impl_imports,
- ast::Instruction::Bfi { typ, arg },
- fn_name,
- )?);
- }
- Statement::Instruction(ast::Instruction::Brev { typ, arg }) => {
- let fn_name = [ZLUDA_PTX_PREFIX, "brev_", typ.to_ptx_name()].concat();
- local.push(instruction_to_fn_call(
- id_def,
- ptx_impl_imports,
- ast::Instruction::Brev { typ, arg },
- fn_name,
- )?);
- }
- Statement::Instruction(ast::Instruction::Activemask { arg }) => {
- let fn_name = [ZLUDA_PTX_PREFIX, "activemask"].concat();
- local.push(instruction_to_fn_call(
- id_def,
- ptx_impl_imports,
- ast::Instruction::Activemask { arg },
- fn_name,
- )?);
- }
- Statement::Instruction(ast::Instruction::Atom(
- details @ ast::AtomDetails {
- inner:
- ast::AtomInnerDetails::Unsigned {
- op: ast::AtomUIntOp::Inc,
- ..
- },
- ..
- },
- args,
- )) => {
- let fn_name = [
- ZLUDA_PTX_PREFIX,
- "atom_",
- details.semantics.to_ptx_name(),
- "_",
- details.scope.to_ptx_name(),
- "_",
- details.space.to_ptx_name(),
- "_inc",
- ]
- .concat();
- local.push(instruction_to_fn_call(
- id_def,
- ptx_impl_imports,
- ast::Instruction::Atom(details, args),
- fn_name,
- )?);
- }
- Statement::Instruction(ast::Instruction::Atom(
- details @ ast::AtomDetails {
- inner:
- ast::AtomInnerDetails::Unsigned {
- op: ast::AtomUIntOp::Dec,
- ..
- },
- ..
- },
- args,
- )) => {
- let fn_name = [
- ZLUDA_PTX_PREFIX,
- "atom_",
- details.semantics.to_ptx_name(),
- "_",
- details.scope.to_ptx_name(),
- "_",
- details.space.to_ptx_name(),
- "_dec",
- ]
- .concat();
- local.push(instruction_to_fn_call(
- id_def,
- ptx_impl_imports,
- ast::Instruction::Atom(details, args),
- fn_name,
- )?);
- }
- Statement::Instruction(ast::Instruction::Atom(
- details @ ast::AtomDetails {
- inner:
- ast::AtomInnerDetails::Float {
- op: ast::AtomFloatOp::Add,
- ..
- },
- ..
- },
- args,
- )) => {
- let fn_name = [
- ZLUDA_PTX_PREFIX,
- "atom_",
- details.semantics.to_ptx_name(),
- "_",
- details.scope.to_ptx_name(),
- "_",
- details.space.to_ptx_name(),
- "_add_",
- details.inner.get_type().to_ptx_name(),
- ]
- .concat();
- local.push(instruction_to_fn_call(
- id_def,
- ptx_impl_imports,
- ast::Instruction::Atom(details, args),
- fn_name,
- )?);
- }
- s => local.push(s),
- }
- }
- Ok((local, global))
-}
-
-impl ast::ScalarType {
- fn to_ptx_name(self) -> &'static str {
- match self {
- ast::ScalarType::B8 => "b8",
- ast::ScalarType::B16 => "b16",
- ast::ScalarType::B32 => "b32",
- ast::ScalarType::B64 => "b64",
- ast::ScalarType::U8 => "u8",
- ast::ScalarType::U16 => "u16",
- ast::ScalarType::U32 => "u32",
- ast::ScalarType::U64 => "u64",
- ast::ScalarType::S8 => "s8",
- ast::ScalarType::S16 => "s16",
- ast::ScalarType::S32 => "s32",
- ast::ScalarType::S64 => "s64",
- ast::ScalarType::F16 => "f16",
- ast::ScalarType::F32 => "f32",
- ast::ScalarType::F64 => "f64",
- ast::ScalarType::F16x2 => "f16x2",
- ast::ScalarType::Pred => "pred",
- }
- }
-}
-
-impl ast::AtomSemantics {
- fn to_ptx_name(self) -> &'static str {
- match self {
- ast::AtomSemantics::Relaxed => "relaxed",
- ast::AtomSemantics::Acquire => "acquire",
- ast::AtomSemantics::Release => "release",
- ast::AtomSemantics::AcquireRelease => "acq_rel",
- }
- }
-}
-
-impl ast::MemScope {
- fn to_ptx_name(self) -> &'static str {
- match self {
- ast::MemScope::Cta => "cta",
- ast::MemScope::Gpu => "gpu",
- ast::MemScope::Sys => "sys",
- }
- }
-}
-
-impl ast::StateSpace {
- fn to_ptx_name(self) -> &'static str {
- match self {
- ast::StateSpace::Generic => "generic",
- ast::StateSpace::Global => "global",
- ast::StateSpace::Shared => "shared",
- ast::StateSpace::Reg => "reg",
- ast::StateSpace::Const => "const",
- ast::StateSpace::Local => "local",
- ast::StateSpace::Param => "param",
- ast::StateSpace::Sreg => "sreg",
- }
- }
-}
-
-fn normalize_variable_decls(directives: &mut Vec<Directive>) {
- for directive in directives {
- match directive {
- Directive::Method(Function {
- body: Some(func), ..
- }) => {
- func[1..].sort_by_key(|s| match s {
- Statement::Variable(_) => 0,
- _ => 1,
- });
- }
- _ => (),
- }
- }
-}
-
-fn convert_to_typed_statements(
- func: Vec<UnconditionalStatement>,
- fn_defs: &GlobalFnDeclResolver,
- id_defs: &mut NumericIdResolver,
-) -> Result<Vec<TypedStatement>, TranslateError> {
- let mut result = Vec::<TypedStatement>::with_capacity(func.len());
- for s in func {
- match s {
- Statement::Instruction(inst) => match inst {
- ast::Instruction::Mov(
- mov,
- ast::Arg2Mov {
- dst: ast::Operand::Reg(dst_reg),
- src: ast::Operand::Reg(src_reg),
- },
- ) if fn_defs.fns.contains_key(&src_reg) => {
- if mov.typ != ast::Type::Scalar(ast::ScalarType::U64) {
- return Err(TranslateError::MismatchedType);
- }
- result.push(TypedStatement::FunctionPointer(FunctionPointerDetails {
- dst: dst_reg,
- src: src_reg,
- }));
- }
- ast::Instruction::Call(call) => {
- let resolver = fn_defs.get_fn_sig_resolver(call.func)?;
- let resolved_call = resolver.resolve_in_spirv_repr(call)?;
- let mut visitor = VectorRepackVisitor::new(&mut result, id_defs);
- let reresolved_call = resolved_call.visit(&mut visitor)?;
- visitor.func.push(reresolved_call);
- visitor.func.extend(visitor.post_stmts);
- }
- inst => {
- let mut visitor = VectorRepackVisitor::new(&mut result, id_defs);
- let instruction = Statement::Instruction(inst.map(&mut visitor)?);
- visitor.func.push(instruction);
- visitor.func.extend(visitor.post_stmts);
- }
- },
- Statement::Label(i) => result.push(Statement::Label(i)),
- Statement::Variable(v) => result.push(Statement::Variable(v)),
- Statement::Conditional(c) => result.push(Statement::Conditional(c)),
- _ => return Err(error_unreachable()),
- }
- }
- Ok(result)
-}
-
-struct VectorRepackVisitor<'a, 'b> {
- func: &'b mut Vec<TypedStatement>,
- id_def: &'b mut NumericIdResolver<'a>,
- post_stmts: Option<TypedStatement>,
-}
-
-impl<'a, 'b> VectorRepackVisitor<'a, 'b> {
- fn new(func: &'b mut Vec<TypedStatement>, id_def: &'b mut NumericIdResolver<'a>) -> Self {
- VectorRepackVisitor {
- func,
- id_def,
- post_stmts: None,
- }
- }
-
- fn convert_vector(
- &mut self,
- is_dst: bool,
- non_default_implicit_conversion: Option<
- fn(
- (ast::StateSpace, &ast::Type),
- (ast::StateSpace, &ast::Type),
- ) -> Result<Option<ConversionKind>, TranslateError>,
- >,
- typ: &ast::Type,
- state_space: ast::StateSpace,
- idx: Vec<spirv::Word>,
- ) -> Result<spirv::Word, TranslateError> {
- // mov.u32 foobar, {a,b};
- let scalar_t = match typ {
- ast::Type::Vector(scalar_t, _) => *scalar_t,
- _ => return Err(TranslateError::MismatchedType),
- };
- let temp_vec = self
- .id_def
- .register_intermediate(Some((typ.clone(), state_space)));
- let statement = Statement::RepackVector(RepackVectorDetails {
- is_extract: is_dst,
- typ: scalar_t,
- packed: temp_vec,
- unpacked: idx,
- non_default_implicit_conversion,
- });
- if is_dst {
- self.post_stmts = Some(statement);
- } else {
- self.func.push(statement);
- }
- Ok(temp_vec)
- }
-}
-
-impl<'a, 'b> ArgumentMapVisitor<NormalizedArgParams, TypedArgParams>
- for VectorRepackVisitor<'a, 'b>
-{
- fn id(
- &mut self,
- desc: ArgumentDescriptor<spirv::Word>,
- _: Option<(&ast::Type, ast::StateSpace)>,
- ) -> Result<spirv::Word, TranslateError> {
- Ok(desc.op)
- }
-
- fn operand(
- &mut self,
- desc: ArgumentDescriptor<ast::Operand<spirv::Word>>,
- typ: &ast::Type,
- state_space: ast::StateSpace,
- ) -> Result<TypedOperand, TranslateError> {
- Ok(match desc.op {
- ast::Operand::Reg(reg) => TypedOperand::Reg(reg),
- ast::Operand::RegOffset(reg, offset) => TypedOperand::RegOffset(reg, offset),
- ast::Operand::Imm(x) => TypedOperand::Imm(x),
- ast::Operand::VecMember(vec, idx) => TypedOperand::VecMember(vec, idx),
- ast::Operand::VecPack(vec) => TypedOperand::Reg(self.convert_vector(
- desc.is_dst,
- desc.non_default_implicit_conversion,
- typ,
- state_space,
- vec,
- )?),
- })
- }
-}
-
-fn instruction_to_fn_call(
- id_defs: &mut NumericIdResolver,
- ptx_impl_imports: &mut HashMap<String, Directive>,
- inst: ast::Instruction<ExpandedArgParams>,
- fn_name: String,
-) -> Result<ExpandedStatement, TranslateError> {
- let mut arguments = Vec::new();
- inst.visit(&mut |desc: ArgumentDescriptor<spirv::Word>,
- typ: Option<(&ast::Type, ast::StateSpace)>| {
- let (typ, space) = match typ {
- Some((typ, space)) => (typ.clone(), space),
- None => return Err(error_unreachable()),
- };
- arguments.push((desc, typ, space));
- Ok(0)
- })?;
- let return_arguments_count = arguments
- .iter()
- .position(|(desc, _, _)| !desc.is_dst)
- .unwrap_or(arguments.len());
- let (return_arguments, input_arguments) = arguments.split_at(return_arguments_count);
- let fn_id = register_external_fn_call(
- id_defs,
- ptx_impl_imports,
- fn_name,
- return_arguments.iter().map(|(_, typ, state)| (typ, *state)),
- input_arguments.iter().map(|(_, typ, state)| (typ, *state)),
- )?;
- Ok(Statement::Call(ResolvedCall {
- uniform: false,
- name: fn_id,
- return_arguments: arguments_to_resolved_arguments(return_arguments),
- input_arguments: arguments_to_resolved_arguments(input_arguments),
- }))
-}
-
-fn register_external_fn_call<'a>(
- id_defs: &mut NumericIdResolver,
- ptx_impl_imports: &mut HashMap<String, Directive>,
- name: String,
- return_arguments: impl Iterator<Item = (&'a ast::Type, ast::StateSpace)>,
- input_arguments: impl Iterator<Item = (&'a ast::Type, ast::StateSpace)>,
-) -> Result<spirv::Word, TranslateError> {
- match ptx_impl_imports.entry(name) {
- hash_map::Entry::Vacant(entry) => {
- let fn_id = id_defs.register_intermediate(None);
- let return_arguments = fn_arguments_to_variables(id_defs, return_arguments);
- let input_arguments = fn_arguments_to_variables(id_defs, input_arguments);
- let func_decl = ast::MethodDeclaration::<spirv::Word> {
- return_arguments,
- name: ast::MethodName::Func(fn_id),
- input_arguments,
- shared_mem: None,
- };
- let func = Function {
- func_decl: Rc::new(RefCell::new(func_decl)),
- globals: Vec::new(),
- body: None,
- import_as: Some(entry.key().clone()),
- tuning: Vec::new(),
- linkage: ast::LinkingDirective::EXTERN,
- };
- entry.insert(Directive::Method(func));
- Ok(fn_id)
- }
- hash_map::Entry::Occupied(entry) => match entry.get() {
- Directive::Method(Function { func_decl, .. }) => match (**func_decl).borrow().name {
- ast::MethodName::Func(fn_id) => Ok(fn_id),
- ast::MethodName::Kernel(_) => Err(error_unreachable()),
- },
- _ => Err(error_unreachable()),
- },
- }
-}
-
-fn fn_arguments_to_variables<'a>(
- id_defs: &mut NumericIdResolver,
- args: impl Iterator<Item = (&'a ast::Type, ast::StateSpace)>,
-) -> Vec<ast::Variable<spirv::Word>> {
- args.map(|(typ, space)| ast::Variable {
- align: None,
- v_type: typ.clone(),
- state_space: space,
- name: id_defs.register_intermediate(None),
- array_init: Vec::new(),
- })
- .collect::<Vec<_>>()
-}
-
-fn arguments_to_resolved_arguments(
- args: &[(ArgumentDescriptor<spirv::Word>, ast::Type, ast::StateSpace)],
-) -> Vec<(spirv::Word, ast::Type, ast::StateSpace)> {
- args.iter()
- .map(|(desc, typ, space)| (desc.op, typ.clone(), *space))
- .collect::<Vec<_>>()
-}
-
-fn normalize_labels(
- func: Vec<ExpandedStatement>,
- id_def: &mut NumericIdResolver,
-) -> Vec<ExpandedStatement> {
- let mut labels_in_use = HashSet::new();
- for s in func.iter() {
- match s {
- Statement::Instruction(i) => {
- if let Some(target) = i.jump_target() {
- labels_in_use.insert(target);
- }
- }
- Statement::Conditional(cond) => {
- labels_in_use.insert(cond.if_true);
- labels_in_use.insert(cond.if_false);
- }
- Statement::Call(..)
- | Statement::Variable(..)
- | Statement::LoadVar(..)
- | Statement::StoreVar(..)
- | Statement::RetValue(..)
- | Statement::Conversion(..)
- | Statement::Constant(..)
- | Statement::Label(..)
- | Statement::PtrAccess { .. }
- | Statement::RepackVector(..)
- | Statement::FunctionPointer(..) => {}
- }
- }
- iter::once(Statement::Label(id_def.register_intermediate(None)))
- .chain(func.into_iter().filter(|s| match s {
- Statement::Label(i) => labels_in_use.contains(i),
- _ => true,
- }))
- .collect::<Vec<_>>()
-}
-
-fn normalize_predicates(
- func: Vec<NormalizedStatement>,
- id_def: &mut NumericIdResolver,
-) -> Result<Vec<UnconditionalStatement>, TranslateError> {
- let mut result = Vec::with_capacity(func.len());
- for s in func {
- match s {
- Statement::Label(id) => result.push(Statement::Label(id)),
- Statement::Instruction((pred, inst)) => {
- if let Some(pred) = pred {
- let if_true = id_def.register_intermediate(None);
- let if_false = id_def.register_intermediate(None);
- let folded_bra = match &inst {
- ast::Instruction::Bra(_, arg) => Some(arg.src),
- _ => None,
- };
- let mut branch = BrachCondition {
- predicate: pred.label,
- if_true: folded_bra.unwrap_or(if_true),
- if_false,
- };
- if pred.not {
- std::mem::swap(&mut branch.if_true, &mut branch.if_false);
- }
- result.push(Statement::Conditional(branch));
- if folded_bra.is_none() {
- result.push(Statement::Label(if_true));
- result.push(Statement::Instruction(inst));
- }
- result.push(Statement::Label(if_false));
- } else {
- result.push(Statement::Instruction(inst));
- }
- }
- Statement::Variable(var) => result.push(Statement::Variable(var)),
- // Blocks are flattened when resolving ids
- _ => return Err(error_unreachable()),
- }
- }
- Ok(result)
-}
-
-/*
- How do we handle arguments:
- - input .params in kernels
- .param .b64 in_arg
- get turned into this SPIR-V:
- %1 = OpFunctionParameter %ulong
- %2 = OpVariable %_ptr_Function_ulong Function
- OpStore %2 %1
- We do this for two reasons. One, common treatment for argument-declared
- .param variables and .param variables inside function (we assume that
- at SPIR-V level every .param is a pointer in Function storage class)
- - input .params in functions
- .param .b64 in_arg
- get turned into this SPIR-V:
- %1 = OpFunctionParameter %_ptr_Function_ulong
- - input .regs
- .reg .b64 in_arg
- get turned into the same SPIR-V as kernel .params:
- %1 = OpFunctionParameter %ulong
- %2 = OpVariable %_ptr_Function_ulong Function
- OpStore %2 %1
- - output .regs
- .reg .b64 out_arg
- get just a variable declaration:
- %2 = OpVariable %%_ptr_Function_ulong Function
- - output .params don't exist, they have been moved to input positions
- by an earlier pass
- Distinguishing betweem kernel .params and function .params is not the
- cleanest solution. Alternatively, we could "deparamize" all kernel .param
- arguments by turning them into .reg arguments like this:
- .param .b64 arg -> .reg ptr<.b64,.param> arg
- This has the massive downside that this transformation would have to run
- very early and would muddy up already difficult code. It's simpler to just
- have an if here
-*/
-fn insert_mem_ssa_statements<'a, 'b>(
- func: Vec<TypedStatement>,
- id_def: &mut NumericIdResolver,
- fn_decl: &'a mut ast::MethodDeclaration<'b, spirv::Word>,
-) -> Result<Vec<TypedStatement>, TranslateError> {
- let mut result = Vec::with_capacity(func.len());
- for arg in fn_decl.input_arguments.iter_mut() {
- insert_mem_ssa_argument(id_def, &mut result, arg, fn_decl.name.is_kernel());
- }
- for arg in fn_decl.return_arguments.iter() {
- insert_mem_ssa_argument_reg_return(&mut result, arg);
- }
- for s in func {
- match s {
- Statement::Call(call) => {
- insert_mem_ssa_statement_default(id_def, &mut result, call.cast())?
- }
- Statement::Instruction(inst) => match inst {
- ast::Instruction::Ret(d) => {
- // TODO: handle multiple output args
- match &fn_decl.return_arguments[..] {
- [return_reg] => {
- let new_id = id_def.register_intermediate(Some((
- return_reg.v_type.clone(),
- ast::StateSpace::Reg,
- )));
- result.push(Statement::LoadVar(LoadVarDetails {
- arg: ast::Arg2 {
- dst: new_id,
- src: return_reg.name,
- },
- // TODO: ret with stateful conversion
- state_space: ast::StateSpace::Reg,
- typ: return_reg.v_type.clone(),
- member_index: None,
- }));
- result.push(Statement::RetValue(d, new_id));
- }
- [] => result.push(Statement::Instruction(ast::Instruction::Ret(d))),
- _ => unimplemented!(),
- }
- }
- inst => insert_mem_ssa_statement_default(id_def, &mut result, inst)?,
- },
- Statement::Conditional(bra) => {
- insert_mem_ssa_statement_default(id_def, &mut result, bra)?
- }
- Statement::Conversion(conv) => {
- insert_mem_ssa_statement_default(id_def, &mut result, conv)?
- }
- Statement::PtrAccess(ptr_access) => {
- insert_mem_ssa_statement_default(id_def, &mut result, ptr_access)?
- }
- Statement::RepackVector(repack) => {
- insert_mem_ssa_statement_default(id_def, &mut result, repack)?
- }
- Statement::FunctionPointer(func_ptr) => {
- insert_mem_ssa_statement_default(id_def, &mut result, func_ptr)?
- }
- s @ Statement::Variable(_) | s @ Statement::Label(_) | s @ Statement::Constant(..) => {
- result.push(s)
- }
- _ => return Err(error_unreachable()),
- }
- }
- Ok(result)
-}
-
-fn insert_mem_ssa_argument(
- id_def: &mut NumericIdResolver,
- func: &mut Vec<TypedStatement>,
- arg: &mut ast::Variable<spirv::Word>,
- is_kernel: bool,
-) {
- if !is_kernel && arg.state_space == ast::StateSpace::Param {
- return;
- }
- let new_id = id_def.register_intermediate(Some((arg.v_type.clone(), arg.state_space)));
- func.push(Statement::Variable(ast::Variable {
- align: arg.align,
- v_type: arg.v_type.clone(),
- state_space: ast::StateSpace::Reg,
- name: arg.name,
- array_init: Vec::new(),
- }));
- func.push(Statement::StoreVar(StoreVarDetails {
- arg: ast::Arg2St {
- src1: arg.name,
- src2: new_id,
- },
- typ: arg.v_type.clone(),
- member_index: None,
- }));
- arg.name = new_id;
-}
-
-fn insert_mem_ssa_argument_reg_return(
- func: &mut Vec<TypedStatement>,
- arg: &ast::Variable<spirv::Word>,
-) {
- func.push(Statement::Variable(ast::Variable {
- align: arg.align,
- v_type: arg.v_type.clone(),
- state_space: arg.state_space,
- name: arg.name,
- array_init: arg.array_init.clone(),
- }));
-}
-
-trait Visitable<From: ArgParamsEx, To: ArgParamsEx>: Sized {
- fn visit(
- self,
- visitor: &mut impl ArgumentMapVisitor<From, To>,
- ) -> Result<Statement<ast::Instruction<To>, To>, TranslateError>;
-}
-
-struct VisitArgumentDescriptor<
- 'a,
- Ctor: FnOnce(spirv::Word) -> Statement<ast::Instruction<U>, U>,
- U: ArgParamsEx,
-> {
- desc: ArgumentDescriptor<spirv::Word>,
- typ: &'a ast::Type,
- state_space: ast::StateSpace,
- stmt_ctor: Ctor,
-}
-
-impl<
- 'a,
- Ctor: FnOnce(spirv::Word) -> Statement<ast::Instruction<U>, U>,
- T: ArgParamsEx<Id = spirv::Word>,
- U: ArgParamsEx<Id = spirv::Word>,
- > Visitable<T, U> for VisitArgumentDescriptor<'a, Ctor, U>
-{
- fn visit(
- self,
- visitor: &mut impl ArgumentMapVisitor<T, U>,
- ) -> Result<Statement<ast::Instruction<U>, U>, TranslateError> {
- Ok((self.stmt_ctor)(
- visitor.id(self.desc, Some((self.typ, self.state_space)))?,
- ))
- }
-}
-
-struct InsertMemSSAVisitor<'a, 'input> {
- id_def: &'a mut NumericIdResolver<'input>,
- func: &'a mut Vec<TypedStatement>,
- post_statements: Vec<TypedStatement>,
-}
-
-impl<'a, 'input> InsertMemSSAVisitor<'a, 'input> {
- fn symbol(
- &mut self,
- desc: ArgumentDescriptor<(spirv::Word, Option<u8>)>,
- expected: Option<(&ast::Type, ast::StateSpace)>,
- ) -> Result<spirv::Word, TranslateError> {
- let symbol = desc.op.0;
- if expected.is_none() {
- return Ok(symbol);
- };
- let (mut var_type, var_space, is_variable) = self.id_def.get_typed(symbol)?;
- if !var_space.is_compatible(ast::StateSpace::Reg) || !is_variable {
- return Ok(symbol);
- };
- let member_index = match desc.op.1 {
- Some(idx) => {
- let vector_width = match var_type {
- ast::Type::Vector(scalar_t, width) => {
- var_type = ast::Type::Scalar(scalar_t);
- width
- }
- _ => return Err(TranslateError::MismatchedType),
- };
- Some((
- idx,
- if self.id_def.special_registers.get(symbol).is_some() {
- Some(vector_width)
- } else {
- None
- },
- ))
- }
- None => None,
- };
- let generated_id = self
- .id_def
- .register_intermediate(Some((var_type.clone(), ast::StateSpace::Reg)));
- if !desc.is_dst {
- self.func.push(Statement::LoadVar(LoadVarDetails {
- arg: Arg2 {
- dst: generated_id,
- src: symbol,
- },
- state_space: ast::StateSpace::Reg,
- typ: var_type,
- member_index,
- }));
- } else {
- self.post_statements
- .push(Statement::StoreVar(StoreVarDetails {
- arg: Arg2St {
- src1: symbol,
- src2: generated_id,
- },
- typ: var_type,
- member_index: member_index.map(|(idx, _)| idx),
- }));
- }
- Ok(generated_id)
- }
-}
-
-impl<'a, 'input> ArgumentMapVisitor<TypedArgParams, TypedArgParams>
- for InsertMemSSAVisitor<'a, 'input>
-{
- fn id(
- &mut self,
- desc: ArgumentDescriptor<spirv::Word>,
- typ: Option<(&ast::Type, ast::StateSpace)>,
- ) -> Result<spirv::Word, TranslateError> {
- self.symbol(desc.new_op((desc.op, None)), typ)
- }
-
- fn operand(
- &mut self,
- desc: ArgumentDescriptor<TypedOperand>,
- typ: &ast::Type,
- state_space: ast::StateSpace,
- ) -> Result<TypedOperand, TranslateError> {
- Ok(match desc.op {
- TypedOperand::Reg(reg) => {
- TypedOperand::Reg(self.symbol(desc.new_op((reg, None)), Some((typ, state_space)))?)
- }
- TypedOperand::RegOffset(reg, offset) => TypedOperand::RegOffset(
- self.symbol(desc.new_op((reg, None)), Some((typ, state_space)))?,
- offset,
- ),
- op @ TypedOperand::Imm(..) => op,
- TypedOperand::VecMember(symbol, index) => TypedOperand::Reg(
- self.symbol(desc.new_op((symbol, Some(index))), Some((typ, state_space)))?,
- ),
- })
- }
-}
-
-fn insert_mem_ssa_statement_default<'a, 'input, S: Visitable<TypedArgParams, TypedArgParams>>(
- id_def: &'a mut NumericIdResolver<'input>,
- func: &'a mut Vec<TypedStatement>,
- stmt: S,
-) -> Result<(), TranslateError> {
- let mut visitor = InsertMemSSAVisitor {
- id_def,
- func,
- post_statements: Vec::new(),
- };
- let new_stmt = stmt.visit(&mut visitor)?;
- visitor.func.push(new_stmt);
- visitor.func.extend(visitor.post_statements);
- Ok(())
-}
-
-fn expand_arguments<'a, 'b>(
- func: Vec<TypedStatement>,
- id_def: &'b mut MutableNumericIdResolver<'a>,
-) -> Result<Vec<ExpandedStatement>, TranslateError> {
- let mut result = Vec::with_capacity(func.len());
- for s in func {
- match s {
- Statement::Call(call) => {
- let mut visitor = FlattenArguments::new(&mut result, id_def);
- let (new_call, post_stmts) = (call.map(&mut visitor)?, visitor.post_stmts);
- result.push(Statement::Call(new_call));
- result.extend(post_stmts);
- }
- Statement::Instruction(inst) => {
- let mut visitor = FlattenArguments::new(&mut result, id_def);
- let (new_inst, post_stmts) = (inst.map(&mut visitor)?, visitor.post_stmts);
- result.push(Statement::Instruction(new_inst));
- result.extend(post_stmts);
- }
- Statement::Variable(ast::Variable {
- align,
- v_type,
- state_space,
- name,
- array_init,
- }) => result.push(Statement::Variable(ast::Variable {
- align,
- v_type,
- state_space,
- name,
- array_init,
- })),
- Statement::PtrAccess(ptr_access) => {
- let mut visitor = FlattenArguments::new(&mut result, id_def);
- let (new_inst, post_stmts) = (ptr_access.map(&mut visitor)?, visitor.post_stmts);
- result.push(Statement::PtrAccess(new_inst));
- result.extend(post_stmts);
- }
- Statement::RepackVector(repack) => {
- let mut visitor = FlattenArguments::new(&mut result, id_def);
- let (new_inst, post_stmts) = (repack.map(&mut visitor)?, visitor.post_stmts);
- result.push(Statement::RepackVector(new_inst));
- result.extend(post_stmts);
- }
- Statement::Label(id) => result.push(Statement::Label(id)),
- Statement::Conditional(bra) => result.push(Statement::Conditional(bra)),
- Statement::LoadVar(details) => result.push(Statement::LoadVar(details)),
- Statement::StoreVar(details) => result.push(Statement::StoreVar(details)),
- Statement::RetValue(d, id) => result.push(Statement::RetValue(d, id)),
- Statement::Conversion(conv) => result.push(Statement::Conversion(conv)),
- Statement::Constant(c) => result.push(Statement::Constant(c)),
- Statement::FunctionPointer(d) => result.push(Statement::FunctionPointer(d)),
- }
- }
- Ok(result)
-}
-
-struct FlattenArguments<'a, 'b> {
- func: &'b mut Vec<ExpandedStatement>,
- id_def: &'b mut MutableNumericIdResolver<'a>,
- post_stmts: Vec<ExpandedStatement>,
-}
-
-impl<'a, 'b> FlattenArguments<'a, 'b> {
- fn new(
- func: &'b mut Vec<ExpandedStatement>,
- id_def: &'b mut MutableNumericIdResolver<'a>,
- ) -> Self {
- FlattenArguments {
- func,
- id_def,
- post_stmts: Vec::new(),
- }
- }
-
- fn reg(
- &mut self,
- desc: ArgumentDescriptor<spirv::Word>,
- _: Option<(&ast::Type, ast::StateSpace)>,
- ) -> Result<spirv::Word, TranslateError> {
- Ok(desc.op)
- }
-
- fn reg_offset(
- &mut self,
- desc: ArgumentDescriptor<(spirv::Word, i32)>,
- typ: &ast::Type,
- state_space: ast::StateSpace,
- ) -> Result<spirv::Word, TranslateError> {
- let (reg, offset) = desc.op;
- if !desc.is_memory_access {
- let (reg_type, reg_space) = self.id_def.get_typed(reg)?;
- if !reg_space.is_compatible(ast::StateSpace::Reg) {
- return Err(TranslateError::MismatchedType);
- }
- let reg_scalar_type = match reg_type {
- ast::Type::Scalar(underlying_type) => underlying_type,
- _ => return Err(TranslateError::MismatchedType),
- };
- let id_constant_stmt = self
- .id_def
- .register_intermediate(reg_type.clone(), ast::StateSpace::Reg);
- self.func.push(Statement::Constant(ConstantDefinition {
- dst: id_constant_stmt,
- typ: reg_scalar_type,
- value: ast::ImmediateValue::S64(offset as i64),
- }));
- let arith_details = match reg_scalar_type.kind() {
- ast::ScalarKind::Signed => ast::ArithDetails::Signed(ast::ArithSInt {
- typ: reg_scalar_type,
- saturate: false,
- }),
- ast::ScalarKind::Unsigned | ast::ScalarKind::Bit => {
- ast::ArithDetails::Unsigned(reg_scalar_type)
- }
- _ => return Err(error_unreachable()),
- };
- let id_add_result = self.id_def.register_intermediate(reg_type, state_space);
- self.func.push(Statement::Instruction(ast::Instruction::Add(
- arith_details,
- ast::Arg3 {
- dst: id_add_result,
- src1: reg,
- src2: id_constant_stmt,
- },
- )));
- Ok(id_add_result)
- } else {
- let id_constant_stmt = self.id_def.register_intermediate(
- ast::Type::Scalar(ast::ScalarType::S64),
- ast::StateSpace::Reg,
- );
- self.func.push(Statement::Constant(ConstantDefinition {
- dst: id_constant_stmt,
- typ: ast::ScalarType::S64,
- value: ast::ImmediateValue::S64(offset as i64),
- }));
- let dst = self.id_def.register_intermediate(typ.clone(), state_space);
- self.func.push(Statement::PtrAccess(PtrAccess {
- underlying_type: typ.clone(),
- state_space: state_space,
- dst,
- ptr_src: reg,
- offset_src: id_constant_stmt,
- }));
- Ok(dst)
- }
- }
-
- fn immediate(
- &mut self,
- desc: ArgumentDescriptor<ast::ImmediateValue>,
- typ: &ast::Type,
- state_space: ast::StateSpace,
- ) -> Result<spirv::Word, TranslateError> {
- let scalar_t = if let ast::Type::Scalar(scalar) = typ {
- *scalar
- } else {
- todo!()
- };
- let id = self
- .id_def
- .register_intermediate(ast::Type::Scalar(scalar_t), state_space);
- self.func.push(Statement::Constant(ConstantDefinition {
- dst: id,
- typ: scalar_t,
- value: desc.op,
- }));
- Ok(id)
- }
-}
-
-impl<'a, 'b> ArgumentMapVisitor<TypedArgParams, ExpandedArgParams> for FlattenArguments<'a, 'b> {
- fn id(
- &mut self,
- desc: ArgumentDescriptor<spirv::Word>,
- t: Option<(&ast::Type, ast::StateSpace)>,
- ) -> Result<spirv::Word, TranslateError> {
- self.reg(desc, t)
- }
-
- fn operand(
- &mut self,
- desc: ArgumentDescriptor<TypedOperand>,
- typ: &ast::Type,
- state_space: ast::StateSpace,
- ) -> Result<spirv::Word, TranslateError> {
- match desc.op {
- TypedOperand::Reg(r) => self.reg(desc.new_op(r), Some((typ, state_space))),
- TypedOperand::Imm(x) => self.immediate(desc.new_op(x), typ, state_space),
- TypedOperand::RegOffset(reg, offset) => {
- self.reg_offset(desc.new_op((reg, offset)), typ, state_space)
- }
- TypedOperand::VecMember(..) => Err(error_unreachable()),
- }
- }
-}
-
-/*
- There are several kinds of implicit conversions in PTX:
- * auto-bitcast: https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#type-information-for-instructions-and-operands
- * special ld/st/cvt conversion rules: https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#operand-size-exceeding-instruction-type-size
- - ld.param: not documented, but for instruction `ld.param.<type> x, [y]`,
- semantics are to first zext/chop/bitcast `y` as needed and then do
- documented special ld/st/cvt conversion rules for destination operands
- - st.param [x] y (used as function return arguments) same rule as above applies
- - generic/global ld: for instruction `ld x, [y]`, y must be of type
- b64/u64/s64, which is bitcast to a pointer, dereferenced and then
- documented special ld/st/cvt conversion rules are applied to dst
- - generic/global st: for instruction `st [x], y`, x must be of type
- b64/u64/s64, which is bitcast to a pointer
-*/
-fn insert_implicit_conversions(
- func: Vec<ExpandedStatement>,
- id_def: &mut MutableNumericIdResolver,
-) -> Result<Vec<ExpandedStatement>, TranslateError> {
- let mut result = Vec::with_capacity(func.len());
- for s in func.into_iter() {
- match s {
- Statement::Call(call) => {
- insert_implicit_conversions_impl(&mut result, id_def, call)?;
- }
- Statement::Instruction(inst) => {
- insert_implicit_conversions_impl(&mut result, id_def, inst)?;
- }
- Statement::PtrAccess(access) => {
- insert_implicit_conversions_impl(&mut result, id_def, access)?;
- }
- Statement::RepackVector(repack) => {
- insert_implicit_conversions_impl(&mut result, id_def, repack)?;
- }
- s @ Statement::Conditional(_)
- | s @ Statement::Conversion(_)
- | s @ Statement::Label(_)
- | s @ Statement::Constant(_)
- | s @ Statement::Variable(_)
- | s @ Statement::LoadVar(..)
- | s @ Statement::StoreVar(..)
- | s @ Statement::RetValue(..)
- | s @ Statement::FunctionPointer(..) => result.push(s),
- }
- }
- Ok(result)
-}
-
-fn insert_implicit_conversions_impl(
- func: &mut Vec<ExpandedStatement>,
- id_def: &mut MutableNumericIdResolver,
- stmt: impl Visitable<ExpandedArgParams, ExpandedArgParams>,
-) -> Result<(), TranslateError> {
- let mut post_conv = Vec::new();
- let statement =
- stmt.visit(&mut |desc: ArgumentDescriptor<spirv::Word>,
- typ: Option<(&ast::Type, ast::StateSpace)>| {
- let (instr_type, instruction_space) = match typ {
- None => return Ok(desc.op),
- Some(t) => t,
- };
- let (operand_type, operand_space) = id_def.get_typed(desc.op)?;
- let conversion_fn = desc
- .non_default_implicit_conversion
- .unwrap_or(default_implicit_conversion);
- match conversion_fn(
- (operand_space, &operand_type),
- (instruction_space, instr_type),
- )? {
- Some(conv_kind) => {
- let conv_output = if desc.is_dst {
- &mut post_conv
- } else {
- &mut *func
- };
- let mut from_type = instr_type.clone();
- let mut from_space = instruction_space;
- let mut to_type = operand_type;
- let mut to_space = operand_space;
- let mut src =
- id_def.register_intermediate(instr_type.clone(), instruction_space);
- let mut dst = desc.op;
- let result = Ok(src);
- if !desc.is_dst {
- mem::swap(&mut src, &mut dst);
- mem::swap(&mut from_type, &mut to_type);
- mem::swap(&mut from_space, &mut to_space);
- }
- conv_output.push(Statement::Conversion(ImplicitConversion {
- src,
- dst,
- from_type,
- from_space,
- to_type,
- to_space,
- kind: conv_kind,
- }));
- result
- }
- None => Ok(desc.op),
- }
- })?;
- func.push(statement);
- func.append(&mut post_conv);
- Ok(())
-}
-
-fn get_function_type(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- spirv_input: impl Iterator<Item = SpirvType>,
- spirv_output: &[ast::Variable<spirv::Word>],
-) -> (spirv::Word, spirv::Word) {
- map.get_or_add_fn(
- builder,
- spirv_input,
- spirv_output
- .iter()
- .map(|var| SpirvType::new(var.v_type.clone())),
- )
-}
-
-fn emit_function_body_ops<'input>(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- id_defs: &GlobalStringIdResolver<'input>,
- opencl: spirv::Word,
- func: &[ExpandedStatement],
-) -> Result<(), TranslateError> {
- for s in func {
- match s {
- Statement::Label(id) => {
- if builder.selected_block().is_some() {
- builder.branch(*id)?;
- }
- builder.begin_block(Some(*id))?;
- }
- _ => {
- if builder.selected_block().is_none() && builder.selected_function().is_some() {
- builder.begin_block(None)?;
- }
- }
- }
- match s {
- Statement::Label(_) => (),
- Statement::Call(call) => {
- let (result_type, result_id) = match &*call.return_arguments {
- [(id, typ, space)] => {
- if *space != ast::StateSpace::Reg {
- return Err(error_unreachable());
- }
- (
- map.get_or_add(builder, SpirvType::new(typ.clone())),
- Some(*id),
- )
- }
- [] => (map.void(), None),
- _ => todo!(),
- };
- let arg_list = call
- .input_arguments
- .iter()
- .map(|(id, _, _)| *id)
- .collect::<Vec<_>>();
- builder.function_call(result_type, result_id, call.name, arg_list)?;
- }
- Statement::Variable(var) => {
- emit_variable(builder, map, id_defs, ast::LinkingDirective::NONE, var)?;
- }
- Statement::Constant(cnst) => {
- let typ_id = map.get_or_add_scalar(builder, cnst.typ);
- match (cnst.typ, cnst.value) {
- (ast::ScalarType::B8, ast::ImmediateValue::U64(value))
- | (ast::ScalarType::U8, ast::ImmediateValue::U64(value)) => {
- builder.constant_u32(typ_id, Some(cnst.dst), value as u8 as u32);
- }
- (ast::ScalarType::B16, ast::ImmediateValue::U64(value))
- | (ast::ScalarType::U16, ast::ImmediateValue::U64(value)) => {
- builder.constant_u32(typ_id, Some(cnst.dst), value as u16 as u32);
- }
- (ast::ScalarType::B32, ast::ImmediateValue::U64(value))
- | (ast::ScalarType::U32, ast::ImmediateValue::U64(value)) => {
- builder.constant_u32(typ_id, Some(cnst.dst), value as u32);
- }
- (ast::ScalarType::B64, ast::ImmediateValue::U64(value))
- | (ast::ScalarType::U64, ast::ImmediateValue::U64(value)) => {
- builder.constant_u64(typ_id, Some(cnst.dst), value);
- }
- (ast::ScalarType::S8, ast::ImmediateValue::U64(value)) => {
- builder.constant_u32(typ_id, Some(cnst.dst), value as i8 as u32);
- }
- (ast::ScalarType::S16, ast::ImmediateValue::U64(value)) => {
- builder.constant_u32(typ_id, Some(cnst.dst), value as i16 as u32);
- }
- (ast::ScalarType::S32, ast::ImmediateValue::U64(value)) => {
- builder.constant_u32(typ_id, Some(cnst.dst), value as i32 as u32);
- }
- (ast::ScalarType::S64, ast::ImmediateValue::U64(value)) => {
- builder.constant_u64(typ_id, Some(cnst.dst), value as i64 as u64);
- }
- (ast::ScalarType::B8, ast::ImmediateValue::S64(value))
- | (ast::ScalarType::U8, ast::ImmediateValue::S64(value)) => {
- builder.constant_u32(typ_id, Some(cnst.dst), value as u8 as u32);
- }
- (ast::ScalarType::B16, ast::ImmediateValue::S64(value))
- | (ast::ScalarType::U16, ast::ImmediateValue::S64(value)) => {
- builder.constant_u32(typ_id, Some(cnst.dst), value as u16 as u32);
- }
- (ast::ScalarType::B32, ast::ImmediateValue::S64(value))
- | (ast::ScalarType::U32, ast::ImmediateValue::S64(value)) => {
- builder.constant_u32(typ_id, Some(cnst.dst), value as u32);
- }
- (ast::ScalarType::B64, ast::ImmediateValue::S64(value))
- | (ast::ScalarType::U64, ast::ImmediateValue::S64(value)) => {
- builder.constant_u64(typ_id, Some(cnst.dst), value as u64);
- }
- (ast::ScalarType::S8, ast::ImmediateValue::S64(value)) => {
- builder.constant_u32(typ_id, Some(cnst.dst), value as i8 as u32);
- }
- (ast::ScalarType::S16, ast::ImmediateValue::S64(value)) => {
- builder.constant_u32(typ_id, Some(cnst.dst), value as i16 as u32);
- }
- (ast::ScalarType::S32, ast::ImmediateValue::S64(value)) => {
- builder.constant_u32(typ_id, Some(cnst.dst), value as i32 as u32);
- }
- (ast::ScalarType::S64, ast::ImmediateValue::S64(value)) => {
- builder.constant_u64(typ_id, Some(cnst.dst), value as u64);
- }
- (ast::ScalarType::F16, ast::ImmediateValue::F32(value)) => {
- builder.constant_f32(typ_id, Some(cnst.dst), f16::from_f32(value).to_f32());
- }
- (ast::ScalarType::F32, ast::ImmediateValue::F32(value)) => {
- builder.constant_f32(typ_id, Some(cnst.dst), value);
- }
- (ast::ScalarType::F64, ast::ImmediateValue::F32(value)) => {
- builder.constant_f64(typ_id, Some(cnst.dst), value as f64);
- }
- (ast::ScalarType::F16, ast::ImmediateValue::F64(value)) => {
- builder.constant_f32(typ_id, Some(cnst.dst), f16::from_f64(value).to_f32());
- }
- (ast::ScalarType::F32, ast::ImmediateValue::F64(value)) => {
- builder.constant_f32(typ_id, Some(cnst.dst), value as f32);
- }
- (ast::ScalarType::F64, ast::ImmediateValue::F64(value)) => {
- builder.constant_f64(typ_id, Some(cnst.dst), value);
- }
- (ast::ScalarType::Pred, ast::ImmediateValue::U64(value)) => {
- let bool_type = map.get_or_add_scalar(builder, ast::ScalarType::Pred);
- if value == 0 {
- builder.constant_false(bool_type, Some(cnst.dst));
- } else {
- builder.constant_true(bool_type, Some(cnst.dst));
- }
- }
- (ast::ScalarType::Pred, ast::ImmediateValue::S64(value)) => {
- let bool_type = map.get_or_add_scalar(builder, ast::ScalarType::Pred);
- if value == 0 {
- builder.constant_false(bool_type, Some(cnst.dst));
- } else {
- builder.constant_true(bool_type, Some(cnst.dst));
- }
- }
- _ => return Err(TranslateError::MismatchedType),
- }
- }
- Statement::Conversion(cv) => emit_implicit_conversion(builder, map, cv)?,
- Statement::Conditional(bra) => {
- builder.branch_conditional(
- bra.predicate,
- bra.if_true,
- bra.if_false,
- iter::empty(),
- )?;
- }
- Statement::FunctionPointer(FunctionPointerDetails { dst, src }) => {
- // TODO: implement properly
- let zero = map.get_or_add_constant(
- builder,
- &ast::Type::Scalar(ast::ScalarType::U64),
- &vec_repr(0u64),
- )?;
- let result_type = map.get_or_add_scalar(builder, ast::ScalarType::U64);
- builder.copy_object(result_type, Some(*dst), zero)?;
- }
- Statement::Instruction(inst) => match inst {
- ast::Instruction::Abs(d, arg) => emit_abs(builder, map, opencl, d, arg)?,
- ast::Instruction::Call(_) => unreachable!(),
- // SPIR-V does not support marking jumps as guaranteed-converged
- ast::Instruction::Bra(_, arg) => {
- builder.branch(arg.src)?;
- }
- ast::Instruction::Ld(data, arg) => {
- let mem_access = match data.qualifier {
- ast::LdStQualifier::Weak => spirv::MemoryAccess::NONE,
- // ld.volatile does not match Volatile OpLoad nor Relaxed OpAtomicLoad
- ast::LdStQualifier::Volatile => spirv::MemoryAccess::VOLATILE,
- _ => return Err(TranslateError::Todo),
- };
- let result_type =
- map.get_or_add(builder, SpirvType::new(ast::Type::from(data.typ.clone())));
- builder.load(
- result_type,
- Some(arg.dst),
- arg.src,
- Some(mem_access | spirv::MemoryAccess::ALIGNED),
- [dr::Operand::LiteralInt32(
- ast::Type::from(data.typ.clone()).size_of() as u32,
- )]
- .iter()
- .cloned(),
- )?;
- }
- ast::Instruction::St(data, arg) => {
- let mem_access = match data.qualifier {
- ast::LdStQualifier::Weak => spirv::MemoryAccess::NONE,
- // st.volatile does not match Volatile OpStore nor Relaxed OpAtomicStore
- ast::LdStQualifier::Volatile => spirv::MemoryAccess::VOLATILE,
- _ => return Err(TranslateError::Todo),
- };
- builder.store(
- arg.src1,
- arg.src2,
- Some(mem_access | spirv::MemoryAccess::ALIGNED),
- [dr::Operand::LiteralInt32(
- ast::Type::from(data.typ.clone()).size_of() as u32,
- )]
- .iter()
- .cloned(),
- )?;
- }
- // SPIR-V does not support ret as guaranteed-converged
- ast::Instruction::Ret(_) => builder.ret()?,
- ast::Instruction::Mov(d, arg) => {
- let result_type =
- map.get_or_add(builder, SpirvType::new(ast::Type::from(d.typ.clone())));
- builder.copy_object(result_type, Some(arg.dst), arg.src)?;
- }
- ast::Instruction::Mul(mul, arg) => match mul {
- ast::MulDetails::Signed(ref ctr) => {
- emit_mul_sint(builder, map, opencl, ctr, arg)?
- }
- ast::MulDetails::Unsigned(ref ctr) => {
- emit_mul_uint(builder, map, opencl, ctr, arg)?
- }
- ast::MulDetails::Float(ref ctr) => emit_mul_float(builder, map, ctr, arg)?,
- },
- ast::Instruction::Add(add, arg) => match add {
- ast::ArithDetails::Signed(ref desc) => {
- emit_add_int(builder, map, desc.typ.into(), desc.saturate, arg)?
- }
- ast::ArithDetails::Unsigned(ref desc) => {
- emit_add_int(builder, map, (*desc).into(), false, arg)?
- }
- ast::ArithDetails::Float(desc) => emit_add_float(builder, map, desc, arg)?,
- },
- ast::Instruction::Setp(setp, arg) => {
- if arg.dst2.is_some() {
- todo!()
- }
- emit_setp(builder, map, setp, arg)?;
- }
- ast::Instruction::Not(t, a) => {
- let result_type = map.get_or_add(builder, SpirvType::from(*t));
- let result_id = Some(a.dst);
- let operand = a.src;
- match t {
- ast::ScalarType::Pred => {
- logical_not(builder, result_type, result_id, operand)
- }
- _ => builder.not(result_type, result_id, operand),
- }?;
- }
- ast::Instruction::Shl(t, a) => {
- let full_type = ast::Type::Scalar(*t);
- let size_of = full_type.size_of();
- let result_type = map.get_or_add(builder, SpirvType::new(full_type));
- let offset_src = insert_shift_hack(builder, map, a.src2, size_of)?;
- builder.shift_left_logical(result_type, Some(a.dst), a.src1, offset_src)?;
- }
- ast::Instruction::Shr(t, a) => {
- let full_type = ast::ScalarType::from(*t);
- let size_of = full_type.size_of();
- let result_type = map.get_or_add_scalar(builder, full_type);
- let offset_src = insert_shift_hack(builder, map, a.src2, size_of as usize)?;
- if t.kind() == ast::ScalarKind::Signed {
- builder.shift_right_arithmetic(
- result_type,
- Some(a.dst),
- a.src1,
- offset_src,
- )?;
- } else {
- builder.shift_right_logical(
- result_type,
- Some(a.dst),
- a.src1,
- offset_src,
- )?;
- }
- }
- ast::Instruction::Cvt(dets, arg) => {
- emit_cvt(builder, map, opencl, dets, arg)?;
- }
- ast::Instruction::Cvta(_, arg) => {
- // This would be only meaningful if const/slm/global pointers
- // had a different format than generic pointers, but they don't pretty much by ptx definition
- // Honestly, I have no idea why this instruction exists and is emitted by the compiler
- let result_type = map.get_or_add_scalar(builder, ast::ScalarType::B64);
- builder.copy_object(result_type, Some(arg.dst), arg.src)?;
- }
- ast::Instruction::SetpBool(_, _) => todo!(),
- ast::Instruction::Mad(mad, arg) => match mad {
- ast::MulDetails::Signed(ref desc) => {
- emit_mad_sint(builder, map, opencl, desc, arg)?
- }
- ast::MulDetails::Unsigned(ref desc) => {
- emit_mad_uint(builder, map, opencl, desc, arg)?
- }
- ast::MulDetails::Float(desc) => {
- emit_mad_float(builder, map, opencl, desc, arg)?
- }
- },
- ast::Instruction::Fma(fma, arg) => emit_fma_float(builder, map, opencl, fma, arg)?,
- ast::Instruction::Or(t, a) => {
- let result_type = map.get_or_add_scalar(builder, ast::ScalarType::from(*t));
- if *t == ast::ScalarType::Pred {
- builder.logical_or(result_type, Some(a.dst), a.src1, a.src2)?;
- } else {
- builder.bitwise_or(result_type, Some(a.dst), a.src1, a.src2)?;
- }
- }
- ast::Instruction::Sub(d, arg) => match d {
- ast::ArithDetails::Signed(desc) => {
- emit_sub_int(builder, map, desc.typ.into(), desc.saturate, arg)?;
- }
- ast::ArithDetails::Unsigned(desc) => {
- emit_sub_int(builder, map, (*desc).into(), false, arg)?;
- }
- ast::ArithDetails::Float(desc) => {
- emit_sub_float(builder, map, desc, arg)?;
- }
- },
- ast::Instruction::Min(d, a) => {
- emit_min(builder, map, opencl, d, a)?;
- }
- ast::Instruction::Max(d, a) => {
- emit_max(builder, map, opencl, d, a)?;
- }
- ast::Instruction::Rcp(d, a) => {
- emit_rcp(builder, map, opencl, d, a)?;
- }
- ast::Instruction::And(t, a) => {
- let result_type = map.get_or_add_scalar(builder, ast::ScalarType::from(*t));
- if *t == ast::ScalarType::Pred {
- builder.logical_and(result_type, Some(a.dst), a.src1, a.src2)?;
- } else {
- builder.bitwise_and(result_type, Some(a.dst), a.src1, a.src2)?;
- }
- }
- ast::Instruction::Selp(t, a) => {
- let result_type = map.get_or_add_scalar(builder, ast::ScalarType::from(*t));
- builder.select(result_type, Some(a.dst), a.src3, a.src1, a.src2)?;
- }
- // TODO: implement named barriers
- ast::Instruction::Bar(d, _) => {
- let workgroup_scope = map.get_or_add_constant(
- builder,
- &ast::Type::Scalar(ast::ScalarType::U32),
- &vec_repr(spirv::Scope::Workgroup as u32),
- )?;
- let barrier_semantics = match d {
- ast::BarDetails::SyncAligned => map.get_or_add_constant(
- builder,
- &ast::Type::Scalar(ast::ScalarType::U32),
- &vec_repr(
- spirv::MemorySemantics::CROSS_WORKGROUP_MEMORY
- | spirv::MemorySemantics::WORKGROUP_MEMORY
- | spirv::MemorySemantics::SEQUENTIALLY_CONSISTENT,
- ),
- )?,
- };
- builder.control_barrier(workgroup_scope, workgroup_scope, barrier_semantics)?;
- }
- ast::Instruction::Atom(details, arg) => {
- emit_atom(builder, map, details, arg)?;
- }
- ast::Instruction::AtomCas(details, arg) => {
- let result_type = map.get_or_add_scalar(builder, details.typ.into());
- let memory_const = map.get_or_add_constant(
- builder,
- &ast::Type::Scalar(ast::ScalarType::U32),
- &vec_repr(details.scope.to_spirv() as u32),
- )?;
- let semantics_const = map.get_or_add_constant(
- builder,
- &ast::Type::Scalar(ast::ScalarType::U32),
- &vec_repr(details.semantics.to_spirv().bits()),
- )?;
- builder.atomic_compare_exchange(
- result_type,
- Some(arg.dst),
- arg.src1,
- memory_const,
- semantics_const,
- semantics_const,
- arg.src3,
- arg.src2,
- )?;
- }
- ast::Instruction::Div(details, arg) => match details {
- ast::DivDetails::Unsigned(t) => {
- let result_type = map.get_or_add_scalar(builder, (*t).into());
- builder.u_div(result_type, Some(arg.dst), arg.src1, arg.src2)?;
- }
- ast::DivDetails::Signed(t) => {
- let result_type = map.get_or_add_scalar(builder, (*t).into());
- builder.s_div(result_type, Some(arg.dst), arg.src1, arg.src2)?;
- }
- ast::DivDetails::Float(t) => {
- let result_type = map.get_or_add_scalar(builder, t.typ.into());
- builder.f_div(result_type, Some(arg.dst), arg.src1, arg.src2)?;
- emit_float_div_decoration(builder, arg.dst, t.kind);
- }
- },
- ast::Instruction::Sqrt(details, a) => {
- emit_sqrt(builder, map, opencl, details, a)?;
- }
- ast::Instruction::Rsqrt(details, a) => {
- let result_type = map.get_or_add_scalar(builder, details.typ.into());
- builder.ext_inst(
- result_type,
- Some(a.dst),
- opencl,
- spirv::CLOp::rsqrt as spirv::Word,
- [dr::Operand::IdRef(a.src)].iter().cloned(),
- )?;
- }
- ast::Instruction::Neg(details, arg) => {
- let result_type = map.get_or_add_scalar(builder, details.typ);
- let negate_func = if details.typ.kind() == ast::ScalarKind::Float {
- dr::Builder::f_negate
- } else {
- dr::Builder::s_negate
- };
- negate_func(builder, result_type, Some(arg.dst), arg.src)?;
- }
- ast::Instruction::Sin { arg, .. } => {
- let result_type = map.get_or_add_scalar(builder, ast::ScalarType::F32);
- builder.ext_inst(
- result_type,
- Some(arg.dst),
- opencl,
- spirv::CLOp::sin as u32,
- [dr::Operand::IdRef(arg.src)].iter().cloned(),
- )?;
- }
- ast::Instruction::Cos { arg, .. } => {
- let result_type = map.get_or_add_scalar(builder, ast::ScalarType::F32);
- builder.ext_inst(
- result_type,
- Some(arg.dst),
- opencl,
- spirv::CLOp::cos as u32,
- [dr::Operand::IdRef(arg.src)].iter().cloned(),
- )?;
- }
- ast::Instruction::Lg2 { arg, .. } => {
- let result_type = map.get_or_add_scalar(builder, ast::ScalarType::F32);
- builder.ext_inst(
- result_type,
- Some(arg.dst),
- opencl,
- spirv::CLOp::log2 as u32,
- [dr::Operand::IdRef(arg.src)].iter().cloned(),
- )?;
- }
- ast::Instruction::Ex2 { arg, .. } => {
- let result_type = map.get_or_add_scalar(builder, ast::ScalarType::F32);
- builder.ext_inst(
- result_type,
- Some(arg.dst),
- opencl,
- spirv::CLOp::exp2 as u32,
- [dr::Operand::IdRef(arg.src)].iter().cloned(),
- )?;
- }
- ast::Instruction::Clz { typ, arg } => {
- let result_type = map.get_or_add_scalar(builder, (*typ).into());
- builder.ext_inst(
- result_type,
- Some(arg.dst),
- opencl,
- spirv::CLOp::clz as u32,
- [dr::Operand::IdRef(arg.src)].iter().cloned(),
- )?;
- }
- ast::Instruction::Brev { typ, arg } => {
- let result_type = map.get_or_add_scalar(builder, (*typ).into());
- builder.bit_reverse(result_type, Some(arg.dst), arg.src)?;
- }
- ast::Instruction::Popc { typ, arg } => {
- let result_type = map.get_or_add_scalar(builder, (*typ).into());
- builder.bit_count(result_type, Some(arg.dst), arg.src)?;
- }
- ast::Instruction::Xor { typ, arg } => {
- let builder_fn = match typ {
- ast::ScalarType::Pred => emit_logical_xor_spirv,
- _ => dr::Builder::bitwise_xor,
- };
- let result_type = map.get_or_add_scalar(builder, (*typ).into());
- builder_fn(builder, result_type, Some(arg.dst), arg.src1, arg.src2)?;
- }
- ast::Instruction::Bfe { .. }
- | ast::Instruction::Bfi { .. }
- | ast::Instruction::Activemask { .. } => {
- // Should have beeen replaced with a funciton call earlier
- return Err(error_unreachable());
- }
-
- ast::Instruction::Rem { typ, arg } => {
- let builder_fn = if typ.kind() == ast::ScalarKind::Signed {
- dr::Builder::s_mod
- } else {
- dr::Builder::u_mod
- };
- let result_type = map.get_or_add_scalar(builder, (*typ).into());
- builder_fn(builder, result_type, Some(arg.dst), arg.src1, arg.src2)?;
- }
- ast::Instruction::Prmt { control, arg } => {
- let control = *control as u32;
- let components = [
- (control >> 0) & 0b1111,
- (control >> 4) & 0b1111,
- (control >> 8) & 0b1111,
- (control >> 12) & 0b1111,
- ];
- if components.iter().any(|&c| c > 7) {
- return Err(TranslateError::Todo);
- }
- let vec4_b8_type =
- map.get_or_add(builder, SpirvType::Vector(SpirvScalarKey::B8, 4));
- let b32_type = map.get_or_add_scalar(builder, ast::ScalarType::B32);
- let src1_vector = builder.bitcast(vec4_b8_type, None, arg.src1)?;
- let src2_vector = builder.bitcast(vec4_b8_type, None, arg.src2)?;
- let dst_vector = builder.vector_shuffle(
- vec4_b8_type,
- None,
- src1_vector,
- src2_vector,
- components,
- )?;
- builder.bitcast(b32_type, Some(arg.dst), dst_vector)?;
- }
- ast::Instruction::Membar { level } => {
- let (scope, semantics) = match level {
- ast::MemScope::Cta => (
- spirv::Scope::Workgroup,
- spirv::MemorySemantics::CROSS_WORKGROUP_MEMORY
- | spirv::MemorySemantics::WORKGROUP_MEMORY
- | spirv::MemorySemantics::SEQUENTIALLY_CONSISTENT,
- ),
- ast::MemScope::Gpu => (
- spirv::Scope::Device,
- spirv::MemorySemantics::CROSS_WORKGROUP_MEMORY
- | spirv::MemorySemantics::WORKGROUP_MEMORY
- | spirv::MemorySemantics::SEQUENTIALLY_CONSISTENT,
- ),
- ast::MemScope::Sys => (
- spirv::Scope::CrossDevice,
- spirv::MemorySemantics::CROSS_WORKGROUP_MEMORY
- | spirv::MemorySemantics::WORKGROUP_MEMORY
- | spirv::MemorySemantics::SEQUENTIALLY_CONSISTENT,
- ),
- };
- let spirv_scope = map.get_or_add_constant(
- builder,
- &ast::Type::Scalar(ast::ScalarType::U32),
- &vec_repr(scope as u32),
- )?;
- let spirv_semantics = map.get_or_add_constant(
- builder,
- &ast::Type::Scalar(ast::ScalarType::U32),
- &vec_repr(semantics),
- )?;
- builder.memory_barrier(spirv_scope, spirv_semantics)?;
- }
- },
- Statement::LoadVar(details) => {
- emit_load_var(builder, map, details)?;
- }
- Statement::StoreVar(details) => {
- let dst_ptr = match details.member_index {
- Some(index) => {
- let result_ptr_type = map.get_or_add(
- builder,
- SpirvType::pointer_to(
- details.typ.clone(),
- spirv::StorageClass::Function,
- ),
- );
- let index_spirv = map.get_or_add_constant(
- builder,
- &ast::Type::Scalar(ast::ScalarType::U32),
- &vec_repr(index as u32),
- )?;
- builder.in_bounds_access_chain(
- result_ptr_type,
- None,
- details.arg.src1,
- [index_spirv].iter().copied(),
- )?
- }
- None => details.arg.src1,
- };
- builder.store(dst_ptr, details.arg.src2, None, iter::empty())?;
- }
- Statement::RetValue(_, id) => {
- builder.ret_value(*id)?;
- }
- Statement::PtrAccess(PtrAccess {
- underlying_type,
- state_space,
- dst,
- ptr_src,
- offset_src,
- }) => {
- let u8_pointer = map.get_or_add(
- builder,
- SpirvType::new(ast::Type::Pointer(ast::ScalarType::U8, *state_space)),
- );
- let result_type = map.get_or_add(
- builder,
- SpirvType::pointer_to(underlying_type.clone(), state_space.to_spirv()),
- );
- let ptr_src_u8 = builder.bitcast(u8_pointer, None, *ptr_src)?;
- let temp = builder.in_bounds_ptr_access_chain(
- u8_pointer,
- None,
- ptr_src_u8,
- *offset_src,
- iter::empty(),
- )?;
- builder.bitcast(result_type, Some(*dst), temp)?;
- }
- Statement::RepackVector(repack) => {
- if repack.is_extract {
- let scalar_type = map.get_or_add_scalar(builder, repack.typ);
- for (index, dst_id) in repack.unpacked.iter().enumerate() {
- builder.composite_extract(
- scalar_type,
- Some(*dst_id),
- repack.packed,
- [index as u32].iter().copied(),
- )?;
- }
- } else {
- let vector_type = map.get_or_add(
- builder,
- SpirvType::Vector(
- SpirvScalarKey::from(repack.typ),
- repack.unpacked.len() as u8,
- ),
- );
- let mut temp_vec = builder.undef(vector_type, None);
- for (index, src_id) in repack.unpacked.iter().enumerate() {
- temp_vec = builder.composite_insert(
- vector_type,
- None,
- *src_id,
- temp_vec,
- [index as u32].iter().copied(),
- )?;
- }
- builder.copy_object(vector_type, Some(repack.packed), temp_vec)?;
- }
- }
- }
- }
- Ok(())
-}
-
-// HACK ALERT
-// For some reason IGC fails linking if the value and shift size are of different type
-fn insert_shift_hack(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- offset_var: spirv::Word,
- size_of: usize,
-) -> Result<spirv::Word, TranslateError> {
- let result_type = match size_of {
- 2 => map.get_or_add_scalar(builder, ast::ScalarType::B16),
- 8 => map.get_or_add_scalar(builder, ast::ScalarType::B64),
- 4 => return Ok(offset_var),
- _ => return Err(error_unreachable()),
- };
- Ok(builder.u_convert(result_type, None, offset_var)?)
-}
-
-// TODO: check what kind of assembly do we emit
-fn emit_logical_xor_spirv(
- builder: &mut dr::Builder,
- result_type: spirv::Word,
- result_id: Option<spirv::Word>,
- op1: spirv::Word,
- op2: spirv::Word,
-) -> Result<spirv::Word, dr::Error> {
- let temp_or = builder.logical_or(result_type, None, op1, op2)?;
- let temp_and = builder.logical_and(result_type, None, op1, op2)?;
- let temp_neg = logical_not(builder, result_type, None, temp_and)?;
- builder.logical_and(result_type, result_id, temp_or, temp_neg)
-}
-
-fn emit_sqrt(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- opencl: spirv::Word,
- details: &ast::SqrtDetails,
- a: &ast::Arg2<ExpandedArgParams>,
-) -> Result<(), TranslateError> {
- let result_type = map.get_or_add_scalar(builder, details.typ.into());
- let (ocl_op, rounding) = match details.kind {
- ast::SqrtKind::Approx => (spirv::CLOp::sqrt, None),
- ast::SqrtKind::Rounding(rnd) => (spirv::CLOp::sqrt, Some(rnd)),
- };
- builder.ext_inst(
- result_type,
- Some(a.dst),
- opencl,
- ocl_op as spirv::Word,
- [dr::Operand::IdRef(a.src)].iter().cloned(),
- )?;
- emit_rounding_decoration(builder, a.dst, rounding);
- Ok(())
-}
-
-fn emit_float_div_decoration(builder: &mut dr::Builder, dst: spirv::Word, kind: ast::DivFloatKind) {
- match kind {
- ast::DivFloatKind::Approx => {
- builder.decorate(
- dst,
- spirv::Decoration::FPFastMathMode,
- [dr::Operand::FPFastMathMode(
- spirv::FPFastMathMode::ALLOW_RECIP,
- )]
- .iter()
- .cloned(),
- );
- }
- ast::DivFloatKind::Rounding(rnd) => {
- emit_rounding_decoration(builder, dst, Some(rnd));
- }
- ast::DivFloatKind::Full => {}
- }
-}
-
-fn emit_atom(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- details: &ast::AtomDetails,
- arg: &ast::Arg3<ExpandedArgParams>,
-) -> Result<(), TranslateError> {
- let (spirv_op, typ) = match details.inner {
- ast::AtomInnerDetails::Bit { op, typ } => {
- let spirv_op = match op {
- ast::AtomBitOp::And => dr::Builder::atomic_and,
- ast::AtomBitOp::Or => dr::Builder::atomic_or,
- ast::AtomBitOp::Xor => dr::Builder::atomic_xor,
- ast::AtomBitOp::Exchange => dr::Builder::atomic_exchange,
- };
- (spirv_op, ast::ScalarType::from(typ))
- }
- ast::AtomInnerDetails::Unsigned { op, typ } => {
- let spirv_op = match op {
- ast::AtomUIntOp::Add => dr::Builder::atomic_i_add,
- ast::AtomUIntOp::Inc | ast::AtomUIntOp::Dec => {
- return Err(error_unreachable());
- }
- ast::AtomUIntOp::Min => dr::Builder::atomic_u_min,
- ast::AtomUIntOp::Max => dr::Builder::atomic_u_max,
- };
- (spirv_op, typ.into())
- }
- ast::AtomInnerDetails::Signed { op, typ } => {
- let spirv_op = match op {
- ast::AtomSIntOp::Add => dr::Builder::atomic_i_add,
- ast::AtomSIntOp::Min => dr::Builder::atomic_s_min,
- ast::AtomSIntOp::Max => dr::Builder::atomic_s_max,
- };
- (spirv_op, typ.into())
- }
- ast::AtomInnerDetails::Float { op, typ } => {
- let spirv_op: fn(&mut dr::Builder, _, _, _, _, _, _) -> _ = match op {
- ast::AtomFloatOp::Add => dr::Builder::atomic_f_add_ext,
- };
- (spirv_op, typ.into())
- }
- };
- let result_type = map.get_or_add_scalar(builder, typ);
- let memory_const = map.get_or_add_constant(
- builder,
- &ast::Type::Scalar(ast::ScalarType::U32),
- &vec_repr(details.scope.to_spirv() as u32),
- )?;
- let semantics_const = map.get_or_add_constant(
- builder,
- &ast::Type::Scalar(ast::ScalarType::U32),
- &vec_repr(details.semantics.to_spirv().bits()),
- )?;
- spirv_op(
- builder,
- result_type,
- Some(arg.dst),
- arg.src1,
- memory_const,
- semantics_const,
- arg.src2,
- )?;
- Ok(())
-}
-
-#[derive(Clone)]
-struct PtxImplImport {
- out_arg: ast::Type,
- fn_id: u32,
- in_args: Vec<ast::Type>,
-}
-
-fn emit_mul_float(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- ctr: &ast::ArithFloat,
- arg: &ast::Arg3<ExpandedArgParams>,
-) -> Result<(), dr::Error> {
- if ctr.saturate {
- todo!()
- }
- let result_type = map.get_or_add_scalar(builder, ctr.typ.into());
- builder.f_mul(result_type, Some(arg.dst), arg.src1, arg.src2)?;
- emit_rounding_decoration(builder, arg.dst, ctr.rounding);
- Ok(())
-}
-
-fn emit_rcp(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- opencl: spirv::Word,
- desc: &ast::RcpDetails,
- arg: &ast::Arg2<ExpandedArgParams>,
-) -> Result<(), TranslateError> {
- let (instr_type, constant) = if desc.is_f64 {
- (ast::ScalarType::F64, vec_repr(1.0f64))
- } else {
- (ast::ScalarType::F32, vec_repr(1.0f32))
- };
- let result_type = map.get_or_add_scalar(builder, instr_type);
- if !desc.is_f64 && desc.rounding.is_none() {
- builder.ext_inst(
- result_type,
- Some(arg.dst),
- opencl,
- spirv::CLOp::native_recip as u32,
- [dr::Operand::IdRef(arg.src)].iter().cloned(),
- )?;
- return Ok(());
- }
- let one = map.get_or_add_constant(builder, &ast::Type::Scalar(instr_type), &constant)?;
- builder.f_div(result_type, Some(arg.dst), one, arg.src)?;
- emit_rounding_decoration(builder, arg.dst, desc.rounding);
- builder.decorate(
- arg.dst,
- spirv::Decoration::FPFastMathMode,
- [dr::Operand::FPFastMathMode(
- spirv::FPFastMathMode::ALLOW_RECIP,
- )]
- .iter()
- .cloned(),
- );
- Ok(())
-}
-
-fn vec_repr<T: Copy>(t: T) -> Vec<u8> {
- let mut result = vec![0; mem::size_of::<T>()];
- unsafe { std::ptr::copy_nonoverlapping(&t, result.as_mut_ptr() as *mut _, 1) };
- result
-}
-
-fn emit_variable<'input>(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- id_defs: &GlobalStringIdResolver<'input>,
- linking: ast::LinkingDirective,
- var: &ast::Variable<spirv::Word>,
-) -> Result<(), TranslateError> {
- let (must_init, st_class) = match var.state_space {
- ast::StateSpace::Reg | ast::StateSpace::Param | ast::StateSpace::Local => {
- (false, spirv::StorageClass::Function)
- }
- ast::StateSpace::Global => (true, spirv::StorageClass::CrossWorkgroup),
- ast::StateSpace::Shared => (false, spirv::StorageClass::Workgroup),
- ast::StateSpace::Const => (false, spirv::StorageClass::UniformConstant),
- ast::StateSpace::Generic => todo!(),
- ast::StateSpace::Sreg => todo!(),
- };
- let initalizer = if var.array_init.len() > 0 {
- Some(map.get_or_add_constant(
- builder,
- &ast::Type::from(var.v_type.clone()),
- &*var.array_init,
- )?)
- } else if must_init {
- let type_id = map.get_or_add(builder, SpirvType::new(var.v_type.clone()));
- Some(builder.constant_null(type_id, None))
- } else {
- None
- };
- let ptr_type_id = map.get_or_add(builder, SpirvType::pointer_to(var.v_type.clone(), st_class));
- builder.variable(ptr_type_id, Some(var.name), st_class, initalizer);
- if let Some(align) = var.align {
- builder.decorate(
- var.name,
- spirv::Decoration::Alignment,
- [dr::Operand::LiteralInt32(align)].iter().cloned(),
- );
- }
- if var.state_space != ast::StateSpace::Shared
- || !linking.contains(ast::LinkingDirective::EXTERN)
- {
- emit_linking_decoration(builder, id_defs, None, var.name, linking);
- }
- Ok(())
-}
-
-fn emit_linking_decoration<'input>(
- builder: &mut dr::Builder,
- id_defs: &GlobalStringIdResolver<'input>,
- name_override: Option<&str>,
- name: spirv::Word,
- linking: ast::LinkingDirective,
-) {
- if linking == ast::LinkingDirective::NONE {
- return;
- }
- if linking.contains(ast::LinkingDirective::VISIBLE) {
- let string_name =
- name_override.unwrap_or_else(|| id_defs.reverse_variables.get(&name).unwrap());
- builder.decorate(
- name,
- spirv::Decoration::LinkageAttributes,
- [
- dr::Operand::LiteralString(string_name.to_string()),
- dr::Operand::LinkageType(spirv::LinkageType::Export),
- ]
- .iter()
- .cloned(),
- );
- } else if linking.contains(ast::LinkingDirective::EXTERN) {
- let string_name =
- name_override.unwrap_or_else(|| id_defs.reverse_variables.get(&name).unwrap());
- builder.decorate(
- name,
- spirv::Decoration::LinkageAttributes,
- [
- dr::Operand::LiteralString(string_name.to_string()),
- dr::Operand::LinkageType(spirv::LinkageType::Import),
- ]
- .iter()
- .cloned(),
- );
- }
- // TODO: handle LinkingDirective::WEAK
-}
-
-fn emit_mad_uint(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- opencl: spirv::Word,
- desc: &ast::MulUInt,
- arg: &ast::Arg4<ExpandedArgParams>,
-) -> Result<(), dr::Error> {
- let inst_type = map.get_or_add(builder, SpirvType::from(ast::ScalarType::from(desc.typ)));
- match desc.control {
- ast::MulIntControl::Low => {
- let mul_result = builder.i_mul(inst_type, None, arg.src1, arg.src2)?;
- builder.i_add(inst_type, Some(arg.dst), arg.src3, mul_result)?;
- }
- ast::MulIntControl::High => {
- builder.ext_inst(
- inst_type,
- Some(arg.dst),
- opencl,
- spirv::CLOp::u_mad_hi as spirv::Word,
- [
- dr::Operand::IdRef(arg.src1),
- dr::Operand::IdRef(arg.src2),
- dr::Operand::IdRef(arg.src3),
- ]
- .iter()
- .cloned(),
- )?;
- }
- ast::MulIntControl::Wide => todo!(),
- };
- Ok(())
-}
-
-fn emit_mad_sint(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- opencl: spirv::Word,
- desc: &ast::MulSInt,
- arg: &ast::Arg4<ExpandedArgParams>,
-) -> Result<(), dr::Error> {
- let inst_type = map.get_or_add(builder, SpirvType::from(ast::ScalarType::from(desc.typ)));
- match desc.control {
- ast::MulIntControl::Low => {
- let mul_result = builder.i_mul(inst_type, None, arg.src1, arg.src2)?;
- builder.i_add(inst_type, Some(arg.dst), arg.src3, mul_result)?;
- }
- ast::MulIntControl::High => {
- builder.ext_inst(
- inst_type,
- Some(arg.dst),
- opencl,
- spirv::CLOp::s_mad_hi as spirv::Word,
- [
- dr::Operand::IdRef(arg.src1),
- dr::Operand::IdRef(arg.src2),
- dr::Operand::IdRef(arg.src3),
- ]
- .iter()
- .cloned(),
- )?;
- }
- ast::MulIntControl::Wide => todo!(),
- };
- Ok(())
-}
-
-fn emit_fma_float(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- opencl: spirv::Word,
- desc: &ast::ArithFloat,
- arg: &ast::Arg4<ExpandedArgParams>,
-) -> Result<(), dr::Error> {
- let inst_type = map.get_or_add(builder, SpirvType::from(ast::ScalarType::from(desc.typ)));
- builder.ext_inst(
- inst_type,
- Some(arg.dst),
- opencl,
- spirv::CLOp::fma as spirv::Word,
- [
- dr::Operand::IdRef(arg.src1),
- dr::Operand::IdRef(arg.src2),
- dr::Operand::IdRef(arg.src3),
- ]
- .iter()
- .cloned(),
- )?;
- Ok(())
-}
-
-fn emit_mad_float(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- opencl: spirv::Word,
- desc: &ast::ArithFloat,
- arg: &ast::Arg4<ExpandedArgParams>,
-) -> Result<(), dr::Error> {
- let inst_type = map.get_or_add(builder, SpirvType::from(ast::ScalarType::from(desc.typ)));
- builder.ext_inst(
- inst_type,
- Some(arg.dst),
- opencl,
- spirv::CLOp::mad as spirv::Word,
- [
- dr::Operand::IdRef(arg.src1),
- dr::Operand::IdRef(arg.src2),
- dr::Operand::IdRef(arg.src3),
- ]
- .iter()
- .cloned(),
- )?;
- Ok(())
-}
-
-fn emit_add_float(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- desc: &ast::ArithFloat,
- arg: &ast::Arg3<ExpandedArgParams>,
-) -> Result<(), dr::Error> {
- let inst_type = map.get_or_add(builder, SpirvType::from(ast::ScalarType::from(desc.typ)));
- builder.f_add(inst_type, Some(arg.dst), arg.src1, arg.src2)?;
- emit_rounding_decoration(builder, arg.dst, desc.rounding);
- Ok(())
-}
-
-fn emit_sub_float(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- desc: &ast::ArithFloat,
- arg: &ast::Arg3<ExpandedArgParams>,
-) -> Result<(), dr::Error> {
- let inst_type = map.get_or_add(builder, SpirvType::from(ast::ScalarType::from(desc.typ)));
- builder.f_sub(inst_type, Some(arg.dst), arg.src1, arg.src2)?;
- emit_rounding_decoration(builder, arg.dst, desc.rounding);
- Ok(())
-}
-
-fn emit_min(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- opencl: spirv::Word,
- desc: &ast::MinMaxDetails,
- arg: &ast::Arg3<ExpandedArgParams>,
-) -> Result<(), dr::Error> {
- let cl_op = match desc {
- ast::MinMaxDetails::Signed(_) => spirv::CLOp::s_min,
- ast::MinMaxDetails::Unsigned(_) => spirv::CLOp::u_min,
- ast::MinMaxDetails::Float(_) => spirv::CLOp::fmin,
- };
- let inst_type = map.get_or_add(builder, SpirvType::new(desc.get_type()));
- builder.ext_inst(
- inst_type,
- Some(arg.dst),
- opencl,
- cl_op as spirv::Word,
- [dr::Operand::IdRef(arg.src1), dr::Operand::IdRef(arg.src2)]
- .iter()
- .cloned(),
- )?;
- Ok(())
-}
-
-fn emit_max(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- opencl: spirv::Word,
- desc: &ast::MinMaxDetails,
- arg: &ast::Arg3<ExpandedArgParams>,
-) -> Result<(), dr::Error> {
- let cl_op = match desc {
- ast::MinMaxDetails::Signed(_) => spirv::CLOp::s_max,
- ast::MinMaxDetails::Unsigned(_) => spirv::CLOp::u_max,
- ast::MinMaxDetails::Float(_) => spirv::CLOp::fmax,
- };
- let inst_type = map.get_or_add(builder, SpirvType::new(desc.get_type()));
- builder.ext_inst(
- inst_type,
- Some(arg.dst),
- opencl,
- cl_op as spirv::Word,
- [dr::Operand::IdRef(arg.src1), dr::Operand::IdRef(arg.src2)]
- .iter()
- .cloned(),
- )?;
- Ok(())
-}
-
-fn emit_cvt(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- opencl: spirv::Word,
- dets: &ast::CvtDetails,
- arg: &ast::Arg2<ExpandedArgParams>,
-) -> Result<(), TranslateError> {
- match dets {
- ast::CvtDetails::FloatFromFloat(desc) => {
- if desc.saturate {
- todo!()
- }
- let dest_t: ast::ScalarType = desc.dst.into();
- let result_type = map.get_or_add(builder, SpirvType::from(dest_t));
- if desc.dst == desc.src {
- match desc.rounding {
- Some(ast::RoundingMode::NearestEven) => {
- builder.ext_inst(
- result_type,
- Some(arg.dst),
- opencl,
- spirv::CLOp::rint as u32,
- [dr::Operand::IdRef(arg.src)].iter().cloned(),
- )?;
- }
- Some(ast::RoundingMode::Zero) => {
- builder.ext_inst(
- result_type,
- Some(arg.dst),
- opencl,
- spirv::CLOp::trunc as u32,
- [dr::Operand::IdRef(arg.src)].iter().cloned(),
- )?;
- }
- Some(ast::RoundingMode::NegativeInf) => {
- builder.ext_inst(
- result_type,
- Some(arg.dst),
- opencl,
- spirv::CLOp::floor as u32,
- [dr::Operand::IdRef(arg.src)].iter().cloned(),
- )?;
- }
- Some(ast::RoundingMode::PositiveInf) => {
- builder.ext_inst(
- result_type,
- Some(arg.dst),
- opencl,
- spirv::CLOp::ceil as u32,
- [dr::Operand::IdRef(arg.src)].iter().cloned(),
- )?;
- }
- None => {
- builder.copy_object(result_type, Some(arg.dst), arg.src)?;
- }
- }
- } else {
- builder.f_convert(result_type, Some(arg.dst), arg.src)?;
- emit_rounding_decoration(builder, arg.dst, desc.rounding);
- }
- }
- ast::CvtDetails::FloatFromInt(desc) => {
- if desc.saturate {
- todo!()
- }
- let dest_t: ast::ScalarType = desc.dst.into();
- let result_type = map.get_or_add(builder, SpirvType::from(dest_t));
- if desc.src.kind() == ast::ScalarKind::Signed {
- builder.convert_s_to_f(result_type, Some(arg.dst), arg.src)?;
- } else {
- builder.convert_u_to_f(result_type, Some(arg.dst), arg.src)?;
- }
- emit_rounding_decoration(builder, arg.dst, desc.rounding);
- }
- ast::CvtDetails::IntFromFloat(desc) => {
- let dest_t: ast::ScalarType = desc.dst.into();
- let result_type = map.get_or_add(builder, SpirvType::from(dest_t));
- if desc.dst.kind() == ast::ScalarKind::Signed {
- builder.convert_f_to_s(result_type, Some(arg.dst), arg.src)?;
- } else {
- builder.convert_f_to_u(result_type, Some(arg.dst), arg.src)?;
- }
- emit_rounding_decoration(builder, arg.dst, desc.rounding);
- emit_saturating_decoration(builder, arg.dst, desc.saturate);
- }
- ast::CvtDetails::IntFromInt(desc) => {
- let dest_t: ast::ScalarType = desc.dst.into();
- let src_t: ast::ScalarType = desc.src.into();
- // first do shortening/widening
- let src = if desc.dst.size_of() != desc.src.size_of() {
- let new_dst = if dest_t.kind() == src_t.kind() {
- arg.dst
- } else {
- builder.id()
- };
- let cv = ImplicitConversion {
- src: arg.src,
- dst: new_dst,
- from_type: ast::Type::Scalar(src_t),
- from_space: ast::StateSpace::Reg,
- to_type: ast::Type::Scalar(ast::ScalarType::from_parts(
- dest_t.size_of(),
- src_t.kind(),
- )),
- to_space: ast::StateSpace::Reg,
- kind: ConversionKind::Default,
- };
- emit_implicit_conversion(builder, map, &cv)?;
- new_dst
- } else {
- arg.src
- };
- if dest_t.kind() == src_t.kind() {
- return Ok(());
- }
- // now do actual conversion
- let result_type = map.get_or_add(builder, SpirvType::from(dest_t));
- if desc.saturate {
- if desc.dst.kind() == ast::ScalarKind::Signed {
- builder.sat_convert_u_to_s(result_type, Some(arg.dst), src)?;
- } else {
- builder.sat_convert_s_to_u(result_type, Some(arg.dst), src)?;
- }
- } else {
- builder.bitcast(result_type, Some(arg.dst), src)?;
- }
- }
- }
- Ok(())
-}
-
-fn emit_saturating_decoration(builder: &mut dr::Builder, dst: u32, saturate: bool) {
- if saturate {
- builder.decorate(dst, spirv::Decoration::SaturatedConversion, iter::empty());
- }
-}
-
-fn emit_rounding_decoration(
- builder: &mut dr::Builder,
- dst: spirv::Word,
- rounding: Option<ast::RoundingMode>,
-) {
- if let Some(rounding) = rounding {
- builder.decorate(
- dst,
- spirv::Decoration::FPRoundingMode,
- [rounding.to_spirv()].iter().cloned(),
- );
- }
-}
-
-impl ast::RoundingMode {
- fn to_spirv(self) -> rspirv::dr::Operand {
- let mode = match self {
- ast::RoundingMode::NearestEven => spirv::FPRoundingMode::RTE,
- ast::RoundingMode::Zero => spirv::FPRoundingMode::RTZ,
- ast::RoundingMode::PositiveInf => spirv::FPRoundingMode::RTP,
- ast::RoundingMode::NegativeInf => spirv::FPRoundingMode::RTN,
- };
- rspirv::dr::Operand::FPRoundingMode(mode)
- }
-}
-
-fn emit_setp(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- setp: &ast::SetpData,
- arg: &ast::Arg4Setp<ExpandedArgParams>,
-) -> Result<(), dr::Error> {
- let result_type = map.get_or_add(builder, SpirvType::Base(SpirvScalarKey::Pred));
- let result_id = Some(arg.dst1);
- let operand_1 = arg.src1;
- let operand_2 = arg.src2;
- match (setp.cmp_op, setp.typ.kind()) {
- (ast::SetpCompareOp::Eq, ast::ScalarKind::Signed)
- | (ast::SetpCompareOp::Eq, ast::ScalarKind::Unsigned)
- | (ast::SetpCompareOp::Eq, ast::ScalarKind::Bit) => {
- builder.i_equal(result_type, result_id, operand_1, operand_2)
- }
- (ast::SetpCompareOp::Eq, ast::ScalarKind::Float) => {
- builder.f_ord_equal(result_type, result_id, operand_1, operand_2)
- }
- (ast::SetpCompareOp::NotEq, ast::ScalarKind::Signed)
- | (ast::SetpCompareOp::NotEq, ast::ScalarKind::Unsigned)
- | (ast::SetpCompareOp::NotEq, ast::ScalarKind::Bit) => {
- builder.i_not_equal(result_type, result_id, operand_1, operand_2)
- }
- (ast::SetpCompareOp::NotEq, ast::ScalarKind::Float) => {
- builder.f_ord_not_equal(result_type, result_id, operand_1, operand_2)
- }
- (ast::SetpCompareOp::Less, ast::ScalarKind::Unsigned)
- | (ast::SetpCompareOp::Less, ast::ScalarKind::Bit) => {
- builder.u_less_than(result_type, result_id, operand_1, operand_2)
- }
- (ast::SetpCompareOp::Less, ast::ScalarKind::Signed) => {
- builder.s_less_than(result_type, result_id, operand_1, operand_2)
- }
- (ast::SetpCompareOp::Less, ast::ScalarKind::Float) => {
- builder.f_ord_less_than(result_type, result_id, operand_1, operand_2)
- }
- (ast::SetpCompareOp::LessOrEq, ast::ScalarKind::Unsigned)
- | (ast::SetpCompareOp::LessOrEq, ast::ScalarKind::Bit) => {
- builder.u_less_than_equal(result_type, result_id, operand_1, operand_2)
- }
- (ast::SetpCompareOp::LessOrEq, ast::ScalarKind::Signed) => {
- builder.s_less_than_equal(result_type, result_id, operand_1, operand_2)
- }
- (ast::SetpCompareOp::LessOrEq, ast::ScalarKind::Float) => {
- builder.f_ord_less_than_equal(result_type, result_id, operand_1, operand_2)
- }
- (ast::SetpCompareOp::Greater, ast::ScalarKind::Unsigned)
- | (ast::SetpCompareOp::Greater, ast::ScalarKind::Bit) => {
- builder.u_greater_than(result_type, result_id, operand_1, operand_2)
- }
- (ast::SetpCompareOp::Greater, ast::ScalarKind::Signed) => {
- builder.s_greater_than(result_type, result_id, operand_1, operand_2)
- }
- (ast::SetpCompareOp::Greater, ast::ScalarKind::Float) => {
- builder.f_ord_greater_than(result_type, result_id, operand_1, operand_2)
- }
- (ast::SetpCompareOp::GreaterOrEq, ast::ScalarKind::Unsigned)
- | (ast::SetpCompareOp::GreaterOrEq, ast::ScalarKind::Bit) => {
- builder.u_greater_than_equal(result_type, result_id, operand_1, operand_2)
- }
- (ast::SetpCompareOp::GreaterOrEq, ast::ScalarKind::Signed) => {
- builder.s_greater_than_equal(result_type, result_id, operand_1, operand_2)
- }
- (ast::SetpCompareOp::GreaterOrEq, ast::ScalarKind::Float) => {
- builder.f_ord_greater_than_equal(result_type, result_id, operand_1, operand_2)
- }
- (ast::SetpCompareOp::NanEq, _) => {
- builder.f_unord_equal(result_type, result_id, operand_1, operand_2)
- }
- (ast::SetpCompareOp::NanNotEq, _) => {
- builder.f_unord_not_equal(result_type, result_id, operand_1, operand_2)
- }
- (ast::SetpCompareOp::NanLess, _) => {
- builder.f_unord_less_than(result_type, result_id, operand_1, operand_2)
- }
- (ast::SetpCompareOp::NanLessOrEq, _) => {
- builder.f_unord_less_than_equal(result_type, result_id, operand_1, operand_2)
- }
- (ast::SetpCompareOp::NanGreater, _) => {
- builder.f_unord_greater_than(result_type, result_id, operand_1, operand_2)
- }
- (ast::SetpCompareOp::NanGreaterOrEq, _) => {
- builder.f_unord_greater_than_equal(result_type, result_id, operand_1, operand_2)
- }
- (ast::SetpCompareOp::IsAnyNan, _) => {
- let temp1 = builder.is_nan(result_type, None, operand_1)?;
- let temp2 = builder.is_nan(result_type, None, operand_2)?;
- builder.logical_or(result_type, result_id, temp1, temp2)
- }
- (ast::SetpCompareOp::IsNotNan, _) => {
- let temp1 = builder.is_nan(result_type, None, operand_1)?;
- let temp2 = builder.is_nan(result_type, None, operand_2)?;
- let any_nan = builder.logical_or(result_type, None, temp1, temp2)?;
- logical_not(builder, result_type, result_id, any_nan)
- }
- _ => todo!(),
- }?;
- Ok(())
-}
-
-// HACK ALERT
-// Temporary workaround until IGC gets its shit together
-// Currently IGC carries two copies of SPIRV-LLVM translator
-// a new one in /llvm-spirv/ and old one in /IGC/AdaptorOCL/SPIRV/.
-// Obviously, old and buggy one is used for compiling L0 SPIRV
-// https://github.com/intel/intel-graphics-compiler/issues/148
-fn logical_not(
- builder: &mut dr::Builder,
- result_type: spirv::Word,
- result_id: Option<spirv::Word>,
- operand: spirv::Word,
-) -> Result<spirv::Word, dr::Error> {
- let const_true = builder.constant_true(result_type, None);
- let const_false = builder.constant_false(result_type, None);
- builder.select(result_type, result_id, operand, const_false, const_true)
-}
-
-fn emit_mul_sint(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- opencl: spirv::Word,
- desc: &ast::MulSInt,
- arg: &ast::Arg3<ExpandedArgParams>,
-) -> Result<(), dr::Error> {
- let instruction_type = desc.typ;
- let inst_type = map.get_or_add(builder, SpirvType::from(desc.typ));
- match desc.control {
- ast::MulIntControl::Low => {
- builder.i_mul(inst_type, Some(arg.dst), arg.src1, arg.src2)?;
- }
- ast::MulIntControl::High => {
- builder.ext_inst(
- inst_type,
- Some(arg.dst),
- opencl,
- spirv::CLOp::s_mul_hi as spirv::Word,
- [dr::Operand::IdRef(arg.src1), dr::Operand::IdRef(arg.src2)]
- .iter()
- .cloned(),
- )?;
- }
- ast::MulIntControl::Wide => {
- let instr_width = instruction_type.size_of();
- let instr_kind = instruction_type.kind();
- let dst_type = ast::ScalarType::from_parts(instr_width * 2, instr_kind);
- let dst_type_id = map.get_or_add_scalar(builder, dst_type);
- let src1 = builder.s_convert(dst_type_id, None, arg.src1)?;
- let src2 = builder.s_convert(dst_type_id, None, arg.src2)?;
- builder.i_mul(dst_type_id, Some(arg.dst), src1, src2)?;
- builder.decorate(arg.dst, spirv::Decoration::NoSignedWrap, iter::empty());
- }
- }
- Ok(())
-}
-
-fn emit_mul_uint(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- opencl: spirv::Word,
- desc: &ast::MulUInt,
- arg: &ast::Arg3<ExpandedArgParams>,
-) -> Result<(), dr::Error> {
- let instruction_type = ast::ScalarType::from(desc.typ);
- let inst_type = map.get_or_add(builder, SpirvType::from(ast::ScalarType::from(desc.typ)));
- match desc.control {
- ast::MulIntControl::Low => {
- builder.i_mul(inst_type, Some(arg.dst), arg.src1, arg.src2)?;
- }
- ast::MulIntControl::High => {
- builder.ext_inst(
- inst_type,
- Some(arg.dst),
- opencl,
- spirv::CLOp::u_mul_hi as spirv::Word,
- [dr::Operand::IdRef(arg.src1), dr::Operand::IdRef(arg.src2)]
- .iter()
- .cloned(),
- )?;
- }
- ast::MulIntControl::Wide => {
- let instr_width = instruction_type.size_of();
- let instr_kind = instruction_type.kind();
- let dst_type = ast::ScalarType::from_parts(instr_width * 2, instr_kind);
- let dst_type_id = map.get_or_add_scalar(builder, dst_type);
- let src1 = builder.u_convert(dst_type_id, None, arg.src1)?;
- let src2 = builder.u_convert(dst_type_id, None, arg.src2)?;
- builder.i_mul(dst_type_id, Some(arg.dst), src1, src2)?;
- builder.decorate(arg.dst, spirv::Decoration::NoUnsignedWrap, iter::empty());
- }
- }
- Ok(())
-}
-
-// Surprisingly, structs can't be bitcast, so we route everything through a vector
-fn struct2_bitcast_to_wide(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- base_type_key: SpirvScalarKey,
- instruction_type: spirv::Word,
- dst: spirv::Word,
- dst_type_id: spirv::Word,
- src: spirv::Word,
-) -> Result<(), dr::Error> {
- let low_bits = builder.composite_extract(instruction_type, None, src, [0].iter().copied())?;
- let high_bits = builder.composite_extract(instruction_type, None, src, [1].iter().copied())?;
- let vector_type = map.get_or_add(builder, SpirvType::Vector(base_type_key, 2));
- let vector =
- builder.composite_construct(vector_type, None, [low_bits, high_bits].iter().copied())?;
- builder.bitcast(dst_type_id, Some(dst), vector)?;
- Ok(())
-}
-
-fn emit_abs(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- opencl: spirv::Word,
- d: &ast::AbsDetails,
- arg: &ast::Arg2<ExpandedArgParams>,
-) -> Result<(), dr::Error> {
- let scalar_t = ast::ScalarType::from(d.typ);
- let result_type = map.get_or_add(builder, SpirvType::from(scalar_t));
- let cl_abs = if scalar_t.kind() == ast::ScalarKind::Signed {
- spirv::CLOp::s_abs
- } else {
- spirv::CLOp::fabs
- };
- builder.ext_inst(
- result_type,
- Some(arg.dst),
- opencl,
- cl_abs as spirv::Word,
- [dr::Operand::IdRef(arg.src)].iter().cloned(),
- )?;
- Ok(())
-}
-
-fn emit_add_int(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- typ: ast::ScalarType,
- saturate: bool,
- arg: &ast::Arg3<ExpandedArgParams>,
-) -> Result<(), dr::Error> {
- if saturate {
- todo!()
- }
- let inst_type = map.get_or_add(builder, SpirvType::from(ast::ScalarType::from(typ)));
- builder.i_add(inst_type, Some(arg.dst), arg.src1, arg.src2)?;
- Ok(())
-}
-
-fn emit_sub_int(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- typ: ast::ScalarType,
- saturate: bool,
- arg: &ast::Arg3<ExpandedArgParams>,
-) -> Result<(), dr::Error> {
- if saturate {
- todo!()
- }
- let inst_type = map.get_or_add(builder, SpirvType::from(ast::ScalarType::from(typ)));
- builder.i_sub(inst_type, Some(arg.dst), arg.src1, arg.src2)?;
- Ok(())
-}
-
-fn emit_implicit_conversion(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- cv: &ImplicitConversion,
-) -> Result<(), TranslateError> {
- let from_parts = cv.from_type.to_parts();
- let to_parts = cv.to_type.to_parts();
- match (from_parts.kind, to_parts.kind, &cv.kind) {
- (_, _, &ConversionKind::BitToPtr) => {
- let dst_type = map.get_or_add(
- builder,
- SpirvType::pointer_to(cv.to_type.clone(), cv.to_space.to_spirv()),
- );
- builder.convert_u_to_ptr(dst_type, Some(cv.dst), cv.src)?;
- }
- (TypeKind::Scalar, TypeKind::Scalar, &ConversionKind::Default) => {
- if from_parts.width == to_parts.width {
- let dst_type = map.get_or_add(builder, SpirvType::new(cv.to_type.clone()));
- if from_parts.scalar_kind != ast::ScalarKind::Float
- && to_parts.scalar_kind != ast::ScalarKind::Float
- {
- // It is noop, but another instruction expects result of this conversion
- builder.copy_object(dst_type, Some(cv.dst), cv.src)?;
- } else {
- builder.bitcast(dst_type, Some(cv.dst), cv.src)?;
- }
- } else {
- // This block is safe because it's illegal to implictly convert between floating point values
- let same_width_bit_type = map.get_or_add(
- builder,
- SpirvType::new(ast::Type::from_parts(TypeParts {
- scalar_kind: ast::ScalarKind::Bit,
- ..from_parts
- })),
- );
- let same_width_bit_value = builder.bitcast(same_width_bit_type, None, cv.src)?;
- let wide_bit_type = ast::Type::from_parts(TypeParts {
- scalar_kind: ast::ScalarKind::Bit,
- ..to_parts
- });
- let wide_bit_type_spirv =
- map.get_or_add(builder, SpirvType::new(wide_bit_type.clone()));
- if to_parts.scalar_kind == ast::ScalarKind::Unsigned
- || to_parts.scalar_kind == ast::ScalarKind::Bit
- {
- builder.u_convert(wide_bit_type_spirv, Some(cv.dst), same_width_bit_value)?;
- } else {
- let conversion_fn = if from_parts.scalar_kind == ast::ScalarKind::Signed
- && to_parts.scalar_kind == ast::ScalarKind::Signed
- {
- dr::Builder::s_convert
- } else {
- dr::Builder::u_convert
- };
- let wide_bit_value =
- conversion_fn(builder, wide_bit_type_spirv, None, same_width_bit_value)?;
- emit_implicit_conversion(
- builder,
- map,
- &ImplicitConversion {
- src: wide_bit_value,
- dst: cv.dst,
- from_type: wide_bit_type,
- from_space: cv.from_space,
- to_type: cv.to_type.clone(),
- to_space: cv.to_space,
- kind: ConversionKind::Default,
- },
- )?;
- }
- }
- }
- (TypeKind::Scalar, TypeKind::Scalar, &ConversionKind::SignExtend) => {
- let result_type = map.get_or_add(builder, SpirvType::new(cv.to_type.clone()));
- builder.s_convert(result_type, Some(cv.dst), cv.src)?;
- }
- (TypeKind::Vector, TypeKind::Scalar, &ConversionKind::Default)
- | (TypeKind::Scalar, TypeKind::Array, &ConversionKind::Default)
- | (TypeKind::Array, TypeKind::Scalar, &ConversionKind::Default) => {
- let into_type = map.get_or_add(builder, SpirvType::new(cv.to_type.clone()));
- builder.bitcast(into_type, Some(cv.dst), cv.src)?;
- }
- (_, _, &ConversionKind::PtrToPtr) => {
- let result_type = map.get_or_add(
- builder,
- SpirvType::Pointer(
- Box::new(SpirvType::new(cv.to_type.clone())),
- cv.to_space.to_spirv(),
- ),
- );
- if cv.to_space == ast::StateSpace::Generic && cv.from_space != ast::StateSpace::Generic
- {
- let src = if cv.from_type != cv.to_type {
- let temp_type = map.get_or_add(
- builder,
- SpirvType::Pointer(
- Box::new(SpirvType::new(cv.to_type.clone())),
- cv.from_space.to_spirv(),
- ),
- );
- builder.bitcast(temp_type, None, cv.src)?
- } else {
- cv.src
- };
- builder.ptr_cast_to_generic(result_type, Some(cv.dst), src)?;
- } else if cv.from_space == ast::StateSpace::Generic
- && cv.to_space != ast::StateSpace::Generic
- {
- let src = if cv.from_type != cv.to_type {
- let temp_type = map.get_or_add(
- builder,
- SpirvType::Pointer(
- Box::new(SpirvType::new(cv.to_type.clone())),
- cv.from_space.to_spirv(),
- ),
- );
- builder.bitcast(temp_type, None, cv.src)?
- } else {
- cv.src
- };
- builder.generic_cast_to_ptr(result_type, Some(cv.dst), src)?;
- } else {
- builder.bitcast(result_type, Some(cv.dst), cv.src)?;
- }
- }
- (_, _, &ConversionKind::AddressOf) => {
- let dst_type = map.get_or_add(builder, SpirvType::new(cv.to_type.clone()));
- builder.convert_ptr_to_u(dst_type, Some(cv.dst), cv.src)?;
- }
- (TypeKind::Pointer, TypeKind::Scalar, &ConversionKind::Default) => {
- let result_type = map.get_or_add(builder, SpirvType::new(cv.to_type.clone()));
- builder.convert_ptr_to_u(result_type, Some(cv.dst), cv.src)?;
- }
- (TypeKind::Scalar, TypeKind::Pointer, &ConversionKind::Default) => {
- let result_type = map.get_or_add(builder, SpirvType::new(cv.to_type.clone()));
- builder.convert_u_to_ptr(result_type, Some(cv.dst), cv.src)?;
- }
- _ => unreachable!(),
- }
- Ok(())
-}
-
-fn emit_load_var(
- builder: &mut dr::Builder,
- map: &mut TypeWordMap,
- details: &LoadVarDetails,
-) -> Result<(), TranslateError> {
- let result_type = map.get_or_add(builder, SpirvType::new(details.typ.clone()));
- match details.member_index {
- Some((index, Some(width))) => {
- let vector_type = match details.typ {
- ast::Type::Scalar(scalar_t) => ast::Type::Vector(scalar_t, width),
- _ => return Err(TranslateError::MismatchedType),
- };
- let vector_type_spirv = map.get_or_add(builder, SpirvType::new(vector_type));
- let vector_temp = builder.load(
- vector_type_spirv,
- None,
- details.arg.src,
- None,
- iter::empty(),
- )?;
- builder.composite_extract(
- result_type,
- Some(details.arg.dst),
- vector_temp,
- [index as u32].iter().copied(),
- )?;
- }
- Some((index, None)) => {
- let result_ptr_type = map.get_or_add(
- builder,
- SpirvType::pointer_to(details.typ.clone(), spirv::StorageClass::Function),
- );
- let index_spirv = map.get_or_add_constant(
- builder,
- &ast::Type::Scalar(ast::ScalarType::U32),
- &vec_repr(index as u32),
- )?;
- let src = builder.in_bounds_access_chain(
- result_ptr_type,
- None,
- details.arg.src,
- [index_spirv].iter().copied(),
- )?;
- builder.load(result_type, Some(details.arg.dst), src, None, iter::empty())?;
- }
- None => {
- builder.load(
- result_type,
- Some(details.arg.dst),
- details.arg.src,
- None,
- iter::empty(),
- )?;
- }
- };
- Ok(())
-}
-
-fn normalize_identifiers<'input, 'b>(
- id_defs: &mut FnStringIdResolver<'input, 'b>,
- fn_defs: &GlobalFnDeclResolver<'input, 'b>,
- func: Vec<ast::Statement<ast::ParsedArgParams<'input>>>,
-) -> Result<Vec<NormalizedStatement>, TranslateError> {
- for s in func.iter() {
- match s {
- ast::Statement::Label(id) => {
- id_defs.add_def(*id, None, false);
- }
- _ => (),
- }
- }
- let mut result = Vec::new();
- for s in func {
- expand_map_variables(id_defs, fn_defs, &mut result, s)?;
- }
- Ok(result)
-}
-
-fn expand_map_variables<'a, 'b>(
- id_defs: &mut FnStringIdResolver<'a, 'b>,
- fn_defs: &GlobalFnDeclResolver<'a, 'b>,
- result: &mut Vec<NormalizedStatement>,
- s: ast::Statement<ast::ParsedArgParams<'a>>,
-) -> Result<(), TranslateError> {
- match s {
- ast::Statement::Block(block) => {
- id_defs.start_block();
- for s in block {
- expand_map_variables(id_defs, fn_defs, result, s)?;
- }
- id_defs.end_block();
- }
- ast::Statement::Label(name) => result.push(Statement::Label(id_defs.get_id(name)?)),
- ast::Statement::Instruction(p, i) => result.push(Statement::Instruction((
- p.map(|p| p.map_variable(&mut |id| id_defs.get_id(id)))
- .transpose()?,
- i.map_variable(&mut |id| id_defs.get_id(id))?,
- ))),
- ast::Statement::Variable(var) => {
- let var_type = var.var.v_type.clone();
- match var.count {
- Some(count) => {
- for new_id in
- id_defs.add_defs(var.var.name, count, var_type, var.var.state_space, true)
- {
- result.push(Statement::Variable(ast::Variable {
- align: var.var.align,
- v_type: var.var.v_type.clone(),
- state_space: var.var.state_space,
- name: new_id,
- array_init: var.var.array_init.clone(),
- }))
- }
- }
- None => {
- let new_id =
- id_defs.add_def(var.var.name, Some((var_type, var.var.state_space)), true);
- result.push(Statement::Variable(ast::Variable {
- align: var.var.align,
- v_type: var.var.v_type.clone(),
- state_space: var.var.state_space,
- name: new_id,
- array_init: var.var.array_init,
- }));
- }
- }
- }
- };
- Ok(())
-}
-
-/*
- Our goal here is to transform
- .visible .entry foobar(.param .u64 input) {
- .reg .b64 in_addr;
- .reg .b64 in_addr2;
- ld.param.u64 in_addr, [input];
- cvta.to.global.u64 in_addr2, in_addr;
- }
- into:
- .visible .entry foobar(.param .u8 input[]) {
- .reg .u8 in_addr[];
- .reg .u8 in_addr2[];
- ld.param.u8[] in_addr, [input];
- mov.u8[] in_addr2, in_addr;
- }
- or:
- .visible .entry foobar(.reg .u8 input[]) {
- .reg .u8 in_addr[];
- .reg .u8 in_addr2[];
- mov.u8[] in_addr, input;
- mov.u8[] in_addr2, in_addr;
- }
- or:
- .visible .entry foobar(.param ptr<u8, global> input) {
- .reg ptr<u8, global> in_addr;
- .reg ptr<u8, global> in_addr2;
- ld.param.ptr<u8, global> in_addr, [input];
- mov.ptr<u8, global> in_addr2, in_addr;
- }
-*/
-// TODO: detect more patterns (mov, call via reg, call via param)
-// TODO: don't convert to ptr if the register is not ultimately used for ld/st
-// TODO: once insert_mem_ssa_statements is moved to later, move this pass after
-// argument expansion
-// TODO: propagate out of calls and into calls
-fn convert_to_stateful_memory_access<'a, 'input>(
- func_args: Rc<RefCell<ast::MethodDeclaration<'input, spirv::Word>>>,
- func_body: Vec<TypedStatement>,
- id_defs: &mut NumericIdResolver<'a>,
-) -> Result<
- (
- Rc<RefCell<ast::MethodDeclaration<'input, spirv::Word>>>,
- Vec<TypedStatement>,
- ),
- TranslateError,
-> {
- let mut method_decl = func_args.borrow_mut();
- if !method_decl.name.is_kernel() {
- drop(method_decl);
- return Ok((func_args, func_body));
- }
- if Rc::strong_count(&func_args) != 1 {
- return Err(error_unreachable());
- }
- let func_args_64bit = (*method_decl)
- .input_arguments
- .iter()
- .filter_map(|arg| match arg.v_type {
- ast::Type::Scalar(ast::ScalarType::U64)
- | ast::Type::Scalar(ast::ScalarType::B64)
- | ast::Type::Scalar(ast::ScalarType::S64) => Some(arg.name),
- _ => None,
- })
- .collect::<HashSet<_>>();
- let mut stateful_markers = Vec::new();
- let mut stateful_init_reg = HashMap::<_, Vec<_>>::new();
- for statement in func_body.iter() {
- match statement {
- Statement::Instruction(ast::Instruction::Cvta(
- ast::CvtaDetails {
- to: ast::StateSpace::Global,
- size: ast::CvtaSize::U64,
- from: ast::StateSpace::Generic,
- },
- arg,
- )) => {
- if let (TypedOperand::Reg(dst), Some(src)) =
- (arg.dst, arg.src.upcast().underlying_register())
- {
- if is_64_bit_integer(id_defs, *src) && is_64_bit_integer(id_defs, dst) {
- stateful_markers.push((dst, *src));
- }
- }
- }
- Statement::Instruction(ast::Instruction::Ld(
- ast::LdDetails {
- state_space: ast::StateSpace::Param,
- typ: ast::Type::Scalar(ast::ScalarType::U64),
- ..
- },
- arg,
- ))
- | Statement::Instruction(ast::Instruction::Ld(
- ast::LdDetails {
- state_space: ast::StateSpace::Param,
- typ: ast::Type::Scalar(ast::ScalarType::S64),
- ..
- },
- arg,
- ))
- | Statement::Instruction(ast::Instruction::Ld(
- ast::LdDetails {
- state_space: ast::StateSpace::Param,
- typ: ast::Type::Scalar(ast::ScalarType::B64),
- ..
- },
- arg,
- )) => {
- if let (TypedOperand::Reg(dst), Some(src)) =
- (&arg.dst, arg.src.upcast().underlying_register())
- {
- if func_args_64bit.contains(src) {
- multi_hash_map_append(&mut stateful_init_reg, *dst, *src);
- }
- }
- }
- _ => {}
- }
- }
- if stateful_markers.len() == 0 {
- drop(method_decl);
- return Ok((func_args, func_body));
- }
- let mut func_args_ptr = HashSet::new();
- let mut regs_ptr_current = HashSet::new();
- for (dst, src) in stateful_markers {
- if let Some(func_args) = stateful_init_reg.get(&src) {
- for a in func_args {
- func_args_ptr.insert(*a);
- regs_ptr_current.insert(src);
- regs_ptr_current.insert(dst);
- }
- }
- }
- // BTreeSet here to have a stable order of iteration,
- // unfortunately our tests rely on it
- let mut regs_ptr_seen = BTreeSet::new();
- while regs_ptr_current.len() > 0 {
- let mut regs_ptr_new = HashSet::new();
- for statement in func_body.iter() {
- match statement {
- Statement::Instruction(ast::Instruction::Add(
- ast::ArithDetails::Unsigned(ast::ScalarType::U64),
- arg,
- ))
- | Statement::Instruction(ast::Instruction::Add(
- ast::ArithDetails::Signed(ast::ArithSInt {
- typ: ast::ScalarType::S64,
- saturate: false,
- }),
- arg,
- ))
- | Statement::Instruction(ast::Instruction::Sub(
- ast::ArithDetails::Unsigned(ast::ScalarType::U64),
- arg,
- ))
- | Statement::Instruction(ast::Instruction::Sub(
- ast::ArithDetails::Signed(ast::ArithSInt {
- typ: ast::ScalarType::S64,
- saturate: false,
- }),
- arg,
- )) => {
- // TODO: don't mark result of double pointer sub or double
- // pointer add as ptr result
- if let (TypedOperand::Reg(dst), Some(src1)) =
- (arg.dst, arg.src1.upcast().underlying_register())
- {
- if regs_ptr_current.contains(src1) && !regs_ptr_seen.contains(src1) {
- regs_ptr_new.insert(dst);
- }
- } else if let (TypedOperand::Reg(dst), Some(src2)) =
- (arg.dst, arg.src2.upcast().underlying_register())
- {
- if regs_ptr_current.contains(src2) && !regs_ptr_seen.contains(src2) {
- regs_ptr_new.insert(dst);
- }
- }
- }
- _ => {}
- }
- }
- for id in regs_ptr_current {
- regs_ptr_seen.insert(id);
- }
- regs_ptr_current = regs_ptr_new;
- }
- drop(regs_ptr_current);
- let mut remapped_ids = HashMap::new();
- let mut result = Vec::with_capacity(regs_ptr_seen.len() + func_body.len());
- for reg in regs_ptr_seen {
- let new_id = id_defs.register_variable(
- ast::Type::Pointer(ast::ScalarType::U8, ast::StateSpace::Global),
- ast::StateSpace::Reg,
- );
- result.push(Statement::Variable(ast::Variable {
- align: None,
- name: new_id,
- array_init: Vec::new(),
- v_type: ast::Type::Pointer(ast::ScalarType::U8, ast::StateSpace::Global),
- state_space: ast::StateSpace::Reg,
- }));
- remapped_ids.insert(reg, new_id);
- }
- for arg in (*method_decl).input_arguments.iter_mut() {
- if !func_args_ptr.contains(&arg.name) {
- continue;
- }
- let new_id = id_defs.register_variable(
- ast::Type::Pointer(ast::ScalarType::U8, ast::StateSpace::Global),
- ast::StateSpace::Param,
- );
- let old_name = arg.name;
- arg.v_type = ast::Type::Pointer(ast::ScalarType::U8, ast::StateSpace::Global);
- arg.name = new_id;
- remapped_ids.insert(old_name, new_id);
- }
- for statement in func_body {
- match statement {
- l @ Statement::Label(_) => result.push(l),
- c @ Statement::Conditional(_) => result.push(c),
- c @ Statement::Constant(..) => result.push(c),
- Statement::Variable(var) => {
- if !remapped_ids.contains_key(&var.name) {
- result.push(Statement::Variable(var));
- }
- }
- Statement::Instruction(ast::Instruction::Add(
- ast::ArithDetails::Unsigned(ast::ScalarType::U64),
- arg,
- ))
- | Statement::Instruction(ast::Instruction::Add(
- ast::ArithDetails::Signed(ast::ArithSInt {
- typ: ast::ScalarType::S64,
- saturate: false,
- }),
- arg,
- )) if is_add_ptr_direct(&remapped_ids, &arg) => {
- let (ptr, offset) = match arg.src1.upcast().underlying_register() {
- Some(src1) if remapped_ids.contains_key(src1) => {
- (remapped_ids.get(src1).unwrap(), arg.src2)
- }
- Some(src2) if remapped_ids.contains_key(src2) => {
- (remapped_ids.get(src2).unwrap(), arg.src1)
- }
- _ => return Err(error_unreachable()),
- };
- let dst = arg.dst.upcast().unwrap_reg()?;
- result.push(Statement::PtrAccess(PtrAccess {
- underlying_type: ast::Type::Scalar(ast::ScalarType::U8),
- state_space: ast::StateSpace::Global,
- dst: *remapped_ids.get(&dst).unwrap(),
- ptr_src: *ptr,
- offset_src: offset,
- }))
- }
- Statement::Instruction(ast::Instruction::Sub(
- ast::ArithDetails::Unsigned(ast::ScalarType::U64),
- arg,
- ))
- | Statement::Instruction(ast::Instruction::Sub(
- ast::ArithDetails::Signed(ast::ArithSInt {
- typ: ast::ScalarType::S64,
- saturate: false,
- }),
- arg,
- )) if is_sub_ptr_direct(&remapped_ids, &arg) => {
- let (ptr, offset) = match arg.src1.upcast().underlying_register() {
- Some(src1) => (remapped_ids.get(src1).unwrap(), arg.src2),
- _ => return Err(error_unreachable()),
- };
- let offset_neg = id_defs.register_intermediate(Some((
- ast::Type::Scalar(ast::ScalarType::S64),
- ast::StateSpace::Reg,
- )));
- result.push(Statement::Instruction(ast::Instruction::Neg(
- ast::NegDetails {
- typ: ast::ScalarType::S64,
- flush_to_zero: None,
- },
- ast::Arg2 {
- src: offset,
- dst: TypedOperand::Reg(offset_neg),
- },
- )));
- let dst = arg.dst.upcast().unwrap_reg()?;
- result.push(Statement::PtrAccess(PtrAccess {
- underlying_type: ast::Type::Scalar(ast::ScalarType::U8),
- state_space: ast::StateSpace::Global,
- dst: *remapped_ids.get(&dst).unwrap(),
- ptr_src: *ptr,
- offset_src: TypedOperand::Reg(offset_neg),
- }))
- }
- Statement::Instruction(inst) => {
- let mut post_statements = Vec::new();
- let new_statement =
- inst.visit(&mut |arg_desc, expected_type: Option<(&ast::Type, _)>| {
- convert_to_stateful_memory_access_postprocess(
- id_defs,
- &remapped_ids,
- &mut result,
- &mut post_statements,
- arg_desc,
- expected_type,
- )
- })?;
- result.push(new_statement);
- result.extend(post_statements);
- }
- Statement::Call(call) => {
- let mut post_statements = Vec::new();
- let new_statement =
- call.visit(&mut |arg_desc, expected_type: Option<(&ast::Type, _)>| {
- convert_to_stateful_memory_access_postprocess(
- id_defs,
- &remapped_ids,
- &mut result,
- &mut post_statements,
- arg_desc,
- expected_type,
- )
- })?;
- result.push(new_statement);
- result.extend(post_statements);
- }
- Statement::RepackVector(pack) => {
- let mut post_statements = Vec::new();
- let new_statement =
- pack.visit(&mut |arg_desc, expected_type: Option<(&ast::Type, _)>| {
- convert_to_stateful_memory_access_postprocess(
- id_defs,
- &remapped_ids,
- &mut result,
- &mut post_statements,
- arg_desc,
- expected_type,
- )
- })?;
- result.push(new_statement);
- result.extend(post_statements);
- }
- _ => return Err(error_unreachable()),
- }
- }
- drop(method_decl);
- Ok((func_args, result))
-}
-
-fn convert_to_stateful_memory_access_postprocess(
- id_defs: &mut NumericIdResolver,
- remapped_ids: &HashMap<spirv::Word, spirv::Word>,
- result: &mut Vec<TypedStatement>,
- post_statements: &mut Vec<TypedStatement>,
- arg_desc: ArgumentDescriptor<spirv::Word>,
- expected_type: Option<(&ast::Type, ast::StateSpace)>,
-) -> Result<spirv::Word, TranslateError> {
- Ok(match remapped_ids.get(&arg_desc.op) {
- Some(new_id) => {
- let (new_operand_type, new_operand_space, _) = id_defs.get_typed(*new_id)?;
- if let Some((expected_type, expected_space)) = expected_type {
- let implicit_conversion = arg_desc
- .non_default_implicit_conversion
- .unwrap_or(default_implicit_conversion);
- if implicit_conversion(
- (new_operand_space, &new_operand_type),
- (expected_space, expected_type),
- )
- .is_ok()
- {
- return Ok(*new_id);
- }
- }
- let (old_operand_type, old_operand_space, _) = id_defs.get_typed(arg_desc.op)?;
- let converting_id =
- id_defs.register_intermediate(Some((old_operand_type.clone(), old_operand_space)));
- let kind = if new_operand_space.is_compatible(ast::StateSpace::Reg) {
- ConversionKind::Default
- } else {
- ConversionKind::PtrToPtr
- };
- if arg_desc.is_dst {
- post_statements.push(Statement::Conversion(ImplicitConversion {
- src: converting_id,
- dst: *new_id,
- from_type: old_operand_type,
- from_space: old_operand_space,
- to_type: new_operand_type,
- to_space: new_operand_space,
- kind,
- }));
- converting_id
- } else {
- result.push(Statement::Conversion(ImplicitConversion {
- src: *new_id,
- dst: converting_id,
- from_type: new_operand_type,
- from_space: new_operand_space,
- to_type: old_operand_type,
- to_space: old_operand_space,
- kind,
- }));
- converting_id
- }
- }
- None => arg_desc.op,
- })
-}
-
-fn is_add_ptr_direct(remapped_ids: &HashMap<u32, u32>, arg: &ast::Arg3<TypedArgParams>) -> bool {
- match arg.dst {
- TypedOperand::Imm(..) | TypedOperand::RegOffset(..) | TypedOperand::VecMember(..) => {
- return false
- }
- TypedOperand::Reg(dst) => {
- if !remapped_ids.contains_key(&dst) {
- return false;
- }
- if let Some(src1_reg) = arg.src1.upcast().underlying_register() {
- if remapped_ids.contains_key(src1_reg) {
- // don't trigger optimization when adding two pointers
- if let Some(src2_reg) = arg.src2.upcast().underlying_register() {
- return !remapped_ids.contains_key(src2_reg);
- }
- }
- }
- if let Some(src2_reg) = arg.src2.upcast().underlying_register() {
- remapped_ids.contains_key(src2_reg)
- } else {
- false
- }
- }
- }
-}
-
-fn is_sub_ptr_direct(remapped_ids: &HashMap<u32, u32>, arg: &ast::Arg3<TypedArgParams>) -> bool {
- match arg.dst {
- TypedOperand::Imm(..) | TypedOperand::RegOffset(..) | TypedOperand::VecMember(..) => {
- return false
- }
- TypedOperand::Reg(dst) => {
- if !remapped_ids.contains_key(&dst) {
- return false;
- }
- match arg.src1.upcast().underlying_register() {
- Some(src1_reg) => {
- if remapped_ids.contains_key(src1_reg) {
- // don't trigger optimization when subtracting two pointers
- arg.src2
- .upcast()
- .underlying_register()
- .map_or(true, |src2_reg| !remapped_ids.contains_key(src2_reg))
- } else {
- false
- }
- }
- None => false,
- }
- }
- }
-}
-
-fn is_64_bit_integer(id_defs: &NumericIdResolver, id: spirv::Word) -> bool {
- match id_defs.get_typed(id) {
- Ok((ast::Type::Scalar(ast::ScalarType::U64), _, _))
- | Ok((ast::Type::Scalar(ast::ScalarType::S64), _, _))
- | Ok((ast::Type::Scalar(ast::ScalarType::B64), _, _)) => true,
- _ => false,
- }
-}
-
-#[derive(Ord, PartialOrd, Eq, PartialEq, Hash, Copy, Clone)]
-enum PtxSpecialRegister {
- Tid,
- Ntid,
- Ctaid,
- Nctaid,
- Clock,
- LanemaskLt,
-}
-
-impl PtxSpecialRegister {
- fn try_parse(s: &str) -> Option<Self> {
- match s {
- "%tid" => Some(Self::Tid),
- "%ntid" => Some(Self::Ntid),
- "%ctaid" => Some(Self::Ctaid),
- "%nctaid" => Some(Self::Nctaid),
- "%clock" => Some(Self::Clock),
- "%lanemask_lt" => Some(Self::LanemaskLt),
- _ => None,
- }
- }
-
- fn get_type(self) -> ast::Type {
- match self {
- PtxSpecialRegister::Tid
- | PtxSpecialRegister::Ntid
- | PtxSpecialRegister::Ctaid
- | PtxSpecialRegister::Nctaid => ast::Type::Vector(self.get_function_return_type(), 4),
- _ => ast::Type::Scalar(self.get_function_return_type()),
- }
- }
-
- fn get_function_return_type(self) -> ast::ScalarType {
- match self {
- PtxSpecialRegister::Tid => ast::ScalarType::U32,
- PtxSpecialRegister::Ntid => ast::ScalarType::U32,
- PtxSpecialRegister::Ctaid => ast::ScalarType::U32,
- PtxSpecialRegister::Nctaid => ast::ScalarType::U32,
- PtxSpecialRegister::Clock => ast::ScalarType::U32,
- PtxSpecialRegister::LanemaskLt => ast::ScalarType::U32,
- }
- }
-
- fn get_function_input_type(self) -> Option<ast::ScalarType> {
- match self {
- PtxSpecialRegister::Tid
- | PtxSpecialRegister::Ntid
- | PtxSpecialRegister::Ctaid
- | PtxSpecialRegister::Nctaid => Some(ast::ScalarType::U8),
- PtxSpecialRegister::Clock | PtxSpecialRegister::LanemaskLt => None,
- }
- }
-
- fn get_unprefixed_function_name(self) -> &'static str {
- match self {
- PtxSpecialRegister::Tid => "sreg_tid",
- PtxSpecialRegister::Ntid => "sreg_ntid",
- PtxSpecialRegister::Ctaid => "sreg_ctaid",
- PtxSpecialRegister::Nctaid => "sreg_nctaid",
- PtxSpecialRegister::Clock => "sreg_clock",
- PtxSpecialRegister::LanemaskLt => "sreg_lanemask_lt",
- }
- }
-}
-
-struct SpecialRegistersMap {
- reg_to_id: HashMap<PtxSpecialRegister, spirv::Word>,
- id_to_reg: HashMap<spirv::Word, PtxSpecialRegister>,
-}
-
-impl SpecialRegistersMap {
- fn new() -> Self {
- SpecialRegistersMap {
- reg_to_id: HashMap::new(),
- id_to_reg: HashMap::new(),
- }
- }
-
- fn get(&self, id: spirv::Word) -> Option<PtxSpecialRegister> {
- self.id_to_reg.get(&id).copied()
- }
-
- fn get_or_add(&mut self, current_id: &mut spirv::Word, reg: PtxSpecialRegister) -> spirv::Word {
- match self.reg_to_id.entry(reg) {
- hash_map::Entry::Occupied(e) => *e.get(),
- hash_map::Entry::Vacant(e) => {
- let numeric_id = *current_id;
- *current_id += 1;
- e.insert(numeric_id);
- self.id_to_reg.insert(numeric_id, reg);
- numeric_id
- }
- }
- }
-}
-
-struct FnSigMapper<'input> {
- // true - stays as return argument
- // false - is moved to input argument
- return_param_args: Vec<bool>,
- func_decl: Rc<RefCell<ast::MethodDeclaration<'input, spirv::Word>>>,
-}
-
-impl<'input> FnSigMapper<'input> {
- fn remap_to_spirv_repr(mut method: ast::MethodDeclaration<'input, spirv::Word>) -> Self {
- let return_param_args = method
- .return_arguments
- .iter()
- .map(|a| a.state_space != ast::StateSpace::Param)
- .collect::<Vec<_>>();
- let mut new_return_arguments = Vec::new();
- for arg in method.return_arguments.into_iter() {
- if arg.state_space == ast::StateSpace::Param {
- method.input_arguments.push(arg);
- } else {
- new_return_arguments.push(arg);
- }
- }
- method.return_arguments = new_return_arguments;
- FnSigMapper {
- return_param_args,
- func_decl: Rc::new(RefCell::new(method)),
- }
- }
-
- fn resolve_in_spirv_repr(
- &self,
- call_inst: ast::CallInst<NormalizedArgParams>,
- ) -> Result<ResolvedCall<NormalizedArgParams>, TranslateError> {
- let func_decl = (*self.func_decl).borrow();
- let mut return_arguments = Vec::new();
- let mut input_arguments = call_inst
- .param_list
- .into_iter()
- .zip(func_decl.input_arguments.iter())
- .map(|(id, var)| (id, var.v_type.clone(), var.state_space))
- .collect::<Vec<_>>();
- let mut func_decl_return_iter = func_decl.return_arguments.iter();
- let mut func_decl_input_iter = func_decl.input_arguments[input_arguments.len()..].iter();
- for (idx, id) in call_inst.ret_params.iter().enumerate() {
- let stays_as_return = match self.return_param_args.get(idx) {
- Some(x) => *x,
- None => return Err(TranslateError::MismatchedType),
- };
- if stays_as_return {
- if let Some(var) = func_decl_return_iter.next() {
- return_arguments.push((*id, var.v_type.clone(), var.state_space));
- } else {
- return Err(TranslateError::MismatchedType);
- }
- } else {
- if let Some(var) = func_decl_input_iter.next() {
- input_arguments.push((
- ast::Operand::Reg(*id),
- var.v_type.clone(),
- var.state_space,
- ));
- } else {
- return Err(TranslateError::MismatchedType);
- }
- }
- }
- if return_arguments.len() != func_decl.return_arguments.len()
- || input_arguments.len() != func_decl.input_arguments.len()
- {
- return Err(TranslateError::MismatchedType);
- }
- Ok(ResolvedCall {
- return_arguments,
- input_arguments,
- uniform: call_inst.uniform,
- name: call_inst.func,
- })
- }
-}
-
-struct GlobalStringIdResolver<'input> {
- current_id: spirv::Word,
- variables: HashMap<Cow<'input, str>, spirv::Word>,
- reverse_variables: HashMap<spirv::Word, &'input str>,
- variables_type_check: HashMap<u32, Option<(ast::Type, ast::StateSpace, bool)>>,
- special_registers: SpecialRegistersMap,
- fns: HashMap<spirv::Word, FnSigMapper<'input>>,
-}
-
-impl<'input> GlobalStringIdResolver<'input> {
- fn new(start_id: spirv::Word) -> Self {
- Self {
- current_id: start_id,
- variables: HashMap::new(),
- reverse_variables: HashMap::new(),
- variables_type_check: HashMap::new(),
- special_registers: SpecialRegistersMap::new(),
- fns: HashMap::new(),
- }
- }
-
- fn get_or_add_def(&mut self, id: &'input str) -> spirv::Word {
- self.get_or_add_impl(id, None)
- }
-
- fn get_or_add_def_typed(
- &mut self,
- id: &'input str,
- typ: ast::Type,
- state_space: ast::StateSpace,
- is_variable: bool,
- ) -> spirv::Word {
- self.get_or_add_impl(id, Some((typ, state_space, is_variable)))
- }
-
- fn get_or_add_impl(
- &mut self,
- id: &'input str,
- typ: Option<(ast::Type, ast::StateSpace, bool)>,
- ) -> spirv::Word {
- let id = match self.variables.entry(Cow::Borrowed(id)) {
- hash_map::Entry::Occupied(e) => *(e.get()),
- hash_map::Entry::Vacant(e) => {
- let numeric_id = self.current_id;
- e.insert(numeric_id);
- self.reverse_variables.insert(numeric_id, id);
- self.current_id += 1;
- numeric_id
- }
- };
- self.variables_type_check.insert(id, typ);
- id
- }
-
- fn get_id(&self, id: &str) -> Result<spirv::Word, TranslateError> {
- self.variables
- .get(id)
- .copied()
- .ok_or_else(error_unknown_symbol)
- }
-
- fn current_id(&self) -> spirv::Word {
- self.current_id
- }
-
- fn start_fn<'b>(
- &'b mut self,
- header: &'b ast::MethodDeclaration<'input, &'input str>,
- ) -> Result<
- (
- FnStringIdResolver<'input, 'b>,
- GlobalFnDeclResolver<'input, 'b>,
- Rc<RefCell<ast::MethodDeclaration<'input, spirv::Word>>>,
- ),
- TranslateError,
- > {
- // In case a function decl was inserted earlier we want to use its id
- let name_id = self.get_or_add_def(header.name());
- let mut fn_resolver = FnStringIdResolver {
- current_id: &mut self.current_id,
- global_variables: &self.variables,
- global_type_check: &self.variables_type_check,
- special_registers: &mut self.special_registers,
- variables: vec![HashMap::new(); 1],
- type_check: HashMap::new(),
- };
- let return_arguments = rename_fn_params(&mut fn_resolver, &header.return_arguments);
- let input_arguments = rename_fn_params(&mut fn_resolver, &header.input_arguments);
- let name = match header.name {
- ast::MethodName::Kernel(name) => ast::MethodName::Kernel(name),
- ast::MethodName::Func(_) => ast::MethodName::Func(name_id),
- };
- let fn_decl = ast::MethodDeclaration {
- return_arguments,
- name,
- input_arguments,
- shared_mem: None,
- };
- let new_fn_decl = if !fn_decl.name.is_kernel() {
- let resolver = FnSigMapper::remap_to_spirv_repr(fn_decl);
- let new_fn_decl = resolver.func_decl.clone();
- self.fns.insert(name_id, resolver);
- new_fn_decl
- } else {
- Rc::new(RefCell::new(fn_decl))
- };
- Ok((
- fn_resolver,
- GlobalFnDeclResolver { fns: &self.fns },
- new_fn_decl,
- ))
- }
-}
-
-pub struct GlobalFnDeclResolver<'input, 'a> {
- fns: &'a HashMap<spirv::Word, FnSigMapper<'input>>,
-}
-
-impl<'input, 'a> GlobalFnDeclResolver<'input, 'a> {
- fn get_fn_sig_resolver(&self, id: spirv::Word) -> Result<&FnSigMapper<'input>, TranslateError> {
- self.fns.get(&id).ok_or_else(error_unknown_symbol)
- }
-}
-
-struct FnStringIdResolver<'input, 'b> {
- current_id: &'b mut spirv::Word,
- global_variables: &'b HashMap<Cow<'input, str>, spirv::Word>,
- global_type_check: &'b HashMap<u32, Option<(ast::Type, ast::StateSpace, bool)>>,
- special_registers: &'b mut SpecialRegistersMap,
- variables: Vec<HashMap<Cow<'input, str>, spirv::Word>>,
- type_check: HashMap<u32, Option<(ast::Type, ast::StateSpace, bool)>>,
-}
-
-impl<'a, 'b> FnStringIdResolver<'a, 'b> {
- fn finish(self) -> NumericIdResolver<'b> {
- NumericIdResolver {
- current_id: self.current_id,
- global_type_check: self.global_type_check,
- type_check: self.type_check,
- special_registers: self.special_registers,
- }
- }
-
- fn start_block(&mut self) {
- self.variables.push(HashMap::new())
- }
-
- fn end_block(&mut self) {
- self.variables.pop();
- }
-
- fn get_id(&mut self, id: &str) -> Result<spirv::Word, TranslateError> {
- for scope in self.variables.iter().rev() {
- match scope.get(id) {
- Some(id) => return Ok(*id),
- None => continue,
- }
- }
- match self.global_variables.get(id) {
- Some(id) => Ok(*id),
- None => {
- let sreg = PtxSpecialRegister::try_parse(id).ok_or_else(error_unknown_symbol)?;
- Ok(self.special_registers.get_or_add(self.current_id, sreg))
- }
- }
- }
-
- fn add_def(
- &mut self,
- id: &'a str,
- typ: Option<(ast::Type, ast::StateSpace)>,
- is_variable: bool,
- ) -> spirv::Word {
- let numeric_id = *self.current_id;
- self.variables
- .last_mut()
- .unwrap()
- .insert(Cow::Borrowed(id), numeric_id);
- self.type_check.insert(
- numeric_id,
- typ.map(|(typ, space)| (typ, space, is_variable)),
- );
- *self.current_id += 1;
- numeric_id
- }
-
- #[must_use]
- fn add_defs(
- &mut self,
- base_id: &'a str,
- count: u32,
- typ: ast::Type,
- state_space: ast::StateSpace,
- is_variable: bool,
- ) -> impl Iterator<Item = spirv::Word> {
- let numeric_id = *self.current_id;
- for i in 0..count {
- self.variables
- .last_mut()
- .unwrap()
- .insert(Cow::Owned(format!("{}{}", base_id, i)), numeric_id + i);
- self.type_check.insert(
- numeric_id + i,
- Some((typ.clone(), state_space, is_variable)),
- );
- }
- *self.current_id += count;
- (0..count).into_iter().map(move |i| i + numeric_id)
- }
-}
-
-struct NumericIdResolver<'b> {
- current_id: &'b mut spirv::Word,
- global_type_check: &'b HashMap<u32, Option<(ast::Type, ast::StateSpace, bool)>>,
- type_check: HashMap<u32, Option<(ast::Type, ast::StateSpace, bool)>>,
- special_registers: &'b mut SpecialRegistersMap,
-}
-
-impl<'b> NumericIdResolver<'b> {
- fn finish(self) -> MutableNumericIdResolver<'b> {
- MutableNumericIdResolver { base: self }
- }
-
- fn get_typed(
- &self,
- id: spirv::Word,
- ) -> Result<(ast::Type, ast::StateSpace, bool), TranslateError> {
- match self.type_check.get(&id) {
- Some(Some(x)) => Ok(x.clone()),
- Some(None) => Err(TranslateError::UntypedSymbol),
- None => match self.special_registers.get(id) {
- Some(x) => Ok((x.get_type(), ast::StateSpace::Sreg, true)),
- None => match self.global_type_check.get(&id) {
- Some(Some(result)) => Ok(result.clone()),
- Some(None) | None => Err(TranslateError::UntypedSymbol),
- },
- },
- }
- }
-
- // This is for identifiers which will be emitted later as OpVariable
- // They are candidates for insertion of LoadVar/StoreVar
- fn register_variable(&mut self, typ: ast::Type, state_space: ast::StateSpace) -> spirv::Word {
- let new_id = *self.current_id;
- self.type_check
- .insert(new_id, Some((typ, state_space, true)));
- *self.current_id += 1;
- new_id
- }
-
- fn register_intermediate(&mut self, typ: Option<(ast::Type, ast::StateSpace)>) -> spirv::Word {
- let new_id = *self.current_id;
- self.type_check
- .insert(new_id, typ.map(|(t, space)| (t, space, false)));
- *self.current_id += 1;
- new_id
- }
-}
-
-struct MutableNumericIdResolver<'b> {
- base: NumericIdResolver<'b>,
-}
-
-impl<'b> MutableNumericIdResolver<'b> {
- fn unmut(self) -> NumericIdResolver<'b> {
- self.base
- }
-
- fn get_typed(&self, id: spirv::Word) -> Result<(ast::Type, ast::StateSpace), TranslateError> {
- self.base.get_typed(id).map(|(t, space, _)| (t, space))
- }
-
- fn register_intermediate(
- &mut self,
- typ: ast::Type,
- state_space: ast::StateSpace,
- ) -> spirv::Word {
- self.base.register_intermediate(Some((typ, state_space)))
- }
-}
-
-struct FunctionPointerDetails {
- dst: spirv::Word,
- src: spirv::Word,
-}
-
-impl<T: ArgParamsEx<Id = spirv::Word>, U: ArgParamsEx<Id = spirv::Word>> Visitable<T, U>
- for FunctionPointerDetails
-{
- fn visit(
- self,
- visitor: &mut impl ArgumentMapVisitor<T, U>,
- ) -> Result<Statement<ast::Instruction<U>, U>, TranslateError> {
- Ok(Statement::FunctionPointer(FunctionPointerDetails {
- dst: visitor.id(
- ArgumentDescriptor {
- op: self.dst,
- is_dst: true,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- Some((
- &ast::Type::Scalar(ast::ScalarType::U64),
- ast::StateSpace::Reg,
- )),
- )?,
- src: visitor.id(
- ArgumentDescriptor {
- op: self.src,
- is_dst: false,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- None,
- )?,
- }))
- }
-}
-
-enum Statement<I, P: ast::ArgParams> {
- Label(u32),
- Variable(ast::Variable<P::Id>),
- Instruction(I),
- // SPIR-V compatible replacement for PTX predicates
- Conditional(BrachCondition),
- Call(ResolvedCall<P>),
- LoadVar(LoadVarDetails),
- StoreVar(StoreVarDetails),
- Conversion(ImplicitConversion),
- Constant(ConstantDefinition),
- RetValue(ast::RetData, spirv::Word),
- PtrAccess(PtrAccess<P>),
- RepackVector(RepackVectorDetails),
- FunctionPointer(FunctionPointerDetails),
-}
-
-impl ExpandedStatement {
- fn map_id(self, f: &mut impl FnMut(spirv::Word, bool) -> spirv::Word) -> ExpandedStatement {
- match self {
- Statement::Label(id) => Statement::Label(f(id, false)),
- Statement::Variable(mut var) => {
- var.name = f(var.name, true);
- Statement::Variable(var)
- }
- Statement::Instruction(inst) => inst
- .visit(&mut |arg: ArgumentDescriptor<_>,
- _: Option<(&ast::Type, ast::StateSpace)>| {
- Ok(f(arg.op, arg.is_dst))
- })
- .unwrap(),
- Statement::LoadVar(mut details) => {
- details.arg.dst = f(details.arg.dst, true);
- details.arg.src = f(details.arg.src, false);
- Statement::LoadVar(details)
- }
- Statement::StoreVar(mut details) => {
- details.arg.src1 = f(details.arg.src1, false);
- details.arg.src2 = f(details.arg.src2, false);
- Statement::StoreVar(details)
- }
- Statement::Call(mut call) => {
- for (id, _, space) in call.return_arguments.iter_mut() {
- let is_dst = match space {
- ast::StateSpace::Reg => true,
- ast::StateSpace::Param => false,
- ast::StateSpace::Shared => false,
- _ => todo!(),
- };
- *id = f(*id, is_dst);
- }
- call.name = f(call.name, false);
- for (id, _, _) in call.input_arguments.iter_mut() {
- *id = f(*id, false);
- }
- Statement::Call(call)
- }
- Statement::Conditional(mut conditional) => {
- conditional.predicate = f(conditional.predicate, false);
- conditional.if_true = f(conditional.if_true, false);
- conditional.if_false = f(conditional.if_false, false);
- Statement::Conditional(conditional)
- }
- Statement::Conversion(mut conv) => {
- conv.dst = f(conv.dst, true);
- conv.src = f(conv.src, false);
- Statement::Conversion(conv)
- }
- Statement::Constant(mut constant) => {
- constant.dst = f(constant.dst, true);
- Statement::Constant(constant)
- }
- Statement::RetValue(data, id) => {
- let id = f(id, false);
- Statement::RetValue(data, id)
- }
- Statement::PtrAccess(PtrAccess {
- underlying_type,
- state_space,
- dst,
- ptr_src,
- offset_src: constant_src,
- }) => {
- let dst = f(dst, true);
- let ptr_src = f(ptr_src, false);
- let constant_src = f(constant_src, false);
- Statement::PtrAccess(PtrAccess {
- underlying_type,
- state_space,
- dst,
- ptr_src,
- offset_src: constant_src,
- })
- }
- Statement::RepackVector(repack) => {
- let packed = f(repack.packed, !repack.is_extract);
- let unpacked = repack
- .unpacked
- .iter()
- .map(|id| f(*id, repack.is_extract))
- .collect();
- Statement::RepackVector(RepackVectorDetails {
- packed,
- unpacked,
- ..repack
- })
- }
- Statement::FunctionPointer(FunctionPointerDetails { dst, src }) => {
- Statement::FunctionPointer(FunctionPointerDetails {
- dst: f(dst, true),
- src: f(src, false),
- })
- }
- }
- }
-}
-
-struct LoadVarDetails {
- arg: ast::Arg2<ExpandedArgParams>,
- typ: ast::Type,
- state_space: ast::StateSpace,
- // (index, vector_width)
- // HACK ALERT
- // For some reason IGC explodes when you try to load from builtin vectors
- // using OpInBoundsAccessChain, the one true way to do it is to
- // OpLoad+OpCompositeExtract
- member_index: Option<(u8, Option<u8>)>,
-}
-
-struct StoreVarDetails {
- arg: ast::Arg2St<ExpandedArgParams>,
- typ: ast::Type,
- member_index: Option<u8>,
-}
-
-struct RepackVectorDetails {
- is_extract: bool,
- typ: ast::ScalarType,
- packed: spirv::Word,
- unpacked: Vec<spirv::Word>,
- non_default_implicit_conversion: Option<
- fn(
- (ast::StateSpace, &ast::Type),
- (ast::StateSpace, &ast::Type),
- ) -> Result<Option<ConversionKind>, TranslateError>,
- >,
-}
-
-impl RepackVectorDetails {
- fn map<
- From: ArgParamsEx<Id = spirv::Word>,
- To: ArgParamsEx<Id = spirv::Word>,
- V: ArgumentMapVisitor<From, To>,
- >(
- self,
- visitor: &mut V,
- ) -> Result<RepackVectorDetails, TranslateError> {
- let scalar = visitor.id(
- ArgumentDescriptor {
- op: self.packed,
- is_dst: !self.is_extract,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- Some((
- &ast::Type::Vector(self.typ, self.unpacked.len() as u8),
- ast::StateSpace::Reg,
- )),
- )?;
- let scalar_type = self.typ;
- let is_extract = self.is_extract;
- let non_default_implicit_conversion = self.non_default_implicit_conversion;
- let vector = self
- .unpacked
- .into_iter()
- .map(|id| {
- visitor.id(
- ArgumentDescriptor {
- op: id,
- is_dst: is_extract,
- is_memory_access: false,
- non_default_implicit_conversion,
- },
- Some((&ast::Type::Scalar(scalar_type), ast::StateSpace::Reg)),
- )
- })
- .collect::<Result<_, _>>()?;
- Ok(RepackVectorDetails {
- is_extract,
- typ: self.typ,
- packed: scalar,
- unpacked: vector,
- non_default_implicit_conversion,
- })
- }
-}
-
-impl<T: ArgParamsEx<Id = spirv::Word>, U: ArgParamsEx<Id = spirv::Word>> Visitable<T, U>
- for RepackVectorDetails
-{
- fn visit(
- self,
- visitor: &mut impl ArgumentMapVisitor<T, U>,
- ) -> Result<Statement<ast::Instruction<U>, U>, TranslateError> {
- Ok(Statement::RepackVector(self.map::<_, _, _>(visitor)?))
- }
-}
-
-struct ResolvedCall<P: ast::ArgParams> {
- pub uniform: bool,
- pub return_arguments: Vec<(P::Id, ast::Type, ast::StateSpace)>,
- pub name: P::Id,
- pub input_arguments: Vec<(P::Operand, ast::Type, ast::StateSpace)>,
-}
-
-impl<T: ast::ArgParams> ResolvedCall<T> {
- fn cast<U: ast::ArgParams<Id = T::Id, Operand = T::Operand>>(self) -> ResolvedCall<U> {
- ResolvedCall {
- uniform: self.uniform,
- return_arguments: self.return_arguments,
- name: self.name,
- input_arguments: self.input_arguments,
- }
- }
-}
-
-impl<From: ArgParamsEx<Id = spirv::Word>> ResolvedCall<From> {
- fn map<To: ArgParamsEx<Id = spirv::Word>, V: ArgumentMapVisitor<From, To>>(
- self,
- visitor: &mut V,
- ) -> Result<ResolvedCall<To>, TranslateError> {
- let return_arguments = self
- .return_arguments
- .into_iter()
- .map::<Result<_, TranslateError>, _>(|(id, typ, space)| {
- let new_id = visitor.id(
- ArgumentDescriptor {
- op: id,
- is_dst: space != ast::StateSpace::Param,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- Some((&typ, space)),
- )?;
- Ok((new_id, typ, space))
- })
- .collect::<Result<Vec<_>, _>>()?;
- let func = visitor.id(
- ArgumentDescriptor {
- op: self.name,
- is_dst: false,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- None,
- )?;
- let input_arguments = self
- .input_arguments
- .into_iter()
- .map::<Result<_, TranslateError>, _>(|(id, typ, space)| {
- let new_id = visitor.operand(
- ArgumentDescriptor {
- op: id,
- is_dst: false,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- &typ,
- space,
- )?;
- Ok((new_id, typ, space))
- })
- .collect::<Result<Vec<_>, _>>()?;
- Ok(ResolvedCall {
- uniform: self.uniform,
- return_arguments,
- name: func,
- input_arguments,
- })
- }
-}
-
-impl<T: ArgParamsEx<Id = spirv::Word>, U: ArgParamsEx<Id = spirv::Word>> Visitable<T, U>
- for ResolvedCall<T>
-{
- fn visit(
- self,
- visitor: &mut impl ArgumentMapVisitor<T, U>,
- ) -> Result<Statement<ast::Instruction<U>, U>, TranslateError> {
- Ok(Statement::Call(self.map(visitor)?))
- }
-}
-
-impl<P: ArgParamsEx<Id = spirv::Word>> PtrAccess<P> {
- fn map<To: ArgParamsEx<Id = spirv::Word>, V: ArgumentMapVisitor<P, To>>(
- self,
- visitor: &mut V,
- ) -> Result<PtrAccess<To>, TranslateError> {
- let new_dst = visitor.id(
- ArgumentDescriptor {
- op: self.dst,
- is_dst: true,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- Some((&self.underlying_type, self.state_space)),
- )?;
- let new_ptr_src = visitor.id(
- ArgumentDescriptor {
- op: self.ptr_src,
- is_dst: false,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- Some((&self.underlying_type, self.state_space)),
- )?;
- let new_constant_src = visitor.operand(
- ArgumentDescriptor {
- op: self.offset_src,
- is_dst: false,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- &ast::Type::Scalar(ast::ScalarType::S64),
- ast::StateSpace::Reg,
- )?;
- Ok(PtrAccess {
- underlying_type: self.underlying_type,
- state_space: self.state_space,
- dst: new_dst,
- ptr_src: new_ptr_src,
- offset_src: new_constant_src,
- })
- }
-}
-
-impl<T: ArgParamsEx<Id = spirv::Word>, U: ArgParamsEx<Id = spirv::Word>> Visitable<T, U>
- for PtrAccess<T>
-{
- fn visit(
- self,
- visitor: &mut impl ArgumentMapVisitor<T, U>,
- ) -> Result<Statement<ast::Instruction<U>, U>, TranslateError> {
- Ok(Statement::PtrAccess(self.map(visitor)?))
- }
-}
-
-pub trait ArgParamsEx: ast::ArgParams + Sized {}
-
-impl<'input> ArgParamsEx for ast::ParsedArgParams<'input> {}
-
-enum NormalizedArgParams {}
-
-impl ast::ArgParams for NormalizedArgParams {
- type Id = spirv::Word;
- type Operand = ast::Operand<spirv::Word>;
-}
-
-impl ArgParamsEx for NormalizedArgParams {}
-
-type NormalizedStatement = Statement<
- (
- Option<ast::PredAt<spirv::Word>>,
- ast::Instruction<NormalizedArgParams>,
- ),
- NormalizedArgParams,
->;
-
-type UnconditionalStatement = Statement<ast::Instruction<NormalizedArgParams>, NormalizedArgParams>;
-
-enum TypedArgParams {}
-
-impl ast::ArgParams for TypedArgParams {
- type Id = spirv::Word;
- type Operand = TypedOperand;
-}
-
-impl ArgParamsEx for TypedArgParams {}
-
-#[derive(Copy, Clone)]
-enum TypedOperand {
- Reg(spirv::Word),
- RegOffset(spirv::Word, i32),
- Imm(ast::ImmediateValue),
- VecMember(spirv::Word, u8),
-}
-
-impl TypedOperand {
- fn upcast(self) -> ast::Operand<spirv::Word> {
- match self {
- TypedOperand::Reg(reg) => ast::Operand::Reg(reg),
- TypedOperand::RegOffset(reg, idx) => ast::Operand::RegOffset(reg, idx),
- TypedOperand::Imm(x) => ast::Operand::Imm(x),
- TypedOperand::VecMember(vec, idx) => ast::Operand::VecMember(vec, idx),
- }
- }
-}
-
-type TypedStatement = Statement<ast::Instruction<TypedArgParams>, TypedArgParams>;
-
-enum ExpandedArgParams {}
-type ExpandedStatement = Statement<ast::Instruction<ExpandedArgParams>, ExpandedArgParams>;
-
-impl ast::ArgParams for ExpandedArgParams {
- type Id = spirv::Word;
- type Operand = spirv::Word;
-}
-
-impl ArgParamsEx for ExpandedArgParams {}
-
-enum Directive<'input> {
- Variable(ast::LinkingDirective, ast::Variable<spirv::Word>),
- Method(Function<'input>),
-}
-
-struct Function<'input> {
- pub func_decl: Rc<RefCell<ast::MethodDeclaration<'input, spirv::Word>>>,
- pub globals: Vec<ast::Variable<spirv::Word>>,
- pub body: Option<Vec<ExpandedStatement>>,
- import_as: Option<String>,
- tuning: Vec<ast::TuningDirective>,
- linkage: ast::LinkingDirective,
-}
-
-pub trait ArgumentMapVisitor<T: ArgParamsEx, U: ArgParamsEx> {
- fn id(
- &mut self,
- desc: ArgumentDescriptor<T::Id>,
- typ: Option<(&ast::Type, ast::StateSpace)>,
- ) -> Result<U::Id, TranslateError>;
- fn operand(
- &mut self,
- desc: ArgumentDescriptor<T::Operand>,
- typ: &ast::Type,
- state_space: ast::StateSpace,
- ) -> Result<U::Operand, TranslateError>;
-}
-
-impl<T> ArgumentMapVisitor<ExpandedArgParams, ExpandedArgParams> for T
-where
- T: FnMut(
- ArgumentDescriptor<spirv::Word>,
- Option<(&ast::Type, ast::StateSpace)>,
- ) -> Result<spirv::Word, TranslateError>,
-{
- fn id(
- &mut self,
- desc: ArgumentDescriptor<spirv::Word>,
- t: Option<(&ast::Type, ast::StateSpace)>,
- ) -> Result<spirv::Word, TranslateError> {
- self(desc, t)
- }
-
- fn operand(
- &mut self,
- desc: ArgumentDescriptor<spirv::Word>,
- typ: &ast::Type,
- state_space: ast::StateSpace,
- ) -> Result<spirv::Word, TranslateError> {
- self(desc, Some((typ, state_space)))
- }
-}
-
-impl<'a, T> ArgumentMapVisitor<ast::ParsedArgParams<'a>, NormalizedArgParams> for T
-where
- T: FnMut(&str) -> Result<spirv::Word, TranslateError>,
-{
- fn id(
- &mut self,
- desc: ArgumentDescriptor<&str>,
- _: Option<(&ast::Type, ast::StateSpace)>,
- ) -> Result<spirv::Word, TranslateError> {
- self(desc.op)
- }
-
- fn operand(
- &mut self,
- desc: ArgumentDescriptor<ast::Operand<&str>>,
- typ: &ast::Type,
- state_space: ast::StateSpace,
- ) -> Result<ast::Operand<spirv::Word>, TranslateError> {
- Ok(match desc.op {
- ast::Operand::Reg(id) => ast::Operand::Reg(self(id)?),
- ast::Operand::RegOffset(id, imm) => ast::Operand::RegOffset(self(id)?, imm),
- ast::Operand::Imm(imm) => ast::Operand::Imm(imm),
- ast::Operand::VecMember(id, member) => ast::Operand::VecMember(self(id)?, member),
- ast::Operand::VecPack(ref ids) => ast::Operand::VecPack(
- ids.into_iter()
- .map(|id| self.id(desc.new_op(id), Some((typ, state_space))))
- .collect::<Result<Vec<_>, _>>()?,
- ),
- })
- }
-}
-
-pub struct ArgumentDescriptor<Op> {
- op: Op,
- is_dst: bool,
- is_memory_access: bool,
- non_default_implicit_conversion: Option<
- fn(
- (ast::StateSpace, &ast::Type),
- (ast::StateSpace, &ast::Type),
- ) -> Result<Option<ConversionKind>, TranslateError>,
- >,
-}
-
-pub struct PtrAccess<P: ast::ArgParams> {
- underlying_type: ast::Type,
- state_space: ast::StateSpace,
- dst: spirv::Word,
- ptr_src: spirv::Word,
- offset_src: P::Operand,
-}
-
-impl<T> ArgumentDescriptor<T> {
- fn new_op<U>(&self, u: U) -> ArgumentDescriptor<U> {
- ArgumentDescriptor {
- op: u,
- is_dst: self.is_dst,
- is_memory_access: self.is_memory_access,
- non_default_implicit_conversion: self.non_default_implicit_conversion,
- }
- }
-}
-
-impl<T: ArgParamsEx> ast::Instruction<T> {
- fn map<U: ArgParamsEx, V: ArgumentMapVisitor<T, U>>(
- self,
- visitor: &mut V,
- ) -> Result<ast::Instruction<U>, TranslateError> {
- Ok(match self {
- ast::Instruction::Abs(d, arg) => {
- ast::Instruction::Abs(d, arg.map(visitor, &ast::Type::Scalar(d.typ))?)
- }
- // Call instruction is converted to a call statement early on
- ast::Instruction::Call(_) => return Err(error_unreachable()),
- ast::Instruction::Ld(d, a) => {
- let new_args = a.map(visitor, &d)?;
- ast::Instruction::Ld(d, new_args)
- }
- ast::Instruction::Mov(d, a) => {
- let mapped = a.map(visitor, &d)?;
- ast::Instruction::Mov(d, mapped)
- }
- ast::Instruction::Mul(d, a) => {
- let inst_type = d.get_type();
- let is_wide = d.is_wide();
- ast::Instruction::Mul(d, a.map_non_shift(visitor, &inst_type, is_wide)?)
- }
- ast::Instruction::Add(d, a) => {
- let inst_type = d.get_type();
- ast::Instruction::Add(d, a.map_non_shift(visitor, &inst_type, false)?)
- }
- ast::Instruction::Setp(d, a) => {
- let inst_type = d.typ;
- ast::Instruction::Setp(d, a.map(visitor, &ast::Type::Scalar(inst_type))?)
- }
- ast::Instruction::SetpBool(d, a) => {
- let inst_type = d.typ;
- ast::Instruction::SetpBool(d, a.map(visitor, &ast::Type::Scalar(inst_type))?)
- }
- ast::Instruction::Not(t, a) => {
- ast::Instruction::Not(t, a.map(visitor, &ast::Type::Scalar(t))?)
- }
- ast::Instruction::Cvt(d, a) => {
- let (dst_t, src_t, int_to_int) = match &d {
- ast::CvtDetails::FloatFromFloat(desc) => ((desc.dst, desc.src, false)),
- ast::CvtDetails::FloatFromInt(desc) => ((desc.dst, desc.src, false)),
- ast::CvtDetails::IntFromFloat(desc) => ((desc.dst, desc.src, false)),
- ast::CvtDetails::IntFromInt(desc) => ((desc.dst, desc.src, true)),
- };
- ast::Instruction::Cvt(d, a.map_cvt(visitor, dst_t, src_t, int_to_int)?)
- }
- ast::Instruction::Shl(t, a) => {
- ast::Instruction::Shl(t, a.map_shift(visitor, &ast::Type::Scalar(t))?)
- }
- ast::Instruction::Shr(t, a) => {
- ast::Instruction::Shr(t, a.map_shift(visitor, &ast::Type::Scalar(t.into()))?)
- }
- ast::Instruction::St(d, a) => {
- let new_args = a.map(visitor, &d)?;
- ast::Instruction::St(d, new_args)
- }
- ast::Instruction::Bra(d, a) => ast::Instruction::Bra(d, a.map(visitor, false, None)?),
- ast::Instruction::Ret(d) => ast::Instruction::Ret(d),
- ast::Instruction::Cvta(d, a) => {
- let inst_type = ast::Type::Scalar(ast::ScalarType::B64);
- ast::Instruction::Cvta(d, a.map(visitor, &inst_type)?)
- }
- ast::Instruction::Mad(d, a) => {
- let inst_type = d.get_type();
- let is_wide = d.is_wide();
- ast::Instruction::Mad(d, a.map(visitor, &inst_type, is_wide)?)
- }
- ast::Instruction::Fma(d, a) => {
- let inst_type = ast::Type::Scalar(d.typ);
- ast::Instruction::Fma(d, a.map(visitor, &inst_type, false)?)
- }
- ast::Instruction::Or(t, a) => ast::Instruction::Or(
- t,
- a.map_non_shift(visitor, &ast::Type::Scalar(t.into()), false)?,
- ),
- ast::Instruction::Sub(d, a) => {
- let typ = d.get_type();
- ast::Instruction::Sub(d, a.map_non_shift(visitor, &typ, false)?)
- }
- ast::Instruction::Min(d, a) => {
- let typ = d.get_type();
- ast::Instruction::Min(d, a.map_non_shift(visitor, &typ, false)?)
- }
- ast::Instruction::Max(d, a) => {
- let typ = d.get_type();
- ast::Instruction::Max(d, a.map_non_shift(visitor, &typ, false)?)
- }
- ast::Instruction::Rcp(d, a) => {
- let typ = ast::Type::Scalar(if d.is_f64 {
- ast::ScalarType::F64
- } else {
- ast::ScalarType::F32
- });
- ast::Instruction::Rcp(d, a.map(visitor, &typ)?)
- }
- ast::Instruction::And(t, a) => ast::Instruction::And(
- t,
- a.map_non_shift(visitor, &ast::Type::Scalar(t.into()), false)?,
- ),
- ast::Instruction::Selp(t, a) => ast::Instruction::Selp(t, a.map_selp(visitor, t)?),
- ast::Instruction::Bar(d, a) => ast::Instruction::Bar(d, a.map(visitor)?),
- ast::Instruction::Atom(d, a) => {
- ast::Instruction::Atom(d, a.map_atom(visitor, d.inner.get_type(), d.space)?)
- }
- ast::Instruction::AtomCas(d, a) => {
- ast::Instruction::AtomCas(d, a.map_atom(visitor, d.typ, d.space)?)
- }
- ast::Instruction::Div(d, a) => {
- ast::Instruction::Div(d, a.map_non_shift(visitor, &d.get_type(), false)?)
- }
- ast::Instruction::Sqrt(d, a) => {
- ast::Instruction::Sqrt(d, a.map(visitor, &ast::Type::Scalar(d.typ.into()))?)
- }
- ast::Instruction::Rsqrt(d, a) => {
- ast::Instruction::Rsqrt(d, a.map(visitor, &ast::Type::Scalar(d.typ.into()))?)
- }
- ast::Instruction::Neg(d, a) => {
- ast::Instruction::Neg(d, a.map(visitor, &ast::Type::Scalar(d.typ))?)
- }
- ast::Instruction::Sin { flush_to_zero, arg } => {
- let typ = ast::Type::Scalar(ast::ScalarType::F32);
- ast::Instruction::Sin {
- flush_to_zero,
- arg: arg.map(visitor, &typ)?,
- }
- }
- ast::Instruction::Cos { flush_to_zero, arg } => {
- let typ = ast::Type::Scalar(ast::ScalarType::F32);
- ast::Instruction::Cos {
- flush_to_zero,
- arg: arg.map(visitor, &typ)?,
- }
- }
- ast::Instruction::Lg2 { flush_to_zero, arg } => {
- let typ = ast::Type::Scalar(ast::ScalarType::F32);
- ast::Instruction::Lg2 {
- flush_to_zero,
- arg: arg.map(visitor, &typ)?,
- }
- }
- ast::Instruction::Ex2 { flush_to_zero, arg } => {
- let typ = ast::Type::Scalar(ast::ScalarType::F32);
- ast::Instruction::Ex2 {
- flush_to_zero,
- arg: arg.map(visitor, &typ)?,
- }
- }
- ast::Instruction::Clz { typ, arg } => {
- let dst_type = ast::Type::Scalar(ast::ScalarType::B32);
- let src_type = ast::Type::Scalar(typ.into());
- ast::Instruction::Clz {
- typ,
- arg: arg.map_different_types(visitor, &dst_type, &src_type)?,
- }
- }
- ast::Instruction::Brev { typ, arg } => {
- let full_type = ast::Type::Scalar(typ.into());
- ast::Instruction::Brev {
- typ,
- arg: arg.map(visitor, &full_type)?,
- }
- }
- ast::Instruction::Popc { typ, arg } => {
- let dst_type = ast::Type::Scalar(ast::ScalarType::B32);
- let src_type = ast::Type::Scalar(typ.into());
- ast::Instruction::Popc {
- typ,
- arg: arg.map_different_types(visitor, &dst_type, &src_type)?,
- }
- }
- ast::Instruction::Xor { typ, arg } => {
- let full_type = ast::Type::Scalar(typ.into());
- ast::Instruction::Xor {
- typ,
- arg: arg.map_non_shift(visitor, &full_type, false)?,
- }
- }
- ast::Instruction::Bfe { typ, arg } => {
- let full_type = ast::Type::Scalar(typ.into());
- ast::Instruction::Bfe {
- typ,
- arg: arg.map_bfe(visitor, &full_type)?,
- }
- }
- ast::Instruction::Bfi { typ, arg } => {
- let full_type = ast::Type::Scalar(typ.into());
- ast::Instruction::Bfi {
- typ,
- arg: arg.map_bfi(visitor, &full_type)?,
- }
- }
- ast::Instruction::Rem { typ, arg } => {
- let full_type = ast::Type::Scalar(typ.into());
- ast::Instruction::Rem {
- typ,
- arg: arg.map_non_shift(visitor, &full_type, false)?,
- }
- }
- ast::Instruction::Prmt { control, arg } => ast::Instruction::Prmt {
- control,
- arg: arg.map_prmt(visitor)?,
- },
- ast::Instruction::Activemask { arg } => ast::Instruction::Activemask {
- arg: arg.map(
- visitor,
- true,
- Some((
- &ast::Type::Scalar(ast::ScalarType::B32),
- ast::StateSpace::Reg,
- )),
- )?,
- },
- ast::Instruction::Membar { level } => ast::Instruction::Membar { level },
- })
- }
-}
-
-impl<T: ArgParamsEx, U: ArgParamsEx> Visitable<T, U> for ast::Instruction<T> {
- fn visit(
- self,
- visitor: &mut impl ArgumentMapVisitor<T, U>,
- ) -> Result<Statement<ast::Instruction<U>, U>, TranslateError> {
- Ok(Statement::Instruction(self.map(visitor)?))
- }
-}
-
-impl ImplicitConversion {
- fn map<
- T: ArgParamsEx<Id = spirv::Word>,
- U: ArgParamsEx<Id = spirv::Word>,
- V: ArgumentMapVisitor<T, U>,
- >(
- self,
- visitor: &mut V,
- ) -> Result<Statement<ast::Instruction<U>, U>, TranslateError> {
- let new_dst = visitor.id(
- ArgumentDescriptor {
- op: self.dst,
- is_dst: true,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- Some((&self.to_type, self.to_space)),
- )?;
- let new_src = visitor.id(
- ArgumentDescriptor {
- op: self.src,
- is_dst: false,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- Some((&self.from_type, self.from_space)),
- )?;
- Ok(Statement::Conversion({
- ImplicitConversion {
- src: new_src,
- dst: new_dst,
- ..self
- }
- }))
- }
-}
-
-impl<From: ArgParamsEx<Id = spirv::Word>, To: ArgParamsEx<Id = spirv::Word>> Visitable<From, To>
- for ImplicitConversion
-{
- fn visit(
- self,
- visitor: &mut impl ArgumentMapVisitor<From, To>,
- ) -> Result<Statement<ast::Instruction<To>, To>, TranslateError> {
- Ok(self.map(visitor)?)
- }
-}
-
-impl<T> ArgumentMapVisitor<TypedArgParams, TypedArgParams> for T
-where
- T: FnMut(
- ArgumentDescriptor<spirv::Word>,
- Option<(&ast::Type, ast::StateSpace)>,
- ) -> Result<spirv::Word, TranslateError>,
-{
- fn id(
- &mut self,
- desc: ArgumentDescriptor<spirv::Word>,
- t: Option<(&ast::Type, ast::StateSpace)>,
- ) -> Result<spirv::Word, TranslateError> {
- self(desc, t)
- }
-
- fn operand(
- &mut self,
- desc: ArgumentDescriptor<TypedOperand>,
- typ: &ast::Type,
- state_space: ast::StateSpace,
- ) -> Result<TypedOperand, TranslateError> {
- Ok(match desc.op {
- TypedOperand::Reg(id) => {
- TypedOperand::Reg(self(desc.new_op(id), Some((typ, state_space)))?)
- }
- TypedOperand::Imm(imm) => TypedOperand::Imm(imm),
- TypedOperand::RegOffset(id, imm) => {
- TypedOperand::RegOffset(self(desc.new_op(id), Some((typ, state_space)))?, imm)
- }
- TypedOperand::VecMember(reg, index) => {
- let scalar_type = match typ {
- ast::Type::Scalar(scalar_t) => *scalar_t,
- _ => return Err(error_unreachable()),
- };
- let vec_type = ast::Type::Vector(scalar_type, index + 1);
- TypedOperand::VecMember(
- self(desc.new_op(reg), Some((&vec_type, state_space)))?,
- index,
- )
- }
- })
- }
-}
-
-impl ast::Type {
- fn widen(self) -> Result<Self, TranslateError> {
- match self {
- ast::Type::Scalar(scalar) => {
- let kind = scalar.kind();
- let width = scalar.size_of();
- if (kind != ast::ScalarKind::Signed
- && kind != ast::ScalarKind::Unsigned
- && kind != ast::ScalarKind::Bit)
- || (width == 8)
- {
- return Err(TranslateError::MismatchedType);
- }
- Ok(ast::Type::Scalar(ast::ScalarType::from_parts(
- width * 2,
- kind,
- )))
- }
- _ => Err(error_unreachable()),
- }
- }
-
- fn to_parts(&self) -> TypeParts {
- match self {
- ast::Type::Scalar(scalar) => TypeParts {
- kind: TypeKind::Scalar,
- state_space: ast::StateSpace::Reg,
- scalar_kind: scalar.kind(),
- width: scalar.size_of(),
- components: Vec::new(),
- },
- ast::Type::Vector(scalar, components) => TypeParts {
- kind: TypeKind::Vector,
- state_space: ast::StateSpace::Reg,
- scalar_kind: scalar.kind(),
- width: scalar.size_of(),
- components: vec![*components as u32],
- },
- ast::Type::Array(scalar, components) => TypeParts {
- kind: TypeKind::Array,
- state_space: ast::StateSpace::Reg,
- scalar_kind: scalar.kind(),
- width: scalar.size_of(),
- components: components.clone(),
- },
- ast::Type::Pointer(scalar, space) => TypeParts {
- kind: TypeKind::Pointer,
- state_space: *space,
- scalar_kind: scalar.kind(),
- width: scalar.size_of(),
- components: Vec::new(),
- },
- }
- }
-
- fn from_parts(t: TypeParts) -> Self {
- match t.kind {
- TypeKind::Scalar => {
- ast::Type::Scalar(ast::ScalarType::from_parts(t.width, t.scalar_kind))
- }
- TypeKind::Vector => ast::Type::Vector(
- ast::ScalarType::from_parts(t.width, t.scalar_kind),
- t.components[0] as u8,
- ),
- TypeKind::Array => ast::Type::Array(
- ast::ScalarType::from_parts(t.width, t.scalar_kind),
- t.components,
- ),
- TypeKind::Pointer => ast::Type::Pointer(
- ast::ScalarType::from_parts(t.width, t.scalar_kind),
- t.state_space,
- ),
- }
- }
-
- pub fn size_of(&self) -> usize {
- match self {
- ast::Type::Scalar(typ) => typ.size_of() as usize,
- ast::Type::Vector(typ, len) => (typ.size_of() as usize) * (*len as usize),
- ast::Type::Array(typ, len) => len
- .iter()
- .fold(typ.size_of() as usize, |x, y| (x as usize) * (*y as usize)),
- ast::Type::Pointer(..) => mem::size_of::<usize>(),
- }
- }
-}
-
-#[derive(Eq, PartialEq, Clone)]
-struct TypeParts {
- kind: TypeKind,
- scalar_kind: ast::ScalarKind,
- width: u8,
- state_space: ast::StateSpace,
- components: Vec<u32>,
-}
-
-#[derive(Eq, PartialEq, Copy, Clone)]
-enum TypeKind {
- Scalar,
- Vector,
- Array,
- Pointer,
-}
-
-impl ast::Instruction<ExpandedArgParams> {
- fn jump_target(&self) -> Option<spirv::Word> {
- match self {
- ast::Instruction::Bra(_, a) => Some(a.src),
- _ => None,
- }
- }
-
- // .wide instructions don't support ftz, so it's enough to just look at the
- // type declared by the instruction
- fn flush_to_zero(&self) -> Option<(bool, u8)> {
- match self {
- ast::Instruction::Ld(_, _) => None,
- ast::Instruction::St(_, _) => None,
- ast::Instruction::Mov(_, _) => None,
- ast::Instruction::Not(_, _) => None,
- ast::Instruction::Bra(_, _) => None,
- ast::Instruction::Shl(_, _) => None,
- ast::Instruction::Shr(_, _) => None,
- ast::Instruction::Ret(_) => None,
- ast::Instruction::Call(_) => None,
- ast::Instruction::Or(_, _) => None,
- ast::Instruction::And(_, _) => None,
- ast::Instruction::Cvta(_, _) => None,
- ast::Instruction::Selp(_, _) => None,
- ast::Instruction::Bar(_, _) => None,
- ast::Instruction::Atom(_, _) => None,
- ast::Instruction::AtomCas(_, _) => None,
- ast::Instruction::Sub(ast::ArithDetails::Signed(_), _) => None,
- ast::Instruction::Sub(ast::ArithDetails::Unsigned(_), _) => None,
- ast::Instruction::Add(ast::ArithDetails::Signed(_), _) => None,
- ast::Instruction::Add(ast::ArithDetails::Unsigned(_), _) => None,
- ast::Instruction::Mul(ast::MulDetails::Unsigned(_), _) => None,
- ast::Instruction::Mul(ast::MulDetails::Signed(_), _) => None,
- ast::Instruction::Mad(ast::MulDetails::Unsigned(_), _) => None,
- ast::Instruction::Mad(ast::MulDetails::Signed(_), _) => None,
- ast::Instruction::Min(ast::MinMaxDetails::Signed(_), _) => None,
- ast::Instruction::Min(ast::MinMaxDetails::Unsigned(_), _) => None,
- ast::Instruction::Max(ast::MinMaxDetails::Signed(_), _) => None,
- ast::Instruction::Max(ast::MinMaxDetails::Unsigned(_), _) => None,
- ast::Instruction::Cvt(ast::CvtDetails::IntFromInt(_), _) => None,
- ast::Instruction::Cvt(ast::CvtDetails::FloatFromInt(_), _) => None,
- ast::Instruction::Div(ast::DivDetails::Unsigned(_), _) => None,
- ast::Instruction::Div(ast::DivDetails::Signed(_), _) => None,
- ast::Instruction::Clz { .. } => None,
- ast::Instruction::Brev { .. } => None,
- ast::Instruction::Popc { .. } => None,
- ast::Instruction::Xor { .. } => None,
- ast::Instruction::Bfe { .. } => None,
- ast::Instruction::Bfi { .. } => None,
- ast::Instruction::Rem { .. } => None,
- ast::Instruction::Prmt { .. } => None,
- ast::Instruction::Activemask { .. } => None,
- ast::Instruction::Membar { .. } => None,
- ast::Instruction::Sub(ast::ArithDetails::Float(float_control), _)
- | ast::Instruction::Add(ast::ArithDetails::Float(float_control), _)
- | ast::Instruction::Mul(ast::MulDetails::Float(float_control), _)
- | ast::Instruction::Mad(ast::MulDetails::Float(float_control), _) => float_control
- .flush_to_zero
- .map(|ftz| (ftz, ast::ScalarType::from(float_control.typ).size_of())),
- ast::Instruction::Fma(d, _) => d.flush_to_zero.map(|ftz| (ftz, d.typ.size_of())),
- ast::Instruction::Setp(details, _) => details
- .flush_to_zero
- .map(|ftz| (ftz, details.typ.size_of())),
- ast::Instruction::SetpBool(details, _) => details
- .flush_to_zero
- .map(|ftz| (ftz, details.typ.size_of())),
- ast::Instruction::Abs(details, _) => details
- .flush_to_zero
- .map(|ftz| (ftz, details.typ.size_of())),
- ast::Instruction::Min(ast::MinMaxDetails::Float(float_control), _)
- | ast::Instruction::Max(ast::MinMaxDetails::Float(float_control), _) => float_control
- .flush_to_zero
- .map(|ftz| (ftz, ast::ScalarType::from(float_control.typ).size_of())),
- ast::Instruction::Rcp(details, _) => details
- .flush_to_zero
- .map(|ftz| (ftz, if details.is_f64 { 8 } else { 4 })),
- // Modifier .ftz can only be specified when either .dtype or .atype
- // is .f32 and applies only to single precision (.f32) inputs and results.
- ast::Instruction::Cvt(
- ast::CvtDetails::FloatFromFloat(ast::CvtDesc { flush_to_zero, .. }),
- _,
- )
- | ast::Instruction::Cvt(
- ast::CvtDetails::IntFromFloat(ast::CvtDesc { flush_to_zero, .. }),
- _,
- ) => flush_to_zero.map(|ftz| (ftz, 4)),
- ast::Instruction::Div(ast::DivDetails::Float(details), _) => details
- .flush_to_zero
- .map(|ftz| (ftz, ast::ScalarType::from(details.typ).size_of())),
- ast::Instruction::Sqrt(details, _) => details
- .flush_to_zero
- .map(|ftz| (ftz, ast::ScalarType::from(details.typ).size_of())),
- ast::Instruction::Rsqrt(details, _) => Some((
- details.flush_to_zero,
- ast::ScalarType::from(details.typ).size_of(),
- )),
- ast::Instruction::Neg(details, _) => details
- .flush_to_zero
- .map(|ftz| (ftz, details.typ.size_of())),
- ast::Instruction::Sin { flush_to_zero, .. }
- | ast::Instruction::Cos { flush_to_zero, .. }
- | ast::Instruction::Lg2 { flush_to_zero, .. }
- | ast::Instruction::Ex2 { flush_to_zero, .. } => {
- Some((*flush_to_zero, mem::size_of::<f32>() as u8))
- }
- }
- }
-}
-
-type Arg2 = ast::Arg2<ExpandedArgParams>;
-type Arg2St = ast::Arg2St<ExpandedArgParams>;
-
-struct ConstantDefinition {
- pub dst: spirv::Word,
- pub typ: ast::ScalarType,
- pub value: ast::ImmediateValue,
-}
-
-struct BrachCondition {
- predicate: spirv::Word,
- if_true: spirv::Word,
- if_false: spirv::Word,
-}
-
-impl<From: ArgParamsEx<Id = spirv::Word>, To: ArgParamsEx<Id = spirv::Word>> Visitable<From, To>
- for BrachCondition
-{
- fn visit(
- self,
- visitor: &mut impl ArgumentMapVisitor<From, To>,
- ) -> Result<Statement<ast::Instruction<To>, To>, TranslateError> {
- let predicate = visitor.id(
- ArgumentDescriptor {
- op: self.predicate,
- is_dst: false,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- Some((
- &ast::Type::Scalar(ast::ScalarType::Pred),
- ast::StateSpace::Reg,
- )),
- )?;
- let if_true = self.if_true;
- let if_false = self.if_false;
- Ok(Statement::Conditional(BrachCondition {
- predicate,
- if_true,
- if_false,
- }))
- }
-}
-
-#[derive(Clone)]
-struct ImplicitConversion {
- src: spirv::Word,
- dst: spirv::Word,
- from_type: ast::Type,
- to_type: ast::Type,
- from_space: ast::StateSpace,
- to_space: ast::StateSpace,
- kind: ConversionKind,
-}
-
-#[derive(PartialEq, Clone)]
-enum ConversionKind {
- Default,
- // zero-extend/chop/bitcast depending on types
- SignExtend,
- BitToPtr,
- PtrToPtr,
- AddressOf,
-}
-
-impl<T> ast::PredAt<T> {
- fn map_variable<U, F: FnMut(T) -> Result<U, TranslateError>>(
- self,
- f: &mut F,
- ) -> Result<ast::PredAt<U>, TranslateError> {
- let new_label = f(self.label)?;
- Ok(ast::PredAt {
- not: self.not,
- label: new_label,
- })
- }
-}
-
-impl<'a> ast::Instruction<ast::ParsedArgParams<'a>> {
- fn map_variable<F: FnMut(&str) -> Result<spirv::Word, TranslateError>>(
- self,
- f: &mut F,
- ) -> Result<ast::Instruction<NormalizedArgParams>, TranslateError> {
- match self {
- ast::Instruction::Call(call) => {
- let call_inst = ast::CallInst {
- uniform: call.uniform,
- ret_params: call
- .ret_params
- .into_iter()
- .map(|p| f(p))
- .collect::<Result<_, _>>()?,
- func: f(call.func)?,
- param_list: call
- .param_list
- .into_iter()
- .map(|p| p.map_variable(f))
- .collect::<Result<_, _>>()?,
- };
- Ok(ast::Instruction::Call(call_inst))
- }
- i => i.map(f),
- }
- }
-}
-
-impl<T: ArgParamsEx> ast::Arg1<T> {
- fn map<U: ArgParamsEx, V: ArgumentMapVisitor<T, U>>(
- self,
- visitor: &mut V,
- is_dst: bool,
- t: Option<(&ast::Type, ast::StateSpace)>,
- ) -> Result<ast::Arg1<U>, TranslateError> {
- let new_src = visitor.id(
- ArgumentDescriptor {
- op: self.src,
- is_dst,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- t,
- )?;
- Ok(ast::Arg1 { src: new_src })
- }
-}
-
-impl<T: ArgParamsEx> ast::Arg1Bar<T> {
- fn map<U: ArgParamsEx, V: ArgumentMapVisitor<T, U>>(
- self,
- visitor: &mut V,
- ) -> Result<ast::Arg1Bar<U>, TranslateError> {
- let new_src = visitor.operand(
- ArgumentDescriptor {
- op: self.src,
- is_dst: false,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- &ast::Type::Scalar(ast::ScalarType::U32),
- ast::StateSpace::Reg,
- )?;
- Ok(ast::Arg1Bar { src: new_src })
- }
-}
-
-impl<T: ArgParamsEx> ast::Arg2<T> {
- fn map<U: ArgParamsEx, V: ArgumentMapVisitor<T, U>>(
- self,
- visitor: &mut V,
- t: &ast::Type,
- ) -> Result<ast::Arg2<U>, TranslateError> {
- let new_dst = visitor.operand(
- ArgumentDescriptor {
- op: self.dst,
- is_dst: true,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- t,
- ast::StateSpace::Reg,
- )?;
- let new_src = visitor.operand(
- ArgumentDescriptor {
- op: self.src,
- is_dst: false,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- t,
- ast::StateSpace::Reg,
- )?;
- Ok(ast::Arg2 {
- dst: new_dst,
- src: new_src,
- })
- }
-
- fn map_cvt<U: ArgParamsEx, V: ArgumentMapVisitor<T, U>>(
- self,
- visitor: &mut V,
- dst_t: ast::ScalarType,
- src_t: ast::ScalarType,
- is_int_to_int: bool,
- ) -> Result<ast::Arg2<U>, TranslateError> {
- let dst = visitor.operand(
- ArgumentDescriptor {
- op: self.dst,
- is_dst: true,
- is_memory_access: false,
- non_default_implicit_conversion: if is_int_to_int {
- Some(should_convert_relaxed_dst_wrapper)
- } else {
- None
- },
- },
- &ast::Type::Scalar(dst_t),
- ast::StateSpace::Reg,
- )?;
- let src = visitor.operand(
- ArgumentDescriptor {
- op: self.src,
- is_dst: false,
- is_memory_access: false,
- non_default_implicit_conversion: if is_int_to_int {
- Some(should_convert_relaxed_src_wrapper)
- } else {
- None
- },
- },
- &ast::Type::Scalar(src_t),
- ast::StateSpace::Reg,
- )?;
- Ok(ast::Arg2 { dst, src })
- }
-
- fn map_different_types<U: ArgParamsEx, V: ArgumentMapVisitor<T, U>>(
- self,
- visitor: &mut V,
- dst_t: &ast::Type,
- src_t: &ast::Type,
- ) -> Result<ast::Arg2<U>, TranslateError> {
- let dst = visitor.operand(
- ArgumentDescriptor {
- op: self.dst,
- is_dst: true,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- dst_t,
- ast::StateSpace::Reg,
- )?;
- let src = visitor.operand(
- ArgumentDescriptor {
- op: self.src,
- is_dst: false,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- src_t,
- ast::StateSpace::Reg,
- )?;
- Ok(ast::Arg2 { dst, src })
- }
-}
-
-impl<T: ArgParamsEx> ast::Arg2Ld<T> {
- fn map<U: ArgParamsEx, V: ArgumentMapVisitor<T, U>>(
- self,
- visitor: &mut V,
- details: &ast::LdDetails,
- ) -> Result<ast::Arg2Ld<U>, TranslateError> {
- let dst = visitor.operand(
- ArgumentDescriptor {
- op: self.dst,
- is_dst: true,
- is_memory_access: false,
- non_default_implicit_conversion: Some(should_convert_relaxed_dst_wrapper),
- },
- &ast::Type::from(details.typ.clone()),
- ast::StateSpace::Reg,
- )?;
- let src = visitor.operand(
- ArgumentDescriptor {
- op: self.src,
- is_dst: false,
- is_memory_access: true,
- non_default_implicit_conversion: None,
- },
- &details.typ,
- details.state_space,
- )?;
- Ok(ast::Arg2Ld { dst, src })
- }
-}
-
-impl<T: ArgParamsEx> ast::Arg2St<T> {
- fn map<U: ArgParamsEx, V: ArgumentMapVisitor<T, U>>(
- self,
- visitor: &mut V,
- details: &ast::StData,
- ) -> Result<ast::Arg2St<U>, TranslateError> {
- let src1 = visitor.operand(
- ArgumentDescriptor {
- op: self.src1,
- is_dst: false,
- is_memory_access: true,
- non_default_implicit_conversion: None,
- },
- &details.typ,
- details.state_space,
- )?;
- let src2 = visitor.operand(
- ArgumentDescriptor {
- op: self.src2,
- is_dst: false,
- is_memory_access: false,
- non_default_implicit_conversion: Some(should_convert_relaxed_src_wrapper),
- },
- &details.typ.clone().into(),
- ast::StateSpace::Reg,
- )?;
- Ok(ast::Arg2St { src1, src2 })
- }
-}
-
-impl<T: ArgParamsEx> ast::Arg2Mov<T> {
- fn map<U: ArgParamsEx, V: ArgumentMapVisitor<T, U>>(
- self,
- visitor: &mut V,
- details: &ast::MovDetails,
- ) -> Result<ast::Arg2Mov<U>, TranslateError> {
- let dst = visitor.operand(
- ArgumentDescriptor {
- op: self.dst,
- is_dst: true,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- &details.typ.clone().into(),
- ast::StateSpace::Reg,
- )?;
- let src = visitor.operand(
- ArgumentDescriptor {
- op: self.src,
- is_dst: false,
- is_memory_access: false,
- non_default_implicit_conversion: Some(implicit_conversion_mov),
- },
- &details.typ.clone().into(),
- ast::StateSpace::Reg,
- )?;
- Ok(ast::Arg2Mov { dst, src })
- }
-}
-
-impl<T: ArgParamsEx> ast::Arg3<T> {
- fn map_non_shift<U: ArgParamsEx, V: ArgumentMapVisitor<T, U>>(
- self,
- visitor: &mut V,
- typ: &ast::Type,
- is_wide: bool,
- ) -> Result<ast::Arg3<U>, TranslateError> {
- let wide_type = if is_wide {
- Some(typ.clone().widen()?)
- } else {
- None
- };
- let dst = visitor.operand(
- ArgumentDescriptor {
- op: self.dst,
- is_dst: true,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- wide_type.as_ref().unwrap_or(typ),
- ast::StateSpace::Reg,
- )?;
- let src1 = visitor.operand(
- ArgumentDescriptor {
- op: self.src1,
- is_dst: false,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- typ,
- ast::StateSpace::Reg,
- )?;
- let src2 = visitor.operand(
- ArgumentDescriptor {
- op: self.src2,
- is_dst: false,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- typ,
- ast::StateSpace::Reg,
- )?;
- Ok(ast::Arg3 { dst, src1, src2 })
- }
-
- fn map_shift<U: ArgParamsEx, V: ArgumentMapVisitor<T, U>>(
- self,
- visitor: &mut V,
- t: &ast::Type,
- ) -> Result<ast::Arg3<U>, TranslateError> {
- let dst = visitor.operand(
- ArgumentDescriptor {
- op: self.dst,
- is_dst: true,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- t,
- ast::StateSpace::Reg,
- )?;
- let src1 = visitor.operand(
- ArgumentDescriptor {
- op: self.src1,
- is_dst: false,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- t,
- ast::StateSpace::Reg,
- )?;
- let src2 = visitor.operand(
- ArgumentDescriptor {
- op: self.src2,
- is_dst: false,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- &ast::Type::Scalar(ast::ScalarType::U32),
- ast::StateSpace::Reg,
- )?;
- Ok(ast::Arg3 { dst, src1, src2 })
- }
-
- fn map_atom<U: ArgParamsEx, V: ArgumentMapVisitor<T, U>>(
- self,
- visitor: &mut V,
- t: ast::ScalarType,
- state_space: ast::StateSpace,
- ) -> Result<ast::Arg3<U>, TranslateError> {
- let scalar_type = ast::ScalarType::from(t);
- let dst = visitor.operand(
- ArgumentDescriptor {
- op: self.dst,
- is_dst: true,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- &ast::Type::Scalar(scalar_type),
- ast::StateSpace::Reg,
- )?;
- let src1 = visitor.operand(
- ArgumentDescriptor {
- op: self.src1,
- is_dst: false,
- is_memory_access: true,
- non_default_implicit_conversion: None,
- },
- &ast::Type::Scalar(scalar_type),
- state_space,
- )?;
- let src2 = visitor.operand(
- ArgumentDescriptor {
- op: self.src2,
- is_dst: false,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- &ast::Type::Scalar(scalar_type),
- ast::StateSpace::Reg,
- )?;
- Ok(ast::Arg3 { dst, src1, src2 })
- }
-
- fn map_prmt<U: ArgParamsEx, V: ArgumentMapVisitor<T, U>>(
- self,
- visitor: &mut V,
- ) -> Result<ast::Arg3<U>, TranslateError> {
- let dst = visitor.operand(
- ArgumentDescriptor {
- op: self.dst,
- is_dst: true,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- &ast::Type::Scalar(ast::ScalarType::B32),
- ast::StateSpace::Reg,
- )?;
- let src1 = visitor.operand(
- ArgumentDescriptor {
- op: self.src1,
- is_dst: false,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- &ast::Type::Scalar(ast::ScalarType::B32),
- ast::StateSpace::Reg,
- )?;
- let src2 = visitor.operand(
- ArgumentDescriptor {
- op: self.src2,
- is_dst: false,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- &ast::Type::Scalar(ast::ScalarType::B32),
- ast::StateSpace::Reg,
- )?;
- Ok(ast::Arg3 { dst, src1, src2 })
- }
-}
-
-impl<T: ArgParamsEx> ast::Arg4<T> {
- fn map<U: ArgParamsEx, V: ArgumentMapVisitor<T, U>>(
- self,
- visitor: &mut V,
- t: &ast::Type,
- is_wide: bool,
- ) -> Result<ast::Arg4<U>, TranslateError> {
- let wide_type = if is_wide {
- Some(t.clone().widen()?)
- } else {
- None
- };
- let dst = visitor.operand(
- ArgumentDescriptor {
- op: self.dst,
- is_dst: true,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- wide_type.as_ref().unwrap_or(t),
- ast::StateSpace::Reg,
- )?;
- let src1 = visitor.operand(
- ArgumentDescriptor {
- op: self.src1,
- is_dst: false,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- t,
- ast::StateSpace::Reg,
- )?;
- let src2 = visitor.operand(
- ArgumentDescriptor {
- op: self.src2,
- is_dst: false,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- t,
- ast::StateSpace::Reg,
- )?;
- let src3 = visitor.operand(
- ArgumentDescriptor {
- op: self.src3,
- is_dst: false,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- t,
- ast::StateSpace::Reg,
- )?;
- Ok(ast::Arg4 {
- dst,
- src1,
- src2,
- src3,
- })
- }
-
- fn map_selp<U: ArgParamsEx, V: ArgumentMapVisitor<T, U>>(
- self,
- visitor: &mut V,
- t: ast::ScalarType,
- ) -> Result<ast::Arg4<U>, TranslateError> {
- let dst = visitor.operand(
- ArgumentDescriptor {
- op: self.dst,
- is_dst: true,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- &ast::Type::Scalar(t.into()),
- ast::StateSpace::Reg,
- )?;
- let src1 = visitor.operand(
- ArgumentDescriptor {
- op: self.src1,
- is_dst: false,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- &ast::Type::Scalar(t.into()),
- ast::StateSpace::Reg,
- )?;
- let src2 = visitor.operand(
- ArgumentDescriptor {
- op: self.src2,
- is_dst: false,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- &ast::Type::Scalar(t.into()),
- ast::StateSpace::Reg,
- )?;
- let src3 = visitor.operand(
- ArgumentDescriptor {
- op: self.src3,
- is_dst: false,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- &ast::Type::Scalar(ast::ScalarType::Pred),
- ast::StateSpace::Reg,
- )?;
- Ok(ast::Arg4 {
- dst,
- src1,
- src2,
- src3,
- })
- }
-
- fn map_atom<U: ArgParamsEx, V: ArgumentMapVisitor<T, U>>(
- self,
- visitor: &mut V,
- t: ast::ScalarType,
- state_space: ast::StateSpace,
- ) -> Result<ast::Arg4<U>, TranslateError> {
- let scalar_type = ast::ScalarType::from(t);
- let dst = visitor.operand(
- ArgumentDescriptor {
- op: self.dst,
- is_dst: true,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- &ast::Type::Scalar(scalar_type),
- ast::StateSpace::Reg,
- )?;
- let src1 = visitor.operand(
- ArgumentDescriptor {
- op: self.src1,
- is_dst: false,
- is_memory_access: true,
- non_default_implicit_conversion: None,
- },
- &ast::Type::Scalar(scalar_type),
- state_space,
- )?;
- let src2 = visitor.operand(
- ArgumentDescriptor {
- op: self.src2,
- is_dst: false,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- &ast::Type::Scalar(scalar_type),
- ast::StateSpace::Reg,
- )?;
- let src3 = visitor.operand(
- ArgumentDescriptor {
- op: self.src3,
- is_dst: false,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- &ast::Type::Scalar(scalar_type),
- ast::StateSpace::Reg,
- )?;
- Ok(ast::Arg4 {
- dst,
- src1,
- src2,
- src3,
- })
- }
-
- fn map_bfe<U: ArgParamsEx, V: ArgumentMapVisitor<T, U>>(
- self,
- visitor: &mut V,
- typ: &ast::Type,
- ) -> Result<ast::Arg4<U>, TranslateError> {
- let dst = visitor.operand(
- ArgumentDescriptor {
- op: self.dst,
- is_dst: true,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- typ,
- ast::StateSpace::Reg,
- )?;
- let src1 = visitor.operand(
- ArgumentDescriptor {
- op: self.src1,
- is_dst: false,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- typ,
- ast::StateSpace::Reg,
- )?;
- let u32_type = ast::Type::Scalar(ast::ScalarType::U32);
- let src2 = visitor.operand(
- ArgumentDescriptor {
- op: self.src2,
- is_dst: false,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- &u32_type,
- ast::StateSpace::Reg,
- )?;
- let src3 = visitor.operand(
- ArgumentDescriptor {
- op: self.src3,
- is_dst: false,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- &u32_type,
- ast::StateSpace::Reg,
- )?;
- Ok(ast::Arg4 {
- dst,
- src1,
- src2,
- src3,
- })
- }
-}
-
-impl<T: ArgParamsEx> ast::Arg4Setp<T> {
- fn map<U: ArgParamsEx, V: ArgumentMapVisitor<T, U>>(
- self,
- visitor: &mut V,
- t: &ast::Type,
- ) -> Result<ast::Arg4Setp<U>, TranslateError> {
- let dst1 = visitor.id(
- ArgumentDescriptor {
- op: self.dst1,
- is_dst: true,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- Some((
- &ast::Type::Scalar(ast::ScalarType::Pred),
- ast::StateSpace::Reg,
- )),
- )?;
- let dst2 = self
- .dst2
- .map(|dst2| {
- visitor.id(
- ArgumentDescriptor {
- op: dst2,
- is_dst: true,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- Some((
- &ast::Type::Scalar(ast::ScalarType::Pred),
- ast::StateSpace::Reg,
- )),
- )
- })
- .transpose()?;
- let src1 = visitor.operand(
- ArgumentDescriptor {
- op: self.src1,
- is_dst: false,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- t,
- ast::StateSpace::Reg,
- )?;
- let src2 = visitor.operand(
- ArgumentDescriptor {
- op: self.src2,
- is_dst: false,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- t,
- ast::StateSpace::Reg,
- )?;
- Ok(ast::Arg4Setp {
- dst1,
- dst2,
- src1,
- src2,
- })
- }
-}
-
-impl<T: ArgParamsEx> ast::Arg5<T> {
- fn map_bfi<U: ArgParamsEx, V: ArgumentMapVisitor<T, U>>(
- self,
- visitor: &mut V,
- base_type: &ast::Type,
- ) -> Result<ast::Arg5<U>, TranslateError> {
- let dst = visitor.operand(
- ArgumentDescriptor {
- op: self.dst,
- is_dst: true,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- base_type,
- ast::StateSpace::Reg,
- )?;
- let src1 = visitor.operand(
- ArgumentDescriptor {
- op: self.src1,
- is_dst: false,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- base_type,
- ast::StateSpace::Reg,
- )?;
- let src2 = visitor.operand(
- ArgumentDescriptor {
- op: self.src2,
- is_dst: false,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- base_type,
- ast::StateSpace::Reg,
- )?;
- let src3 = visitor.operand(
- ArgumentDescriptor {
- op: self.src3,
- is_dst: false,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- &ast::Type::Scalar(ast::ScalarType::U32),
- ast::StateSpace::Reg,
- )?;
- let src4 = visitor.operand(
- ArgumentDescriptor {
- op: self.src4,
- is_dst: false,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- &ast::Type::Scalar(ast::ScalarType::U32),
- ast::StateSpace::Reg,
- )?;
- Ok(ast::Arg5 {
- dst,
- src1,
- src2,
- src3,
- src4,
- })
- }
-}
-
-impl<T: ArgParamsEx> ast::Arg5Setp<T> {
- fn map<U: ArgParamsEx, V: ArgumentMapVisitor<T, U>>(
- self,
- visitor: &mut V,
- t: &ast::Type,
- ) -> Result<ast::Arg5Setp<U>, TranslateError> {
- let dst1 = visitor.id(
- ArgumentDescriptor {
- op: self.dst1,
- is_dst: true,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- Some((
- &ast::Type::Scalar(ast::ScalarType::Pred),
- ast::StateSpace::Reg,
- )),
- )?;
- let dst2 = self
- .dst2
- .map(|dst2| {
- visitor.id(
- ArgumentDescriptor {
- op: dst2,
- is_dst: true,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- Some((
- &ast::Type::Scalar(ast::ScalarType::Pred),
- ast::StateSpace::Reg,
- )),
- )
- })
- .transpose()?;
- let src1 = visitor.operand(
- ArgumentDescriptor {
- op: self.src1,
- is_dst: false,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- t,
- ast::StateSpace::Reg,
- )?;
- let src2 = visitor.operand(
- ArgumentDescriptor {
- op: self.src2,
- is_dst: false,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- t,
- ast::StateSpace::Reg,
- )?;
- let src3 = visitor.operand(
- ArgumentDescriptor {
- op: self.src3,
- is_dst: false,
- is_memory_access: false,
- non_default_implicit_conversion: None,
- },
- &ast::Type::Scalar(ast::ScalarType::Pred),
- ast::StateSpace::Reg,
- )?;
- Ok(ast::Arg5Setp {
- dst1,
- dst2,
- src1,
- src2,
- src3,
- })
- }
-}
-
-impl<T> ast::Operand<T> {
- fn map_variable<U, F: FnMut(T) -> Result<U, TranslateError>>(
- self,
- f: &mut F,
- ) -> Result<ast::Operand<U>, TranslateError> {
- Ok(match self {
- ast::Operand::Reg(reg) => ast::Operand::Reg(f(reg)?),
- ast::Operand::RegOffset(reg, offset) => ast::Operand::RegOffset(f(reg)?, offset),
- ast::Operand::Imm(x) => ast::Operand::Imm(x),
- ast::Operand::VecMember(reg, idx) => ast::Operand::VecMember(f(reg)?, idx),
- ast::Operand::VecPack(vec) => {
- ast::Operand::VecPack(vec.into_iter().map(f).collect::<Result<_, _>>()?)
- }
- })
- }
-}
-
-impl ast::Operand<spirv::Word> {
- fn unwrap_reg(&self) -> Result<spirv::Word, TranslateError> {
- match self {
- ast::Operand::Reg(reg) => Ok(*reg),
- _ => Err(error_unreachable()),
- }
- }
-}
-
-impl ast::ScalarType {
- fn from_parts(width: u8, kind: ast::ScalarKind) -> Self {
- match kind {
- ast::ScalarKind::Float => match width {
- 2 => ast::ScalarType::F16,
- 4 => ast::ScalarType::F32,
- 8 => ast::ScalarType::F64,
- _ => unreachable!(),
- },
- ast::ScalarKind::Bit => match width {
- 1 => ast::ScalarType::B8,
- 2 => ast::ScalarType::B16,
- 4 => ast::ScalarType::B32,
- 8 => ast::ScalarType::B64,
- _ => unreachable!(),
- },
- ast::ScalarKind::Signed => match width {
- 1 => ast::ScalarType::S8,
- 2 => ast::ScalarType::S16,
- 4 => ast::ScalarType::S32,
- 8 => ast::ScalarType::S64,
- _ => unreachable!(),
- },
- ast::ScalarKind::Unsigned => match width {
- 1 => ast::ScalarType::U8,
- 2 => ast::ScalarType::U16,
- 4 => ast::ScalarType::U32,
- 8 => ast::ScalarType::U64,
- _ => unreachable!(),
- },
- ast::ScalarKind::Float2 => match width {
- 4 => ast::ScalarType::F16x2,
- _ => unreachable!(),
- },
- ast::ScalarKind::Pred => ast::ScalarType::Pred,
- }
- }
-}
-
-impl ast::ArithDetails {
- fn get_type(&self) -> ast::Type {
- ast::Type::Scalar(match self {
- ast::ArithDetails::Unsigned(t) => (*t).into(),
- ast::ArithDetails::Signed(d) => d.typ.into(),
- ast::ArithDetails::Float(d) => d.typ.into(),
- })
- }
-}
-
-impl ast::MulDetails {
- fn get_type(&self) -> ast::Type {
- ast::Type::Scalar(match self {
- ast::MulDetails::Unsigned(d) => d.typ.into(),
- ast::MulDetails::Signed(d) => d.typ.into(),
- ast::MulDetails::Float(d) => d.typ.into(),
- })
- }
-}
-
-impl ast::MinMaxDetails {
- fn get_type(&self) -> ast::Type {
- ast::Type::Scalar(match self {
- ast::MinMaxDetails::Signed(t) => (*t).into(),
- ast::MinMaxDetails::Unsigned(t) => (*t).into(),
- ast::MinMaxDetails::Float(d) => d.typ.into(),
- })
- }
-}
-
-impl ast::DivDetails {
- fn get_type(&self) -> ast::Type {
- ast::Type::Scalar(match self {
- ast::DivDetails::Unsigned(t) => (*t).into(),
- ast::DivDetails::Signed(t) => (*t).into(),
- ast::DivDetails::Float(d) => d.typ.into(),
- })
- }
-}
-
-impl ast::AtomInnerDetails {
- fn get_type(&self) -> ast::ScalarType {
- match self {
- ast::AtomInnerDetails::Bit { typ, .. } => (*typ).into(),
- ast::AtomInnerDetails::Unsigned { typ, .. } => (*typ).into(),
- ast::AtomInnerDetails::Signed { typ, .. } => (*typ).into(),
- ast::AtomInnerDetails::Float { typ, .. } => (*typ).into(),
- }
- }
-}
-
-impl ast::StateSpace {
- fn to_spirv(self) -> spirv::StorageClass {
- match self {
- ast::StateSpace::Const => spirv::StorageClass::UniformConstant,
- ast::StateSpace::Generic => spirv::StorageClass::Generic,
- ast::StateSpace::Global => spirv::StorageClass::CrossWorkgroup,
- ast::StateSpace::Local => spirv::StorageClass::Function,
- ast::StateSpace::Shared => spirv::StorageClass::Workgroup,
- ast::StateSpace::Param => spirv::StorageClass::Function,
- ast::StateSpace::Reg => spirv::StorageClass::Function,
- ast::StateSpace::Sreg => spirv::StorageClass::Input,
- }
- }
-
- fn is_compatible(self, other: ast::StateSpace) -> bool {
- self == other
- || self == ast::StateSpace::Reg && other == ast::StateSpace::Sreg
- || self == ast::StateSpace::Sreg && other == ast::StateSpace::Reg
- }
-
- fn coerces_to_generic(self) -> bool {
- match self {
- ast::StateSpace::Global
- | ast::StateSpace::Const
- | ast::StateSpace::Local
- | ast::StateSpace::Shared => true,
- ast::StateSpace::Reg
- | ast::StateSpace::Param
- | ast::StateSpace::Generic
- | ast::StateSpace::Sreg => false,
- }
- }
-
- fn is_addressable(self) -> bool {
- match self {
- ast::StateSpace::Const
- | ast::StateSpace::Generic
- | ast::StateSpace::Global
- | ast::StateSpace::Local
- | ast::StateSpace::Shared => true,
- ast::StateSpace::Param | ast::StateSpace::Reg | ast::StateSpace::Sreg => false,
- }
- }
-}
-
-impl<T> ast::Operand<T> {
- fn underlying_register(&self) -> Option<&T> {
- match self {
- ast::Operand::Reg(r)
- | ast::Operand::RegOffset(r, _)
- | ast::Operand::VecMember(r, _) => Some(r),
- ast::Operand::Imm(_) | ast::Operand::VecPack(..) => None,
- }
- }
-}
-
-impl ast::MulDetails {
- fn is_wide(&self) -> bool {
- match self {
- ast::MulDetails::Unsigned(d) => d.control == ast::MulIntControl::Wide,
- ast::MulDetails::Signed(d) => d.control == ast::MulIntControl::Wide,
- ast::MulDetails::Float(_) => false,
- }
- }
-}
-
-impl ast::MemScope {
- fn to_spirv(self) -> spirv::Scope {
- match self {
- ast::MemScope::Cta => spirv::Scope::Workgroup,
- ast::MemScope::Gpu => spirv::Scope::Device,
- ast::MemScope::Sys => spirv::Scope::CrossDevice,
- }
- }
-}
-
-impl ast::AtomSemantics {
- fn to_spirv(self) -> spirv::MemorySemantics {
- match self {
- ast::AtomSemantics::Relaxed => spirv::MemorySemantics::RELAXED,
- ast::AtomSemantics::Acquire => spirv::MemorySemantics::ACQUIRE,
- ast::AtomSemantics::Release => spirv::MemorySemantics::RELEASE,
- ast::AtomSemantics::AcquireRelease => spirv::MemorySemantics::ACQUIRE_RELEASE,
- }
- }
-}
-
-fn default_implicit_conversion(
- (operand_space, operand_type): (ast::StateSpace, &ast::Type),
- (instruction_space, instruction_type): (ast::StateSpace, &ast::Type),
-) -> Result<Option<ConversionKind>, TranslateError> {
- if !instruction_space.is_compatible(operand_space) {
- default_implicit_conversion_space(
- (operand_space, operand_type),
- (instruction_space, instruction_type),
- )
- } else if instruction_type != operand_type {
- default_implicit_conversion_type(instruction_space, operand_type, instruction_type)
- } else {
- Ok(None)
- }
-}
-
-// Space is different
-fn default_implicit_conversion_space(
- (operand_space, operand_type): (ast::StateSpace, &ast::Type),
- (instruction_space, instruction_type): (ast::StateSpace, &ast::Type),
-) -> Result<Option<ConversionKind>, TranslateError> {
- if (instruction_space == ast::StateSpace::Generic && operand_space.coerces_to_generic())
- || (operand_space == ast::StateSpace::Generic && instruction_space.coerces_to_generic())
- {
- Ok(Some(ConversionKind::PtrToPtr))
- } else if operand_space.is_compatible(ast::StateSpace::Reg) {
- match operand_type {
- ast::Type::Pointer(operand_ptr_type, operand_ptr_space)
- if *operand_ptr_space == instruction_space =>
- {
- if instruction_type != &ast::Type::Scalar(*operand_ptr_type) {
- Ok(Some(ConversionKind::PtrToPtr))
- } else {
- Ok(None)
- }
- }
- // TODO: 32 bit
- ast::Type::Scalar(ast::ScalarType::B64)
- | ast::Type::Scalar(ast::ScalarType::U64)
- | ast::Type::Scalar(ast::ScalarType::S64) => match instruction_space {
- ast::StateSpace::Global
- | ast::StateSpace::Generic
- | ast::StateSpace::Const
- | ast::StateSpace::Local
- | ast::StateSpace::Shared => Ok(Some(ConversionKind::BitToPtr)),
- _ => Err(TranslateError::MismatchedType),
- },
- ast::Type::Scalar(ast::ScalarType::B32)
- | ast::Type::Scalar(ast::ScalarType::U32)
- | ast::Type::Scalar(ast::ScalarType::S32) => match instruction_space {
- ast::StateSpace::Const | ast::StateSpace::Local | ast::StateSpace::Shared => {
- Ok(Some(ConversionKind::BitToPtr))
- }
- _ => Err(TranslateError::MismatchedType),
- },
- _ => Err(TranslateError::MismatchedType),
- }
- } else if instruction_space.is_compatible(ast::StateSpace::Reg) {
- match instruction_type {
- ast::Type::Pointer(instruction_ptr_type, instruction_ptr_space)
- if operand_space == *instruction_ptr_space =>
- {
- if operand_type != &ast::Type::Scalar(*instruction_ptr_type) {
- Ok(Some(ConversionKind::PtrToPtr))
- } else {
- Ok(None)
- }
- }
- _ => Err(TranslateError::MismatchedType),
- }
- } else {
- Err(TranslateError::MismatchedType)
- }
-}
-
-// Space is same, but type is different
-fn default_implicit_conversion_type(
- space: ast::StateSpace,
- operand_type: &ast::Type,
- instruction_type: &ast::Type,
-) -> Result<Option<ConversionKind>, TranslateError> {
- if space.is_compatible(ast::StateSpace::Reg) {
- if should_bitcast(instruction_type, operand_type) {
- Ok(Some(ConversionKind::Default))
- } else {
- Err(TranslateError::MismatchedType)
- }
- } else {
- Ok(Some(ConversionKind::PtrToPtr))
- }
-}
-
-fn should_bitcast(instr: &ast::Type, operand: &ast::Type) -> bool {
- match (instr, operand) {
- (ast::Type::Scalar(inst), ast::Type::Scalar(operand)) => {
- if inst.size_of() != operand.size_of() {
- return false;
- }
- match inst.kind() {
- ast::ScalarKind::Bit => operand.kind() != ast::ScalarKind::Bit,
- ast::ScalarKind::Float => operand.kind() == ast::ScalarKind::Bit,
- ast::ScalarKind::Signed => {
- operand.kind() == ast::ScalarKind::Bit
- || operand.kind() == ast::ScalarKind::Unsigned
- }
- ast::ScalarKind::Unsigned => {
- operand.kind() == ast::ScalarKind::Bit
- || operand.kind() == ast::ScalarKind::Signed
- }
- ast::ScalarKind::Float2 => false,
- ast::ScalarKind::Pred => false,
- }
- }
- (ast::Type::Vector(inst, _), ast::Type::Vector(operand, _))
- | (ast::Type::Array(inst, _), ast::Type::Array(operand, _)) => {
- should_bitcast(&ast::Type::Scalar(*inst), &ast::Type::Scalar(*operand))
- }
- _ => false,
- }
-}
-
-fn implicit_conversion_mov(
- (operand_space, operand_type): (ast::StateSpace, &ast::Type),
- (instruction_space, instruction_type): (ast::StateSpace, &ast::Type),
-) -> Result<Option<ConversionKind>, TranslateError> {
- // instruction_space is always reg
- if operand_space.is_compatible(ast::StateSpace::Reg) {
- if let (ast::Type::Vector(vec_underlying_type, vec_len), ast::Type::Scalar(scalar)) =
- (operand_type, instruction_type)
- {
- if scalar.kind() == ast::ScalarKind::Bit
- && scalar.size_of() == (vec_underlying_type.size_of() * vec_len)
- {
- return Ok(Some(ConversionKind::Default));
- }
- }
- // TODO: verify .params addressability:
- // * kernel arg
- // * func arg
- // * variable
- } else if operand_space.is_addressable() {
- return Ok(Some(ConversionKind::AddressOf));
- }
- default_implicit_conversion(
- (operand_space, operand_type),
- (instruction_space, instruction_type),
- )
-}
-
-fn should_convert_relaxed_src_wrapper(
- (operand_space, operand_type): (ast::StateSpace, &ast::Type),
- (instruction_space, instruction_type): (ast::StateSpace, &ast::Type),
-) -> Result<Option<ConversionKind>, TranslateError> {
- if !operand_space.is_compatible(instruction_space) {
- return Err(TranslateError::MismatchedType);
- }
- if operand_type == instruction_type {
- return Ok(None);
- }
- match should_convert_relaxed_src(operand_type, instruction_type) {
- conv @ Some(_) => Ok(conv),
- None => Err(TranslateError::MismatchedType),
- }
-}
-
-// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#operand-size-exceeding-instruction-type-size__relaxed-type-checking-rules-source-operands
-fn should_convert_relaxed_src(
- src_type: &ast::Type,
- instr_type: &ast::Type,
-) -> Option<ConversionKind> {
- if src_type == instr_type {
- return None;
- }
- match (src_type, instr_type) {
- (ast::Type::Scalar(src_type), ast::Type::Scalar(instr_type)) => match instr_type.kind() {
- ast::ScalarKind::Bit => {
- if instr_type.size_of() <= src_type.size_of() {
- Some(ConversionKind::Default)
- } else {
- None
- }
- }
- ast::ScalarKind::Signed | ast::ScalarKind::Unsigned => {
- if instr_type.size_of() <= src_type.size_of()
- && src_type.kind() != ast::ScalarKind::Float
- {
- Some(ConversionKind::Default)
- } else {
- None
- }
- }
- ast::ScalarKind::Float => {
- if instr_type.size_of() <= src_type.size_of()
- && src_type.kind() == ast::ScalarKind::Bit
- {
- Some(ConversionKind::Default)
- } else {
- None
- }
- }
- ast::ScalarKind::Float2 => todo!(),
- ast::ScalarKind::Pred => None,
- },
- (ast::Type::Vector(dst_type, _), ast::Type::Vector(instr_type, _))
- | (ast::Type::Array(dst_type, _), ast::Type::Array(instr_type, _)) => {
- should_convert_relaxed_src(
- &ast::Type::Scalar(*dst_type),
- &ast::Type::Scalar(*instr_type),
- )
- }
- _ => None,
- }
-}
-
-fn should_convert_relaxed_dst_wrapper(
- (operand_space, operand_type): (ast::StateSpace, &ast::Type),
- (instruction_space, instruction_type): (ast::StateSpace, &ast::Type),
-) -> Result<Option<ConversionKind>, TranslateError> {
- if !operand_space.is_compatible(instruction_space) {
- return Err(TranslateError::MismatchedType);
- }
- if operand_type == instruction_type {
- return Ok(None);
- }
- match should_convert_relaxed_dst(operand_type, instruction_type) {
- conv @ Some(_) => Ok(conv),
- None => Err(TranslateError::MismatchedType),
- }
-}
-
-// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#operand-size-exceeding-instruction-type-size__relaxed-type-checking-rules-destination-operands
-fn should_convert_relaxed_dst(
- dst_type: &ast::Type,
- instr_type: &ast::Type,
-) -> Option<ConversionKind> {
- if dst_type == instr_type {
- return None;
- }
- match (dst_type, instr_type) {
- (ast::Type::Scalar(dst_type), ast::Type::Scalar(instr_type)) => match instr_type.kind() {
- ast::ScalarKind::Bit => {
- if instr_type.size_of() <= dst_type.size_of() {
- Some(ConversionKind::Default)
- } else {
- None
- }
- }
- ast::ScalarKind::Signed => {
- if dst_type.kind() != ast::ScalarKind::Float {
- if instr_type.size_of() == dst_type.size_of() {
- Some(ConversionKind::Default)
- } else if instr_type.size_of() < dst_type.size_of() {
- Some(ConversionKind::SignExtend)
- } else {
- None
- }
- } else {
- None
- }
- }
- ast::ScalarKind::Unsigned => {
- if instr_type.size_of() <= dst_type.size_of()
- && dst_type.kind() != ast::ScalarKind::Float
- {
- Some(ConversionKind::Default)
- } else {
- None
- }
- }
- ast::ScalarKind::Float => {
- if instr_type.size_of() <= dst_type.size_of()
- && dst_type.kind() == ast::ScalarKind::Bit
- {
- Some(ConversionKind::Default)
- } else {
- None
- }
- }
- ast::ScalarKind::Float2 => todo!(),
- ast::ScalarKind::Pred => None,
- },
- (ast::Type::Vector(dst_type, _), ast::Type::Vector(instr_type, _))
- | (ast::Type::Array(dst_type, _), ast::Type::Array(instr_type, _)) => {
- should_convert_relaxed_dst(
- &ast::Type::Scalar(*dst_type),
- &ast::Type::Scalar(*instr_type),
- )
- }
- _ => None,
- }
-}
-
-impl<'a> ast::MethodDeclaration<'a, &'a str> {
- fn name(&self) -> &'a str {
- match self.name {
- ast::MethodName::Kernel(name) => name,
- ast::MethodName::Func(name) => name,
- }
- }
-}
-
-impl<'a> ast::MethodDeclaration<'a, spirv::Word> {
- fn effective_input_arguments(&self) -> impl Iterator<Item = (spirv::Word, SpirvType)> + '_ {
- let is_kernel = self.name.is_kernel();
- self.input_arguments.iter().map(move |arg| {
- if !is_kernel && arg.state_space != ast::StateSpace::Reg {
- let spirv_type =
- SpirvType::pointer_to(arg.v_type.clone(), arg.state_space.to_spirv());
- (arg.name, spirv_type)
- } else {
- (arg.name, SpirvType::new(arg.v_type.clone()))
- }
- })
- }
-}
-
-impl<'input, ID> ast::MethodName<'input, ID> {
- fn is_kernel(&self) -> bool {
- match self {
- ast::MethodName::Kernel(..) => true,
- ast::MethodName::Func(..) => false,
- }
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::ast;
-
- static SCALAR_TYPES: [ast::ScalarType; 15] = [
- ast::ScalarType::B8,
- ast::ScalarType::B16,
- ast::ScalarType::B32,
- ast::ScalarType::B64,
- ast::ScalarType::S8,
- ast::ScalarType::S16,
- ast::ScalarType::S32,
- ast::ScalarType::S64,
- ast::ScalarType::U8,
- ast::ScalarType::U16,
- ast::ScalarType::U32,
- ast::ScalarType::U64,
- ast::ScalarType::F16,
- ast::ScalarType::F32,
- ast::ScalarType::F64,
- ];
-
- static RELAXED_SRC_CONVERSION_TABLE: &'static str =
- "b8 - chop chop chop - chop chop chop - chop chop chop chop chop chop
- b16 inv - chop chop inv - chop chop inv - chop chop - chop chop
- b32 inv inv - chop inv inv - chop inv inv - chop inv - chop
- b64 inv inv inv - inv inv inv - inv inv inv - inv inv -
- s8 - chop chop chop - chop chop chop - chop chop chop inv inv inv
- s16 inv - chop chop inv - chop chop inv - chop chop inv inv inv
- s32 inv inv - chop inv inv - chop inv inv - chop inv inv inv
- s64 inv inv inv - inv inv inv - inv inv inv - inv inv inv
- u8 - chop chop chop - chop chop chop - chop chop chop inv inv inv
- u16 inv - chop chop inv - chop chop inv - chop chop inv inv inv
- u32 inv inv - chop inv inv - chop inv inv - chop inv inv inv
- u64 inv inv inv - inv inv inv - inv inv inv - inv inv inv
- f16 inv - chop chop inv inv inv inv inv inv inv inv - inv inv
- f32 inv inv - chop inv inv inv inv inv inv inv inv inv - inv
- f64 inv inv inv - inv inv inv inv inv inv inv inv inv inv -";
-
- static RELAXED_DST_CONVERSION_TABLE: &'static str =
- "b8 - zext zext zext - zext zext zext - zext zext zext zext zext zext
- b16 inv - zext zext inv - zext zext inv - zext zext - zext zext
- b32 inv inv - zext inv inv - zext inv inv - zext inv - zext
- b64 inv inv inv - inv inv inv - inv inv inv - inv inv -
- s8 - sext sext sext - sext sext sext - sext sext sext inv inv inv
- s16 inv - sext sext inv - sext sext inv - sext sext inv inv inv
- s32 inv inv - sext inv inv - sext inv inv - sext inv inv inv
- s64 inv inv inv - inv inv inv - inv inv inv - inv inv inv
- u8 - zext zext zext - zext zext zext - zext zext zext inv inv inv
- u16 inv - zext zext inv - zext zext inv - zext zext inv inv inv
- u32 inv inv - zext inv inv - zext inv inv - zext inv inv inv
- u64 inv inv inv - inv inv inv - inv inv inv - inv inv inv
- f16 inv - zext zext inv inv inv inv inv inv inv inv - inv inv
- f32 inv inv - zext inv inv inv inv inv inv inv inv inv - inv
- f64 inv inv inv - inv inv inv inv inv inv inv inv inv inv -";
-
- fn table_entry_to_conversion(entry: &'static str) -> Option<ConversionKind> {
- match entry {
- "-" => Some(ConversionKind::Default),
- "inv" => None,
- "zext" => Some(ConversionKind::Default),
- "chop" => Some(ConversionKind::Default),
- "sext" => Some(ConversionKind::SignExtend),
- _ => unreachable!(),
- }
- }
-
- fn parse_conversion_table(table: &'static str) -> Vec<Vec<Option<ConversionKind>>> {
- table
- .lines()
- .map(|line| {
- line.split_ascii_whitespace()
- .skip(1)
- .map(table_entry_to_conversion)
- .collect::<Vec<_>>()
- })
- .collect::<Vec<_>>()
- }
-
- fn assert_conversion_table<F: Fn(&ast::Type, &ast::Type) -> Option<ConversionKind>>(
- table: &'static str,
- f: F,
- ) {
- let conv_table = parse_conversion_table(table);
- for (instr_idx, instr_type) in SCALAR_TYPES.iter().enumerate() {
- for (op_idx, op_type) in SCALAR_TYPES.iter().enumerate() {
- let conversion = f(
- &ast::Type::Scalar(*op_type),
- &ast::Type::Scalar(*instr_type),
- );
- if instr_idx == op_idx {
- assert!(conversion == None);
- } else {
- assert!(conversion == conv_table[instr_idx][op_idx]);
- }
- }
- }
- }
-
- #[test]
- fn should_convert_relaxed_src_all_combinations() {
- assert_conversion_table(RELAXED_SRC_CONVERSION_TABLE, should_convert_relaxed_src);
- }
-
- #[test]
- fn should_convert_relaxed_dst_all_combinations() {
- assert_conversion_table(RELAXED_DST_CONVERSION_TABLE, should_convert_relaxed_dst);
- }
-}
diff --git a/ptx_parser/src/lib.rs b/ptx_parser/src/lib.rs index fee11aa..b49503b 100644 --- a/ptx_parser/src/lib.rs +++ b/ptx_parser/src/lib.rs @@ -1349,10 +1349,10 @@ impl std::error::Error for TokenError {} // * After parsing, each instruction needs to do some early validation and generate a specific, // strongly-typed object. We want strong-typing because we have a single PTX parser frontend, but // there can be multiple different code emitter backends -// * Most importantly, instruction modifiers can come in aby order, so e.g. both +// * Most importantly, instruction modifiers can come in aby order, so e.g. both // `ld.relaxed.global.u32 a, b` and `ld.global.relaxed.u32 a, b` are equally valid. This makes // classic parsing generators fail: if we tried to generate parsing rules that cover every possible -// ordering we'd need thousands of rules. This is not a purely theoretical problem. NVCC and Clang +// ordering we'd need thousands of rules. This is not a purely theoretical problem. NVCC and Clang // will always emit modifiers in the correct order, but people who write inline assembly usually // get it wrong (even first party developers) // @@ -1398,7 +1398,7 @@ impl std::error::Error for TokenError {} // * List of rules. They are associated with the preceding patterns (until different opcode or // different rules). Rules are used to resolve modifiers. There are two types of rules: // * Normal rule: `.foobar: FoobarEnum => { .a, .b, .c }`. This means that instead of `.foobar` we -// expecte one of `.a`, `.b`, `.c` and will emit value FoobarEnum::DotA, FoobarEnum::DotB, +// expecte one of `.a`, `.b`, `.c` and will emit value FoobarEnum::DotA, FoobarEnum::DotB, // FoobarEnum::DotC appropriately // * Type-only rule: `FoobarEnum => { .a, .b, .c }` this means that all the occurences of `.a` will // emit FoobarEnum::DotA to the code block. This helps to avoid copy-paste errors @@ -3233,36 +3233,42 @@ mod tests { #[test] fn sm_11() { let tokens = Token::lexer(".target sm_11") - .collect::<Result<Vec<_>, ()>>() + .collect::<Result<Vec<_>, _>>() .unwrap(); + let mut errors = Vec::new(); let stream = super::PtxParser { input: &tokens[..], - state: PtxParserState::new(), + state: PtxParserState::new(&mut errors), }; assert_eq!(target.parse(stream).unwrap(), (11, None)); + assert_eq!(errors.len(), 0); } #[test] fn sm_90a() { let tokens = Token::lexer(".target sm_90a") - .collect::<Result<Vec<_>, ()>>() + .collect::<Result<Vec<_>, _>>() .unwrap(); + let mut errors = Vec::new(); let stream = super::PtxParser { input: &tokens[..], - state: PtxParserState::new(), + state: PtxParserState::new(&mut errors), }; assert_eq!(target.parse(stream).unwrap(), (90, Some('a'))); + assert_eq!(errors.len(), 0); } #[test] fn sm_90ab() { let tokens = Token::lexer(".target sm_90ab") - .collect::<Result<Vec<_>, ()>>() + .collect::<Result<Vec<_>, _>>() .unwrap(); + let mut errors = Vec::new(); let stream = super::PtxParser { input: &tokens[..], - state: PtxParserState::new(), + state: PtxParserState::new(&mut errors), }; assert!(target.parse(stream).is_err()); + assert_eq!(errors.len(), 0); } } |