Welcome to mirror list, hosted at ThFree Co, Russian Federation.

test-run-wasm-simd-liftoff.cc « wasm « cctest « test « v8 « deps - github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 56c6dca248a35dafc46ff6ca5bb2fe18fd153b20 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// This file contains tests that run only on Liftoff, and each test verifies
// that the code was compiled by Liftoff. The default behavior is that each
// function is first attempted to be compiled by Liftoff, and if it fails, fall
// back to TurboFan. However we want to enforce that Liftoff is the tier that
// compiles these functions, in order to verify correctness of SIMD
// implementation in Liftoff.

#include "test/cctest/cctest.h"
#include "test/cctest/wasm/wasm-run-utils.h"
#include "test/common/wasm/test-signatures.h"
#include "test/common/wasm/wasm-macro-gen.h"

namespace v8 {
namespace internal {
namespace wasm {
namespace test_run_wasm_simd_liftoff {

#define WASM_SIMD_LIFTOFF_TEST(name) \
  void RunWasm_##name##_Impl();      \
  TEST(RunWasm_##name##_liftoff) {   \
    EXPERIMENTAL_FLAG_SCOPE(simd);   \
    RunWasm_##name##_Impl();         \
  }                                  \
  void RunWasm_##name##_Impl()

WASM_SIMD_LIFTOFF_TEST(S128Local) {
  WasmRunner<int32_t> r(ExecutionTier::kLiftoff, kNoLowerSimd);
  byte temp1 = r.AllocateLocal(kWasmS128);
  BUILD(r, WASM_SET_LOCAL(temp1, WASM_GET_LOCAL(temp1)), WASM_ONE);
  CHECK_EQ(1, r.Call());
}

WASM_SIMD_LIFTOFF_TEST(S128Global) {
  WasmRunner<int32_t> r(ExecutionTier::kLiftoff, kNoLowerSimd);

  int32_t* g0 = r.builder().AddGlobal<int32_t>(kWasmS128);
  int32_t* g1 = r.builder().AddGlobal<int32_t>(kWasmS128);
  BUILD(r, WASM_SET_GLOBAL(1, WASM_GET_GLOBAL(0)), WASM_ONE);

  int32_t expected = 0x1234;
  for (int i = 0; i < 4; i++) {
    WriteLittleEndianValue<int32_t>(&g0[i], expected);
  }
  r.Call();
  for (int i = 0; i < 4; i++) {
    int32_t actual = ReadLittleEndianValue<int32_t>(&g1[i]);
    CHECK_EQ(actual, expected);
  }
}

WASM_SIMD_LIFTOFF_TEST(S128Param) {
  // Test how SIMD parameters in functions are processed. There is no easy way
  // to specify a SIMD value when initializing a WasmRunner, so we manually
  // add a new function with the right signature, and call it from main.
  WasmRunner<int32_t> r(ExecutionTier::kLiftoff, kNoLowerSimd);
  TestSignatures sigs;
  // We use a temp local to materialize a SIMD value, since at this point
  // Liftoff does not support any SIMD operations.
  byte temp1 = r.AllocateLocal(kWasmS128);
  WasmFunctionCompiler& simd_func = r.NewFunction(sigs.i_s());
  BUILD(simd_func, WASM_ONE);

  BUILD(r,
        WASM_CALL_FUNCTION(simd_func.function_index(), WASM_GET_LOCAL(temp1)));

  CHECK_EQ(1, r.Call());
}

WASM_SIMD_LIFTOFF_TEST(S128Return) {
  // Test how functions returning SIMD values are processed.
  WasmRunner<int32_t> r(ExecutionTier::kLiftoff, kNoLowerSimd);
  TestSignatures sigs;
  WasmFunctionCompiler& simd_func = r.NewFunction(sigs.s_i());
  byte temp1 = simd_func.AllocateLocal(kWasmS128);
  BUILD(simd_func, WASM_GET_LOCAL(temp1));

  BUILD(r, WASM_CALL_FUNCTION(simd_func.function_index(), WASM_ONE), kExprDrop,
        WASM_ONE);

  CHECK_EQ(1, r.Call());
}

// Exercise Liftoff's logic for zero-initializing stack slots. We were using an
// incorrect instruction for storing zeroes into the slot when the slot offset
// was too large to fit in the instruction as an immediate.
WASM_SIMD_LIFTOFF_TEST(FillStackSlotsWithZero_CheckStartOffset) {
  WasmRunner<int64_t> r(ExecutionTier::kLiftoff, kNoLowerSimd);
  // Function that takes in 32 i64 arguments, returns i64. This gets us a large
  // enough starting offset from which we spill locals.
  // start = 32 * 8 + 16 (instance) = 272 (cannot fit in signed int9).
  FunctionSig* sig =
      r.CreateSig<int64_t, int64_t, int64_t, int64_t, int64_t, int64_t, int64_t,
                  int64_t, int64_t, int64_t, int64_t, int64_t, int64_t, int64_t,
                  int64_t, int64_t, int64_t, int64_t, int64_t, int64_t, int64_t,
                  int64_t, int64_t, int64_t, int64_t, int64_t, int64_t, int64_t,
                  int64_t, int64_t, int64_t, int64_t, int64_t>();
  WasmFunctionCompiler& simd_func = r.NewFunction(sig);

  // We zero 16 bytes at a time using stp, so allocate locals such that we get a
  // remainder, 8 in this case, so we hit the case where we use str.
  simd_func.AllocateLocal(kWasmS128);
  simd_func.AllocateLocal(kWasmI64);
  BUILD(simd_func, WASM_I64V_1(1));

  BUILD(r, WASM_I64V_1(1), WASM_I64V_1(1), WASM_I64V_1(1), WASM_I64V_1(1),
        WASM_I64V_1(1), WASM_I64V_1(1), WASM_I64V_1(1), WASM_I64V_1(1),
        WASM_I64V_1(1), WASM_I64V_1(1), WASM_I64V_1(1), WASM_I64V_1(1),
        WASM_I64V_1(1), WASM_I64V_1(1), WASM_I64V_1(1), WASM_I64V_1(1),
        WASM_I64V_1(1), WASM_I64V_1(1), WASM_I64V_1(1), WASM_I64V_1(1),
        WASM_I64V_1(1), WASM_I64V_1(1), WASM_I64V_1(1), WASM_I64V_1(1),
        WASM_I64V_1(1), WASM_I64V_1(1), WASM_I64V_1(1), WASM_I64V_1(1),
        WASM_I64V_1(1), WASM_I64V_1(1), WASM_I64V_1(1), WASM_I64V_1(1),
        WASM_CALL_FUNCTION0(simd_func.function_index()));

  CHECK_EQ(1, r.Call());
}

#undef WASM_SIMD_LIFTOFF_TEST

}  // namespace test_run_wasm_simd_liftoff
}  // namespace wasm
}  // namespace internal
}  // namespace v8