Bug 1278183: Implement MTest for int64 inputs; r=lth

MozReview-Commit-ID: DrOOz7MhSOC

--HG--
extra : rebase_source : eaecf556514cf06a6065ef0e063011e823c6b24b
This commit is contained in:
Benjamin Bouvier 2016-06-09 10:15:38 +02:00
parent efe80ab561
commit 5835e4951b
8 changed files with 47 additions and 7 deletions

View File

@ -139,6 +139,11 @@ testComparison32('gt_u', 40, 40, 0);
testComparison32('ge_s', 40, 40, 1);
testComparison32('ge_u', 40, 40, 1);
// Test MTest's GVN branch inversion.
var testTrunc = wasmEvalText(`(module (func (param f32) (result i32) (if (i32.eqz (i32.trunc_s/f32 (get_local 0))) (i32.const 0) (i32.const 1))) (export "" 0))`);
assertEq(testTrunc(0), 0);
assertEq(testTrunc(13.37), 1);
if (hasI64()) {
setJitCompilerOption('wasm.test-mode', 1);
@ -253,6 +258,11 @@ if (hasI64()) {
testUnary('i64', 'popcnt', -1, 64);
testUnary('i64', 'popcnt', 0, 0);
// Test MTest's GVN branch inversion.
var testTrunc = wasmEvalText(`(module (func (param f32) (result i32) (if (i64.eqz (i64.trunc_s/f32 (get_local 0))) (i32.const 0) (i32.const 1))) (export "" 0))`);
assertEq(testTrunc(0), 0);
assertEq(testTrunc(13.37), 1);
testI64Eqz(40, 0);
testI64Eqz(0, 1);

View File

@ -936,6 +936,9 @@ LIRGenerator::visitTest(MTest* test)
case MIRType::Boolean:
add(new(alloc()) LTestIAndBranch(useRegister(opd), ifTrue, ifFalse));
break;
case MIRType::Int64:
add(new(alloc()) LTestI64AndBranch(useInt64Register(opd), ifTrue, ifFalse));
break;
default:
MOZ_CRASH("Bad type");
}

View File

@ -4568,10 +4568,8 @@ MNot::foldsTo(TempAllocator& alloc)
if (MConstant* inputConst = input()->maybeConstantValue()) {
bool b;
if (inputConst->valueToBoolean(&b)) {
if (type() == MIRType::Int32)
if (type() == MIRType::Int32 || type() == MIRType::Int64)
return MConstant::New(alloc, Int32Value(!b));
if (type() == MIRType::Int64)
return MConstant::NewInt64(alloc, int64_t(!b));
return MConstant::New(alloc, BooleanValue(!b));
}
}

View File

@ -2258,6 +2258,27 @@ class LTestIAndBranch : public LControlInstructionHelper<2, 1, 0>
}
};
// Takes in an int64 input and tests it for truthiness.
class LTestI64AndBranch : public LControlInstructionHelper<2, INT64_PIECES, 0>
{
public:
LIR_HEADER(TestI64AndBranch)
LTestI64AndBranch(const LInt64Allocation& in, MBasicBlock* ifTrue, MBasicBlock* ifFalse)
{
setInt64Operand(0, in);
setSuccessor(0, ifTrue);
setSuccessor(1, ifFalse);
}
MBasicBlock* ifTrue() const {
return getSuccessor(0);
}
MBasicBlock* ifFalse() const {
return getSuccessor(1);
}
};
// Takes in either an integer or boolean input and tests it for truthiness.
class LTestDAndBranch : public LControlInstructionHelper<2, 1, 0>
{

View File

@ -116,6 +116,7 @@
_(Throw) \
_(Phi) \
_(TestIAndBranch) \
_(TestI64AndBranch) \
_(TestDAndBranch) \
_(TestFAndBranch) \
_(TestVAndBranch) \

View File

@ -1391,3 +1391,11 @@ CodeGeneratorX64::visitPopcntI64(LPopcntI64* lir)
masm.popcnt64(input, output, temp);
}
void
CodeGeneratorX64::visitTestI64AndBranch(LTestI64AndBranch* lir)
{
Register input = ToRegister(lir->input());
masm.testq(input, input);
emitBranch(Assembler::NonZero, lir->ifTrue(), lir->ifFalse());
}

View File

@ -80,6 +80,7 @@ class CodeGeneratorX64 : public CodeGeneratorX86Shared
void visitAsmJSUInt32ToFloat32(LAsmJSUInt32ToFloat32* lir);
void visitAsmReinterpretFromI64(LAsmReinterpretFromI64* lir);
void visitAsmReinterpretToI64(LAsmReinterpretToI64* lir);
void visitTestI64AndBranch(LTestI64AndBranch* lir);
void visitWasmTruncateToInt32(LWasmTruncateToInt32* lir);
};

View File

@ -81,10 +81,8 @@ CodeGeneratorX86Shared::visitFloat32(LFloat32* ins)
void
CodeGeneratorX86Shared::visitTestIAndBranch(LTestIAndBranch* test)
{
const LAllocation* opd = test->input();
// Test the operand
masm.test32(ToRegister(opd), ToRegister(opd));
Register input = ToRegister(test->input());
masm.test32(input, input);
emitBranch(Assembler::NonZero, test->ifTrue(), test->ifFalse());
}