Skip to content

Commit 7af1f55

Browse files
committed
Auto merge of #84205 - workingjubilee:more-simd-intrin, r=bjorn3
Add simd_{round,trunc} intrinsics LLVM supports many functions from math.h in its IR. Many of these have SIMD instructions on various platforms. So, let's add round and trunc so std::arch can use them. Yes, exact comparison is intentional: rounding must always return a valid integer-equal value, except for inf/NAN.
2 parents 60158f4 + 003b8ea commit 7af1f55

File tree

5 files changed

+34
-13
lines changed

5 files changed

+34
-13
lines changed

compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs

+2
Original file line numberDiff line numberDiff line change
@@ -277,5 +277,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
277277
// simd_select
278278
// simd_rem
279279
// simd_neg
280+
// simd_trunc
281+
// simd_floor
280282
}
281283
}

compiler/rustc_codegen_llvm/src/intrinsic.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -1057,8 +1057,10 @@ fn generic_simd_intrinsic(
10571057
sym::simd_fsin => ("sin", bx.type_func(&[vec_ty], vec_ty)),
10581058
sym::simd_fcos => ("cos", bx.type_func(&[vec_ty], vec_ty)),
10591059
sym::simd_fabs => ("fabs", bx.type_func(&[vec_ty], vec_ty)),
1060-
sym::simd_floor => ("floor", bx.type_func(&[vec_ty], vec_ty)),
10611060
sym::simd_ceil => ("ceil", bx.type_func(&[vec_ty], vec_ty)),
1061+
sym::simd_floor => ("floor", bx.type_func(&[vec_ty], vec_ty)),
1062+
sym::simd_round => ("round", bx.type_func(&[vec_ty], vec_ty)),
1063+
sym::simd_trunc => ("trunc", bx.type_func(&[vec_ty], vec_ty)),
10621064
sym::simd_fexp => ("exp", bx.type_func(&[vec_ty], vec_ty)),
10631065
sym::simd_fexp2 => ("exp2", bx.type_func(&[vec_ty], vec_ty)),
10641066
sym::simd_flog10 => ("log10", bx.type_func(&[vec_ty], vec_ty)),
@@ -1083,8 +1085,10 @@ fn generic_simd_intrinsic(
10831085
| sym::simd_fsin
10841086
| sym::simd_fcos
10851087
| sym::simd_fabs
1086-
| sym::simd_floor
10871088
| sym::simd_ceil
1089+
| sym::simd_floor
1090+
| sym::simd_round
1091+
| sym::simd_trunc
10881092
| sym::simd_fexp
10891093
| sym::simd_fexp2
10901094
| sym::simd_flog10

compiler/rustc_span/src/symbol.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1103,6 +1103,7 @@ symbols! {
11031103
simd_reduce_or,
11041104
simd_reduce_xor,
11051105
simd_rem,
1106+
simd_round,
11061107
simd_saturating_add,
11071108
simd_saturating_sub,
11081109
simd_scatter,
@@ -1111,6 +1112,7 @@ symbols! {
11111112
simd_shl,
11121113
simd_shr,
11131114
simd_sub,
1115+
simd_trunc,
11141116
simd_xor,
11151117
since,
11161118
sinf32,

compiler/rustc_typeck/src/check/intrinsic.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -407,8 +407,8 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>)
407407
| sym::simd_fpow
408408
| sym::simd_saturating_add
409409
| sym::simd_saturating_sub => (1, vec![param(0), param(0)], param(0)),
410-
sym::simd_neg => (1, vec![param(0)], param(0)),
411-
sym::simd_fsqrt
410+
sym::simd_neg
411+
| sym::simd_fsqrt
412412
| sym::simd_fsin
413413
| sym::simd_fcos
414414
| sym::simd_fexp
@@ -417,8 +417,10 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>)
417417
| sym::simd_flog10
418418
| sym::simd_flog
419419
| sym::simd_fabs
420+
| sym::simd_ceil
420421
| sym::simd_floor
421-
| sym::simd_ceil => (1, vec![param(0)], param(0)),
422+
| sym::simd_round
423+
| sym::simd_trunc => (1, vec![param(0)], param(0)),
422424
sym::simd_fpowi => (1, vec![param(0), tcx.types.i32], param(0)),
423425
sym::simd_fma => (1, vec![param(0), param(0), param(0)], param(0)),
424426
sym::simd_gather => (3, vec![param(0), param(1), param(2)], param(0)),

src/test/ui/simd/simd-intrinsic-float-math.rs

+19-8
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,20 @@ extern "platform-intrinsic" {
2020
fn simd_fabs<T>(x: T) -> T;
2121
fn simd_fsin<T>(x: T) -> T;
2222
fn simd_fcos<T>(x: T) -> T;
23-
fn simd_ceil<T>(x: T) -> T;
2423
fn simd_fexp<T>(x: T) -> T;
2524
fn simd_fexp2<T>(x: T) -> T;
26-
fn simd_floor<T>(x: T) -> T;
2725
fn simd_fma<T>(x: T, y: T, z: T) -> T;
2826
fn simd_flog<T>(x: T) -> T;
2927
fn simd_flog10<T>(x: T) -> T;
3028
fn simd_flog2<T>(x: T) -> T;
3129
fn simd_fpow<T>(x: T, y: T) -> T;
3230
fn simd_fpowi<T>(x: T, y: i32) -> T;
31+
32+
// rounding functions
33+
fn simd_ceil<T>(x: T) -> T;
34+
fn simd_floor<T>(x: T) -> T;
35+
fn simd_round<T>(x: T) -> T;
36+
fn simd_trunc<T>(x: T) -> T;
3337
}
3438

3539
macro_rules! assert_approx_eq_f32 {
@@ -64,18 +68,12 @@ fn main() {
6468
let r = simd_fcos(z);
6569
assert_approx_eq!(x, r);
6670

67-
let r = simd_ceil(h);
68-
assert_approx_eq!(x, r);
69-
7071
let r = simd_fexp(z);
7172
assert_approx_eq!(x, r);
7273

7374
let r = simd_fexp2(z);
7475
assert_approx_eq!(x, r);
7576

76-
let r = simd_floor(h);
77-
assert_approx_eq!(z, r);
78-
7977
let r = simd_fma(x, h, h);
8078
assert_approx_eq!(x, r);
8179

@@ -99,5 +97,18 @@ fn main() {
9997

10098
let r = simd_fsin(z);
10199
assert_approx_eq!(z, r);
100+
101+
// rounding functions
102+
let r = simd_floor(h);
103+
assert_eq!(z, r);
104+
105+
let r = simd_ceil(h);
106+
assert_eq!(x, r);
107+
108+
let r = simd_round(h);
109+
assert_eq!(x, r);
110+
111+
let r = simd_trunc(h);
112+
assert_eq!(z, r);
102113
}
103114
}

0 commit comments

Comments
 (0)