Auto merge of #125904 - workingjubilee:test-packed-simd-more, r=calebzulawski

Test codegen for `repr(packed,simd)` -> `repr(simd)`

This adds the codegen test originally requested in #117116 but exploiting the collection of features in FileCheck and compiletest to make it more resilient to expectations being broken by optimization levels. Mostly by presetting optimization levels for each revision of the tests.

I do not think the dereferenceable attribute's presence or absence is that important.

r? `@calebzulawski`
This commit is contained in:
bors 2024-06-03 06:05:12 +00:00
commit 621e957b4d

View File

@ -0,0 +1,44 @@
//@ revisions:opt3 noopt
//@[opt3] compile-flags: -Copt-level=3
//@[noopt] compile-flags: -Cno-prepopulate-passes
#![crate_type = "lib"]
#![no_std]
#![feature(repr_simd, core_intrinsics)]
use core::intrinsics::simd as intrinsics;
use core::{mem, ptr};
// Test codegen for not only "packed" but also "fully aligned" SIMD types, and conversion between
// A repr(packed,simd) type with 3 elements can't exceed its element alignment,
// whereas the same type as repr(simd) will instead have padding.
#[repr(simd, packed)]
pub struct Simd<T, const N: usize>([T; N]);
#[repr(simd)]
#[derive(Copy, Clone)]
pub struct FullSimd<T, const N: usize>([T; N]);
// non-powers-of-two have padding and need to be expanded to full vectors
fn load<T, const N: usize>(v: Simd<T, N>) -> FullSimd<T, N> {
unsafe {
let mut tmp = mem::MaybeUninit::<FullSimd<T, N>>::uninit();
ptr::copy_nonoverlapping(&v as *const _, tmp.as_mut_ptr().cast(), 1);
tmp.assume_init()
}
}
// CHECK-LABEL: square_packed
// CHECK-SAME: ptr{{[a-z_ ]*}} sret([[RET_TYPE:[^)]+]]) [[RET_ALIGN:align (8|16)]]{{[^%]*}} [[RET_VREG:%[_0-9]*]]
// CHECK-SAME: ptr{{[a-z_ ]*}} align 4
#[no_mangle]
pub fn square_packed(x: Simd<f32, 3>) -> FullSimd<f32, 3> {
// CHECK-NEXT: start
// noopt: alloca [[RET_TYPE]], [[RET_ALIGN]]
// CHECK: load <3 x float>
let x = load(x);
// CHECK: [[VREG:%[a-z0-9_]+]] = fmul <3 x float>
// CHECK-NEXT: store <3 x float> [[VREG]], ptr [[RET_VREG]], [[RET_ALIGN]]
// CHECK-NEXT: ret void
unsafe { intrinsics::simd_mul(x, x) }
}