Bug 1067373: Fold SimdValueX4 with same non constant operands into SimdSplatX4; r=sunfish

This commit is contained in:
Benjamin Bouvier 2014-09-16 16:01:08 +02:00
parent 3f88a5537e
commit b77d6aa63f
3 changed files with 38 additions and 24 deletions

View File

@ -4949,10 +4949,7 @@ CheckSimdCtorCall(FunctionCompiler &f, ParseNode *call, const ModuleCompiler::Gl
MOZ_ASSERT(length == 4);
MIRType opType = retType.toMIRType();
if (defs[1] == defs[0] && defs[2] == defs[0] && defs[3] == defs[0])
*def = f.splatSimd(defs[0], opType);
else
*def = f.constructSimd<MSimdValueX4>(defs[0], defs[1], defs[2], defs[3], opType);
*def = f.constructSimd<MSimdValueX4>(defs[0], defs[1], defs[2], defs[3], opType);
*type = retType;
return true;
}

View File

@ -209,6 +209,10 @@ CheckF4('', 'var x=f4(8.,7.,6.,5.); x=f4(x.w, x.z, x.y, x.x)', [5, 6, 7, 8]);
// Optimization for all lanes from the same definition.
CheckI4('', 'var x=i4(1,2,3,4); var c=6; x=i4(c|0,c|0,c|0,c|0)', [6, 6, 6, 6]);
CheckF4(FROUND, 'var x=f4(1,2,3,4); var y=f32(7.); x=f4(y,y,y,y)', [7, 7, 7, 7]);
CheckI4('', 'var x=i4(1,2,3,4); var c=0; c=x.w|0; x=i4(c,c,c,c)', [4, 4, 4, 4]);
CheckF4(FROUND, 'var x=f4(1,2,3,4); var y=f32(0); y=x.z; x=f4(y,y,y,y)', [3, 3, 3, 3]);
CheckI4('', 'var x=i4(1,2,3,4); var c=0; var d=0; c=x.w|0; d=x.w|0; x=i4(c,d,d,c)', [4, 4, 4, 4]);
CheckF4(FROUND, 'var x=f4(1,2,3,4); var y=f32(0); var z=f32(0); y=x.z; z=x.z; x=f4(y,z,y,z)', [3, 3, 3, 3]);
// 1.3.4 Return values
assertAsmTypeFail('glob', USE_ASM + I32 + "function f() {var x=1; return i4(x)} return f");

View File

@ -672,33 +672,46 @@ MDefinition*
MSimdValueX4::foldsTo(TempAllocator &alloc)
{
DebugOnly<MIRType> scalarType = SimdTypeToScalarType(type());
bool allConstants = true;
bool allSame = true;
for (size_t i = 0; i < 4; ++i) {
MDefinition *op = getOperand(i);
MOZ_ASSERT(op->type() == scalarType);
if (!op->isConstant())
return this;
JS_ASSERT(op->type() == scalarType);
allConstants = false;
if (i > 0 && op != getOperand(i - 1))
allSame = false;
}
SimdConstant cst;
switch (type()) {
case MIRType_Int32x4: {
int32_t a[4];
for (size_t i = 0; i < 4; ++i)
a[i] = getOperand(i)->toConstant()->value().toInt32();
cst = SimdConstant::CreateX4(a);
break;
}
case MIRType_Float32x4: {
float a[4];
for (size_t i = 0; i < 4; ++i)
a[i] = getOperand(i)->toConstant()->value().toNumber();
cst = SimdConstant::CreateX4(a);
break;
}
default: MOZ_CRASH("unexpected type in MSimdValueX4::foldsTo");
if (!allConstants && !allSame)
return this;
if (allConstants) {
SimdConstant cst;
switch (type()) {
case MIRType_Int32x4: {
int32_t a[4];
for (size_t i = 0; i < 4; ++i)
a[i] = getOperand(i)->toConstant()->value().toInt32();
cst = SimdConstant::CreateX4(a);
break;
}
case MIRType_Float32x4: {
float a[4];
for (size_t i = 0; i < 4; ++i)
a[i] = getOperand(i)->toConstant()->value().toNumber();
cst = SimdConstant::CreateX4(a);
break;
}
default: MOZ_CRASH("unexpected type in MSimdValueX4::foldsTo");
}
return MSimdConstant::New(alloc, cst, type());
}
return MSimdConstant::New(alloc, cst, type());
MOZ_ASSERT(allSame);
return MSimdSplatX4::New(alloc, type(), getOperand(0));
}
MDefinition*