OLD | NEW |
---|---|
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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 "src/assembler-inl.h" | 5 #include "src/assembler-inl.h" |
6 #include "src/wasm/wasm-macro-gen.h" | 6 #include "src/wasm/wasm-macro-gen.h" |
7 #include "test/cctest/cctest.h" | 7 #include "test/cctest/cctest.h" |
8 #include "test/cctest/compiler/value-helper.h" | 8 #include "test/cctest/compiler/value-helper.h" |
9 #include "test/cctest/wasm/wasm-run-utils.h" | 9 #include "test/cctest/wasm/wasm-run-utils.h" |
10 | 10 |
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
367 #define WASM_SIMD_I8x16_EXTRACT_LANE(lane, x) \ | 367 #define WASM_SIMD_I8x16_EXTRACT_LANE(lane, x) \ |
368 x, WASM_SIMD_OP(kExprI8x16ExtractLane), TO_BYTE(lane) | 368 x, WASM_SIMD_OP(kExprI8x16ExtractLane), TO_BYTE(lane) |
369 #define WASM_SIMD_I8x16_REPLACE_LANE(lane, x, y) \ | 369 #define WASM_SIMD_I8x16_REPLACE_LANE(lane, x, y) \ |
370 x, y, WASM_SIMD_OP(kExprI8x16ReplaceLane), TO_BYTE(lane) | 370 x, y, WASM_SIMD_OP(kExprI8x16ReplaceLane), TO_BYTE(lane) |
371 | 371 |
372 #define WASM_SIMD_F32x4_FROM_I32x4(x) x, WASM_SIMD_OP(kExprF32x4SConvertI32x4) | 372 #define WASM_SIMD_F32x4_FROM_I32x4(x) x, WASM_SIMD_OP(kExprF32x4SConvertI32x4) |
373 #define WASM_SIMD_F32x4_FROM_U32x4(x) x, WASM_SIMD_OP(kExprF32x4UConvertI32x4) | 373 #define WASM_SIMD_F32x4_FROM_U32x4(x) x, WASM_SIMD_OP(kExprF32x4UConvertI32x4) |
374 #define WASM_SIMD_I32x4_FROM_F32x4(x) x, WASM_SIMD_OP(kExprI32x4SConvertF32x4) | 374 #define WASM_SIMD_I32x4_FROM_F32x4(x) x, WASM_SIMD_OP(kExprI32x4SConvertF32x4) |
375 #define WASM_SIMD_U32x4_FROM_F32x4(x) x, WASM_SIMD_OP(kExprI32x4UConvertF32x4) | 375 #define WASM_SIMD_U32x4_FROM_F32x4(x) x, WASM_SIMD_OP(kExprI32x4UConvertF32x4) |
376 | 376 |
377 // Skip FP operations on NaNs or whose expected result is a NaN or so small | 377 // Skip FP operations on extremely large or extremely small values, which may |
378 // that denormalized numbers may flush to zero and cause exact FP comparisons | 378 // cause tests to fail due to non-IEEE-754 arithmetic on some platforms. |
379 // to fail. | 379 bool SkipFPTestInput(float x) { |
Mircea Trofin
2017/03/08 21:57:21
We should think about what our portability story i
| |
380 // TODO(bbudge) Switch FP comparisons in WASM code to WASM code that handles | 380 float abs_x = std::fabs(x); |
381 // NaNs and results with limited precision. | 381 const float kSmallFloatThreshold = 1.0e-32f; |
382 bool SkipFPTestInput(float x) { return std::isnan(x); } | 382 const float kLargeFloatThreshold = 1.0e32f; |
383 return abs_x != 0.0f && // 0 or -0 are fine. | |
384 (abs_x < kSmallFloatThreshold || abs_x > kLargeFloatThreshold); | |
385 } | |
383 | 386 |
384 bool SkipFPTestResult(float x) { | 387 // Skip tests where the expected value is a NaN. Our WASM test code can't |
385 if (std::isnan(x)) return true; | 388 // deal with NaNs. |
386 // Constant empirically determined so existing tests pass on ARM hardware. | 389 bool SkipFPExpectedValue(float x) { return std::isnan(x); } |
387 const float kSmallFloatThreshold = 1.0e-32f; | |
388 float abs_x = std::fabs(x); | |
389 return abs_x != 0 && abs_x < kSmallFloatThreshold; | |
390 } | |
391 | 390 |
392 #if V8_TARGET_ARCH_ARM || SIMD_LOWERING_TARGET | 391 #if V8_TARGET_ARCH_ARM || SIMD_LOWERING_TARGET |
393 WASM_EXEC_COMPILED_TEST(F32x4Splat) { | 392 WASM_EXEC_COMPILED_TEST(F32x4Splat) { |
394 FLAG_wasm_simd_prototype = true; | 393 FLAG_wasm_simd_prototype = true; |
395 | 394 |
396 WasmRunner<int32_t, float> r(kExecuteCompiled); | 395 WasmRunner<int32_t, float> r(kExecuteCompiled); |
397 byte lane_val = 0; | 396 byte lane_val = 0; |
398 byte simd = r.AllocateLocal(kWasmS128); | 397 byte simd = r.AllocateLocal(kWasmS128); |
399 BUILD(r, | 398 BUILD(r, |
400 WASM_SET_LOCAL(simd, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(lane_val))), | 399 WASM_SET_LOCAL(simd, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(lane_val))), |
401 WASM_SIMD_CHECK_SPLAT_F32x4(simd, lane_val), WASM_RETURN1(WASM_ONE)); | 400 WASM_SIMD_CHECK_SPLAT_F32x4(simd, lane_val), WASM_RETURN1(WASM_ONE)); |
402 | 401 |
403 FOR_FLOAT32_INPUTS(i) { | 402 FOR_FLOAT32_INPUTS(i) { |
404 if (SkipFPTestInput(*i)) continue; | 403 if (SkipFPExpectedValue(*i)) continue; |
405 CHECK_EQ(1, r.Call(*i)); | 404 CHECK_EQ(1, r.Call(*i)); |
406 } | 405 } |
407 } | 406 } |
408 | 407 |
409 WASM_EXEC_COMPILED_TEST(F32x4ReplaceLane) { | 408 WASM_EXEC_COMPILED_TEST(F32x4ReplaceLane) { |
410 FLAG_wasm_simd_prototype = true; | 409 FLAG_wasm_simd_prototype = true; |
411 WasmRunner<int32_t, float, float> r(kExecuteCompiled); | 410 WasmRunner<int32_t, float, float> r(kExecuteCompiled); |
412 byte old_val = 0; | 411 byte old_val = 0; |
413 byte new_val = 1; | 412 byte new_val = 1; |
414 byte simd = r.AllocateLocal(kWasmS128); | 413 byte simd = r.AllocateLocal(kWasmS128); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
466 byte high = 2; | 465 byte high = 2; |
467 byte simd = r.AllocateLocal(kWasmS128); | 466 byte simd = r.AllocateLocal(kWasmS128); |
468 BUILD(r, WASM_SET_LOCAL(simd, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(a))), | 467 BUILD(r, WASM_SET_LOCAL(simd, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(a))), |
469 WASM_SET_LOCAL(simd, WASM_SIMD_UNOP(simd_op, WASM_GET_LOCAL(simd))), | 468 WASM_SET_LOCAL(simd, WASM_SIMD_UNOP(simd_op, WASM_GET_LOCAL(simd))), |
470 WASM_SIMD_CHECK_SPLAT_F32x4_ESTIMATE(simd, low, high), | 469 WASM_SIMD_CHECK_SPLAT_F32x4_ESTIMATE(simd, low, high), |
471 WASM_RETURN1(WASM_ONE)); | 470 WASM_RETURN1(WASM_ONE)); |
472 | 471 |
473 FOR_FLOAT32_INPUTS(i) { | 472 FOR_FLOAT32_INPUTS(i) { |
474 if (SkipFPTestInput(*i)) continue; | 473 if (SkipFPTestInput(*i)) continue; |
475 float expected = expected_op(*i); | 474 float expected = expected_op(*i); |
476 if (SkipFPTestResult(expected)) continue; | 475 if (SkipFPExpectedValue(expected)) continue; |
477 float abs_error = std::abs(expected) * error; | 476 float abs_error = std::abs(expected) * error; |
478 CHECK_EQ(1, r.Call(*i, expected - abs_error, expected + abs_error)); | 477 CHECK_EQ(1, r.Call(*i, expected - abs_error, expected + abs_error)); |
479 } | 478 } |
480 } | 479 } |
481 | 480 |
482 WASM_EXEC_COMPILED_TEST(F32x4Abs) { RunF32x4UnOpTest(kExprF32x4Abs, std::abs); } | 481 WASM_EXEC_COMPILED_TEST(F32x4Abs) { RunF32x4UnOpTest(kExprF32x4Abs, std::abs); } |
483 WASM_EXEC_COMPILED_TEST(F32x4Neg) { RunF32x4UnOpTest(kExprF32x4Neg, Negate); } | 482 WASM_EXEC_COMPILED_TEST(F32x4Neg) { RunF32x4UnOpTest(kExprF32x4Neg, Negate); } |
484 #endif // V8_TARGET_ARCH_ARM || SIMD_LOWERING_TARGET | 483 #endif // V8_TARGET_ARCH_ARM || SIMD_LOWERING_TARGET |
485 | 484 |
486 #if SIMD_LOWERING_TARGET | 485 #if SIMD_LOWERING_TARGET |
(...skipping 25 matching lines...) Expand all Loading... | |
512 WASM_SET_LOCAL(simd1, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(b))), | 511 WASM_SET_LOCAL(simd1, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(b))), |
513 WASM_SET_LOCAL(simd1, WASM_SIMD_BINOP(simd_op, WASM_GET_LOCAL(simd0), | 512 WASM_SET_LOCAL(simd1, WASM_SIMD_BINOP(simd_op, WASM_GET_LOCAL(simd0), |
514 WASM_GET_LOCAL(simd1))), | 513 WASM_GET_LOCAL(simd1))), |
515 WASM_SIMD_CHECK_SPLAT_F32x4(simd1, expected), WASM_RETURN1(WASM_ONE)); | 514 WASM_SIMD_CHECK_SPLAT_F32x4(simd1, expected), WASM_RETURN1(WASM_ONE)); |
516 | 515 |
517 FOR_FLOAT32_INPUTS(i) { | 516 FOR_FLOAT32_INPUTS(i) { |
518 if (SkipFPTestInput(*i)) continue; | 517 if (SkipFPTestInput(*i)) continue; |
519 FOR_FLOAT32_INPUTS(j) { | 518 FOR_FLOAT32_INPUTS(j) { |
520 if (SkipFPTestInput(*j)) continue; | 519 if (SkipFPTestInput(*j)) continue; |
521 float expected = expected_op(*i, *j); | 520 float expected = expected_op(*i, *j); |
522 if (SkipFPTestResult(expected)) continue; | 521 if (SkipFPExpectedValue(expected)) continue; |
523 CHECK_EQ(1, r.Call(*i, *j, expected)); | 522 CHECK_EQ(1, r.Call(*i, *j, expected)); |
524 } | 523 } |
525 } | 524 } |
526 } | 525 } |
527 | 526 |
528 WASM_EXEC_COMPILED_TEST(F32x4Add) { RunF32x4BinOpTest(kExprF32x4Add, Add); } | 527 WASM_EXEC_COMPILED_TEST(F32x4Add) { RunF32x4BinOpTest(kExprF32x4Add, Add); } |
529 WASM_EXEC_COMPILED_TEST(F32x4Sub) { RunF32x4BinOpTest(kExprF32x4Sub, Sub); } | 528 WASM_EXEC_COMPILED_TEST(F32x4Sub) { RunF32x4BinOpTest(kExprF32x4Sub, Sub); } |
530 WASM_EXEC_COMPILED_TEST(F32x4Mul) { RunF32x4BinOpTest(kExprF32x4Sub, Sub); } | 529 WASM_EXEC_COMPILED_TEST(F32x4Mul) { RunF32x4BinOpTest(kExprF32x4Sub, Sub); } |
531 WASM_EXEC_COMPILED_TEST(F32x4_Min) { | 530 WASM_EXEC_COMPILED_TEST(F32x4_Min) { |
532 RunF32x4BinOpTest(kExprF32x4Min, Minimum); | 531 RunF32x4BinOpTest(kExprF32x4Min, Minimum); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
565 WASM_SIMD_MATERIALIZE_BOOLS( | 564 WASM_SIMD_MATERIALIZE_BOOLS( |
566 32x4, WASM_SIMD_BINOP(simd_op, WASM_GET_LOCAL(simd0), | 565 32x4, WASM_SIMD_BINOP(simd_op, WASM_GET_LOCAL(simd0), |
567 WASM_GET_LOCAL(simd1)))), | 566 WASM_GET_LOCAL(simd1)))), |
568 WASM_SIMD_CHECK_SPLAT4(I32x4, simd1, I32, expected), WASM_ONE); | 567 WASM_SIMD_CHECK_SPLAT4(I32x4, simd1, I32, expected), WASM_ONE); |
569 | 568 |
570 FOR_FLOAT32_INPUTS(i) { | 569 FOR_FLOAT32_INPUTS(i) { |
571 if (SkipFPTestInput(*i)) continue; | 570 if (SkipFPTestInput(*i)) continue; |
572 FOR_FLOAT32_INPUTS(j) { | 571 FOR_FLOAT32_INPUTS(j) { |
573 if (SkipFPTestInput(*j)) continue; | 572 if (SkipFPTestInput(*j)) continue; |
574 float diff = *i - *j; | 573 float diff = *i - *j; |
575 if (SkipFPTestResult(diff)) continue; | 574 if (SkipFPExpectedValue(diff)) continue; |
576 CHECK_EQ(1, r.Call(*i, *j, expected_op(*i, *j))); | 575 CHECK_EQ(1, r.Call(*i, *j, expected_op(*i, *j))); |
577 } | 576 } |
578 } | 577 } |
579 } | 578 } |
580 | 579 |
581 WASM_EXEC_COMPILED_TEST(F32x4Eq) { RunF32x4CompareOpTest(kExprF32x4Eq, Equal); } | 580 WASM_EXEC_COMPILED_TEST(F32x4Eq) { RunF32x4CompareOpTest(kExprF32x4Eq, Equal); } |
582 | 581 |
583 WASM_EXEC_COMPILED_TEST(F32x4Ne) { | 582 WASM_EXEC_COMPILED_TEST(F32x4Ne) { |
584 RunF32x4CompareOpTest(kExprF32x4Ne, NotEqual); | 583 RunF32x4CompareOpTest(kExprF32x4Ne, NotEqual); |
585 } | 584 } |
(...skipping 1226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1812 WASM_SET_GLOBAL(0, WASM_SIMD_F32x4_REPLACE_LANE(3, WASM_GET_GLOBAL(0), | 1811 WASM_SET_GLOBAL(0, WASM_SIMD_F32x4_REPLACE_LANE(3, WASM_GET_GLOBAL(0), |
1813 WASM_F32(65.0))), | 1812 WASM_F32(65.0))), |
1814 WASM_I32V(1)); | 1813 WASM_I32V(1)); |
1815 FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call(0)); } | 1814 FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call(0)); } |
1816 CHECK_EQ(*global, 13.5); | 1815 CHECK_EQ(*global, 13.5); |
1817 CHECK_EQ(*(global + 1), 45.5); | 1816 CHECK_EQ(*(global + 1), 45.5); |
1818 CHECK_EQ(*(global + 2), 32.25); | 1817 CHECK_EQ(*(global + 2), 32.25); |
1819 CHECK_EQ(*(global + 3), 65.0); | 1818 CHECK_EQ(*(global + 3), 65.0); |
1820 } | 1819 } |
1821 #endif // SIMD_LOWERING_TARGET | 1820 #endif // SIMD_LOWERING_TARGET |
OLD | NEW |