summaryrefslogtreecommitdiff
path: root/deps/v8/test/mjsunit/compiler/fast-api-clamp-annotations.js
blob: d774f941fc2fc28b50d62bc0be8b2bf4671f0fe7 (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 2022 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.

// These tests exercise WebIDL annotations support in the fast API.

// Flags: --turbo-fast-api-calls --expose-fast-api --allow-natives-syntax --turbofan
// Flags: --no-turboshaft
// --always-turbofan is disabled because we rely on particular feedback for
// optimizing to the fastest path.
// Flags: --no-always-turbofan
// The test relies on optimizing/deoptimizing at predictable moments, so
// it's not suitable for deoptimization fuzzing.
// Flags: --deopt-every-n-times=0
// Flags: --enable-sse4-1 --enable-sse4-2

const fast_c_api = new d8.test.FastCAPI();

const min_int32 = -(2 ** 31);
const max_int32 = 2 ** 31 - 1;
const min_uint32 = 0;
const max_uint32 = 2 ** 32 - 1;

// ----------- clamp_compare -----------
// `clamp_compare` has the following signature:
// void clamp_compare(bool /*in_range*/,
//   double, integer_type)
// where integer_type = {int32_t, uint32_t, int64_t, uint64_t}

// ----------- i32 -----------
function is_in_range_i32(in_range, arg, expected) {
  let result = fast_c_api.clamp_compare_i32(in_range, arg, arg);

  assertEquals(expected, result);
}

%PrepareFunctionForOptimization(is_in_range_i32);
is_in_range_i32(true, 123, 123);
%OptimizeFunctionOnNextCall(is_in_range_i32);
is_in_range_i32(true, 123, 123);
is_in_range_i32(true, -0.5, 0);
is_in_range_i32(true, 0.5, 0);
is_in_range_i32(true, 1.5, 2);
is_in_range_i32(true, min_int32, min_int32);
is_in_range_i32(true, max_int32, max_int32);
is_in_range_i32(false, -(2 ** 32), min_int32);
is_in_range_i32(false, -(2 ** 32 + 1), min_int32);
is_in_range_i32(false, 2 ** 32, max_int32);
is_in_range_i32(false, 2 ** 32 + 3.15, max_int32);
is_in_range_i32(false, Number.MIN_SAFE_INTEGER, min_int32);
is_in_range_i32(false, Number.MAX_SAFE_INTEGER, max_int32);

// ----------- u32 -----------
function is_in_range_u32(in_range, arg, expected) {
  let result = fast_c_api.clamp_compare_u32(in_range, arg, arg);

  assertEquals(expected, result);
}

%PrepareFunctionForOptimization(is_in_range_u32);
is_in_range_u32(true, 123, 123);
%OptimizeFunctionOnNextCall(is_in_range_u32);
is_in_range_u32(true, 123, 123);
is_in_range_u32(true, 0, 0);
is_in_range_u32(true, -0.5, 0);
is_in_range_u32(true, 0.5, 0);
is_in_range_u32(true, 2 ** 32 - 1, max_uint32);
is_in_range_u32(false, -(2 ** 31), min_uint32);
is_in_range_u32(false, 2 ** 32, max_uint32);
is_in_range_u32(false, -1, min_uint32);
is_in_range_u32(false, -1.5, min_uint32);
is_in_range_u32(false, Number.MIN_SAFE_INTEGER, min_uint32);
is_in_range_u32(false, Number.MAX_SAFE_INTEGER, max_uint32);

// ----------- i64 -----------
function is_in_range_i64(in_range, arg, expected) {
  let result = fast_c_api.clamp_compare_i64(in_range, arg, arg);
  assertEquals(expected, result);
}

%PrepareFunctionForOptimization(is_in_range_i64);
is_in_range_i64(true, 123, 123);
%OptimizeFunctionOnNextCall(is_in_range_i64);
is_in_range_i64(true, 123, 123);
is_in_range_i64(true, -0.5, 0);
is_in_range_i64(true, 0.5, 0);
is_in_range_i64(true, 1.5, 2);
is_in_range_i64(true, Number.MIN_SAFE_INTEGER, Number.MIN_SAFE_INTEGER);
is_in_range_i64(true, Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER);

// Slow path doesn't perform correct clamping outside of double range.
if (isOptimized(is_in_range_i64) && fast_c_api.fast_call_count() > 0) {
  is_in_range_i64(false, -(2 ** 63), Number.MIN_SAFE_INTEGER);
  is_in_range_i64(false, 2 ** 63 - 1024, Number.MAX_SAFE_INTEGER);
  is_in_range_i64(false, 2 ** 63, Number.MAX_SAFE_INTEGER);
  is_in_range_i64(false, -(2 ** 64), Number.MIN_SAFE_INTEGER);
  is_in_range_i64(false, -(2 ** 64 + 1), Number.MIN_SAFE_INTEGER);
  is_in_range_i64(false, 2 ** 64, Number.MAX_SAFE_INTEGER);
  is_in_range_i64(false, 2 ** 64 + 3.15, Number.MAX_SAFE_INTEGER);
}

// ----------- u64 -----------
function is_in_range_u64(in_range, arg, expected) {
  let result = fast_c_api.clamp_compare_u64(in_range, arg, arg);
  assertEquals(expected, result);
}

%PrepareFunctionForOptimization(is_in_range_u64);
is_in_range_u64(true, 123, 123);
%OptimizeFunctionOnNextCall(is_in_range_u64);
is_in_range_u64(true, 123, 123);
is_in_range_u64(true, 0, 0);
is_in_range_u64(true, -0.5, 0);
is_in_range_u64(true, 0.5, 0);
is_in_range_u64(true, 2 ** 32 - 1, 2 ** 32 - 1);
is_in_range_u64(true, Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER);

is_in_range_u64(false, 1.7976931348623157e+308, Number.MAX_SAFE_INTEGER);
is_in_range_u64(false, Number.MIN_SAFE_INTEGER, 0);
is_in_range_u64(false, -1, 0);
is_in_range_u64(false, -1.5, 0);
is_in_range_u64(false, 2 ** 64, Number.MAX_SAFE_INTEGER);
is_in_range_u64(false, 2 ** 64 + 3.15, Number.MAX_SAFE_INTEGER);

// ---------- invalid arguments for clamp_compare ---------
fast_c_api.clamp_compare_i32(true);
fast_c_api.clamp_compare_i32(true, 753801, -2147483650);