Skip to content

Commit 2038405

Browse files
committed
Add simd_funnel_sh{l,r} and simd_round_ties_even
1 parent cc87afd commit 2038405

File tree

8 files changed

+201
-27
lines changed

8 files changed

+201
-27
lines changed

compiler/rustc_codegen_llvm/src/intrinsic.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1532,6 +1532,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
15321532
sym::simd_fsin => "llvm.sin",
15331533
sym::simd_fsqrt => "llvm.sqrt",
15341534
sym::simd_round => "llvm.round",
1535+
sym::simd_round_ties_even => "llvm.rint",
15351536
sym::simd_trunc => "llvm.trunc",
15361537
_ => return_error!(InvalidMonomorphization::UnrecognizedIntrinsic { span, name }),
15371538
};
@@ -1558,6 +1559,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
15581559
| sym::simd_fsqrt
15591560
| sym::simd_relaxed_fma
15601561
| sym::simd_round
1562+
| sym::simd_round_ties_even
15611563
| sym::simd_trunc
15621564
) {
15631565
return simd_simple_float_intrinsic(name, in_elem, in_ty, in_len, bx, span, args);
@@ -2304,7 +2306,13 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
23042306
// Unary integer intrinsics
23052307
if matches!(
23062308
name,
2307-
sym::simd_bswap | sym::simd_bitreverse | sym::simd_ctlz | sym::simd_ctpop | sym::simd_cttz
2309+
sym::simd_bswap
2310+
| sym::simd_bitreverse
2311+
| sym::simd_ctlz
2312+
| sym::simd_ctpop
2313+
| sym::simd_cttz
2314+
| sym::simd_funnel_shl
2315+
| sym::simd_funnel_shr
23082316
) {
23092317
let vec_ty = bx.cx.type_vector(
23102318
match *in_elem.kind() {
@@ -2325,6 +2333,8 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
23252333
sym::simd_ctlz => "llvm.ctlz",
23262334
sym::simd_ctpop => "llvm.ctpop",
23272335
sym::simd_cttz => "llvm.cttz",
2336+
sym::simd_funnel_shl => "llvm.fshl",
2337+
sym::simd_funnel_shr => "llvm.fshr",
23282338
_ => unreachable!(),
23292339
};
23302340
let int_size = in_elem.int_size_and_signed(bx.tcx()).0.bits();
@@ -2345,6 +2355,11 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
23452355
// simple unary argument cases
23462356
Ok(bx.call_intrinsic(llvm_intrinsic, &[vec_ty], &[args[0].immediate()]))
23472357
}
2358+
sym::simd_funnel_shl | sym::simd_funnel_shr => Ok(bx.call_intrinsic(
2359+
llvm_intrinsic,
2360+
&[vec_ty],
2361+
&[args[0].immediate(), args[1].immediate(), args[2].immediate()],
2362+
)),
23482363
_ => unreachable!(),
23492364
};
23502365
}

compiler/rustc_hir_analysis/src/check/intrinsic.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -594,8 +594,9 @@ pub(crate) fn check_intrinsic_type(
594594
| sym::simd_ceil
595595
| sym::simd_floor
596596
| sym::simd_round
597+
| sym::simd_round_ties_even
597598
| sym::simd_trunc => (1, 0, vec![param(0)], param(0)),
598-
sym::simd_fma | sym::simd_relaxed_fma => {
599+
sym::simd_fma | sym::simd_relaxed_fma | sym::simd_funnel_shl | sym::simd_funnel_shr => {
599600
(1, 0, vec![param(0), param(0), param(0)], param(0))
600601
}
601602
sym::simd_gather => (3, 0, vec![param(0), param(1), param(2)], param(0)),

compiler/rustc_span/src/symbol.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1967,6 +1967,8 @@ symbols! {
19671967
simd_fmin,
19681968
simd_fsin,
19691969
simd_fsqrt,
1970+
simd_funnel_shl,
1971+
simd_funnel_shr,
19701972
simd_gather,
19711973
simd_ge,
19721974
simd_gt,
@@ -1994,6 +1996,7 @@ symbols! {
19941996
simd_relaxed_fma,
19951997
simd_rem,
19961998
simd_round,
1999+
simd_round_ties_even,
19972000
simd_saturating_add,
19982001
simd_saturating_sub,
19992002
simd_scatter,

library/core/src/intrinsics/simd.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,40 @@ pub unsafe fn simd_shl<T>(lhs: T, rhs: T) -> T;
126126
#[rustc_nounwind]
127127
pub unsafe fn simd_shr<T>(lhs: T, rhs: T) -> T;
128128

129+
/// Funnel Shifts vector left elementwise, with UB on overflow.
130+
///
131+
/// Concatenates `a` and `b` elementwise (with `a` in the most significant half),
132+
/// creating a vector of the same length, but with each element being twice as
133+
/// wide. Then shift this vector left elementwise by `shift`, shifting in zeros,
134+
/// and extract the most significant half of each of the elements. If `a` and `b`
135+
/// are the same, this is equivalent to an elementwise rotate left operation.
136+
///
137+
/// `T` must be a vector of integers.
138+
///
139+
/// # Safety
140+
///
141+
/// Each element of `shift` must be less than `<int>::BITS`.
142+
#[rustc_intrinsic]
143+
#[rustc_nounwind]
144+
pub unsafe fn simd_funnel_shl<T>(a: T, b: T, shift: T) -> T;
145+
146+
/// Funnel Shifts vector right elementwise, with UB on overflow.
147+
///
148+
/// Concatenates `a` and `b` elementwise (with `a` in the most significant half),
149+
/// creating a vector of the same length, but with each element being twice as
150+
/// wide. Then shift this vector right elementwise by `shift`, shifting in zeros,
151+
/// and extract the least significant half of each of the elements. If `a` and `b`
152+
/// are the same, this is equivalent to an elementwise rotate right operation.
153+
///
154+
/// `T` must be a vector of integers.
155+
///
156+
/// # Safety
157+
///
158+
/// Each element of `shift` must be less than `<int>::BITS`.
159+
#[rustc_intrinsic]
160+
#[rustc_nounwind]
161+
pub unsafe fn simd_funnel_shr<T>(a: T, b: T, shift: T) -> T;
162+
129163
/// "Ands" vectors elementwise.
130164
///
131165
/// `T` must be a vector of integers.
@@ -678,6 +712,14 @@ pub unsafe fn simd_floor<T>(x: T) -> T;
678712
#[rustc_nounwind]
679713
pub unsafe fn simd_round<T>(x: T) -> T;
680714

715+
/// Rounds each element to the closest integer-valued float.
716+
/// Ties are resolved by rounding to the number with an even least significant digit
717+
///
718+
/// `T` must be a vector of floats.
719+
#[rustc_intrinsic]
720+
#[rustc_nounwind]
721+
pub unsafe fn simd_round_ties_even<T>(x: T) -> T;
722+
681723
/// Returns the integer part of each element as an integer-valued float.
682724
/// In other words, non-integer values are truncated towards zero.
683725
///

tests/ui/simd/intrinsic/float-math-pass.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ fn main() {
8585
let r = simd_round(h);
8686
assert_eq!(x, r);
8787

88+
let r = simd_round_ties_even(h);
89+
assert_eq!(z, r);
90+
8891
let r = simd_trunc(h);
8992
assert_eq!(z, r);
9093
}

tests/ui/simd/intrinsic/generic-arithmetic-2.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ fn main() {
4343
simd_shl(y, y);
4444
simd_shr(x, x);
4545
simd_shr(y, y);
46+
simd_funnel_shl(x, x, x);
47+
simd_funnel_shl(y, y, y);
48+
simd_funnel_shr(x, x, x);
49+
simd_funnel_shr(y, y, y);
4650
simd_and(x, x);
4751
simd_and(y, y);
4852
simd_or(x, x);
@@ -73,6 +77,10 @@ fn main() {
7377
//~^ ERROR expected SIMD input type, found non-SIMD `i32`
7478
simd_shr(0, 0);
7579
//~^ ERROR expected SIMD input type, found non-SIMD `i32`
80+
simd_funnel_shl(0, 0, 0);
81+
//~^ ERROR expected SIMD input type, found non-SIMD `i32`
82+
simd_funnel_shr(0, 0, 0);
83+
//~^ ERROR expected SIMD input type, found non-SIMD `i32`
7684
simd_and(0, 0);
7785
//~^ ERROR expected SIMD input type, found non-SIMD `i32`
7886
simd_or(0, 0);
@@ -95,6 +103,10 @@ fn main() {
95103
//~^ ERROR unsupported operation on `f32x4` with element `f32`
96104
simd_shr(z, z);
97105
//~^ ERROR unsupported operation on `f32x4` with element `f32`
106+
simd_funnel_shl(z, z, z);
107+
//~^ ERROR unsupported operation on `f32x4` with element `f32`
108+
simd_funnel_shr(z, z, z);
109+
//~^ ERROR unsupported operation on `f32x4` with element `f32`
98110
simd_and(z, z);
99111
//~^ ERROR unsupported operation on `f32x4` with element `f32`
100112
simd_or(z, z);
Lines changed: 49 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,147 +1,171 @@
11
error[E0511]: invalid monomorphization of `simd_add` intrinsic: expected SIMD input type, found non-SIMD `i32`
2-
--> $DIR/generic-arithmetic-2.rs:64:9
2+
--> $DIR/generic-arithmetic-2.rs:68:9
33
|
44
LL | simd_add(0, 0);
55
| ^^^^^^^^^^^^^^
66

77
error[E0511]: invalid monomorphization of `simd_sub` intrinsic: expected SIMD input type, found non-SIMD `i32`
8-
--> $DIR/generic-arithmetic-2.rs:66:9
8+
--> $DIR/generic-arithmetic-2.rs:70:9
99
|
1010
LL | simd_sub(0, 0);
1111
| ^^^^^^^^^^^^^^
1212

1313
error[E0511]: invalid monomorphization of `simd_mul` intrinsic: expected SIMD input type, found non-SIMD `i32`
14-
--> $DIR/generic-arithmetic-2.rs:68:9
14+
--> $DIR/generic-arithmetic-2.rs:72:9
1515
|
1616
LL | simd_mul(0, 0);
1717
| ^^^^^^^^^^^^^^
1818

1919
error[E0511]: invalid monomorphization of `simd_div` intrinsic: expected SIMD input type, found non-SIMD `i32`
20-
--> $DIR/generic-arithmetic-2.rs:70:9
20+
--> $DIR/generic-arithmetic-2.rs:74:9
2121
|
2222
LL | simd_div(0, 0);
2323
| ^^^^^^^^^^^^^^
2424

2525
error[E0511]: invalid monomorphization of `simd_shl` intrinsic: expected SIMD input type, found non-SIMD `i32`
26-
--> $DIR/generic-arithmetic-2.rs:72:9
26+
--> $DIR/generic-arithmetic-2.rs:76:9
2727
|
2828
LL | simd_shl(0, 0);
2929
| ^^^^^^^^^^^^^^
3030

3131
error[E0511]: invalid monomorphization of `simd_shr` intrinsic: expected SIMD input type, found non-SIMD `i32`
32-
--> $DIR/generic-arithmetic-2.rs:74:9
32+
--> $DIR/generic-arithmetic-2.rs:78:9
3333
|
3434
LL | simd_shr(0, 0);
3535
| ^^^^^^^^^^^^^^
3636

37+
error[E0511]: invalid monomorphization of `simd_funnel_shl` intrinsic: expected SIMD input type, found non-SIMD `i32`
38+
--> $DIR/generic-arithmetic-2.rs:80:9
39+
|
40+
LL | simd_funnel_shl(0, 0, 0);
41+
| ^^^^^^^^^^^^^^^^^^^^^^^^
42+
43+
error[E0511]: invalid monomorphization of `simd_funnel_shr` intrinsic: expected SIMD input type, found non-SIMD `i32`
44+
--> $DIR/generic-arithmetic-2.rs:82:9
45+
|
46+
LL | simd_funnel_shr(0, 0, 0);
47+
| ^^^^^^^^^^^^^^^^^^^^^^^^
48+
3749
error[E0511]: invalid monomorphization of `simd_and` intrinsic: expected SIMD input type, found non-SIMD `i32`
38-
--> $DIR/generic-arithmetic-2.rs:76:9
50+
--> $DIR/generic-arithmetic-2.rs:84:9
3951
|
4052
LL | simd_and(0, 0);
4153
| ^^^^^^^^^^^^^^
4254

4355
error[E0511]: invalid monomorphization of `simd_or` intrinsic: expected SIMD input type, found non-SIMD `i32`
44-
--> $DIR/generic-arithmetic-2.rs:78:9
56+
--> $DIR/generic-arithmetic-2.rs:86:9
4557
|
4658
LL | simd_or(0, 0);
4759
| ^^^^^^^^^^^^^
4860

4961
error[E0511]: invalid monomorphization of `simd_xor` intrinsic: expected SIMD input type, found non-SIMD `i32`
50-
--> $DIR/generic-arithmetic-2.rs:80:9
62+
--> $DIR/generic-arithmetic-2.rs:88:9
5163
|
5264
LL | simd_xor(0, 0);
5365
| ^^^^^^^^^^^^^^
5466

5567
error[E0511]: invalid monomorphization of `simd_neg` intrinsic: expected SIMD input type, found non-SIMD `i32`
56-
--> $DIR/generic-arithmetic-2.rs:83:9
68+
--> $DIR/generic-arithmetic-2.rs:91:9
5769
|
5870
LL | simd_neg(0);
5971
| ^^^^^^^^^^^
6072

6173
error[E0511]: invalid monomorphization of `simd_bswap` intrinsic: expected SIMD input type, found non-SIMD `i32`
62-
--> $DIR/generic-arithmetic-2.rs:85:9
74+
--> $DIR/generic-arithmetic-2.rs:93:9
6375
|
6476
LL | simd_bswap(0);
6577
| ^^^^^^^^^^^^^
6678

6779
error[E0511]: invalid monomorphization of `simd_bitreverse` intrinsic: expected SIMD input type, found non-SIMD `i32`
68-
--> $DIR/generic-arithmetic-2.rs:87:9
80+
--> $DIR/generic-arithmetic-2.rs:95:9
6981
|
7082
LL | simd_bitreverse(0);
7183
| ^^^^^^^^^^^^^^^^^^
7284

7385
error[E0511]: invalid monomorphization of `simd_ctlz` intrinsic: expected SIMD input type, found non-SIMD `i32`
74-
--> $DIR/generic-arithmetic-2.rs:89:9
86+
--> $DIR/generic-arithmetic-2.rs:97:9
7587
|
7688
LL | simd_ctlz(0);
7789
| ^^^^^^^^^^^^
7890

7991
error[E0511]: invalid monomorphization of `simd_cttz` intrinsic: expected SIMD input type, found non-SIMD `i32`
80-
--> $DIR/generic-arithmetic-2.rs:91:9
92+
--> $DIR/generic-arithmetic-2.rs:99:9
8193
|
8294
LL | simd_cttz(0);
8395
| ^^^^^^^^^^^^
8496

8597
error[E0511]: invalid monomorphization of `simd_shl` intrinsic: unsupported operation on `f32x4` with element `f32`
86-
--> $DIR/generic-arithmetic-2.rs:94:9
98+
--> $DIR/generic-arithmetic-2.rs:102:9
8799
|
88100
LL | simd_shl(z, z);
89101
| ^^^^^^^^^^^^^^
90102

91103
error[E0511]: invalid monomorphization of `simd_shr` intrinsic: unsupported operation on `f32x4` with element `f32`
92-
--> $DIR/generic-arithmetic-2.rs:96:9
104+
--> $DIR/generic-arithmetic-2.rs:104:9
93105
|
94106
LL | simd_shr(z, z);
95107
| ^^^^^^^^^^^^^^
96108

109+
error[E0511]: invalid monomorphization of `simd_funnel_shl` intrinsic: unsupported operation on `f32x4` with element `f32`
110+
--> $DIR/generic-arithmetic-2.rs:106:9
111+
|
112+
LL | simd_funnel_shl(z, z, z);
113+
| ^^^^^^^^^^^^^^^^^^^^^^^^
114+
115+
error[E0511]: invalid monomorphization of `simd_funnel_shr` intrinsic: unsupported operation on `f32x4` with element `f32`
116+
--> $DIR/generic-arithmetic-2.rs:108:9
117+
|
118+
LL | simd_funnel_shr(z, z, z);
119+
| ^^^^^^^^^^^^^^^^^^^^^^^^
120+
97121
error[E0511]: invalid monomorphization of `simd_and` intrinsic: unsupported operation on `f32x4` with element `f32`
98-
--> $DIR/generic-arithmetic-2.rs:98:9
122+
--> $DIR/generic-arithmetic-2.rs:110:9
99123
|
100124
LL | simd_and(z, z);
101125
| ^^^^^^^^^^^^^^
102126

103127
error[E0511]: invalid monomorphization of `simd_or` intrinsic: unsupported operation on `f32x4` with element `f32`
104-
--> $DIR/generic-arithmetic-2.rs:100:9
128+
--> $DIR/generic-arithmetic-2.rs:112:9
105129
|
106130
LL | simd_or(z, z);
107131
| ^^^^^^^^^^^^^
108132

109133
error[E0511]: invalid monomorphization of `simd_xor` intrinsic: unsupported operation on `f32x4` with element `f32`
110-
--> $DIR/generic-arithmetic-2.rs:102:9
134+
--> $DIR/generic-arithmetic-2.rs:114:9
111135
|
112136
LL | simd_xor(z, z);
113137
| ^^^^^^^^^^^^^^
114138

115139
error[E0511]: invalid monomorphization of `simd_bswap` intrinsic: unsupported operation on `f32x4` with element `f32`
116-
--> $DIR/generic-arithmetic-2.rs:104:9
140+
--> $DIR/generic-arithmetic-2.rs:116:9
117141
|
118142
LL | simd_bswap(z);
119143
| ^^^^^^^^^^^^^
120144

121145
error[E0511]: invalid monomorphization of `simd_bitreverse` intrinsic: unsupported operation on `f32x4` with element `f32`
122-
--> $DIR/generic-arithmetic-2.rs:106:9
146+
--> $DIR/generic-arithmetic-2.rs:118:9
123147
|
124148
LL | simd_bitreverse(z);
125149
| ^^^^^^^^^^^^^^^^^^
126150

127151
error[E0511]: invalid monomorphization of `simd_ctlz` intrinsic: unsupported operation on `f32x4` with element `f32`
128-
--> $DIR/generic-arithmetic-2.rs:108:9
152+
--> $DIR/generic-arithmetic-2.rs:120:9
129153
|
130154
LL | simd_ctlz(z);
131155
| ^^^^^^^^^^^^
132156

133157
error[E0511]: invalid monomorphization of `simd_ctpop` intrinsic: unsupported operation on `f32x4` with element `f32`
134-
--> $DIR/generic-arithmetic-2.rs:110:9
158+
--> $DIR/generic-arithmetic-2.rs:122:9
135159
|
136160
LL | simd_ctpop(z);
137161
| ^^^^^^^^^^^^^
138162

139163
error[E0511]: invalid monomorphization of `simd_cttz` intrinsic: unsupported operation on `f32x4` with element `f32`
140-
--> $DIR/generic-arithmetic-2.rs:112:9
164+
--> $DIR/generic-arithmetic-2.rs:124:9
141165
|
142166
LL | simd_cttz(z);
143167
| ^^^^^^^^^^^^
144168

145-
error: aborting due to 24 previous errors
169+
error: aborting due to 28 previous errors
146170

147171
For more information about this error, try `rustc --explain E0511`.

0 commit comments

Comments
 (0)