Skip to content

Commit 768b238

Browse files
authored
Updates for wasm simd support (#1110)
* Uncomment some i64-related instruction assertions now that LLVM supports the opcodes. * Fix the codegen for `{i,u}32x4_trunc_sat_f32x4`. This was originally introduced using `simd_cast` but that inherits LLVM's UB related to float-to-integer casts out of bounds. Since the original inception of these intrinsics in LLVM dedicated intrinsics for the wasm instructions have been added, so this swithces the implementation to using those. * Uncomment `f64x2_convert_low_i32x4` instruction assertion and add a test now that this is implemented in Wasmtime.
1 parent e374266 commit 768b238

File tree

2 files changed

+24
-22
lines changed

2 files changed

+24
-22
lines changed

ci/docker/wasm32-wasi/Dockerfile

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,14 @@
1-
FROM rust:1.50.0
2-
3-
# Install wasmtime from source for now while the `experimental_x64` feature is
4-
# not yet the default. (it's not actually that experimental at the time of this
5-
# writing, wasmtime should switch defaults soon and the backend this enables has
6-
# better support for simd instructions)
7-
RUN \
8-
CARGO_INCREMENTAL=0 \
9-
CARGO_PROFILE_DEV_DEBUGINFO=0 \
10-
cargo install wasmtime-cli --features experimental_x64 --debug --vers 0.25.0 --locked
11-
121
FROM ubuntu:20.04
132

143
ENV DEBIAN_FRONTEND=noninteractive
154
RUN apt-get update -y && apt-get install -y --no-install-recommends \
165
ca-certificates \
6+
curl \
7+
xz-utils \
178
clang
189

19-
COPY --from=0 /usr/local/cargo/bin/wasmtime /usr/local/bin/wasmtime
10+
RUN curl -L https://github.com/bytecodealliance/wasmtime/releases/download/v0.26.0/wasmtime-v0.26.0-x86_64-linux.tar.xz | tar xJf -
11+
ENV PATH=$PATH:/wasmtime-v0.26.0-x86_64-linux
2012

2113
ENV CARGO_TARGET_WASM32_WASI_RUNNER="wasmtime \
2214
--enable-simd \

crates/core_arch/src/wasm32/simd128.rs

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,10 @@ extern "C" {
271271
#[link_name = "llvm.wasm.pmax.v2f64"]
272272
fn llvm_f64x2_pmax(x: simd::f64x2, y: simd::f64x2) -> simd::f64x2;
273273

274+
#[link_name = "llvm.wasm.trunc.saturate.signed.v4i32.v4f32"]
275+
fn llvm_i32x4_trunc_sat_f32x4_s(x: simd::f32x4) -> simd::i32x4;
276+
#[link_name = "llvm.wasm.trunc.saturate.unsigned.v4i32.v4f32"]
277+
fn llvm_i32x4_trunc_sat_f32x4_u(x: simd::f32x4) -> simd::i32x4;
274278
#[link_name = "llvm.wasm.convert.low.signed"]
275279
fn llvm_f64x2_convert_low_i32x4_s(x: simd::i32x4) -> simd::f64x2;
276280
#[link_name = "llvm.wasm.convert.low.unsigned"]
@@ -1564,7 +1568,7 @@ pub unsafe fn u32x4_ge(a: v128, b: v128) -> v128 {
15641568
/// Returns a new vector where each lane is all ones if the pairwise elements
15651569
/// were equal, or all zeros if the elements were not equal.
15661570
#[inline]
1567-
// #[cfg_attr(test, assert_instr(i64x2.eq))] // FIXME llvm
1571+
#[cfg_attr(test, assert_instr(i64x2.eq))]
15681572
#[target_feature(enable = "simd128")]
15691573
pub unsafe fn i64x2_eq(a: v128, b: v128) -> v128 {
15701574
transmute(simd_eq::<_, simd::i64x2>(a.as_i64x2(), b.as_i64x2()))
@@ -1576,7 +1580,7 @@ pub unsafe fn i64x2_eq(a: v128, b: v128) -> v128 {
15761580
/// Returns a new vector where each lane is all ones if the pairwise elements
15771581
/// were not equal, or all zeros if the elements were equal.
15781582
#[inline]
1579-
// #[cfg_attr(test, assert_instr(i64x2.ne))] // FIXME llvm
1583+
#[cfg_attr(test, assert_instr(i64x2.ne))]
15801584
#[target_feature(enable = "simd128")]
15811585
pub unsafe fn i64x2_ne(a: v128, b: v128) -> v128 {
15821586
transmute(simd_ne::<_, simd::i64x2>(a.as_i64x2(), b.as_i64x2()))
@@ -1588,7 +1592,7 @@ pub unsafe fn i64x2_ne(a: v128, b: v128) -> v128 {
15881592
/// Returns a new vector where each lane is all ones if the pairwise left
15891593
/// element is less than the pairwise right element, or all zeros otherwise.
15901594
#[inline]
1591-
// #[cfg_attr(test, assert_instr(i64x2.lt_s))] // FIXME llvm
1595+
#[cfg_attr(test, assert_instr(i64x2.lt_s))]
15921596
#[target_feature(enable = "simd128")]
15931597
pub unsafe fn i64x2_lt(a: v128, b: v128) -> v128 {
15941598
transmute(simd_lt::<_, simd::i64x2>(a.as_i64x2(), b.as_i64x2()))
@@ -1600,7 +1604,7 @@ pub unsafe fn i64x2_lt(a: v128, b: v128) -> v128 {
16001604
/// Returns a new vector where each lane is all ones if the pairwise left
16011605
/// element is greater than the pairwise right element, or all zeros otherwise.
16021606
#[inline]
1603-
// #[cfg_attr(test, assert_instr(i64x2.gt_s))] // FIXME llvm
1607+
#[cfg_attr(test, assert_instr(i64x2.gt_s))]
16041608
#[target_feature(enable = "simd128")]
16051609
pub unsafe fn i64x2_gt(a: v128, b: v128) -> v128 {
16061610
transmute(simd_gt::<_, simd::i64x2>(a.as_i64x2(), b.as_i64x2()))
@@ -1612,7 +1616,7 @@ pub unsafe fn i64x2_gt(a: v128, b: v128) -> v128 {
16121616
/// Returns a new vector where each lane is all ones if the pairwise left
16131617
/// element is less than the pairwise right element, or all zeros otherwise.
16141618
#[inline]
1615-
// #[cfg_attr(test, assert_instr(i64x2.le_s))] // FIXME llvm
1619+
#[cfg_attr(test, assert_instr(i64x2.le_s))]
16161620
#[target_feature(enable = "simd128")]
16171621
pub unsafe fn i64x2_le(a: v128, b: v128) -> v128 {
16181622
transmute(simd_le::<_, simd::i64x2>(a.as_i64x2(), b.as_i64x2()))
@@ -1624,7 +1628,7 @@ pub unsafe fn i64x2_le(a: v128, b: v128) -> v128 {
16241628
/// Returns a new vector where each lane is all ones if the pairwise left
16251629
/// element is greater than the pairwise right element, or all zeros otherwise.
16261630
#[inline]
1627-
// #[cfg_attr(test, assert_instr(i64x2.ge_s))] // FIXME llvm
1631+
#[cfg_attr(test, assert_instr(i64x2.ge_s))]
16281632
#[target_feature(enable = "simd128")]
16291633
pub unsafe fn i64x2_ge(a: v128, b: v128) -> v128 {
16301634
transmute(simd_ge::<_, simd::i64x2>(a.as_i64x2(), b.as_i64x2()))
@@ -1862,7 +1866,7 @@ pub unsafe fn i8x16_neg(a: v128) -> v128 {
18621866

18631867
/// Count the number of bits set to one within each lane.
18641868
#[inline]
1865-
// #[cfg_attr(test, assert_instr(i8x16.popcnt))] // FIXME llvm & wasmtime
1869+
// #[cfg_attr(test, assert_instr(i8x16.popcnt))] // FIXME wasmtime
18661870
#[target_feature(enable = "simd128")]
18671871
pub unsafe fn i8x16_popcnt(v: v128) -> v128 {
18681872
transmute(llvm_popcnt(v.as_i8x16()))
@@ -3088,7 +3092,7 @@ pub unsafe fn f64x2_pmax(a: v128, b: v128) -> v128 {
30883092
#[cfg_attr(test, assert_instr(i32x4.trunc_sat_f32x4_s))]
30893093
#[target_feature(enable = "simd128")]
30903094
pub unsafe fn i32x4_trunc_sat_f32x4(a: v128) -> v128 {
3091-
transmute(simd_cast::<_, simd::i32x4>(a.as_f32x4()))
3095+
transmute(llvm_i32x4_trunc_sat_f32x4_s(a.as_f32x4()))
30923096
}
30933097

30943098
/// Converts a 128-bit vector interpreted as four 32-bit floating point numbers
@@ -3100,7 +3104,7 @@ pub unsafe fn i32x4_trunc_sat_f32x4(a: v128) -> v128 {
31003104
#[cfg_attr(test, assert_instr(i32x4.trunc_sat_f32x4_u))]
31013105
#[target_feature(enable = "simd128")]
31023106
pub unsafe fn u32x4_trunc_sat_f32x4(a: v128) -> v128 {
3103-
transmute(simd_cast::<_, simd::u32x4>(a.as_f32x4()))
3107+
transmute(llvm_i32x4_trunc_sat_f32x4_u(a.as_f32x4()))
31043108
}
31053109

31063110
/// Converts a 128-bit vector interpreted as four 32-bit signed integers into a
@@ -3153,7 +3157,7 @@ pub unsafe fn u32x4_trunc_sat_f64x2_zero(a: v128) -> v128 {
31533157

31543158
/// Lane-wise conversion from integer to floating point.
31553159
#[inline]
3156-
// #[cfg_attr(test, assert_instr(f64x2.convert_low_i32x4_s))] // FIXME wasmtime
3160+
#[cfg_attr(test, assert_instr(f64x2.convert_low_i32x4_s))]
31573161
#[target_feature(enable = "simd128")]
31583162
pub unsafe fn f64x2_convert_low_i32x4(a: v128) -> v128 {
31593163
transmute(llvm_f64x2_convert_low_i32x4_s(a.as_i32x4()))
@@ -3193,6 +3197,7 @@ pub mod tests {
31933197
use super::*;
31943198
use core::ops::{Add, Div, Mul, Neg, Sub};
31953199
use std;
3200+
use std::fmt::Debug;
31963201
use std::mem;
31973202
use std::num::Wrapping;
31983203
use std::prelude::v1::*;
@@ -4722,6 +4727,11 @@ pub mod tests {
47224727
u32x4_trunc_sat_f32x4(f32x4(1., f32::NEG_INFINITY, f32::INFINITY, f32::NAN)),
47234728
u32x4(1, 0, u32::MAX, 0),
47244729
);
4730+
compare_bytes(f64x2_convert_low_i32x4(i32x4(1, 2, 3, 4)), f64x2(1., 2.));
4731+
compare_bytes(
4732+
f64x2_convert_low_i32x4(i32x4(i32::MIN, i32::MAX, 3, 4)),
4733+
f64x2(f64::from(i32::MIN), f64::from(i32::MAX)),
4734+
);
47254735
}
47264736
}
47274737
}

0 commit comments

Comments
 (0)