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 "test/cctest/types-fuzz.h" | 10 #include "test/cctest/types-fuzz.h" |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
139 double x1 = RandomInt(r1); | 139 double x1 = RandomInt(r1); |
140 double x2 = RandomInt(r2); | 140 double x2 = RandomInt(r2); |
141 double result_value = opfun(x1, x2); | 141 double result_value = opfun(x1, x2); |
142 Type* result_type = Type::Constant( | 142 Type* result_type = Type::Constant( |
143 isolate()->factory()->NewNumber(result_value), zone()); | 143 isolate()->factory()->NewNumber(result_value), zone()); |
144 EXPECT_TRUE(result_type->Is(expected_type)); | 144 EXPECT_TRUE(result_type->Is(expected_type)); |
145 } | 145 } |
146 } | 146 } |
147 } | 147 } |
148 | 148 |
| 149 // Careful, this function scales poorly. |
| 150 template <int32_t op(int32_t, int32_t), class DeriveFunction> |
| 151 void TestPreciseBinaryArithOp(DeriveFunction derive, |
| 152 int32_t llow, int32_t lhigh, int32_t linc, |
| 153 int32_t rlow, int32_t rhigh, int32_t rinc) { |
| 154 for (int64_t lmin = llow; lmin <= lhigh; lmin += linc) { |
| 155 for (int64_t lmax = lmin; lmax <= lhigh; lmax += linc) { |
| 156 for (int64_t rmin = rlow; rmin <= rhigh; rmin += rinc) { |
| 157 for (int64_t rmax = rmin; rmax <= rhigh; rmax += rinc) { |
| 158 IntType r1 = IntType(int32_t(lmin), int32_t(lmax)); |
| 159 IntType r2 = IntType(int32_t(rmin), int32_t(rmax)); |
| 160 IntType derived_type = derive(r1, r2); |
| 161 int32_t min = kMaxInt, max = kMinInt; |
| 162 for (int32_t x1 = int32_t(lmin); x1 <= int32_t(lmax); x1++) { |
| 163 for (int32_t x2 = int32_t(rmin); x2 <= int32_t(rmax); x2++) { |
| 164 int32_t result_value = op(x1, x2); |
| 165 min = std::min(result_value, min); |
| 166 max = std::max(result_value, max); |
| 167 } |
| 168 } |
| 169 EXPECT_TRUE(derived_type.min == min && derived_type.max == max); |
| 170 } |
| 171 } |
| 172 } |
| 173 } |
| 174 } |
| 175 |
149 template <class BinaryFunction> | 176 template <class BinaryFunction> |
150 void TestBinaryCompareOp(const Operator* op, BinaryFunction opfun) { | 177 void TestBinaryCompareOp(const Operator* op, BinaryFunction opfun) { |
151 for (int i = 0; i < 100; ++i) { | 178 for (int i = 0; i < 100; ++i) { |
152 Type::RangeType* r1 = RandomRange()->AsRange(); | 179 Type::RangeType* r1 = RandomRange()->AsRange(); |
153 Type::RangeType* r2 = RandomRange()->AsRange(); | 180 Type::RangeType* r2 = RandomRange()->AsRange(); |
154 Type* expected_type = TypeBinaryOp(op, r1, r2); | 181 Type* expected_type = TypeBinaryOp(op, r1, r2); |
155 for (int i = 0; i < 10; i++) { | 182 for (int i = 0; i < 10; i++) { |
156 double x1 = RandomInt(r1); | 183 double x1 = RandomInt(r1); |
157 double x2 = RandomInt(r2); | 184 double x2 = RandomInt(r2); |
158 bool result_value = opfun(x1, x2); | 185 bool result_value = opfun(x1, x2); |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
256 | 283 |
257 TEST_F(TyperTest, TypeJSModulus) { | 284 TEST_F(TyperTest, TypeJSModulus) { |
258 TestBinaryArithOp(javascript_.Modulus(LanguageMode::SLOPPY), modulo); | 285 TestBinaryArithOp(javascript_.Modulus(LanguageMode::SLOPPY), modulo); |
259 TestBinaryArithOp(javascript_.Modulus(LanguageMode::STRONG), modulo); | 286 TestBinaryArithOp(javascript_.Modulus(LanguageMode::STRONG), modulo); |
260 } | 287 } |
261 | 288 |
262 | 289 |
263 TEST_F(TyperTest, TypeJSBitwiseOr) { | 290 TEST_F(TyperTest, TypeJSBitwiseOr) { |
264 TestBinaryBitOp(javascript_.BitwiseOr(LanguageMode::SLOPPY), bit_or); | 291 TestBinaryBitOp(javascript_.BitwiseOr(LanguageMode::SLOPPY), bit_or); |
265 TestBinaryBitOp(javascript_.BitwiseOr(LanguageMode::STRONG), bit_or); | 292 TestBinaryBitOp(javascript_.BitwiseOr(LanguageMode::STRONG), bit_or); |
| 293 // The derivation algorithm works one bit at a time and scales to |
| 294 // any bit width so verify on practical bit widths. |
| 295 TestPreciseBinaryArithOp<bit_or>(JSBitwiseOrIntType, |
| 296 -16, 15, 1, -16, 15, 1); |
| 297 TestPreciseBinaryArithOp<bit_or>(JSBitwiseOrIntType, |
| 298 kMaxInt - 32, kMaxInt, 1, |
| 299 kMaxInt - 32, kMaxInt, 1); |
| 300 TestPreciseBinaryArithOp<bit_or>(JSBitwiseOrIntType, |
| 301 kMinInt, kMinInt + 32, 1, |
| 302 kMinInt, kMinInt + 32, 1); |
| 303 TestPreciseBinaryArithOp<bit_or>(JSBitwiseOrIntType, |
| 304 kMaxInt - 32 * 2, kMaxInt, 2, |
| 305 kMaxInt - 32 * 2, kMaxInt, 2); |
| 306 TestPreciseBinaryArithOp<bit_or>(JSBitwiseOrIntType, |
| 307 kMinInt, kMinInt + 32 * 2, 2, |
| 308 kMinInt, kMinInt + 32 * 2, 2); |
266 } | 309 } |
267 | 310 |
268 | 311 |
269 TEST_F(TyperTest, TypeJSBitwiseAnd) { | 312 TEST_F(TyperTest, TypeJSBitwiseAnd) { |
270 TestBinaryBitOp(javascript_.BitwiseAnd(LanguageMode::SLOPPY), bit_and); | 313 TestBinaryBitOp(javascript_.BitwiseAnd(LanguageMode::SLOPPY), bit_and); |
271 TestBinaryBitOp(javascript_.BitwiseAnd(LanguageMode::STRONG), bit_and); | 314 TestBinaryBitOp(javascript_.BitwiseAnd(LanguageMode::STRONG), bit_and); |
272 } | 315 } |
273 | 316 |
274 | 317 |
275 TEST_F(TyperTest, TypeJSBitwiseXor) { | 318 TEST_F(TyperTest, TypeJSBitwiseXor) { |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
396 | 439 |
397 | 440 |
398 TEST_F(TyperTest, TypeRegressInt32Constant) { | 441 TEST_F(TyperTest, TypeRegressInt32Constant) { |
399 int values[] = {-5, 10}; | 442 int values[] = {-5, 10}; |
400 for (auto i : values) { | 443 for (auto i : values) { |
401 Node* c = graph()->NewNode(common()->Int32Constant(i)); | 444 Node* c = graph()->NewNode(common()->Int32Constant(i)); |
402 Type* type = NodeProperties::GetBounds(c).upper; | 445 Type* type = NodeProperties::GetBounds(c).upper; |
403 EXPECT_TRUE(type->Is(NewRange(i, i))); | 446 EXPECT_TRUE(type->Is(NewRange(i, i))); |
404 } | 447 } |
405 } | 448 } |
OLD | NEW |