Skip to content

Commit

Permalink
Auto merge of #84205 - workingjubilee:more-simd-intrin, r=bjorn3
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
bors committed Apr 15, 2021
2 parents 60158f4 + 003b8ea commit 7af1f55
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 13 deletions.
2 changes: 2 additions & 0 deletions compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -277,5 +277,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
// simd_select
// simd_rem
// simd_neg
// simd_trunc
// simd_floor
}
}
8 changes: 6 additions & 2 deletions compiler/rustc_codegen_llvm/src/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1057,8 +1057,10 @@ fn generic_simd_intrinsic(
sym::simd_fsin => ("sin", bx.type_func(&[vec_ty], vec_ty)),
sym::simd_fcos => ("cos", bx.type_func(&[vec_ty], vec_ty)),
sym::simd_fabs => ("fabs", bx.type_func(&[vec_ty], vec_ty)),
sym::simd_floor => ("floor", bx.type_func(&[vec_ty], vec_ty)),
sym::simd_ceil => ("ceil", bx.type_func(&[vec_ty], vec_ty)),
sym::simd_floor => ("floor", bx.type_func(&[vec_ty], vec_ty)),
sym::simd_round => ("round", bx.type_func(&[vec_ty], vec_ty)),
sym::simd_trunc => ("trunc", bx.type_func(&[vec_ty], vec_ty)),
sym::simd_fexp => ("exp", bx.type_func(&[vec_ty], vec_ty)),
sym::simd_fexp2 => ("exp2", bx.type_func(&[vec_ty], vec_ty)),
sym::simd_flog10 => ("log10", bx.type_func(&[vec_ty], vec_ty)),
Expand All @@ -1083,8 +1085,10 @@ fn generic_simd_intrinsic(
| sym::simd_fsin
| sym::simd_fcos
| sym::simd_fabs
| sym::simd_floor
| sym::simd_ceil
| sym::simd_floor
| sym::simd_round
| sym::simd_trunc
| sym::simd_fexp
| sym::simd_fexp2
| sym::simd_flog10
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1103,6 +1103,7 @@ symbols! {
simd_reduce_or,
simd_reduce_xor,
simd_rem,
simd_round,
simd_saturating_add,
simd_saturating_sub,
simd_scatter,
Expand All @@ -1111,6 +1112,7 @@ symbols! {
simd_shl,
simd_shr,
simd_sub,
simd_trunc,
simd_xor,
since,
sinf32,
Expand Down
8 changes: 5 additions & 3 deletions compiler/rustc_typeck/src/check/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -407,8 +407,8 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>)
| sym::simd_fpow
| sym::simd_saturating_add
| sym::simd_saturating_sub => (1, vec![param(0), param(0)], param(0)),
sym::simd_neg => (1, vec![param(0)], param(0)),
sym::simd_fsqrt
sym::simd_neg
| sym::simd_fsqrt
| sym::simd_fsin
| sym::simd_fcos
| sym::simd_fexp
Expand All @@ -417,8 +417,10 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>)
| sym::simd_flog10
| sym::simd_flog
| sym::simd_fabs
| sym::simd_ceil
| sym::simd_floor
| sym::simd_ceil => (1, vec![param(0)], param(0)),
| sym::simd_round
| sym::simd_trunc => (1, vec![param(0)], param(0)),
sym::simd_fpowi => (1, vec![param(0), tcx.types.i32], param(0)),
sym::simd_fma => (1, vec![param(0), param(0), param(0)], param(0)),
sym::simd_gather => (3, vec![param(0), param(1), param(2)], param(0)),
Expand Down
27 changes: 19 additions & 8 deletions src/test/ui/simd/simd-intrinsic-float-math.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,20 @@ extern "platform-intrinsic" {
fn simd_fabs<T>(x: T) -> T;
fn simd_fsin<T>(x: T) -> T;
fn simd_fcos<T>(x: T) -> T;
fn simd_ceil<T>(x: T) -> T;
fn simd_fexp<T>(x: T) -> T;
fn simd_fexp2<T>(x: T) -> T;
fn simd_floor<T>(x: T) -> T;
fn simd_fma<T>(x: T, y: T, z: T) -> T;
fn simd_flog<T>(x: T) -> T;
fn simd_flog10<T>(x: T) -> T;
fn simd_flog2<T>(x: T) -> T;
fn simd_fpow<T>(x: T, y: T) -> T;
fn simd_fpowi<T>(x: T, y: i32) -> T;

// rounding functions
fn simd_ceil<T>(x: T) -> T;
fn simd_floor<T>(x: T) -> T;
fn simd_round<T>(x: T) -> T;
fn simd_trunc<T>(x: T) -> T;
}

macro_rules! assert_approx_eq_f32 {
Expand Down Expand Up @@ -64,18 +68,12 @@ fn main() {
let r = simd_fcos(z);
assert_approx_eq!(x, r);

let r = simd_ceil(h);
assert_approx_eq!(x, r);

let r = simd_fexp(z);
assert_approx_eq!(x, r);

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

let r = simd_floor(h);
assert_approx_eq!(z, r);

let r = simd_fma(x, h, h);
assert_approx_eq!(x, r);

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

let r = simd_fsin(z);
assert_approx_eq!(z, r);

// rounding functions
let r = simd_floor(h);
assert_eq!(z, r);

let r = simd_ceil(h);
assert_eq!(x, r);

let r = simd_round(h);
assert_eq!(x, r);

let r = simd_trunc(h);
assert_eq!(z, r);
}
}

0 comments on commit 7af1f55

Please sign in to comment.