Skip to content

Commit 42c5d96

Browse files
committed
implement SIMD funnel shifts in const-eval
1 parent a2bf824 commit 42c5d96

File tree

5 files changed

+64
-2
lines changed

5 files changed

+64
-2
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#![feature(core_intrinsics, portable_simd)]
2+
3+
use std::intrinsics::simd::simd_funnel_shl;
4+
use std::simd::*;
5+
6+
fn main() {
7+
unsafe {
8+
let x = i32x2::from_array([1, 1]);
9+
let y = i32x2::from_array([100, 0]);
10+
simd_funnel_shl(x, x, y); //~ERROR: overflowing shift by 100 in `simd_funnel_shl` in lane 0
11+
}
12+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
error: Undefined Behavior: overflowing shift by 100 in `simd_funnel_shl` in lane 0
2+
--> tests/fail/intrinsics/simd-funnel_shl-too-far.rs:LL:CC
3+
|
4+
LL | simd_funnel_shl(x, x, y);
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here
6+
|
7+
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
8+
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
9+
10+
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
11+
12+
error: aborting due to 1 previous error
13+
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#![feature(core_intrinsics, portable_simd)]
2+
3+
use std::intrinsics::simd::simd_funnel_shr;
4+
use std::simd::*;
5+
6+
fn main() {
7+
unsafe {
8+
let x = i32x2::from_array([1, 1]);
9+
let y = i32x2::from_array([20, 40]);
10+
simd_funnel_shr(x, x, y); //~ERROR: overflowing shift by 40 in `simd_funnel_shr` in lane 1
11+
}
12+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
error: Undefined Behavior: overflowing shift by 40 in `simd_funnel_shr` in lane 1
2+
--> tests/fail/intrinsics/simd-funnel_shr-too-far.rs:LL:CC
3+
|
4+
LL | simd_funnel_shr(x, x, y);
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here
6+
|
7+
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
8+
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
9+
10+
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
11+
12+
error: aborting due to 1 previous error
13+

tests/pass/intrinsics/portable-simd.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ impl<T: Copy, const N: usize> PackedSimd<T, N> {
6262
#[rustc_nounwind]
6363
pub unsafe fn simd_shuffle_const_generic<T, U, const IDX: &'static [u32]>(x: T, y: T) -> U;
6464

65-
pub fn simd_ops_f16() {
65+
fn simd_ops_f16() {
6666
use intrinsics::*;
6767

6868
// small hack to make type inference better
@@ -273,7 +273,7 @@ fn simd_ops_f64() {
273273
assert_eq!(f64x2::from_array([f64::NAN, 0.0]).reduce_min(), 0.0);
274274
}
275275

276-
pub fn simd_ops_f128() {
276+
fn simd_ops_f128() {
277277
use intrinsics::*;
278278

279279
// small hack to make type inference better
@@ -454,6 +454,18 @@ fn simd_ops_i32() {
454454
0x3fffffffu32 as i32
455455
])
456456
);
457+
458+
// these values are taken from the doctests of `u32::funnel_shl` and `u32::funnel_shr`
459+
let c = u32x4::splat(0x010000b3);
460+
let d = u32x4::splat(0x2fe78e45);
461+
462+
unsafe {
463+
assert_eq!(intrinsics::simd_funnel_shl(c, d, u32x4::splat(0)), c);
464+
assert_eq!(intrinsics::simd_funnel_shl(c, d, u32x4::splat(8)), u32x4::splat(0x0000b32f));
465+
466+
assert_eq!(intrinsics::simd_funnel_shr(c, d, u32x4::splat(0)), d);
467+
assert_eq!(intrinsics::simd_funnel_shr(c, d, u32x4::splat(8)), u32x4::splat(0xb32fe78e));
468+
}
457469
}
458470

459471
fn simd_mask() {

0 commit comments

Comments
 (0)