Skip to content

Commit be8e67c

Browse files
committed
add codegen test for simd_insert_dyn and simd_extract_dyn
1 parent 1d21b64 commit be8e67c

File tree

2 files changed

+92
-4
lines changed

2 files changed

+92
-4
lines changed

library/core/src/intrinsics/simd.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
55
/// Inserts an element into a vector, returning the updated vector.
66
///
7-
/// `T` must be a vector with element type `U`, and `idx` must be `const`.
7+
/// `T` must be a vector with element type `U`, and `idx` must be const.
88
///
99
/// # Safety
1010
///
@@ -20,7 +20,7 @@ pub unsafe fn simd_insert<T, U>(_x: T, _idx: u32, _val: U) -> T {
2020
///
2121
/// `T` must be a vector with element type `U`.
2222
///
23-
/// If the index is `const`, [`simd_insert`] may emit better assembly.
23+
/// If the index is `const`, using [`simd_insert`] instead may emit better assembly.
2424
///
2525
/// # Safety
2626
///
@@ -35,7 +35,7 @@ pub unsafe fn simd_insert_dyn<T, U>(_x: T, _idx: u32, _val: U) -> T {
3535

3636
/// Extracts an element from a vector.
3737
///
38-
/// `T` must be a vector with element type `U`, and `idx` must be `const`.
38+
/// `T` must be a vector with element type `U`, and `idx` must be const.
3939
///
4040
/// # Safety
4141
///
@@ -51,7 +51,7 @@ pub unsafe fn simd_extract<T, U>(_x: T, _idx: u32) -> U {
5151
///
5252
/// `T` must be a vector with element type `U`.
5353
///
54-
/// If the index is `const`, [`simd_extract`] may emit better assembly.
54+
/// If the index is `const`, using [`simd_extract`] instead may emit better assembly.
5555
///
5656
/// # Safety
5757
///
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
//@compile-flags: -Copt-level=3 -Z merge-functions=disabled
2+
3+
#![feature(core_intrinsics, s390x_target_feature, repr_simd)]
4+
#![no_std]
5+
#![crate_type = "lib"]
6+
#![allow(non_camel_case_types)]
7+
8+
// Test that
9+
//
10+
// - `core::intrinsics::simd::simd_extract_dyn` is lowered to an `extractelement`
11+
// - `core::intrinsics::simd::simd_insert_dyn` is lowered to an `insertelement`
12+
//
13+
// On many platforms (e.g. x86_64) this will ultimately lower to a pointer load, but some platforms
14+
// (e.g. s390x, powerpc) have dedicated instructions for these operations.
15+
16+
use core::intrinsics::simd::{simd_extract, simd_extract_dyn, simd_insert, simd_insert_dyn};
17+
18+
#[repr(simd)]
19+
#[derive(Clone, Copy)]
20+
pub struct u32x16([u32; 16]);
21+
22+
#[repr(simd)]
23+
#[derive(Clone, Copy)]
24+
pub struct i8x16([i8; 16]);
25+
26+
// CHECK-LABEL: dyn_simd_extract
27+
// CHECK: extractelement <16 x i8> %x, i32 %idx
28+
// CHECK-NEXT: ret
29+
#[no_mangle]
30+
unsafe extern "C" fn dyn_simd_extract(x: i8x16, idx: u32) -> i8 {
31+
simd_extract_dyn(x, idx)
32+
}
33+
34+
// CHECK-LABEL: literal_dyn_simd_extract
35+
// CHECK: extractelement <16 x i8> %x, i64 7
36+
// CHECK-NEXT: ret
37+
#[no_mangle]
38+
unsafe extern "C" fn literal_dyn_simd_extract(x: i8x16) -> i8 {
39+
simd_extract_dyn(x, 7)
40+
}
41+
42+
// CHECK-LABEL: const_dyn_simd_extract
43+
// CHECK: extractelement <16 x i8> %x, i64 7
44+
// CHECK-NEXT: ret
45+
#[no_mangle]
46+
unsafe extern "C" fn const_dyn_simd_extract(x: i8x16) -> i8 {
47+
simd_extract_dyn(x, const { 3 + 4 })
48+
}
49+
50+
// CHECK-LABEL: const_simd_extract
51+
// CHECK: extractelement <16 x i8> %x, i64 7
52+
// CHECK-NEXT: ret
53+
#[no_mangle]
54+
unsafe extern "C" fn const_simd_extract(x: i8x16) -> i8 {
55+
simd_extract(x, const { 3 + 4 })
56+
}
57+
58+
// CHECK-LABEL: dyn_simd_insert
59+
// CHECK: insertelement <16 x i8> %x, i8 %e, i32 %idx
60+
// CHECK-NEXT: ret
61+
#[no_mangle]
62+
unsafe extern "C" fn dyn_simd_insert(x: i8x16, e: i8, idx: u32) -> i8x16 {
63+
simd_insert_dyn(x, idx, e)
64+
}
65+
66+
// CHECK-LABEL: literal_dyn_simd_insert
67+
// CHECK: insertelement <16 x i8> %x, i8 %e, i64 7
68+
// CHECK-NEXT: ret
69+
#[no_mangle]
70+
unsafe extern "C" fn literal_dyn_simd_insert(x: i8x16, e: i8) -> i8x16 {
71+
simd_insert_dyn(x, 7, e)
72+
}
73+
74+
// CHECK-LABEL: const_dyn_simd_insert
75+
// CHECK: insertelement <16 x i8> %x, i8 %e, i64 7
76+
// CHECK-NEXT: ret
77+
#[no_mangle]
78+
unsafe extern "C" fn const_dyn_simd_insert(x: i8x16, e: i8) -> i8x16 {
79+
simd_insert_dyn(x, const { 3 + 4 }, e)
80+
}
81+
82+
// CHECK-LABEL: const_simd_insert
83+
// CHECK: insertelement <16 x i8> %x, i8 %e, i64 7
84+
// CHECK-NEXT: ret
85+
#[no_mangle]
86+
unsafe extern "C" fn const_simd_insert(x: i8x16, e: i8) -> i8x16 {
87+
simd_insert(x, const { 3 + 4 }, e)
88+
}

0 commit comments

Comments
 (0)