blob: 1257abe932b0bb10619a2015063da7b53be14544 [file]
//@ add-minicore
//@ revisions: gfx942 gfx950 gfx1030
//@ assembly-output: emit-asm
//@ compile-flags: --target amdgcn-amd-amdhsa
//@[gfx942] compile-flags: -Ctarget-cpu=gfx942
//@[gfx950] compile-flags: -Ctarget-cpu=gfx950
//@[gfx1030] compile-flags: -Ctarget-cpu=gfx1030
//@ needs-llvm-components: amdgpu
//@ needs-rust-lld
// ignore-tidy-linelength
// Tests for different gfx versions that do not fit in gfx11 and 12
#![feature(abi_gpu_kernel, no_core, asm_experimental_arch, repr_simd, f16)]
#![crate_type = "rlib"]
#![no_core]
#![allow(
asm_sub_register,
improper_gpu_kernel_arg,
improper_ctypes_definitions,
non_camel_case_types,
unused_assignments,
unused_variables
)]
extern crate minicore;
use minicore::*;
type ptr = *mut u8;
#[repr(simd)]
pub struct i32x4([i32; 4]);
#[repr(simd)]
pub struct f32x4([f32; 4]);
#[repr(simd)]
pub struct i32x9([i32; 9]);
#[repr(simd)]
pub struct f32x9([f32; 9]);
#[repr(simd)]
pub struct i32x11([i32; 11]);
#[repr(simd)]
pub struct f32x11([f32; 11]);
#[repr(simd)]
pub struct i32x12([i32; 12]);
#[repr(simd)]
pub struct f32x12([f32; 12]);
#[repr(simd)]
pub struct i16x32([i16; 32]);
#[repr(simd)]
pub struct f16x32([f16; 32]);
#[repr(simd)]
pub struct i32x16([i32; 16]);
#[repr(simd)]
pub struct f32x16([f32; 16]);
#[repr(simd)]
pub struct f32x32([f32; 32]);
macro_rules! impl_copy {
($($ty:ident)*) => {
$(
impl Copy for $ty {}
)*
};
}
impl_copy!(
i32x4 f32x4 i32x9 f32x9 i32x11 f32x11 i32x12 f32x12 i16x32 f16x32
i32x16 f32x16 f32x32
);
macro_rules! check {
($func:ident $ty:ident $class:ident $mov:literal) => {
#[no_mangle]
pub unsafe extern "gpu-kernel" fn $func(x: $ty) {
let y: $ty;
asm!(concat!($mov, " {}, {}"), out($class) y, in($class) x);
}
};
($func:ident $ret_ty:ident $ret_class:ident $($arg_name:ident: $arg_ty:ident $arg_class:ident,)*
$mov:literal) => {
check!($func $ret_ty $ret_class $($arg_name: $arg_ty $arg_class,)* $mov, "");
};
($func:ident $ret_ty:ident $ret_class:ident $($arg_name:ident: $arg_ty:ident $arg_class:ident,)*
$mov:literal, $tail:literal) => {
#[no_mangle]
pub unsafe extern "gpu-kernel" fn $func($($arg_name: $arg_ty,)*) {
let result: $ret_ty;
asm!(concat!($mov, " {}", $(", {", stringify!($arg_name), "}",)* $tail),
out($ret_class) result, $($arg_name = in($arg_class) $arg_name,)*);
}
};
}
macro_rules! check_reg {
($func:ident $ty:ident $reg:tt $mov:literal) => {
#[no_mangle]
pub unsafe extern "gpu-kernel" fn $func(x: $ty) {
let y: $ty;
asm!(concat!($mov, " ", $reg, ", ", $reg), lateout($reg) y, in($reg) x);
}
};
($func:ident $ret_ty:ident $ret_reg:tt $($arg_name:ident: $arg_ty:ident $arg_reg:tt,)*
$mov:literal) => {
check_reg!($func $ret_ty $ret_reg $($arg_name: $arg_ty $arg_reg,)* $mov, "");
};
($func:ident $ret_ty:ident $ret_reg:tt $($arg_name:ident: $arg_ty:ident $arg_reg:tt,)*
$mov:literal, $tail:literal) => {
#[no_mangle]
pub unsafe extern "gpu-kernel" fn $func($($arg_name: $arg_ty,)*) {
let result: $ret_ty;
asm!(concat!($mov, " ", $ret_reg, $(", ", $arg_reg,)* $tail), lateout($ret_reg) result,
$(in($arg_reg) $arg_name,)*);
}
};
}
// gfx1030-LABEL: vgpr_i32x9:
// gfx1030: #ASMSTART
// gfx1030: image_bvh64_intersect_ray v{{\[[0-9]+:[0-9]+\]}}, v{{\[[0-9]+:[0-9]+\]}}, s{{\[[0-9]+:[0-9]+\]}} a16
// gfx1030: #ASMEND
#[cfg(gfx1030)]
check!(vgpr_i32x9 i32x4 vgpr128 x: i32x9 vgpr288, y: i32x4 sgpr128, "image_bvh64_intersect_ray",
" a16");
// gfx1030-LABEL: vgpr_f32x9:
// gfx1030: #ASMSTART
// gfx1030: image_bvh64_intersect_ray v{{\[[0-9]+:[0-9]+\]}}, v{{\[[0-9]+:[0-9]+\]}}, s{{\[[0-9]+:[0-9]+\]}} a16
// gfx1030: #ASMEND
#[cfg(gfx1030)]
check!(vgpr_f32x9 i32x4 vgpr128 x: f32x9 vgpr288, y: i32x4 sgpr128, "image_bvh64_intersect_ray",
" a16");
// gfx1030-LABEL: vgpr_i32x11:
// gfx1030: #ASMSTART
// gfx1030: image_bvh_intersect_ray v{{\[[0-9]+:[0-9]+\]}}, v{{\[[0-9]+:[0-9]+\]}}, s{{\[[0-9]+:[0-9]+\]}}
// gfx1030: #ASMEND
#[cfg(gfx1030)]
check!(vgpr_i32x11 i32x4 vgpr128 x: i32x11 vgpr352, y: i32x4 sgpr128, "image_bvh_intersect_ray");
// gfx1030-LABEL: vgpr_f32x11:
// gfx1030: #ASMSTART
// gfx1030: image_bvh_intersect_ray v{{\[[0-9]+:[0-9]+\]}}, v{{\[[0-9]+:[0-9]+\]}}, s{{\[[0-9]+:[0-9]+\]}}
// gfx1030: #ASMEND
#[cfg(gfx1030)]
check!(vgpr_f32x11 i32x4 vgpr128 x: f32x11 vgpr352, y: i32x4 sgpr128, "image_bvh_intersect_ray");
// gfx1030-LABEL: vgpr_i32x12:
// gfx1030: #ASMSTART
// gfx1030: image_bvh64_intersect_ray v{{\[[0-9]+:[0-9]+\]}}, v{{\[[0-9]+:[0-9]+\]}}, s{{\[[0-9]+:[0-9]+\]}}
// gfx1030: #ASMEND
#[cfg(gfx1030)]
check!(vgpr_i32x12 i32x4 vgpr128 x: i32x12 vgpr384, y: i32x4 sgpr128, "image_bvh64_intersect_ray");
// gfx1030-LABEL: vgpr_f32x12:
// gfx1030: #ASMSTART
// gfx1030: image_bvh64_intersect_ray v{{\[[0-9]+:[0-9]+\]}}, v{{\[[0-9]+:[0-9]+\]}}, s{{\[[0-9]+:[0-9]+\]}}
// gfx1030: #ASMEND
#[cfg(gfx1030)]
check!(vgpr_f32x12 i32x4 vgpr128 x: f32x12 vgpr384, y: i32x4 sgpr128, "image_bvh64_intersect_ray");
// gfx950-LABEL: vgpr_i32x16:
// gfx950: #ASMSTART
// gfx950: v_mfma_i32_32x32x32_i8 v{{\[[0-9]+:[0-9]+\]}}, v{{\[[0-9]+:[0-9]+\]}}, v{{\[[0-9]+:[0-9]+\]}}, v{{\[[0-9]+:[0-9]+\]}}
// gfx950: #ASMEND
#[cfg(gfx950)]
check!(vgpr_i32x16 i32x16 vgpr512 x: i32x4 vgpr128, y: i32x4 vgpr128, z: i16x32 vgpr512,
"v_mfma_i32_32x32x32_i8");
// gfx950-LABEL: vgpr_f32x16:
// gfx950: #ASMSTART
// gfx950: v_mfma_f32_32x32x16_f16 v{{\[[0-9]+:[0-9]+\]}}, v{{\[[0-9]+:[0-9]+\]}}, v{{\[[0-9]+:[0-9]+\]}}, v{{\[[0-9]+:[0-9]+\]}}
// gfx950: #ASMEND
#[cfg(gfx950)]
check!(vgpr_f32x16 f32x16 vgpr512 x: f32x4 vgpr128, y: f32x4 vgpr128, z: f16x32 vgpr512,
"v_mfma_f32_32x32x16_f16");
// gfx942-LABEL: vgpr_f32x32:
// gfx942: #ASMSTART
// gfx942: v_mfma_f32_32x32x1_2b_f32 v{{\[[0-9]+:[0-9]+\]}}, v{{[0-9]+}}, v{{[0-9]+}}, v{{\[[0-9]+:[0-9]+\]}}
// gfx942: #ASMEND
#[cfg(gfx942)]
check!(vgpr_f32x32 f32x32 vgpr1024 x: f32 vgpr32, y: f32 vgpr32, "v_mfma_f32_32x32x1_2b_f32",
", v[0:31]");
// gfx1030-LABEL: v0_i32x9:
// gfx1030: #ASMSTART
// gfx1030: image_bvh64_intersect_ray v{{\[[0-9]+:[0-9]+\]}}, v{{\[[0-9]+:[0-9]+\]}}, s{{\[[0-9]+:[0-9]+\]}} a16
// gfx1030: #ASMEND
#[cfg(gfx1030)]
check_reg!(v0_i32x9 i32x4 "v[0:3]" x: i32x9 "v[8:16]", y: i32x4 "s[0:3]",
"image_bvh64_intersect_ray", " a16");
// gfx1030-LABEL: v0_f32x9:
// gfx1030: #ASMSTART
// gfx1030: image_bvh64_intersect_ray v{{\[[0-9]+:[0-9]+\]}}, v{{\[[0-9]+:[0-9]+\]}}, s{{\[[0-9]+:[0-9]+\]}} a16
// gfx1030: #ASMEND
#[cfg(gfx1030)]
check_reg!(v0_f32x9 i32x4 "v[0:3]" x: f32x9 "v[8:16]", y: i32x4 "s[0:3]",
"image_bvh64_intersect_ray", " a16");
// gfx1030-LABEL: v0_i32x11:
// gfx1030: #ASMSTART
// gfx1030: image_bvh_intersect_ray v{{\[[0-9]+:[0-9]+\]}}, v{{\[[0-9]+:[0-9]+\]}}, s{{\[[0-9]+:[0-9]+\]}}
// gfx1030: #ASMEND
#[cfg(gfx1030)]
check_reg!(v0_i32x11 i32x4 "v[0:3]" x: i32x11 "v[8:18]", y: i32x4 "s[0:3]",
"image_bvh_intersect_ray");
// gfx1030-LABEL: v0_f32x11:
// gfx1030: #ASMSTART
// gfx1030: image_bvh_intersect_ray v{{\[[0-9]+:[0-9]+\]}}, v{{\[[0-9]+:[0-9]+\]}}, s{{\[[0-9]+:[0-9]+\]}}
// gfx1030: #ASMEND
#[cfg(gfx1030)]
check_reg!(v0_f32x11 i32x4 "v[0:3]" x: f32x11 "v[8:18]", y: i32x4 "s[0:3]",
"image_bvh_intersect_ray");
// gfx1030-LABEL: v0_i32x12:
// gfx1030: #ASMSTART
// gfx1030: image_bvh64_intersect_ray v{{\[[0-9]+:[0-9]+\]}}, v{{\[[0-9]+:[0-9]+\]}}, s{{\[[0-9]+:[0-9]+\]}}
// gfx1030: #ASMEND
#[cfg(gfx1030)]
check_reg!(v0_i32x12 i32x4 "v[0:3]" x: i32x12 "v[8:19]", y: i32x4 "s[0:3]",
"image_bvh64_intersect_ray");
// gfx1030-LABEL: v0_f32x12:
// gfx1030: #ASMSTART
// gfx1030: image_bvh64_intersect_ray v{{\[[0-9]+:[0-9]+\]}}, v{{\[[0-9]+:[0-9]+\]}}, s{{\[[0-9]+:[0-9]+\]}}
// gfx1030: #ASMEND
#[cfg(gfx1030)]
check_reg!(v0_f32x12 i32x4 "v[0:3]" x: f32x12 "v[8:19]", y: i32x4 "s[0:3]",
"image_bvh64_intersect_ray");
// gfx950-LABEL: v0_i32x16:
// gfx950: #ASMSTART
// gfx950: v_mfma_i32_32x32x32_i8 v{{\[[0-9]+:[0-9]+\]}}, v{{\[[0-9]+:[0-9]+\]}}, v{{\[[0-9]+:[0-9]+\]}}, v{{\[[0-9]+:[0-9]+\]}}
// gfx950: #ASMEND
#[cfg(gfx950)]
check_reg!(v0_i32x16 i32x16 "v[0:15]" x: i32x4 "v[16:19]", y: i32x4 "v[20:23]", z: i16x32 "v[0:15]",
"v_mfma_i32_32x32x32_i8");
// gfx950-LABEL: v0_f32x16:
// gfx950: #ASMSTART
// gfx950: v_mfma_f32_32x32x16_f16 v{{\[[0-9]+:[0-9]+\]}}, v{{\[[0-9]+:[0-9]+\]}}, v{{\[[0-9]+:[0-9]+\]}}, v{{\[[0-9]+:[0-9]+\]}}
// gfx950: #ASMEND
#[cfg(gfx950)]
check_reg!(v0_f32x16 f32x16 "v[0:15]" x: f32x4 "v[16:19]", y: f32x4 "v[20:23]", z: f16x32 "v[0:15]",
"v_mfma_f32_32x32x16_f16");
// gfx942-LABEL: v0_f32x32:
// gfx942: #ASMSTART
// gfx942: v_mfma_f32_32x32x1_2b_f32 v{{\[[0-9]+:[0-9]+\]}}, v{{[0-9]+}}, v{{[0-9]+}}, v{{\[[0-9]+:[0-9]+\]}}
// gfx942: #ASMEND
#[cfg(gfx942)]
check_reg!(v0_f32x32 f32x32 "v[0:31]" x: f32 "v32", y: f32 "v33", "v_mfma_f32_32x32x1_2b_f32",
", v[0:31]");