From 425722073e32dd2a1d18626e8a77398efc06e006 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 9 Jul 2014 13:20:31 -0700 Subject: [PATCH] Bug 1036037 - IonMonkey: Add a unit-test for folding a div to a multiply by reciprocal. r=nbp --- js/src/jsapi-tests/moz.build | 1 + js/src/jsapi-tests/testJitFoldsTo.cpp | 124 ++++++++++++++++++++++++++ 2 files changed, 125 insertions(+) create mode 100644 js/src/jsapi-tests/testJitFoldsTo.cpp diff --git a/js/src/jsapi-tests/moz.build b/js/src/jsapi-tests/moz.build index f0610e83109..19fc2025fa6 100644 --- a/js/src/jsapi-tests/moz.build +++ b/js/src/jsapi-tests/moz.build @@ -81,6 +81,7 @@ UNIFIED_SOURCES += [ if CONFIG['ENABLE_ION']: UNIFIED_SOURCES += [ + 'testJitFoldsTo.cpp', 'testJitRValueAlloc.cpp', ] diff --git a/js/src/jsapi-tests/testJitFoldsTo.cpp b/js/src/jsapi-tests/testJitFoldsTo.cpp new file mode 100644 index 00000000000..e9e32548102 --- /dev/null +++ b/js/src/jsapi-tests/testJitFoldsTo.cpp @@ -0,0 +1,124 @@ +/* -*- 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/tests.h" + +using namespace js; +using namespace js::jit; + +namespace { + +struct MinimalFunc +{ + LifoAlloc lifo; + TempAllocator alloc; + JitCompileOptions options; + CompileInfo info; + MIRGraph graph; + MIRGenerator mir; + uint32_t numParams; + + MinimalFunc() + : lifo(4096), + alloc(&lifo), + options(), + info(0, SequentialExecution), + graph(&alloc), + mir(static_cast(nullptr), options, &alloc, &graph, + &info, static_cast(nullptr)), + numParams(0) + { } + + MBasicBlock *createEntryBlock() + { + MBasicBlock *block = MBasicBlock::NewAsmJS(graph, info, nullptr, MBasicBlock::NORMAL); + graph.addBlock(block); + return block; + } + + MParameter *createParameter() + { + MParameter *p = MParameter::New(alloc, numParams++, nullptr); + return p; + } + + bool runGVN() + { + if (!SplitCriticalEdges(graph)) + return false; + if (!RenumberBlocks(graph)) + return false; + if (!BuildDominatorTree(graph)) + return false; + ValueNumberer gvn(&mir, graph); + if (!gvn.run(ValueNumberer::DontUpdateAliasAnalysis)) + return false; + return true; + } +}; + +} /* anonymous namespace */ + +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); + 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) == p); + 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); + 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) == p); + CHECK(op->getOperand(1) == c); + return true; +} +END_TEST(testJitFoldsTo_NoDivReciprocal)