Skip to content

Commit cc0e31f

Browse files
committed
Add simd_fsh{l,r} and simd_round_ties_even
1 parent 425e142 commit cc0e31f

File tree

8 files changed

+216
-26
lines changed

8 files changed

+216
-26
lines changed

compiler/rustc_codegen_llvm/src/intrinsic.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1557,6 +1557,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
15571557
sym::simd_fsin => ("sin", bx.type_func(&[vec_ty], vec_ty)),
15581558
sym::simd_fsqrt => ("sqrt", bx.type_func(&[vec_ty], vec_ty)),
15591559
sym::simd_round => ("round", bx.type_func(&[vec_ty], vec_ty)),
1560+
sym::simd_round_ties_even => ("rint", bx.type_func(&[vec_ty], vec_ty)),
15601561
sym::simd_trunc => ("trunc", bx.type_func(&[vec_ty], vec_ty)),
15611562
_ => return_error!(InvalidMonomorphization::UnrecognizedIntrinsic { span, name }),
15621563
};
@@ -1590,6 +1591,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
15901591
| sym::simd_fsqrt
15911592
| sym::simd_relaxed_fma
15921593
| sym::simd_round
1594+
| sym::simd_round_ties_even
15931595
| sym::simd_trunc
15941596
) {
15951597
return simd_simple_float_intrinsic(name, in_elem, in_ty, in_len, bx, span, args);
@@ -2523,5 +2525,34 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
25232525
return Ok(v);
25242526
}
25252527

2528+
if name == sym::simd_fshr || name == sym::simd_fshl {
2529+
let a = args[0].immediate();
2530+
let b = args[1].immediate();
2531+
let shift = args[2].immediate();
2532+
let is_left = name == sym::simd_fshl;
2533+
let ptr_bits = bx.tcx().data_layout.pointer_size.bits();
2534+
2535+
let elem_width = match *in_elem.kind() {
2536+
ty::Int(i) => i.bit_width().unwrap_or(ptr_bits),
2537+
ty::Uint(i) => i.bit_width().unwrap_or(ptr_bits),
2538+
_ => return_error!(InvalidMonomorphization::UnsupportedOperation {
2539+
span,
2540+
name,
2541+
in_ty,
2542+
in_elem
2543+
}),
2544+
};
2545+
let elem_ty = bx.type_ix(elem_width);
2546+
2547+
let llvm_intrinsic =
2548+
&format!("llvm.fsh{}.v{in_len}i{elem_width}", if is_left { 'l' } else { 'r' });
2549+
let vec_ty = bx.cx.type_vector(elem_ty, in_len as u64);
2550+
2551+
let fn_ty = bx.type_func(&[vec_ty, vec_ty, vec_ty], vec_ty);
2552+
let f = bx.declare_cfn(llvm_intrinsic, llvm::UnnamedAddr::No, fn_ty);
2553+
let v = bx.call(fn_ty, None, None, f, &[a, b, shift], None, None);
2554+
return Ok(v);
2555+
}
2556+
25262557
span_bug!(span, "unknown SIMD intrinsic");
25272558
}

compiler/rustc_hir_analysis/src/check/intrinsic.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -659,8 +659,9 @@ pub(crate) fn check_intrinsic_type(
659659
| sym::simd_ceil
660660
| sym::simd_floor
661661
| sym::simd_round
662+
| sym::simd_round_ties_even
662663
| sym::simd_trunc => (1, 0, vec![param(0)], param(0)),
663-
sym::simd_fma | sym::simd_relaxed_fma => {
664+
sym::simd_fma | sym::simd_relaxed_fma | sym::simd_fshl | sym::simd_fshr => {
664665
(1, 0, vec![param(0), param(0), param(0)], param(0))
665666
}
666667
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
@@ -1947,6 +1947,8 @@ symbols! {
19471947
simd_fma,
19481948
simd_fmax,
19491949
simd_fmin,
1950+
simd_fshl,
1951+
simd_fshr,
19501952
simd_fsin,
19511953
simd_fsqrt,
19521954
simd_gather,
@@ -1976,6 +1978,7 @@ symbols! {
19761978
simd_relaxed_fma,
19771979
simd_rem,
19781980
simd_round,
1981+
simd_round_ties_even,
19791982
simd_saturating_add,
19801983
simd_saturating_sub,
19811984
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_fshl<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_fshr<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_fshl(x, x, x);
47+
simd_fshl(y, y, y);
48+
simd_fshr(x, x, x);
49+
simd_fshr(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_fshl(0, 0, 0);
81+
//~^ ERROR expected SIMD input type, found non-SIMD `i32`
82+
simd_fshr(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_fshl(z, z, z);
107+
//~^ ERROR unsupported operation on `f32x4` with element `f32`
108+
simd_fshr(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_fshl` intrinsic: expected SIMD input type, found non-SIMD `i32`
38+
--> $DIR/generic-arithmetic-2.rs:80:9
39+
|
40+
LL | simd_fshl(0, 0, 0);
41+
| ^^^^^^^^^^^^^^^^^^
42+
43+
error[E0511]: invalid monomorphization of `simd_fshr` intrinsic: expected SIMD input type, found non-SIMD `i32`
44+
--> $DIR/generic-arithmetic-2.rs:82:9
45+
|
46+
LL | simd_fshr(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_fshl` intrinsic: unsupported operation on `f32x4` with element `f32`
110+
--> $DIR/generic-arithmetic-2.rs:106:9
111+
|
112+
LL | simd_fshl(z, z, z);
113+
| ^^^^^^^^^^^^^^^^^^
114+
115+
error[E0511]: invalid monomorphization of `simd_fshr` intrinsic: unsupported operation on `f32x4` with element `f32`
116+
--> $DIR/generic-arithmetic-2.rs:108:9
117+
|
118+
LL | simd_fshr(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)