зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1252927 - SIMD: Truncate before range check. r=sunfish
Fix this both in the VM and the x86 JIT. MozReview-Commit-ID: IsKyDJUN6tk
This commit is contained in:
Родитель
42c6a18fb5
Коммит
7d10d8fcb4
|
@ -1091,10 +1091,11 @@ struct ThrowIfNotInRange
|
|||
static_assert(mozilla::IsIntegral<IntegerType>::value, "bad destination type");
|
||||
|
||||
static bool value(From v) {
|
||||
double d(v);
|
||||
return mozilla::IsNaN(d) ||
|
||||
d < double(mozilla::MinValue<IntegerType>::value) ||
|
||||
d > double(mozilla::MaxValue<IntegerType>::value);
|
||||
// Truncate to integer value before the range check.
|
||||
double d = trunc(double(v));
|
||||
// Arrange relations so NaN returns true (i.e., it throws a RangeError).
|
||||
return !(d >= double(mozilla::MinValue<IntegerType>::value) &&
|
||||
d <= double(mozilla::MaxValue<IntegerType>::value));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -74,6 +74,11 @@ for (var i = 0; i < 2000; i++) {
|
|||
fsrc[i + 6000] = 0xffffff7f - i;
|
||||
}
|
||||
|
||||
// Truncation towards 0.
|
||||
fsrc[1990] = -0.9
|
||||
fsrc[1991] = 0.9
|
||||
fsrc[1992] = 1.9
|
||||
|
||||
for (var n = 0; n < 10; n++) {
|
||||
cvt_ftou_scalar(fsrc, fdst1);
|
||||
cvt_ftou_simd(fsrc, fdst2);
|
||||
|
|
|
@ -2426,8 +2426,8 @@ CodeGeneratorX86Shared::visitFloat32x4ToUint32x4(LFloat32x4ToUint32x4* ins)
|
|||
|
||||
// Classify lane values into 4 disjoint classes:
|
||||
//
|
||||
// N-lanes: in < -0.0
|
||||
// A-lanes: -0.0 <= in <= 0x0.ffffffp31
|
||||
// N-lanes: in <= -1.0
|
||||
// A-lanes: -1.0 < in <= 0x0.ffffffp31
|
||||
// B-lanes: 0x1.0p31 <= in <= 0x0.ffffffp32
|
||||
// V-lanes: 0x1.0p32 <= in, or isnan(in)
|
||||
//
|
||||
|
@ -2450,22 +2450,6 @@ CodeGeneratorX86Shared::visitFloat32x4ToUint32x4(LFloat32x4ToUint32x4* ins)
|
|||
|
||||
ScratchSimd128Scope scratch(masm);
|
||||
|
||||
// First we need to filter out N-lanes. We need to use a floating point
|
||||
// comparison to do that because cvttps2dq maps the negative range
|
||||
// [-0x0.ffffffp0;-0.0] to 0. We can't simply look at the sign bits of in
|
||||
// because -0.0 is a valid input.
|
||||
// TODO: It may be faster to let ool code deal with -0.0 and skip the
|
||||
// vcmpleps here.
|
||||
masm.zeroFloat32x4(scratch);
|
||||
masm.vcmpleps(Operand(in), scratch, scratch);
|
||||
masm.vmovmskps(scratch, temp);
|
||||
masm.cmp32(temp, Imm32(15));
|
||||
|
||||
if (gen->compilingAsmJS())
|
||||
masm.j(Assembler::NotEqual, wasm::JumpTarget::ConversionError);
|
||||
else
|
||||
bailoutIf(Assembler::NotEqual, ins->snapshot());
|
||||
|
||||
// TODO: If the majority of lanes are A-lanes, it could be faster to compute
|
||||
// A first, use vmovmskps to check for any non-A-lanes and handle them in
|
||||
// ool code. OTOH, we we're wrong about the lane distribution, that would be
|
||||
|
@ -2482,9 +2466,9 @@ CodeGeneratorX86Shared::visitFloat32x4ToUint32x4(LFloat32x4ToUint32x4* ins)
|
|||
// we use |out|, so we can tolerate if they are the same register.
|
||||
masm.convertFloat32x4ToInt32x4(in, out);
|
||||
|
||||
// Since we filtered out N-lanes, we can identify A-lanes by the sign bits
|
||||
// in A: Any A-lanes will be positive in A, and B-lanes and V-lanes will be
|
||||
// 0x80000000 in A. Compute a mask of non-A-lanes into |tempF|.
|
||||
// We can identify A-lanes by the sign bits in A: Any A-lanes will be
|
||||
// positive in A, and N, B, and V-lanes will be 0x80000000 in A. Compute a
|
||||
// mask of non-A-lanes into |tempF|.
|
||||
masm.zeroFloat32x4(tempF);
|
||||
masm.packedGreaterThanInt32x4(Operand(out), tempF);
|
||||
|
||||
|
|
|
@ -374,8 +374,8 @@ function testInt32x4FromFloat32x4() {
|
|||
}
|
||||
|
||||
function testUint32x4FromFloat32x4() {
|
||||
var d = Float32x4(1.1, 2.2, 3.3, 4.6);
|
||||
assertEqX4(Uint32x4.fromFloat32x4(d), [1, 2, 3, 4]);
|
||||
var d = Float32x4(1.1, 2.2, -0.9, 4.6);
|
||||
assertEqX4(Uint32x4.fromFloat32x4(d), [1, 2, 0, 4]);
|
||||
|
||||
var d = Float32x4(NaN, 0, 0, 0);
|
||||
assertThrowsInstanceOf(() => SIMD.Uint32x4.fromFloat32x4(d), RangeError);
|
||||
|
|
Загрузка…
Ссылка в новой задаче