mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:30:27 +00:00
e5aa6ca2dc
- Bug 1249482 - OdinMonkey: Remove the needsBoundsCheck flag from the frontend. r=luke (5004e664a0) - Bug 1249513 - OdinMonkey: MIPS: Clean up long jump patching in asm.js. r=luke (18c7f026f5) - fix misspatch of 1234985 (0713b005b4) - Bug 1248598 part 1 - Some code changes required for the i64.const instruction. r=luke (7bb3eaa57f) - Bug 1247855: Resolve named functions and locals (r=luke) (e06d418fd1) - Bug 1249524 - Baldr: add the other (param) declaration form to the text format (r=mbx) (9492f57377) - Bug 1249523 - Baldr: add return (r=mbx) (36a4eca6a3) - Bug 1249316 - Baldr: move testing functions back into TestingFunctions.cpp (r=jandem) (7daf99a017) - Bug 1249531 - Baldr: add text format and encoding support for control operators (r=mbx) (6dee433349) - Bug 1248598 part 2 - Reject wasm i64 imports/exports as JS doesn't have an int64 type. r=luke (72603cdb3d) - Bug 1246658 part 4 - Replace MConstant's js::Value with a custom union. r=luke (1c78b526d2) - Bug 1246658 part 5 - Support int64 constants, add MIRType_Int64. r=luk (db94c230c6) - Bug 1246658 part 1 followup - Fix a bug introduced by the refactoring. (ec3d444596) - Bug 1248859 - OdinMonkey: MIPS: Fix replace retargetWithOffset. r=arai (dd117fcbf5) - Bug 1249525 - Baldr: accept - and $ in text names (r=sunfish) (64e4e1ddf8) - Bug 1249525 - Baldr: accept integer cases in float constants (r=sunfish) (90a8fbb5d5) - Bug 1248859 - OdinMonkey: MIPS: Implement thunkWithPatch and re/patchThunk. r=luke (722240c9b7) - Bug 1248859 - OdinMonkey: MIPS: Refactor callWithPatch via reative branch. r=luke (0684904686) - Bug 1248503 - Improve log output for MSimdBox and MSimdUnbox. r=nbp (6b65608504) - Bug 1248503 - Fix initial heap assertion. r=nbp (bcf704df34) - Bug 1249525 - Baldr: change order of load/store immediates/subexpressions (r=sunfish) (c2ec5329e2) - Bug 1240055: IonMonkey: When spewing info about range analysis, also spew truncation info, r=nbp (cf477cffce) - fix misspatch in symbol visibility (039e111b31)
261 lines
7.2 KiB
C++
261 lines
7.2 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
* vim: set ts=8 sts=4 et sw=4 tw=99:
|
|
*/
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "jit/IonAnalysis.h"
|
|
#include "jit/MIRGenerator.h"
|
|
#include "jit/MIRGraph.h"
|
|
#include "jit/ValueNumbering.h"
|
|
|
|
#include "jsapi-tests/testJitMinimalFunc.h"
|
|
#include "jsapi-tests/tests.h"
|
|
|
|
using namespace js;
|
|
using namespace js::jit;
|
|
|
|
BEGIN_TEST(testJitFoldsTo_DivReciprocal)
|
|
{
|
|
MinimalFunc func;
|
|
MBasicBlock* block = func.createEntryBlock();
|
|
|
|
// return p / 4.0
|
|
MParameter* p = func.createParameter();
|
|
block->add(p);
|
|
MConstant* c = MConstant::New(func.alloc, DoubleValue(4.0));
|
|
block->add(c);
|
|
MDiv* div = MDiv::New(func.alloc, p, c, MIRType_Double);
|
|
block->add(div);
|
|
if (!div->typePolicy()->adjustInputs(func.alloc, div))
|
|
return false;
|
|
MDefinition* left = div->getOperand(0);
|
|
MReturn* ret = MReturn::New(func.alloc, div);
|
|
block->end(ret);
|
|
|
|
if (!func.runGVN())
|
|
return false;
|
|
|
|
// Test that the div got folded to p * 0.25.
|
|
MDefinition* op = ret->getOperand(0);
|
|
CHECK(op->isMul());
|
|
CHECK(op->getOperand(0) == left);
|
|
CHECK(op->getOperand(1)->isConstant());
|
|
CHECK(op->getOperand(1)->toConstant()->numberToDouble() == 0.25);
|
|
return true;
|
|
}
|
|
END_TEST(testJitFoldsTo_DivReciprocal)
|
|
|
|
BEGIN_TEST(testJitFoldsTo_NoDivReciprocal)
|
|
{
|
|
MinimalFunc func;
|
|
MBasicBlock* block = func.createEntryBlock();
|
|
|
|
// return p / 5.0
|
|
MParameter* p = func.createParameter();
|
|
block->add(p);
|
|
MConstant* c = MConstant::New(func.alloc, DoubleValue(5.0));
|
|
block->add(c);
|
|
MDiv* div = MDiv::New(func.alloc, p, c, MIRType_Double);
|
|
block->add(div);
|
|
if (!div->typePolicy()->adjustInputs(func.alloc, div))
|
|
return false;
|
|
MDefinition* left = div->getOperand(0);
|
|
MDefinition* right = div->getOperand(1);
|
|
MReturn* ret = MReturn::New(func.alloc, div);
|
|
block->end(ret);
|
|
|
|
if (!func.runGVN())
|
|
return false;
|
|
|
|
// Test that the div didn't get folded.
|
|
MDefinition* op = ret->getOperand(0);
|
|
CHECK(op->isDiv());
|
|
CHECK(op->getOperand(0) == left);
|
|
CHECK(op->getOperand(1) == right);
|
|
return true;
|
|
}
|
|
END_TEST(testJitFoldsTo_NoDivReciprocal)
|
|
|
|
BEGIN_TEST(testJitNotNot)
|
|
{
|
|
MinimalFunc func;
|
|
MBasicBlock* block = func.createEntryBlock();
|
|
|
|
// return Not(Not(p))
|
|
MParameter* p = func.createParameter();
|
|
block->add(p);
|
|
MNot* not0 = MNot::New(func.alloc, p);
|
|
block->add(not0);
|
|
MNot* not1 = MNot::New(func.alloc, not0);
|
|
block->add(not1);
|
|
MReturn* ret = MReturn::New(func.alloc, not1);
|
|
block->end(ret);
|
|
|
|
if (!func.runGVN())
|
|
return false;
|
|
|
|
// Test that the nots did not get folded.
|
|
MDefinition* op = ret->getOperand(0);
|
|
CHECK(op->isNot());
|
|
CHECK(op->getOperand(0)->isNot());
|
|
CHECK(op->getOperand(0)->getOperand(0) == p);
|
|
return true;
|
|
}
|
|
END_TEST(testJitNotNot)
|
|
|
|
BEGIN_TEST(testJitNotNotNot)
|
|
{
|
|
MinimalFunc func;
|
|
MBasicBlock* block = func.createEntryBlock();
|
|
|
|
// return Not(Not(Not(p)))
|
|
MParameter* p = func.createParameter();
|
|
block->add(p);
|
|
MNot* not0 = MNot::New(func.alloc, p);
|
|
block->add(not0);
|
|
MNot* not1 = MNot::New(func.alloc, not0);
|
|
block->add(not1);
|
|
MNot* not2 = MNot::New(func.alloc, not1);
|
|
block->add(not2);
|
|
MReturn* ret = MReturn::New(func.alloc, not2);
|
|
block->end(ret);
|
|
|
|
if (!func.runGVN())
|
|
return false;
|
|
|
|
// Test that the nots got folded.
|
|
MDefinition* op = ret->getOperand(0);
|
|
CHECK(op->isNot());
|
|
CHECK(op->getOperand(0) == p);
|
|
return true;
|
|
}
|
|
END_TEST(testJitNotNotNot)
|
|
|
|
BEGIN_TEST(testJitNotTest)
|
|
{
|
|
MinimalFunc func;
|
|
MBasicBlock* block = func.createEntryBlock();
|
|
MBasicBlock* then = func.createBlock(block);
|
|
MBasicBlock* else_ = func.createBlock(block);
|
|
MBasicBlock* exit = func.createBlock(block);
|
|
|
|
// MTest(Not(p))
|
|
MParameter* p = func.createParameter();
|
|
block->add(p);
|
|
MNot* not0 = MNot::New(func.alloc, p);
|
|
block->add(not0);
|
|
MTest* test = MTest::New(func.alloc, not0, then, else_);
|
|
block->end(test);
|
|
|
|
then->end(MGoto::New(func.alloc, exit));
|
|
|
|
else_->end(MGoto::New(func.alloc, exit));
|
|
|
|
MReturn* ret = MReturn::New(func.alloc, p);
|
|
exit->end(ret);
|
|
|
|
exit->addPredecessorWithoutPhis(then);
|
|
|
|
if (!func.runGVN())
|
|
return false;
|
|
|
|
// Test that the not got folded.
|
|
test = block->lastIns()->toTest();
|
|
CHECK(test->getOperand(0) == p);
|
|
CHECK(test->getSuccessor(0) == else_);
|
|
CHECK(test->getSuccessor(1) == then);
|
|
return true;
|
|
}
|
|
END_TEST(testJitNotTest)
|
|
|
|
BEGIN_TEST(testJitNotNotTest)
|
|
{
|
|
MinimalFunc func;
|
|
MBasicBlock* block = func.createEntryBlock();
|
|
MBasicBlock* then = func.createBlock(block);
|
|
MBasicBlock* else_ = func.createBlock(block);
|
|
MBasicBlock* exit = func.createBlock(block);
|
|
|
|
// MTest(Not(Not(p)))
|
|
MParameter* p = func.createParameter();
|
|
block->add(p);
|
|
MNot* not0 = MNot::New(func.alloc, p);
|
|
block->add(not0);
|
|
MNot* not1 = MNot::New(func.alloc, not0);
|
|
block->add(not1);
|
|
MTest* test = MTest::New(func.alloc, not1, then, else_);
|
|
block->end(test);
|
|
|
|
then->end(MGoto::New(func.alloc, exit));
|
|
|
|
else_->end(MGoto::New(func.alloc, exit));
|
|
|
|
MReturn* ret = MReturn::New(func.alloc, p);
|
|
exit->end(ret);
|
|
|
|
exit->addPredecessorWithoutPhis(then);
|
|
|
|
if (!func.runGVN())
|
|
return false;
|
|
|
|
// Test that the nots got folded.
|
|
test = block->lastIns()->toTest();
|
|
CHECK(test->getOperand(0) == p);
|
|
CHECK(test->getSuccessor(0) == then);
|
|
CHECK(test->getSuccessor(1) == else_);
|
|
return true;
|
|
}
|
|
END_TEST(testJitNotNotTest)
|
|
|
|
BEGIN_TEST(testJitFoldsTo_UnsignedDiv)
|
|
{
|
|
MinimalFunc func;
|
|
MBasicBlock* block = func.createEntryBlock();
|
|
|
|
// return 1.0 / 0xffffffff
|
|
MConstant* c0 = MConstant::New(func.alloc, Int32Value(1));
|
|
block->add(c0);
|
|
MConstant* c1 = MConstant::New(func.alloc, Int32Value(0xffffffff));
|
|
block->add(c1);
|
|
MDiv* div = MDiv::NewAsmJS(func.alloc, c0, c1, MIRType_Int32, /*unsignd=*/true);
|
|
block->add(div);
|
|
MReturn* ret = MReturn::New(func.alloc, div);
|
|
block->end(ret);
|
|
|
|
if (!func.runGVN())
|
|
return false;
|
|
|
|
// Test that the div got folded to 0.
|
|
MConstant* op = ret->getOperand(0)->toConstant();
|
|
CHECK(mozilla::NumbersAreIdentical(op->numberToDouble(), 0.0));
|
|
return true;
|
|
}
|
|
END_TEST(testJitFoldsTo_UnsignedDiv)
|
|
|
|
BEGIN_TEST(testJitFoldsTo_UnsignedMod)
|
|
{
|
|
MinimalFunc func;
|
|
MBasicBlock* block = func.createEntryBlock();
|
|
|
|
// return 1.0 % 0xffffffff
|
|
MConstant* c0 = MConstant::New(func.alloc, Int32Value(1));
|
|
block->add(c0);
|
|
MConstant* c1 = MConstant::New(func.alloc, Int32Value(0xffffffff));
|
|
block->add(c1);
|
|
MMod* mod = MMod::NewAsmJS(func.alloc, c0, c1, MIRType_Int32, /*unsignd=*/true);
|
|
block->add(mod);
|
|
MReturn* ret = MReturn::New(func.alloc, mod);
|
|
block->end(ret);
|
|
|
|
if (!func.runGVN())
|
|
return false;
|
|
|
|
// Test that the mod got folded to 1.
|
|
MConstant* op = ret->getOperand(0)->toConstant();
|
|
CHECK(mozilla::NumbersAreIdentical(op->numberToDouble(), 1.0));
|
|
return true;
|
|
}
|
|
END_TEST(testJitFoldsTo_UnsignedMod)
|