OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <functional> | 5 #include <functional> |
6 | 6 |
7 #include "src/codegen.h" | 7 #include "src/codegen.h" |
8 #include "src/compiler/js-operator.h" | 8 #include "src/compiler/js-operator.h" |
9 #include "src/compiler/node-properties.h" | 9 #include "src/compiler/node-properties.h" |
10 #include "src/compiler/operator-properties.h" | 10 #include "src/compiler/operator-properties.h" |
11 #include "src/compiler/simplified-operator.h" | 11 #include "src/compiler/simplified-operator.h" |
12 #include "src/objects-inl.h" | 12 #include "src/objects-inl.h" |
13 #include "test/cctest/types-fuzz.h" | 13 #include "test/cctest/types-fuzz.h" |
14 #include "test/unittests/compiler/graph-unittest.h" | 14 #include "test/unittests/compiler/graph-unittest.h" |
15 | 15 |
16 namespace v8 { | 16 namespace v8 { |
17 namespace internal { | 17 namespace internal { |
18 namespace compiler { | 18 namespace compiler { |
19 | 19 |
20 // TODO(titzer): generate a large set of deterministic inputs for these tests. | 20 // TODO(titzer): generate a large set of deterministic inputs for these tests. |
21 class TyperTest : public TypedGraphTest { | 21 class TyperTest : public TypedGraphTest { |
22 public: | 22 public: |
23 TyperTest() | 23 TyperTest() |
24 : TypedGraphTest(3), | 24 : TypedGraphTest(3), |
| 25 operation_typer_(isolate(), zone()), |
25 types_(zone(), isolate(), random_number_generator()), | 26 types_(zone(), isolate(), random_number_generator()), |
26 javascript_(zone()), | 27 javascript_(zone()), |
27 simplified_(zone()) { | 28 simplified_(zone()) { |
28 context_node_ = graph()->NewNode(common()->Parameter(2), graph()->start()); | 29 context_node_ = graph()->NewNode(common()->Parameter(2), graph()->start()); |
29 rng_ = random_number_generator(); | 30 rng_ = random_number_generator(); |
30 | 31 |
31 integers.push_back(0); | 32 integers.push_back(0); |
32 integers.push_back(0); | 33 integers.push_back(0); |
33 integers.push_back(-1); | 34 integers.push_back(-1); |
34 integers.push_back(+1); | 35 integers.push_back(+1); |
(...skipping 10 matching lines...) Expand all Loading... |
45 int32s.push_back(0); | 46 int32s.push_back(0); |
46 int32s.push_back(-1); | 47 int32s.push_back(-1); |
47 int32s.push_back(+1); | 48 int32s.push_back(+1); |
48 int32s.push_back(kMinInt); | 49 int32s.push_back(kMinInt); |
49 int32s.push_back(kMaxInt); | 50 int32s.push_back(kMaxInt); |
50 for (int i = 0; i < 10; ++i) { | 51 for (int i = 0; i < 10; ++i) { |
51 int32s.push_back(rng_->NextInt()); | 52 int32s.push_back(rng_->NextInt()); |
52 } | 53 } |
53 } | 54 } |
54 | 55 |
| 56 const int kRepetitions = 50; |
| 57 |
| 58 OperationTyper operation_typer_; |
55 Types types_; | 59 Types types_; |
56 JSOperatorBuilder javascript_; | 60 JSOperatorBuilder javascript_; |
57 SimplifiedOperatorBuilder simplified_; | 61 SimplifiedOperatorBuilder simplified_; |
58 BinaryOperationHint const hints_ = BinaryOperationHint::kAny; | 62 BinaryOperationHint const hints_ = BinaryOperationHint::kAny; |
59 Node* context_node_; | 63 Node* context_node_; |
60 v8::base::RandomNumberGenerator* rng_; | 64 v8::base::RandomNumberGenerator* rng_; |
61 std::vector<double> integers; | 65 std::vector<double> integers; |
62 std::vector<double> int32s; | 66 std::vector<double> int32s; |
63 | 67 |
64 Type* TypeBinaryOp(const Operator* op, Type* lhs, Type* rhs) { | 68 Type* TypeBinaryOp(const Operator* op, Type* lhs, Type* rhs) { |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
116 if (IsMinusZero(result)) return 0; | 120 if (IsMinusZero(result)) return 0; |
117 if (std::isnan(result)) return rng_->NextInt(2) ? min : max; | 121 if (std::isnan(result)) return rng_->NextInt(2) ? min : max; |
118 DCHECK(min <= result && result <= max); | 122 DCHECK(min <= result && result <= max); |
119 return result; | 123 return result; |
120 } | 124 } |
121 | 125 |
122 double RandomInt(RangeType* range) { | 126 double RandomInt(RangeType* range) { |
123 return RandomInt(range->Min(), range->Max()); | 127 return RandomInt(range->Min(), range->Max()); |
124 } | 128 } |
125 | 129 |
| 130 Type* RandomSubtype(Type* type) { |
| 131 Type* subtype; |
| 132 do { |
| 133 subtype = types_.Fuzz(); |
| 134 } while (!subtype->Is(type)); |
| 135 return subtype; |
| 136 } |
| 137 |
126 // Careful, this function runs O(max_width^5) trials. | 138 // Careful, this function runs O(max_width^5) trials. |
127 template <class BinaryFunction> | 139 template <class BinaryFunction> |
128 void TestBinaryArithOpCloseToZero(const Operator* op, BinaryFunction opfun, | 140 void TestBinaryArithOpCloseToZero(const Operator* op, BinaryFunction opfun, |
129 int max_width) { | 141 int max_width) { |
130 const int min_min = -2 - max_width / 2; | 142 const int min_min = -2 - max_width / 2; |
131 const int max_min = 2 + max_width / 2; | 143 const int max_min = 2 + max_width / 2; |
132 for (int width = 0; width < max_width; width++) { | 144 for (int width = 0; width < max_width; width++) { |
133 for (int lmin = min_min; lmin <= max_min; lmin++) { | 145 for (int lmin = min_min; lmin <= max_min; lmin++) { |
134 for (int rmin = min_min; rmin <= max_min; rmin++) { | 146 for (int rmin = min_min; rmin <= max_min; rmin++) { |
135 Type* r1 = NewRange(lmin, lmin + width); | 147 Type* r1 = NewRange(lmin, lmin + width); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
206 int32_t x1 = static_cast<int32_t>(RandomInt(r1->AsRange())); | 218 int32_t x1 = static_cast<int32_t>(RandomInt(r1->AsRange())); |
207 int32_t x2 = static_cast<int32_t>(RandomInt(r2->AsRange())); | 219 int32_t x2 = static_cast<int32_t>(RandomInt(r2->AsRange())); |
208 double result_value = opfun(x1, x2); | 220 double result_value = opfun(x1, x2); |
209 Type* result_type = Type::NewConstant( | 221 Type* result_type = Type::NewConstant( |
210 isolate()->factory()->NewNumber(result_value), zone()); | 222 isolate()->factory()->NewNumber(result_value), zone()); |
211 EXPECT_TRUE(result_type->Is(expected_type)); | 223 EXPECT_TRUE(result_type->Is(expected_type)); |
212 } | 224 } |
213 } | 225 } |
214 } | 226 } |
215 | 227 |
216 Type* RandomSubtype(Type* type) { | 228 typedef std::function<Type*(Type*)> UnaryTyper; |
217 Type* subtype; | 229 typedef std::function<Type*(Type*, Type*)> BinaryTyper; |
218 do { | 230 |
219 subtype = types_.Fuzz(); | 231 void TestUnaryMonotonicity(UnaryTyper typer, Type* upper1 = Type::Any()) { |
220 } while (!subtype->Is(type)); | 232 Type* type1 = Type::Intersect(types_.Fuzz(), upper1, zone()); |
221 return subtype; | 233 DCHECK(type1->Is(upper1)); |
| 234 Type* type = typer(type1); |
| 235 |
| 236 Type* subtype1 = RandomSubtype(type1); |
| 237 Type* subtype = typer(subtype1); |
| 238 |
| 239 EXPECT_TRUE(subtype->Is(type)); |
222 } | 240 } |
223 | 241 |
224 void TestBinaryMonotonicity(const Operator* op) { | 242 void TestBinaryMonotonicity(BinaryTyper typer, Type* upper1 = Type::Any(), |
225 for (int i = 0; i < 50; ++i) { | 243 Type* upper2 = Type::Any()) { |
226 Type* type1 = types_.Fuzz(); | 244 Type* type1 = Type::Intersect(types_.Fuzz(), upper1, zone()); |
227 Type* type2 = types_.Fuzz(); | 245 DCHECK(type1->Is(upper1)); |
228 Type* type = TypeBinaryOp(op, type1, type2); | 246 Type* type2 = Type::Intersect(types_.Fuzz(), upper2, zone()); |
229 Type* subtype1 = RandomSubtype(type1); | 247 DCHECK(type2->Is(upper2)); |
230 Type* subtype2 = RandomSubtype(type2); | 248 Type* type = typer(type1, type2); |
231 Type* subtype = TypeBinaryOp(op, subtype1, subtype2); | 249 |
232 EXPECT_TRUE(subtype->Is(type)); | 250 Type* subtype1 = RandomSubtype(type1); |
| 251 Type* subtype2 = RandomSubtype(type2); |
| 252 Type* subtype = typer(subtype1, subtype2); |
| 253 |
| 254 EXPECT_TRUE(subtype->Is(type)); |
| 255 } |
| 256 |
| 257 void TestBinaryMonotonicity(const Operator* op, Type* upper1 = Type::Any(), |
| 258 Type* upper2 = Type::Any()) { |
| 259 BinaryTyper typer = [&](Type* type1, Type* type2) { |
| 260 return TypeBinaryOp(op, type1, type2); |
| 261 }; |
| 262 for (int i = 0; i < kRepetitions; ++i) { |
| 263 TestBinaryMonotonicity(typer, upper1, upper2); |
233 } | 264 } |
234 } | 265 } |
235 }; | 266 }; |
236 | 267 |
237 | 268 |
238 namespace { | 269 namespace { |
239 | 270 |
240 int32_t shift_left(int32_t x, int32_t y) { return x << (y & 0x1f); } | 271 int32_t shift_left(int32_t x, int32_t y) { return x << (y & 0x1f); } |
241 int32_t shift_right(int32_t x, int32_t y) { return x >> (y & 0x1f); } | 272 int32_t shift_right(int32_t x, int32_t y) { return x >> (y & 0x1f); } |
242 int32_t bit_or(int32_t x, int32_t y) { return x | y; } | 273 int32_t bit_or(int32_t x, int32_t y) { return x | y; } |
243 int32_t bit_and(int32_t x, int32_t y) { return x & y; } | 274 int32_t bit_and(int32_t x, int32_t y) { return x & y; } |
244 int32_t bit_xor(int32_t x, int32_t y) { return x ^ y; } | 275 int32_t bit_xor(int32_t x, int32_t y) { return x ^ y; } |
245 | 276 |
246 } // namespace | 277 } // namespace |
247 | 278 |
248 | 279 |
249 //------------------------------------------------------------------------------ | 280 //------------------------------------------------------------------------------ |
250 // Soundness | 281 // Soundness |
251 // For simplicity, we currently only test soundness on expression operators | 282 // For simplicity, we currently only test soundness on expression operators |
252 // that have a direct equivalent in C++. Also, testing is currently limited | 283 // that have a direct equivalent in C++. Also, testing is currently limited |
253 // to ranges as input types. | 284 // to ranges as input types. |
254 | 285 |
255 | |
256 TEST_F(TyperTest, TypeJSAdd) { | 286 TEST_F(TyperTest, TypeJSAdd) { |
257 TestBinaryArithOp(javascript_.Add(hints_), std::plus<double>()); | 287 TestBinaryArithOp(javascript_.Add(hints_), std::plus<double>()); |
258 } | 288 } |
259 | 289 |
260 | |
261 TEST_F(TyperTest, TypeJSSubtract) { | 290 TEST_F(TyperTest, TypeJSSubtract) { |
262 TestBinaryArithOp(javascript_.Subtract(), std::minus<double>()); | 291 TestBinaryArithOp(javascript_.Subtract(), std::minus<double>()); |
263 } | 292 } |
264 | 293 |
265 | |
266 TEST_F(TyperTest, TypeJSMultiply) { | 294 TEST_F(TyperTest, TypeJSMultiply) { |
267 TestBinaryArithOp(javascript_.Multiply(), std::multiplies<double>()); | 295 TestBinaryArithOp(javascript_.Multiply(), std::multiplies<double>()); |
268 } | 296 } |
269 | 297 |
270 | |
271 TEST_F(TyperTest, TypeJSDivide) { | 298 TEST_F(TyperTest, TypeJSDivide) { |
272 TestBinaryArithOp(javascript_.Divide(), std::divides<double>()); | 299 TestBinaryArithOp(javascript_.Divide(), std::divides<double>()); |
273 } | 300 } |
274 | 301 |
275 | |
276 TEST_F(TyperTest, TypeJSModulus) { | 302 TEST_F(TyperTest, TypeJSModulus) { |
277 TestBinaryArithOp(javascript_.Modulus(), modulo); | 303 TestBinaryArithOp(javascript_.Modulus(), modulo); |
278 } | 304 } |
279 | 305 |
280 | |
281 TEST_F(TyperTest, TypeJSBitwiseOr) { | 306 TEST_F(TyperTest, TypeJSBitwiseOr) { |
282 TestBinaryBitOp(javascript_.BitwiseOr(), bit_or); | 307 TestBinaryBitOp(javascript_.BitwiseOr(), bit_or); |
283 } | 308 } |
284 | 309 |
285 | |
286 TEST_F(TyperTest, TypeJSBitwiseAnd) { | 310 TEST_F(TyperTest, TypeJSBitwiseAnd) { |
287 TestBinaryBitOp(javascript_.BitwiseAnd(), bit_and); | 311 TestBinaryBitOp(javascript_.BitwiseAnd(), bit_and); |
288 } | 312 } |
289 | 313 |
290 | |
291 TEST_F(TyperTest, TypeJSBitwiseXor) { | 314 TEST_F(TyperTest, TypeJSBitwiseXor) { |
292 TestBinaryBitOp(javascript_.BitwiseXor(), bit_xor); | 315 TestBinaryBitOp(javascript_.BitwiseXor(), bit_xor); |
293 } | 316 } |
294 | 317 |
295 | |
296 TEST_F(TyperTest, TypeJSShiftLeft) { | 318 TEST_F(TyperTest, TypeJSShiftLeft) { |
297 TestBinaryBitOp(javascript_.ShiftLeft(), shift_left); | 319 TestBinaryBitOp(javascript_.ShiftLeft(), shift_left); |
298 } | 320 } |
299 | 321 |
300 | |
301 TEST_F(TyperTest, TypeJSShiftRight) { | 322 TEST_F(TyperTest, TypeJSShiftRight) { |
302 TestBinaryBitOp(javascript_.ShiftRight(), shift_right); | 323 TestBinaryBitOp(javascript_.ShiftRight(), shift_right); |
303 } | 324 } |
304 | 325 |
305 | |
306 TEST_F(TyperTest, TypeJSLessThan) { | 326 TEST_F(TyperTest, TypeJSLessThan) { |
307 TestBinaryCompareOp(javascript_.LessThan(CompareOperationHint::kAny), | 327 TestBinaryCompareOp(javascript_.LessThan(CompareOperationHint::kAny), |
308 std::less<double>()); | 328 std::less<double>()); |
309 } | 329 } |
310 | 330 |
311 TEST_F(TyperTest, TypeNumberLessThan) { | 331 TEST_F(TyperTest, TypeNumberLessThan) { |
312 TestBinaryCompareOp(simplified_.NumberLessThan(), std::less<double>()); | 332 TestBinaryCompareOp(simplified_.NumberLessThan(), std::less<double>()); |
313 } | 333 } |
314 | 334 |
315 TEST_F(TyperTest, TypeSpeculativeNumberLessThan) { | 335 TEST_F(TyperTest, TypeSpeculativeNumberLessThan) { |
(...skipping 23 matching lines...) Expand all Loading... |
339 std::greater<double>()); | 359 std::greater<double>()); |
340 } | 360 } |
341 | 361 |
342 | 362 |
343 TEST_F(TyperTest, TypeJSGreaterThanOrEqual) { | 363 TEST_F(TyperTest, TypeJSGreaterThanOrEqual) { |
344 TestBinaryCompareOp( | 364 TestBinaryCompareOp( |
345 javascript_.GreaterThanOrEqual(CompareOperationHint::kAny), | 365 javascript_.GreaterThanOrEqual(CompareOperationHint::kAny), |
346 std::greater_equal<double>()); | 366 std::greater_equal<double>()); |
347 } | 367 } |
348 | 368 |
349 | |
350 TEST_F(TyperTest, TypeJSEqual) { | 369 TEST_F(TyperTest, TypeJSEqual) { |
351 TestBinaryCompareOp(javascript_.Equal(CompareOperationHint::kAny), | 370 TestBinaryCompareOp(javascript_.Equal(CompareOperationHint::kAny), |
352 std::equal_to<double>()); | 371 std::equal_to<double>()); |
353 } | 372 } |
354 | 373 |
355 TEST_F(TyperTest, TypeNumberEqual) { | 374 TEST_F(TyperTest, TypeNumberEqual) { |
356 TestBinaryCompareOp(simplified_.NumberEqual(), std::equal_to<double>()); | 375 TestBinaryCompareOp(simplified_.NumberEqual(), std::equal_to<double>()); |
357 } | 376 } |
358 | 377 |
359 TEST_F(TyperTest, TypeSpeculativeNumberEqual) { | 378 TEST_F(TyperTest, TypeSpeculativeNumberEqual) { |
360 TestBinaryCompareOp( | 379 TestBinaryCompareOp( |
361 simplified_.SpeculativeNumberEqual(NumberOperationHint::kNumberOrOddball), | 380 simplified_.SpeculativeNumberEqual(NumberOperationHint::kNumberOrOddball), |
362 std::equal_to<double>()); | 381 std::equal_to<double>()); |
363 } | 382 } |
364 | 383 |
365 // For numbers there's no difference between strict and non-strict equality. | 384 // For numbers there's no difference between strict and non-strict equality. |
366 TEST_F(TyperTest, TypeJSStrictEqual) { | 385 TEST_F(TyperTest, TypeJSStrictEqual) { |
367 TestBinaryCompareOp(javascript_.StrictEqual(CompareOperationHint::kAny), | 386 TestBinaryCompareOp(javascript_.StrictEqual(CompareOperationHint::kAny), |
368 std::equal_to<double>()); | 387 std::equal_to<double>()); |
369 } | 388 } |
370 | 389 |
| 390 //------------------------------------------------------------------------------ |
| 391 // Typer Monotonicity |
371 | 392 |
372 //------------------------------------------------------------------------------ | 393 // JS BINOPs with CompareOperationHint |
373 // Monotonicity | 394 #define TEST_MONOTONICITY(name) \ |
374 | |
375 #define TEST_BINARY_MONOTONICITY(name) \ | |
376 TEST_F(TyperTest, Monotonicity_##name) { \ | 395 TEST_F(TyperTest, Monotonicity_##name) { \ |
377 TestBinaryMonotonicity(javascript_.name(CompareOperationHint::kAny)); \ | 396 TestBinaryMonotonicity(javascript_.name(CompareOperationHint::kAny)); \ |
378 } | 397 } |
379 TEST_BINARY_MONOTONICITY(Equal) | 398 TEST_MONOTONICITY(Equal) |
380 TEST_BINARY_MONOTONICITY(StrictEqual) | 399 TEST_MONOTONICITY(StrictEqual) |
381 TEST_BINARY_MONOTONICITY(LessThan) | 400 TEST_MONOTONICITY(LessThan) |
382 TEST_BINARY_MONOTONICITY(GreaterThan) | 401 TEST_MONOTONICITY(GreaterThan) |
383 TEST_BINARY_MONOTONICITY(LessThanOrEqual) | 402 TEST_MONOTONICITY(LessThanOrEqual) |
384 TEST_BINARY_MONOTONICITY(GreaterThanOrEqual) | 403 TEST_MONOTONICITY(GreaterThanOrEqual) |
385 #undef TEST_BINARY_MONOTONICITY | 404 #undef TEST_MONOTONICITY |
386 | 405 |
387 #define TEST_BINARY_MONOTONICITY(name) \ | 406 // JS BINOPs with BinaryOperationHint |
| 407 #define TEST_MONOTONICITY(name) \ |
| 408 TEST_F(TyperTest, Monotonicity_##name) { \ |
| 409 TestBinaryMonotonicity(javascript_.name(BinaryOperationHint::kAny)); \ |
| 410 } |
| 411 TEST_MONOTONICITY(Add) |
| 412 #undef TEST_MONOTONICITY |
| 413 |
| 414 // JS BINOPS without hint |
| 415 #define TEST_MONOTONICITY(name) \ |
388 TEST_F(TyperTest, Monotonicity_##name) { \ | 416 TEST_F(TyperTest, Monotonicity_##name) { \ |
389 TestBinaryMonotonicity(javascript_.name()); \ | 417 TestBinaryMonotonicity(javascript_.name()); \ |
390 } | 418 } |
391 TEST_BINARY_MONOTONICITY(BitwiseOr) | 419 TEST_MONOTONICITY(BitwiseOr) |
392 TEST_BINARY_MONOTONICITY(BitwiseXor) | 420 TEST_MONOTONICITY(BitwiseXor) |
393 TEST_BINARY_MONOTONICITY(BitwiseAnd) | 421 TEST_MONOTONICITY(BitwiseAnd) |
394 TEST_BINARY_MONOTONICITY(ShiftLeft) | 422 TEST_MONOTONICITY(ShiftLeft) |
395 TEST_BINARY_MONOTONICITY(ShiftRight) | 423 TEST_MONOTONICITY(ShiftRight) |
396 TEST_BINARY_MONOTONICITY(ShiftRightLogical) | 424 TEST_MONOTONICITY(ShiftRightLogical) |
397 TEST_BINARY_MONOTONICITY(Subtract) | 425 TEST_MONOTONICITY(Subtract) |
398 TEST_BINARY_MONOTONICITY(Multiply) | 426 TEST_MONOTONICITY(Multiply) |
399 TEST_BINARY_MONOTONICITY(Divide) | 427 TEST_MONOTONICITY(Divide) |
400 TEST_BINARY_MONOTONICITY(Modulus) | 428 TEST_MONOTONICITY(Modulus) |
401 #undef TEST_BINARY_MONOTONICITY | 429 #undef TEST_MONOTONICITY |
402 | 430 |
403 #define TEST_BINARY_MONOTONICITY(name) \ | 431 // SIMPLIFIED BINOPs without hint, with Number input restriction |
404 TEST_F(TyperTest, Monotonicity_##name) { \ | 432 #define TEST_MONOTONICITY(name) \ |
405 TestBinaryMonotonicity(javascript_.name(BinaryOperationHint::kAny)); \ | 433 TEST_F(TyperTest, Monotonicity_##name) { \ |
| 434 TestBinaryMonotonicity(simplified_.name(), Type::Number(), \ |
| 435 Type::Number()); \ |
406 } | 436 } |
407 TEST_BINARY_MONOTONICITY(Add) | 437 SIMPLIFIED_NUMBER_BINOP_LIST(TEST_MONOTONICITY); |
408 #undef TEST_BINARY_MONOTONICITY | 438 #undef TEST_MONOTONICITY |
| 439 |
| 440 // SIMPLIFIED BINOPs without hint, without input restriction |
| 441 #define TEST_MONOTONICITY(name) \ |
| 442 TEST_F(TyperTest, Monotonicity_##name) { \ |
| 443 TestBinaryMonotonicity(simplified_.name()); \ |
| 444 } |
| 445 TEST_MONOTONICITY(NumberLessThan) |
| 446 TEST_MONOTONICITY(NumberLessThanOrEqual) |
| 447 TEST_MONOTONICITY(NumberEqual) |
| 448 #undef TEST_MONOTONICITY |
| 449 |
| 450 // SIMPLIFIED BINOPs with NumberOperationHint, without input restriction |
| 451 #define TEST_MONOTONICITY(name) \ |
| 452 TEST_F(TyperTest, Monotonicity_##name) { \ |
| 453 TestBinaryMonotonicity(simplified_.name(NumberOperationHint::kNumber)); \ |
| 454 } |
| 455 TEST_MONOTONICITY(SpeculativeNumberEqual) |
| 456 TEST_MONOTONICITY(SpeculativeNumberLessThan) |
| 457 TEST_MONOTONICITY(SpeculativeNumberLessThanOrEqual) |
| 458 #undef TEST_MONOTONICITY |
| 459 |
| 460 // SIMPLIFIED BINOPs with NumberOperationHint, without input restriction |
| 461 #define TEST_MONOTONICITY(name) \ |
| 462 TEST_F(TyperTest, Monotonicity_##name) { \ |
| 463 TestBinaryMonotonicity(simplified_.name(NumberOperationHint::kNumber)); \ |
| 464 } |
| 465 SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(TEST_MONOTONICITY) |
| 466 #undef TEST_MONOTONICITY |
| 467 |
| 468 //------------------------------------------------------------------------------ |
| 469 // OperationTyper Monotonicity |
| 470 |
| 471 // SIMPLIFIED UNOPs with Number input restriction |
| 472 #define TEST_MONOTONICITY(name) \ |
| 473 TEST_F(TyperTest, Monotonicity_Operation_##name) { \ |
| 474 UnaryTyper typer = [&](Type* type1) { \ |
| 475 return operation_typer_.name(type1); \ |
| 476 }; \ |
| 477 for (int i = 0; i < kRepetitions; ++i) { \ |
| 478 TestUnaryMonotonicity(typer, Type::Number()); \ |
| 479 } \ |
| 480 } |
| 481 SIMPLIFIED_NUMBER_UNOP_LIST(TEST_MONOTONICITY) |
| 482 #undef TEST_MONOTONICITY |
| 483 |
| 484 // SIMPLIFIED BINOPs with Number input restriction |
| 485 #define TEST_MONOTONICITY(name) \ |
| 486 TEST_F(TyperTest, Monotonicity_Operation_##name) { \ |
| 487 BinaryTyper typer = [&](Type* type1, Type* type2) { \ |
| 488 return operation_typer_.name(type1, type2); \ |
| 489 }; \ |
| 490 for (int i = 0; i < kRepetitions; ++i) { \ |
| 491 TestBinaryMonotonicity(typer, Type::Number(), Type::Number()); \ |
| 492 } \ |
| 493 } |
| 494 SIMPLIFIED_NUMBER_BINOP_LIST(TEST_MONOTONICITY) |
| 495 #undef TEST_MONOTONICITY |
| 496 |
| 497 // SIMPLIFIED BINOPs without input restriction |
| 498 #define TEST_MONOTONICITY(name) \ |
| 499 TEST_F(TyperTest, Monotonicity_Operation_##name) { \ |
| 500 BinaryTyper typer = [&](Type* type1, Type* type2) { \ |
| 501 return operation_typer_.name(type1, type2); \ |
| 502 }; \ |
| 503 for (int i = 0; i < kRepetitions; ++i) { \ |
| 504 TestBinaryMonotonicity(typer); \ |
| 505 } \ |
| 506 } |
| 507 SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(TEST_MONOTONICITY) |
| 508 #undef TEST_MONOTONICITY |
409 | 509 |
410 } // namespace compiler | 510 } // namespace compiler |
411 } // namespace internal | 511 } // namespace internal |
412 } // namespace v8 | 512 } // namespace v8 |
OLD | NEW |