Provide spec-compliant legalization for SIMD floating point min/max

This commit is contained in:
Andrew Brown
2020-06-01 15:38:24 -07:00
parent c6b01935ec
commit c9d573d841
6 changed files with 165 additions and 35 deletions

View File

@@ -58,8 +58,8 @@ block0(v0: f32x4 [%xmm3], v1: f32x4 [%xmm5]):
[-, %xmm3] v3 = fsub v0, v1 ; bin: 0f 5c dd
[-, %xmm3] v4 = fmul v0, v1 ; bin: 0f 59 dd
[-, %xmm3] v5 = fdiv v0, v1 ; bin: 0f 5e dd
[-, %xmm3] v6 = fmin v0, v1 ; bin: 0f 5d dd
[-, %xmm3] v7 = fmax v0, v1 ; bin: 0f 5f dd
[-, %xmm3] v6 = x86_fmin v0, v1 ; bin: 0f 5d dd
[-, %xmm3] v7 = x86_fmax v0, v1 ; bin: 0f 5f dd
[-, %xmm3] v8 = sqrt v0 ; bin: 0f 51 db
return
}
@@ -70,8 +70,8 @@ block0(v0: f32x4 [%xmm3], v1: f32x4 [%xmm10]):
[-, %xmm3] v3 = fsub v0, v1 ; bin: 41 0f 5c da
[-, %xmm3] v4 = fmul v0, v1 ; bin: 41 0f 59 da
[-, %xmm3] v5 = fdiv v0, v1 ; bin: 41 0f 5e da
[-, %xmm3] v6 = fmin v0, v1 ; bin: 41 0f 5d da
[-, %xmm3] v7 = fmax v0, v1 ; bin: 41 0f 5f da
[-, %xmm3] v6 = x86_fmin v0, v1 ; bin: 41 0f 5d da
[-, %xmm3] v7 = x86_fmax v0, v1 ; bin: 41 0f 5f da
[-, %xmm3] v8 = sqrt v1 ; bin: 41 0f 51 da
return
}
@@ -82,8 +82,8 @@ block0(v0: f64x2 [%xmm3], v1: f64x2 [%xmm5]):
[-, %xmm3] v3 = fsub v0, v1 ; bin: 66 0f 5c dd
[-, %xmm3] v4 = fmul v0, v1 ; bin: 66 0f 59 dd
[-, %xmm3] v5 = fdiv v0, v1 ; bin: 66 0f 5e dd
[-, %xmm3] v6 = fmin v0, v1 ; bin: 66 0f 5d dd
[-, %xmm3] v7 = fmax v0, v1 ; bin: 66 0f 5f dd
[-, %xmm3] v6 = x86_fmin v0, v1 ; bin: 66 0f 5d dd
[-, %xmm3] v7 = x86_fmax v0, v1 ; bin: 66 0f 5f dd
[-, %xmm3] v8 = sqrt v0 ; bin: 66 0f 51 db
return
}
@@ -94,8 +94,8 @@ block0(v0: f64x2 [%xmm11], v1: f64x2 [%xmm13]):
[-, %xmm11] v3 = fsub v0, v1 ; bin: 66 45 0f 5c dd
[-, %xmm11] v4 = fmul v0, v1 ; bin: 66 45 0f 59 dd
[-, %xmm11] v5 = fdiv v0, v1 ; bin: 66 45 0f 5e dd
[-, %xmm11] v6 = fmin v0, v1 ; bin: 66 45 0f 5d dd
[-, %xmm11] v7 = fmax v0, v1 ; bin: 66 45 0f 5f dd
[-, %xmm11] v6 = x86_fmin v0, v1 ; bin: 66 45 0f 5d dd
[-, %xmm11] v7 = x86_fmax v0, v1 ; bin: 66 45 0f 5f dd
[-, %xmm11] v8 = sqrt v0 ; bin: 66 45 0f 51 db
return
}

View File

@@ -83,3 +83,35 @@ block0(v0:i64x2, v1:i64x2):
; nextln: v2 = iadd v9, v8
return
}
function %fmin_f32x4(f32x4, f32x4) {
block0(v0:f32x4, v1:f32x4):
v2 = fmin v0, v1
; check: v3 = x86_fmin v0, v1
; nextln: v4 = x86_fmin v1, v0
; nextln: v5 = bor v4, v3
; nextln: v6 = fcmp uno v3, v5
; nextln: v7 = raw_bitcast.f32x4 v6
; nextln: v8 = bor v5, v7
; nextln: v9 = raw_bitcast.i32x4 v7
; nextln: v10 = ushr_imm v9, 10
; nextln: v11 = raw_bitcast.f32x4 v10
; nextln: v2 = band_not v8, v11
return
}
function %fmax_f64x2(f64x2, f64x2) {
block0(v0:f64x2, v1:f64x2):
v2 = fmax v0, v1
; check: v3 = x86_fmax v0, v1
; nextln: v4 = x86_fmax v1, v0
; nextln: v5 = bxor v3, v4
; nextln: v6 = bor v4, v5
; nextln: v7 = fsub v6, v5
; nextln: v8 = fcmp uno v5, v7
; nextln: v9 = raw_bitcast.i64x2 v8
; nextln: v10 = ushr_imm v9, 13
; nextln: v11 = raw_bitcast.f64x2 v10
; nextln: v2 = band_not v7, v11
return
}

View File

@@ -192,31 +192,31 @@ block0:
}
; run
function %fmax_f64x2() -> b1 {
block0:
v0 = vconst.f64x2 [-0.0 -0x1.0]
v1 = vconst.f64x2 [+0.0 +0x1.0]
function %fmax_f64x2(f64x2, f64x2) -> f64x2 {
block0(v0: f64x2, v1: f64x2):
v2 = fmax v0, v1
v3 = fcmp eq v2, v1
v4 = vall_true v3
return v4
return v2
}
; run
function %fmin_f64x2() -> b1 {
block0:
v0 = vconst.f64x2 [-0x1.0 -0x1.0]
v1 = vconst.f64x2 [+0.0 +0x1.0]
; note below how NaNs are quieted but (unlike fmin), retain their sign: this discrepancy is allowed by non-determinism
; in the spec, see https://webassembly.github.io/spec/core/bikeshed/index.html#nan-propagation%E2%91%A0.
; run: %fmax_f64x2([-0x0.0 -0x1.0], [+0x0.0 0x1.0]) == [+0x0.0 0x1.0]
; run: %fmax_f64x2([-NaN NaN], [0x0.0 0x100.0]) == [-NaN NaN]
; run: %fmax_f64x2([NaN 0.0], [0.0 0.0]) == [NaN 0.0]
; run: %fmax_f64x2([-NaN 0.0], [0x1.0 0.0]) == [-NaN 0.0]
; run: %fmax_f64x2([NaN:0x42 0.0], [0x1.0 0.0]) == [NaN 0.0]
function %fmin_f64x2(f64x2, f64x2) -> f64x2 {
block0(v0: f64x2, v1: f64x2):
v2 = fmin v0, v1
v3 = fcmp eq v2, v0
v4 = vall_true v3
return v4
return v2
}
; run
; note below how NaNs are quieted and negative: this is due to non-determinism in the spec for NaNs, see
; https://webassembly.github.io/spec/core/bikeshed/index.html#nan-propagation%E2%91%A0.
; run: %fmin_f64x2([-0x0.0 -0x1.0], [+0x0.0 0x1.0]) == [-0x0.0 -0x1.0]
; run: %fmin_f64x2([-NaN 0x100.0], [0.0 NaN]) == [-NaN -NaN]
; run: %fmin_f64x2([NaN 0.0], [0.0 0.0]) == [-NaN 0.0]
; run: %fmin_f64x2([-NaN 0.0], [0x1.0 0.0]) == [-NaN 0.0]
; run: %fmin_f64x2([NaN:0x42 0.0], [0x1.0 0.0]) == [-NaN 0.0]
function %fneg_f64x2() -> b1 {
block0: