/* -*- 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()->value().toNumber() == 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->value().toNumber(), 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->value().toNumber(), 1.0));
    return true;
}
END_TEST(testJitFoldsTo_UnsignedMod)
