зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1141629 - SIMD: Clarify that reciprocal and reciprocalSqrt are approximations. r=bbouvier
--HG-- extra : rebase_source : 72f3a65b345364b87c5c80e58606174072fbc841
This commit is contained in:
Родитель
9f585220aa
Коммит
7d68b9894a
|
@ -5934,10 +5934,10 @@ CheckSimdOperationCall(FunctionCompiler &f, ParseNode *call, const ModuleCompile
|
|||
return CheckSimdUnary(f, call, opType, MSimdUnaryArith::not_, def, type);
|
||||
case AsmJSSimdOperation_sqrt:
|
||||
return CheckSimdUnary(f, call, opType, MSimdUnaryArith::sqrt, def, type);
|
||||
case AsmJSSimdOperation_reciprocal:
|
||||
return CheckSimdUnary(f, call, opType, MSimdUnaryArith::reciprocal, def, type);
|
||||
case AsmJSSimdOperation_reciprocalSqrt:
|
||||
return CheckSimdUnary(f, call, opType, MSimdUnaryArith::reciprocalSqrt, def, type);
|
||||
case AsmJSSimdOperation_reciprocalApproximation:
|
||||
return CheckSimdUnary(f, call, opType, MSimdUnaryArith::reciprocalApproximation, def, type);
|
||||
case AsmJSSimdOperation_reciprocalSqrtApproximation:
|
||||
return CheckSimdUnary(f, call, opType, MSimdUnaryArith::reciprocalSqrtApproximation, def, type);
|
||||
|
||||
case AsmJSSimdOperation_swizzle:
|
||||
return CheckSimdSwizzle(f, call, opType, def, type);
|
||||
|
|
|
@ -532,11 +532,11 @@ struct Not {
|
|||
static inline T apply(T x) { return ~x; }
|
||||
};
|
||||
template<typename T>
|
||||
struct Rec {
|
||||
struct RecApprox {
|
||||
static inline T apply(T x) { return 1 / x; }
|
||||
};
|
||||
template<typename T>
|
||||
struct RecSqrt {
|
||||
struct RecSqrtApprox {
|
||||
static inline T apply(T x) { return sqrt(1 / x); }
|
||||
};
|
||||
template<typename T>
|
||||
|
|
|
@ -29,8 +29,8 @@
|
|||
V(fromInt32x4Bits, (FuncConvertBits<Int32x4, Float32x4>), 1, 0) \
|
||||
V(neg, (UnaryFunc<Float32x4, Neg, Float32x4>), 1, 0) \
|
||||
V(not, (CoercedUnaryFunc<Float32x4, Int32x4, Not, Float32x4>), 1, 0) \
|
||||
V(reciprocal, (UnaryFunc<Float32x4, Rec, Float32x4>), 1, 0) \
|
||||
V(reciprocalSqrt, (UnaryFunc<Float32x4, RecSqrt, Float32x4>), 1, 0) \
|
||||
V(reciprocalApproximation, (UnaryFunc<Float32x4, RecApprox, Float32x4>), 1, 0) \
|
||||
V(reciprocalSqrtApproximation, (UnaryFunc<Float32x4, RecSqrtApprox, Float32x4>), 1, 0) \
|
||||
V(splat, (FuncSplat<Float32x4>), 1, 0) \
|
||||
V(sqrt, (UnaryFunc<Float32x4, Sqrt, Float32x4>), 1, 0)
|
||||
|
||||
|
@ -88,8 +88,8 @@
|
|||
V(fromInt32x4, (FuncConvert<Int32x4, Float64x2> ), 1, 0) \
|
||||
V(fromInt32x4Bits, (FuncConvertBits<Int32x4, Float64x2>), 1, 0) \
|
||||
V(neg, (UnaryFunc<Float64x2, Neg, Float64x2>), 1, 0) \
|
||||
V(reciprocal, (UnaryFunc<Float64x2, Rec, Float64x2>), 1, 0) \
|
||||
V(reciprocalSqrt, (UnaryFunc<Float64x2, RecSqrt, Float64x2>), 1, 0) \
|
||||
V(reciprocalApproximation, (UnaryFunc<Float64x2, RecApprox, Float64x2>), 1, 0) \
|
||||
V(reciprocalSqrtApproximation, (UnaryFunc<Float64x2, RecSqrtApprox, Float64x2>), 1, 0) \
|
||||
V(splat, (FuncSplat<Float64x2>), 1, 0) \
|
||||
V(sqrt, (UnaryFunc<Float64x2, Sqrt, Float64x2>), 1, 0)
|
||||
|
||||
|
@ -198,8 +198,8 @@
|
|||
#define UNARY_ARITH_FLOAT32X4_SIMD_OP(_) \
|
||||
_(abs) \
|
||||
_(sqrt) \
|
||||
_(reciprocal) \
|
||||
_(reciprocalSqrt)
|
||||
_(reciprocalApproximation) \
|
||||
_(reciprocalSqrtApproximation)
|
||||
#define BINARY_ARITH_FLOAT32X4_SIMD_OP(_) \
|
||||
_(div) \
|
||||
_(max) \
|
||||
|
|
|
@ -22,8 +22,8 @@ function f() {
|
|||
assertEqX4(SIMD.float32x4.abs(f4), unaryX4(Math.abs, f4, Math.fround));
|
||||
assertEqX4(SIMD.float32x4.sqrt(f4), unaryX4(Math.sqrt, f4, Math.fround));
|
||||
|
||||
assertEqX4(SIMD.float32x4.reciprocal(f4), unaryX4((x) => 1 / x, f4, Math.fround), assertNear);
|
||||
assertEqX4(SIMD.float32x4.reciprocalSqrt(f4), unaryX4((x) => 1 / Math.sqrt(x), f4, Math.fround), assertNear);
|
||||
assertEqX4(SIMD.float32x4.reciprocalApproximation(f4), unaryX4((x) => 1 / x, f4, Math.fround), assertNear);
|
||||
assertEqX4(SIMD.float32x4.reciprocalSqrtApproximation(f4), unaryX4((x) => 1 / Math.sqrt(x), f4, Math.fround), assertNear);
|
||||
|
||||
assertEqX4(SIMD.int32x4.not(i4), unaryX4((x) => ~x, i4, BitOrZero));
|
||||
assertEqX4(SIMD.int32x4.neg(i4), unaryX4((x) => -x, i4, BitOrZero));
|
||||
|
|
|
@ -554,18 +554,18 @@ var CheckSqrt = CheckUnaryF4('sqrt', function(x) { return Math.sqrt(x); });
|
|||
CheckSqrt([1, 42.42, 0.63, 13.37]);
|
||||
CheckSqrt([NaN, -Infinity, Infinity, 0]);
|
||||
|
||||
// Reciprocal and reciprocalSqrt give approximate results
|
||||
// ReciprocalApproximation and reciprocalSqrtApproximation give approximate results
|
||||
function assertNear(a, b) {
|
||||
if (a !== a && b === b)
|
||||
throw 'Observed NaN, expected ' + b;
|
||||
if (Math.abs(a - b) > 1e-3)
|
||||
throw 'More than 1e-3 between ' + a + ' and ' + b;
|
||||
}
|
||||
var CheckRecp = CheckUnaryF4('reciprocal', function(x) { return 1 / x; }, assertNear);
|
||||
var CheckRecp = CheckUnaryF4('reciprocalApproximation', function(x) { return 1 / x; }, assertNear);
|
||||
CheckRecp([1, 42.42, 0.63, 13.37]);
|
||||
CheckRecp([NaN, -Infinity, Infinity, 0]);
|
||||
|
||||
var CheckRecp = CheckUnaryF4('reciprocalSqrt', function(x) { return 1 / Math.sqrt(x); }, assertNear);
|
||||
var CheckRecp = CheckUnaryF4('reciprocalSqrtApproximation', function(x) { return 1 / Math.sqrt(x); }, assertNear);
|
||||
CheckRecp([1, 42.42, 0.63, 13.37]);
|
||||
CheckRecp([NaN, -Infinity, Infinity, 0]);
|
||||
|
||||
|
|
|
@ -1970,12 +1970,12 @@ class MSimdUnaryArith
|
|||
|
||||
static const char* OperationName(Operation op) {
|
||||
switch (op) {
|
||||
case abs: return "abs";
|
||||
case neg: return "neg";
|
||||
case not_: return "not";
|
||||
case reciprocal: return "reciprocal";
|
||||
case reciprocalSqrt: return "reciprocalSqrt";
|
||||
case sqrt: return "sqrt";
|
||||
case abs: return "abs";
|
||||
case neg: return "neg";
|
||||
case not_: return "not";
|
||||
case reciprocalApproximation: return "reciprocalApproximation";
|
||||
case reciprocalSqrtApproximation: return "reciprocalSqrtApproximation";
|
||||
case sqrt: return "sqrt";
|
||||
}
|
||||
MOZ_CRASH("unexpected operation");
|
||||
}
|
||||
|
|
|
@ -3040,8 +3040,8 @@ CodeGeneratorX86Shared::visitSimdUnaryArithIx4(LSimdUnaryArithIx4 *ins)
|
|||
masm.bitwiseXorX4(in, out);
|
||||
return;
|
||||
case MSimdUnaryArith::abs:
|
||||
case MSimdUnaryArith::reciprocal:
|
||||
case MSimdUnaryArith::reciprocalSqrt:
|
||||
case MSimdUnaryArith::reciprocalApproximation:
|
||||
case MSimdUnaryArith::reciprocalSqrtApproximation:
|
||||
case MSimdUnaryArith::sqrt:
|
||||
break;
|
||||
}
|
||||
|
@ -3078,11 +3078,11 @@ CodeGeneratorX86Shared::visitSimdUnaryArithFx4(LSimdUnaryArithFx4 *ins)
|
|||
masm.loadConstantFloat32x4(allOnes, out);
|
||||
masm.bitwiseXorX4(in, out);
|
||||
return;
|
||||
case MSimdUnaryArith::reciprocal:
|
||||
masm.packedReciprocalFloat32x4(in, out);
|
||||
case MSimdUnaryArith::reciprocalApproximation:
|
||||
masm.packedRcpApproximationFloat32x4(in, out);
|
||||
return;
|
||||
case MSimdUnaryArith::reciprocalSqrt:
|
||||
masm.packedReciprocalSqrtFloat32x4(in, out);
|
||||
case MSimdUnaryArith::reciprocalSqrtApproximation:
|
||||
masm.packedRcpSqrtApproximationFloat32x4(in, out);
|
||||
return;
|
||||
case MSimdUnaryArith::sqrt:
|
||||
masm.packedSqrtFloat32x4(in, out);
|
||||
|
|
|
@ -965,13 +965,13 @@ class MacroAssemblerX86Shared : public Assembler
|
|||
void packedSubInt32(const Operand &src, FloatRegister dest) {
|
||||
vpsubd(src, dest, dest);
|
||||
}
|
||||
void packedReciprocalFloat32x4(const Operand &src, FloatRegister dest) {
|
||||
void packedRcpApproximationFloat32x4(const Operand &src, FloatRegister dest) {
|
||||
// This function is an approximation of the result, this might need
|
||||
// fix up if the spec requires a given precision for this operation.
|
||||
// TODO See also bug 1068028.
|
||||
vrcpps(src, dest);
|
||||
}
|
||||
void packedReciprocalSqrtFloat32x4(const Operand &src, FloatRegister dest) {
|
||||
void packedRcpSqrtApproximationFloat32x4(const Operand &src, FloatRegister dest) {
|
||||
// TODO See comment above. See also bug 1068028.
|
||||
vrsqrtps(src, dest);
|
||||
}
|
||||
|
|
|
@ -13,21 +13,21 @@ function test() {
|
|||
print(BUGNUMBER + ": " + summary);
|
||||
|
||||
var a = float32x4(1, 0.5, 0.25, 0.125);
|
||||
var c = SIMD.float32x4.reciprocal(a);
|
||||
var c = SIMD.float32x4.reciprocalApproximation(a);
|
||||
assertEq(c.x, 1);
|
||||
assertEq(c.y, 2);
|
||||
assertEq(c.z, 4);
|
||||
assertEq(c.w, 8);
|
||||
|
||||
var d = float32x4(1.6, 0.8, 0.4, 0.2);
|
||||
var f = SIMD.float32x4.reciprocal(d);
|
||||
var f = SIMD.float32x4.reciprocalApproximation(d);
|
||||
assertEq(f.x, reciprocalf(1.6));
|
||||
assertEq(f.y, reciprocalf(0.8));
|
||||
assertEq(f.z, reciprocalf(0.4));
|
||||
assertEq(f.w, reciprocalf(0.2));
|
||||
|
||||
var g = float32x4(NaN, -0, Infinity, -Infinity);
|
||||
var i = SIMD.float32x4.reciprocal(g);
|
||||
var i = SIMD.float32x4.reciprocalApproximation(g);
|
||||
assertEq(i.x, NaN);
|
||||
assertEq(i.y, -Infinity);
|
||||
assertEq(i.z, 0);
|
||||
|
|
|
@ -13,21 +13,21 @@ function test() {
|
|||
print(BUGNUMBER + ": " + summary);
|
||||
|
||||
var a = float32x4(1, 1, 0.25, 0.25);
|
||||
var c = SIMD.float32x4.reciprocalSqrt(a);
|
||||
var c = SIMD.float32x4.reciprocalSqrtApproximation(a);
|
||||
assertEq(c.x, 1);
|
||||
assertEq(c.y, 1);
|
||||
assertEq(c.z, 2);
|
||||
assertEq(c.w, 2);
|
||||
|
||||
var d = float32x4(25, 16, 6.25, 1.5625);
|
||||
var f = SIMD.float32x4.reciprocalSqrt(d);
|
||||
var f = SIMD.float32x4.reciprocalSqrtApproximation(d);
|
||||
assertEq(f.x, reciprocalsqrtf(25));
|
||||
assertEq(f.y, reciprocalsqrtf(16));
|
||||
assertEq(f.z, reciprocalsqrtf(6.25));
|
||||
assertEq(f.w, reciprocalsqrtf(1.5625));
|
||||
|
||||
var g = float32x4(NaN, -0, Infinity, -Infinity);
|
||||
var i = SIMD.float32x4.reciprocalSqrt(g);
|
||||
var i = SIMD.float32x4.reciprocalSqrtApproximation(g);
|
||||
assertEq(i.x, reciprocalsqrtf(NaN));
|
||||
assertEq(i.y, reciprocalsqrtf(-0));
|
||||
assertEq(i.z, reciprocalsqrtf(Infinity));
|
||||
|
|
|
@ -14,8 +14,8 @@ function sub(a, b) { return a - b; }
|
|||
function mul(a, b) { return a * b; }
|
||||
function div(a, b) { return a / b; }
|
||||
function neg(a) { return -a; }
|
||||
function reciprocal(a) { return 1 / a; }
|
||||
function reciprocalSqrt(a) { return Math.sqrt(1 / a); }
|
||||
function reciprocalApproximation(a) { return 1 / a; }
|
||||
function reciprocalSqrtApproximation(a) { return Math.sqrt(1 / a); }
|
||||
|
||||
function testAdd(v, w) {
|
||||
return testBinaryFunc(v, w, float64x2.add, add);
|
||||
|
@ -35,11 +35,11 @@ function testAbs(v) {
|
|||
function testNeg(v) {
|
||||
return testUnaryFunc(v, float64x2.neg, neg);
|
||||
}
|
||||
function testReciprocal(v) {
|
||||
return testUnaryFunc(v, float64x2.reciprocal, reciprocal);
|
||||
function testReciprocalApproximation(v) {
|
||||
return testUnaryFunc(v, float64x2.reciprocalApproximation, reciprocalApproximation);
|
||||
}
|
||||
function testReciprocalSqrt(v) {
|
||||
return testUnaryFunc(v, float64x2.reciprocalSqrt, reciprocalSqrt);
|
||||
function testReciprocalSqrtApproximation(v) {
|
||||
return testUnaryFunc(v, float64x2.reciprocalSqrtApproximation, reciprocalSqrtApproximation);
|
||||
}
|
||||
function testSqrt(v) {
|
||||
return testUnaryFunc(v, float64x2.sqrt, Math.sqrt);
|
||||
|
@ -60,9 +60,9 @@ function test() {
|
|||
testDiv(v, w);
|
||||
testAbs(v);
|
||||
testNeg(v);
|
||||
testReciprocal(v);
|
||||
testReciprocalApproximation(v);
|
||||
testSqrt(v);
|
||||
testReciprocalSqrt(v);
|
||||
testReciprocalSqrtApproximation(v);
|
||||
}
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
|
|
Загрузка…
Ссылка в новой задаче