| //@ only-aarch64 |
| #![crate_type = "lib"] |
| #![allow(incomplete_features, internal_features)] |
| #![feature(abi_unadjusted, core_intrinsics, link_llvm_intrinsics, rustc_attrs)] |
| |
| // Tests that tuples of scalable vectors are passed as immediates and that the intrinsics for |
| // creating/getting/setting tuples of scalable vectors generate the correct assembly |
| |
| #[derive(Copy, Clone)] |
| #[rustc_scalable_vector(4)] |
| #[allow(non_camel_case_types)] |
| pub struct svfloat32_t(f32); |
| |
| #[derive(Copy, Clone)] |
| #[rustc_scalable_vector] |
| #[allow(non_camel_case_types)] |
| pub struct svfloat32x2_t(svfloat32_t, svfloat32_t); |
| |
| #[derive(Copy, Clone)] |
| #[rustc_scalable_vector] |
| #[allow(non_camel_case_types)] |
| pub struct svfloat32x3_t(svfloat32_t, svfloat32_t, svfloat32_t); |
| |
| #[derive(Copy, Clone)] |
| #[rustc_scalable_vector] |
| #[allow(non_camel_case_types)] |
| pub struct svfloat32x4_t(svfloat32_t, svfloat32_t, svfloat32_t, svfloat32_t); |
| |
| #[inline(never)] |
| #[target_feature(enable = "sve")] |
| pub fn svdup_n_f32(op: f32) -> svfloat32_t { |
| extern "C" { |
| #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.dup.x.nxv4f32")] |
| fn _svdup_n_f32(op: f32) -> svfloat32_t; |
| } |
| unsafe { _svdup_n_f32(op) } |
| } |
| |
| // CHECK-LABEL: define { <vscale x 4 x float>, <vscale x 4 x float> } @svcreate2_f32( |
| // CHECK-SAME: <vscale x 4 x float> %x0, <vscale x 4 x float> %x1) |
| #[no_mangle] |
| #[target_feature(enable = "sve")] |
| pub fn svcreate2_f32(x0: svfloat32_t, x1: svfloat32_t) -> svfloat32x2_t { |
| // CHECK: [[TUP0:%.*]] = insertvalue { <vscale x 4 x float>, <vscale x 4 x float> } poison, <vscale x 4 x float> %x0, 0 |
| // CHECK-NEXT: [[TUP1:%.*]] = insertvalue { <vscale x 4 x float>, <vscale x 4 x float> } [[TUP0]], <vscale x 4 x float> %x1, 1 |
| unsafe { std::intrinsics::simd::scalable::sve_tuple_create2(x0, x1) } |
| } |
| |
| // CHECK-LABEL: define { <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float> } @svcreate3_f32( |
| // CHECK-SAME: <vscale x 4 x float> %x0, <vscale x 4 x float> %x1, <vscale x 4 x float> %x2) |
| #[no_mangle] |
| #[target_feature(enable = "sve")] |
| pub fn svcreate3_f32(x0: svfloat32_t, x1: svfloat32_t, x2: svfloat32_t) -> svfloat32x3_t { |
| // CHECK: [[TUP0:%.*]] = insertvalue { <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float> } poison, <vscale x 4 x float> %x0, 0 |
| // CHECK-NEXT: [[TUP1:%.*]] = insertvalue { <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float> } [[TUP0]], <vscale x 4 x float> %x1, 1 |
| // CHECK-NEXT: [[TUP2:%.*]] = insertvalue { <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float> } [[TUP1]], <vscale x 4 x float> %x2, 2 |
| unsafe { std::intrinsics::simd::scalable::sve_tuple_create3(x0, x1, x2) } |
| } |
| |
| // CHECK-LABEL: define { <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float> } @svcreate4_f32( |
| // CHECK-SAME: <vscale x 4 x float> %x0, <vscale x 4 x float> %x1, <vscale x 4 x float> %x2, <vscale x 4 x float> %x3) |
| #[no_mangle] |
| #[target_feature(enable = "sve")] |
| pub fn svcreate4_f32( |
| x0: svfloat32_t, |
| x1: svfloat32_t, |
| x2: svfloat32_t, |
| x3: svfloat32_t, |
| ) -> svfloat32x4_t { |
| // CHECK: [[TUP0:%.*]] = insertvalue { <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float> } poison, <vscale x 4 x float> %x0, 0 |
| // CHECK-NEXT: [[TUP1:%.*]] = insertvalue { <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float> } [[TUP0]], <vscale x 4 x float> %x1, 1 |
| // CHECK-NEXT: [[TUP2:%.*]] = insertvalue { <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float> } [[TUP1]], <vscale x 4 x float> %x2, 2 |
| // CHECK-NEXT: [[TUP3:%.*]] = insertvalue { <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float> } [[TUP2]], <vscale x 4 x float> %x3, 3 |
| unsafe { std::intrinsics::simd::scalable::sve_tuple_create4(x0, x1, x2, x3) } |
| } |
| |
| // CHECK-LABEL: define <vscale x 4 x float> @svget2_f32( |
| // CHECK-SAME: { <vscale x 4 x float>, <vscale x 4 x float> } %tup) |
| #[no_mangle] |
| #[target_feature(enable = "sve")] |
| pub fn svget2_f32(tup: svfloat32x2_t) -> svfloat32_t { |
| // CHECK: [[X:%.*]] = extractvalue { <vscale x 4 x float>, <vscale x 4 x float> } %tup, 0 |
| unsafe { std::intrinsics::simd::scalable::sve_tuple_get::<_, _, 0>(tup) } |
| } |
| |
| // CHECK-LABEL: define { <vscale x 4 x float>, <vscale x 4 x float> } @svset2_f32( |
| // CHECK-SAME: { <vscale x 4 x float>, <vscale x 4 x float> } %tup, <vscale x 4 x float> %x) |
| #[no_mangle] |
| #[target_feature(enable = "sve")] |
| pub fn svset2_f32(tup: svfloat32x2_t, x: svfloat32_t) -> svfloat32x2_t { |
| // CHECK: [[TUP:%.*]] = insertvalue { <vscale x 4 x float>, <vscale x 4 x float> } %tup, <vscale x 4 x float> %x, 0 |
| unsafe { std::intrinsics::simd::scalable::sve_tuple_set::<_, _, 0>(tup, x) } |
| } |
| |
| // This function exists only so there are calls to the intrinsics |
| #[target_feature(enable = "sve")] |
| pub fn test() { |
| let x = svdup_n_f32(2f32); |
| let tup = svcreate2_f32(x, x); |
| let x = svget2_f32(tup); |
| let _tup = svset2_f32(tup, x); |
| } |