Skip to content

Commit d03683c

Browse files
Allow raw pointers in SIMD types
1 parent 625d5a6 commit d03683c

File tree

2 files changed

+71
-1
lines changed

2 files changed

+71
-1
lines changed

compiler/rustc_middle/src/ty/sty.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -1890,7 +1890,10 @@ impl<'tcx> TyS<'tcx> {
18901890

18911891
#[inline]
18921892
pub fn is_machine(&self) -> bool {
1893-
matches!(self.kind(), Int(..) | Uint(..) | Float(..))
1893+
// Yes, RawPtr is a "machine" type for these purposes.
1894+
// LLVM uses a vector-of-pointers model for scatter/gather ops,
1895+
// which typically use a base pointer and vector of signed integers.
1896+
matches!(self.kind(), Int(..) | Uint(..) | Float(..) | RawPtr(..))
18941897
}
18951898

18961899
#[inline]
+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// run-pass
2+
// ignore-emscripten
3+
4+
// Short form of the generic gather/scatter tests,
5+
// verifying simd([*const T; N]) and simd([*mut T; N]) pass typeck and work.
6+
#![feature(repr_simd, platform_intrinsics)]
7+
#![allow(non_camel_case_types)]
8+
9+
#[repr(simd)]
10+
#[derive(Copy, Clone, PartialEq, Debug)]
11+
struct cptrx4<T>([*const T; 4]);
12+
13+
#[repr(simd)]
14+
#[derive(Copy, Clone, PartialEq, Debug)]
15+
struct mptrx4<T>([*mut T; 4]);
16+
17+
#[repr(simd)]
18+
#[derive(Copy, Clone, PartialEq, Debug)]
19+
struct f32x4([f32; 4]);
20+
21+
#[repr(simd)]
22+
#[derive(Copy, Clone, PartialEq, Debug)]
23+
struct i32x4([i32; 4]);
24+
25+
extern "platform-intrinsic" {
26+
fn simd_gather<T, U, V>(x: T, y: U, z: V) -> T;
27+
fn simd_scatter<T, U, V>(x: T, y: U, z: V) -> ();
28+
}
29+
30+
fn main() {
31+
let mut x = [0_f32, 1., 2., 3., 4., 5., 6., 7.];
32+
33+
let default = f32x4([-3_f32, -3., -3., -3.]);
34+
let s_strided = f32x4([0_f32, 2., -3., 6.]);
35+
let mask = i32x4([-1_i32, -1, 0, -1]);
36+
37+
// reading from *const
38+
unsafe {
39+
let pointer = &x as *const f32;
40+
let pointers = cptrx4([
41+
pointer.offset(0) as *const f32,
42+
pointer.offset(2),
43+
pointer.offset(4),
44+
pointer.offset(6)
45+
]);
46+
47+
let r_strided = simd_gather(default, pointers, mask);
48+
49+
assert_eq!(r_strided, s_strided);
50+
}
51+
52+
// writing to *mut
53+
unsafe {
54+
let pointer = &mut x as *mut f32;
55+
let pointers = mptrx4([
56+
pointer.offset(0) as *mut f32,
57+
pointer.offset(2),
58+
pointer.offset(4),
59+
pointer.offset(6)
60+
]);
61+
62+
let values = f32x4([42_f32, 43_f32, 44_f32, 45_f32]);
63+
simd_scatter(values, pointers, mask);
64+
65+
assert_eq!(x, [42., 1., 43., 3., 4., 5., 45., 7.]);
66+
}
67+
}

0 commit comments

Comments
 (0)