1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
4 /* This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 #include "jit/IonAnalysis.h"
9 #include "jit/MIRGenerator.h"
10 #include "jit/MIRGraph.h"
11 #include "jit/ValueNumbering.h"
13 #include "jsapi-tests/testJitMinimalFunc.h"
14 #include "jsapi-tests/tests.h"
17 using namespace js::jit
;
19 BEGIN_TEST(testJitFoldsTo_DivReciprocal
) {
21 MBasicBlock
* block
= func
.createEntryBlock();
24 MParameter
* p
= func
.createParameter();
26 MConstant
* c
= MConstant::New(func
.alloc
, DoubleValue(4.0));
28 MDiv
* div
= MDiv::New(func
.alloc
, p
, c
, MIRType::Double
);
30 if (!div
->typePolicy()->adjustInputs(func
.alloc
, div
)) {
33 MDefinition
* left
= div
->getOperand(0);
34 MReturn
* ret
= MReturn::New(func
.alloc
, div
);
41 // Test that the div got folded to p * 0.25.
42 MDefinition
* op
= ret
->getOperand(0);
44 CHECK(op
->getOperand(0) == left
);
45 CHECK(op
->getOperand(1)->isConstant());
46 CHECK(op
->getOperand(1)->toConstant()->numberToDouble() == 0.25);
49 END_TEST(testJitFoldsTo_DivReciprocal
)
51 BEGIN_TEST(testJitFoldsTo_NoDivReciprocal
) {
53 MBasicBlock
* block
= func
.createEntryBlock();
56 MParameter
* p
= func
.createParameter();
58 MConstant
* c
= MConstant::New(func
.alloc
, DoubleValue(5.0));
60 MDiv
* div
= MDiv::New(func
.alloc
, p
, c
, MIRType::Double
);
62 if (!div
->typePolicy()->adjustInputs(func
.alloc
, div
)) {
65 MDefinition
* left
= div
->getOperand(0);
66 MDefinition
* right
= div
->getOperand(1);
67 MReturn
* ret
= MReturn::New(func
.alloc
, div
);
74 // Test that the div didn't get folded.
75 MDefinition
* op
= ret
->getOperand(0);
77 CHECK(op
->getOperand(0) == left
);
78 CHECK(op
->getOperand(1) == right
);
81 END_TEST(testJitFoldsTo_NoDivReciprocal
)
83 BEGIN_TEST(testJitNotNot
) {
85 MBasicBlock
* block
= func
.createEntryBlock();
88 MParameter
* p
= func
.createParameter();
90 MNot
* not0
= MNot::New(func
.alloc
, p
);
92 MNot
* not1
= MNot::New(func
.alloc
, not0
);
94 MReturn
* ret
= MReturn::New(func
.alloc
, not1
);
101 // Test that the nots did not get folded.
102 MDefinition
* op
= ret
->getOperand(0);
104 CHECK(op
->getOperand(0)->isNot());
105 CHECK(op
->getOperand(0)->getOperand(0) == p
);
108 END_TEST(testJitNotNot
)
110 BEGIN_TEST(testJitNotNotNot
) {
112 MBasicBlock
* block
= func
.createEntryBlock();
114 // return Not(Not(Not(p)))
115 MParameter
* p
= func
.createParameter();
117 MNot
* not0
= MNot::New(func
.alloc
, p
);
119 MNot
* not1
= MNot::New(func
.alloc
, not0
);
121 MNot
* not2
= MNot::New(func
.alloc
, not1
);
123 MReturn
* ret
= MReturn::New(func
.alloc
, not2
);
126 if (!func
.runGVN()) {
130 // Test that the nots got folded.
131 MDefinition
* op
= ret
->getOperand(0);
133 CHECK(op
->getOperand(0) == p
);
136 END_TEST(testJitNotNotNot
)
138 BEGIN_TEST(testJitNotTest
) {
140 MBasicBlock
* block
= func
.createEntryBlock();
141 MBasicBlock
* then
= func
.createBlock(block
);
142 MBasicBlock
* else_
= func
.createBlock(block
);
143 MBasicBlock
* exit
= func
.createBlock(block
);
146 MParameter
* p
= func
.createParameter();
148 MNot
* not0
= MNot::New(func
.alloc
, p
);
150 MTest
* test
= MTest::New(func
.alloc
, not0
, then
, else_
);
153 then
->end(MGoto::New(func
.alloc
, exit
));
155 else_
->end(MGoto::New(func
.alloc
, exit
));
157 MReturn
* ret
= MReturn::New(func
.alloc
, p
);
160 MOZ_ALWAYS_TRUE(exit
->addPredecessorWithoutPhis(then
));
162 if (!func
.runGVN()) {
166 // Test that the not got folded.
167 test
= block
->lastIns()->toTest();
168 CHECK(test
->getOperand(0) == p
);
169 CHECK(test
->getSuccessor(0) == else_
);
170 CHECK(test
->getSuccessor(1) == then
);
173 END_TEST(testJitNotTest
)
175 BEGIN_TEST(testJitNotNotTest
) {
177 MBasicBlock
* block
= func
.createEntryBlock();
178 MBasicBlock
* then
= func
.createBlock(block
);
179 MBasicBlock
* else_
= func
.createBlock(block
);
180 MBasicBlock
* exit
= func
.createBlock(block
);
182 // MTest(Not(Not(p)))
183 MParameter
* p
= func
.createParameter();
185 MNot
* not0
= MNot::New(func
.alloc
, p
);
187 MNot
* not1
= MNot::New(func
.alloc
, not0
);
189 MTest
* test
= MTest::New(func
.alloc
, not1
, then
, else_
);
192 then
->end(MGoto::New(func
.alloc
, exit
));
194 else_
->end(MGoto::New(func
.alloc
, exit
));
196 MReturn
* ret
= MReturn::New(func
.alloc
, p
);
199 MOZ_ALWAYS_TRUE(exit
->addPredecessorWithoutPhis(then
));
201 if (!func
.runGVN()) {
205 // Test that the nots got folded.
206 test
= block
->lastIns()->toTest();
207 CHECK(test
->getOperand(0) == p
);
208 CHECK(test
->getSuccessor(0) == then
);
209 CHECK(test
->getSuccessor(1) == else_
);
212 END_TEST(testJitNotNotTest
)
214 BEGIN_TEST(testJitFoldsTo_UnsignedDiv
) {
216 MBasicBlock
* block
= func
.createEntryBlock();
218 // return 1.0 / 0xffffffff
219 MConstant
* c0
= MConstant::New(func
.alloc
, Int32Value(1));
221 MConstant
* c1
= MConstant::New(func
.alloc
, Int32Value(0xffffffff));
223 MDiv
* div
= MDiv::New(func
.alloc
, c0
, c1
, MIRType::Int32
, /*unsignd=*/true);
225 MReturn
* ret
= MReturn::New(func
.alloc
, div
);
228 if (!func
.runGVN()) {
232 // Test that the div got folded to 0.
233 MConstant
* op
= ret
->getOperand(0)->toConstant();
234 CHECK(mozilla::NumbersAreIdentical(op
->numberToDouble(), 0.0));
237 END_TEST(testJitFoldsTo_UnsignedDiv
)
239 BEGIN_TEST(testJitFoldsTo_UnsignedMod
) {
241 MBasicBlock
* block
= func
.createEntryBlock();
243 // return 1.0 % 0xffffffff
244 MConstant
* c0
= MConstant::New(func
.alloc
, Int32Value(1));
246 MConstant
* c1
= MConstant::New(func
.alloc
, Int32Value(0xffffffff));
248 MMod
* mod
= MMod::New(func
.alloc
, c0
, c1
, MIRType::Int32
, /*unsignd=*/true);
250 MReturn
* ret
= MReturn::New(func
.alloc
, mod
);
253 if (!func
.runGVN()) {
257 // Test that the mod got folded to 1.
258 MConstant
* op
= ret
->getOperand(0)->toConstant();
259 CHECK(mozilla::NumbersAreIdentical(op
->numberToDouble(), 1.0));
262 END_TEST(testJitFoldsTo_UnsignedMod
)