diff options
Diffstat (limited to 'tests/codegen')
| -rw-r--r-- | tests/codegen/const-vector.rs | 107 | ||||
| -rw-r--r-- | tests/codegen/intrinsics/nontemporal.rs | 30 |
2 files changed, 134 insertions, 3 deletions
diff --git a/tests/codegen/const-vector.rs b/tests/codegen/const-vector.rs new file mode 100644 index 00000000000..d368838201e --- /dev/null +++ b/tests/codegen/const-vector.rs @@ -0,0 +1,107 @@ +//@ compile-flags: -C no-prepopulate-passes -Copt-level=0 + +// This test checks that constants of SIMD type are passed as immediate vectors. +// We ensure that both vector representations (struct with fields and struct wrapping array) work. +#![crate_type = "lib"] +#![feature(abi_unadjusted)] +#![feature(const_trait_impl)] +#![feature(repr_simd)] +#![feature(rustc_attrs)] +#![feature(simd_ffi)] +#![allow(non_camel_case_types)] + +// Setting up structs that can be used as const vectors +#[repr(simd)] +#[derive(Clone)] +pub struct i8x2(i8, i8); + +#[repr(simd)] +#[derive(Clone)] +pub struct i8x2_arr([i8; 2]); + +#[repr(simd)] +#[derive(Clone)] +pub struct f32x2(f32, f32); + +#[repr(simd)] +#[derive(Clone)] +pub struct f32x2_arr([f32; 2]); + +#[repr(simd, packed)] +#[derive(Copy, Clone)] +pub struct Simd<T, const N: usize>([T; N]); + +// The following functions are required for the tests to ensure +// that they are called with a const vector + +extern "unadjusted" { + #[no_mangle] + fn test_i8x2(a: i8x2); +} + +extern "unadjusted" { + #[no_mangle] + fn test_i8x2_two_args(a: i8x2, b: i8x2); +} + +extern "unadjusted" { + #[no_mangle] + fn test_i8x2_mixed_args(a: i8x2, c: i32, b: i8x2); +} + +extern "unadjusted" { + #[no_mangle] + fn test_i8x2_arr(a: i8x2_arr); +} + +extern "unadjusted" { + #[no_mangle] + fn test_f32x2(a: f32x2); +} + +extern "unadjusted" { + #[no_mangle] + fn test_f32x2_arr(a: f32x2_arr); +} + +extern "unadjusted" { + #[no_mangle] + fn test_simd(a: Simd<i32, 4>); +} + +extern "unadjusted" { + #[no_mangle] + fn test_simd_unaligned(a: Simd<i32, 3>); +} + +// Ensure the packed variant of the simd struct does not become a const vector +// if the size is not a power of 2 +// CHECK: %"Simd<i32, 3>" = type { [3 x i32] } + +pub fn do_call() { + unsafe { + // CHECK: call void @test_i8x2(<2 x i8> <i8 32, i8 64> + test_i8x2(const { i8x2(32, 64) }); + + // CHECK: call void @test_i8x2_two_args(<2 x i8> <i8 32, i8 64>, <2 x i8> <i8 8, i8 16> + test_i8x2_two_args(const { i8x2(32, 64) }, const { i8x2(8, 16) }); + + // CHECK: call void @test_i8x2_mixed_args(<2 x i8> <i8 32, i8 64>, i32 43, <2 x i8> <i8 8, i8 16> + test_i8x2_mixed_args(const { i8x2(32, 64) }, 43, const { i8x2(8, 16) }); + + // CHECK: call void @test_i8x2_arr(<2 x i8> <i8 32, i8 64> + test_i8x2_arr(const { i8x2_arr([32, 64]) }); + + // CHECK: call void @test_f32x2(<2 x float> <float 0x3FD47AE140000000, float 0x3FE47AE140000000> + test_f32x2(const { f32x2(0.32, 0.64) }); + + // CHECK: void @test_f32x2_arr(<2 x float> <float 0x3FD47AE140000000, float 0x3FE47AE140000000> + test_f32x2_arr(const { f32x2_arr([0.32, 0.64]) }); + + // CHECK: call void @test_simd(<4 x i32> <i32 2, i32 4, i32 6, i32 8> + test_simd(const { Simd::<i32, 4>([2, 4, 6, 8]) }); + + // CHECK: call void @test_simd_unaligned(%"Simd<i32, 3>" %1 + test_simd_unaligned(const { Simd::<i32, 3>([2, 4, 6]) }); + } +} diff --git a/tests/codegen/intrinsics/nontemporal.rs b/tests/codegen/intrinsics/nontemporal.rs index 076d6d6d9da..ff2d6296066 100644 --- a/tests/codegen/intrinsics/nontemporal.rs +++ b/tests/codegen/intrinsics/nontemporal.rs @@ -1,13 +1,37 @@ //@ compile-flags: -O +//@revisions: with_nontemporal without_nontemporal +//@[with_nontemporal] compile-flags: --target aarch64-unknown-linux-gnu +//@[with_nontemporal] needs-llvm-components: aarch64 +//@[without_nontemporal] compile-flags: --target x86_64-unknown-linux-gnu +//@[without_nontemporal] needs-llvm-components: x86 -#![feature(core_intrinsics)] +// Ensure that we *do* emit the `!nontemporal` flag on architectures where it +// is well-behaved, but do *not* emit it on architectures where it is ill-behaved. +// For more context, see <https://github.com/rust-lang/rust/issues/114582> and +// <https://github.com/llvm/llvm-project/issues/64521>. + +#![feature(no_core, lang_items, intrinsics)] +#![no_core] #![crate_type = "lib"] +#[lang = "sized"] +pub trait Sized {} +#[lang = "copy"] +pub trait Copy {} + +impl Copy for u32 {} +impl<T> Copy for *mut T {} + +extern "rust-intrinsic" { + pub fn nontemporal_store<T>(ptr: *mut T, val: T); +} + #[no_mangle] pub fn a(a: &mut u32, b: u32) { // CHECK-LABEL: define{{.*}}void @a - // CHECK: store i32 %b, ptr %a, align 4, !nontemporal + // with_nontemporal: store i32 %b, ptr %a, align 4, !nontemporal + // without_nontemporal-NOT: nontemporal unsafe { - std::intrinsics::nontemporal_store(a, b); + nontemporal_store(a, b); } } |
