OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/intermediate_language.h" | 5 #include "vm/intermediate_language.h" |
6 #include "vm/unit_test.h" | 6 #include "vm/unit_test.h" |
7 | 7 |
8 namespace dart { | 8 namespace dart { |
9 | 9 |
10 TEST_CASE(InstructionTests) { | 10 TEST_CASE(InstructionTests) { |
(...skipping 22 matching lines...) Expand all Loading... |
33 ConstantInstr* c1 = new ConstantInstr(Bool::True()); | 33 ConstantInstr* c1 = new ConstantInstr(Bool::True()); |
34 ConstantInstr* c2 = new ConstantInstr(Bool::True()); | 34 ConstantInstr* c2 = new ConstantInstr(Bool::True()); |
35 EXPECT(c1->Equals(c2)); | 35 EXPECT(c1->Equals(c2)); |
36 ConstantInstr* c3 = new ConstantInstr(Object::ZoneHandle()); | 36 ConstantInstr* c3 = new ConstantInstr(Object::ZoneHandle()); |
37 ConstantInstr* c4 = new ConstantInstr(Object::ZoneHandle()); | 37 ConstantInstr* c4 = new ConstantInstr(Object::ZoneHandle()); |
38 EXPECT(c3->Equals(c4)); | 38 EXPECT(c3->Equals(c4)); |
39 EXPECT(!c3->Equals(c1)); | 39 EXPECT(!c3->Equals(c1)); |
40 } | 40 } |
41 | 41 |
42 | 42 |
43 TEST_CASE(RangeTests) { | |
44 Range* zero = new Range( | |
45 RangeBoundary::FromConstant(0), | |
46 RangeBoundary::FromConstant(0)); | |
47 Range* positive = new Range( | |
48 RangeBoundary::FromConstant(0), | |
49 RangeBoundary::FromConstant(100)); | |
50 Range* negative = new Range( | |
51 RangeBoundary::FromConstant(-1), | |
52 RangeBoundary::FromConstant(-100)); | |
53 Range* range_x = new Range( | |
54 RangeBoundary::FromConstant(-15), | |
55 RangeBoundary::FromConstant(100)); | |
56 EXPECT(positive->IsPositive()); | |
57 EXPECT(zero->Overlaps(0, 0)); | |
58 EXPECT(positive->Overlaps(0, 0)); | |
59 EXPECT(!negative->Overlaps(0, 0)); | |
60 EXPECT(range_x->Overlaps(0, 0)); | |
61 EXPECT(range_x->IsWithin(-15, 100)); | |
62 EXPECT(!range_x->IsWithin(-15, 99)); | |
63 EXPECT(!range_x->IsWithin(-14, 100)); | |
64 | |
65 #define TEST_RANGE_OP_(Op, l_min, l_max, r_min, r_max, Clamp, res_min, res_max)\ | |
66 { \ | |
67 RangeBoundary min, max; \ | |
68 Range* left_range = new Range( \ | |
69 RangeBoundary::FromConstant(l_min), \ | |
70 RangeBoundary::FromConstant(l_max)); \ | |
71 Range* shift_range = new Range( \ | |
72 RangeBoundary::FromConstant(r_min), \ | |
73 RangeBoundary::FromConstant(r_max)); \ | |
74 Op(left_range, shift_range, &min, &max); \ | |
75 min = Clamp(min); \ | |
76 max = Clamp(max); \ | |
77 EXPECT(min.Equals(res_min)); \ | |
78 if (!min.Equals(res_min)) OS::Print("%s\n", min.ToCString()); \ | |
79 EXPECT(max.Equals(res_max)); \ | |
80 if (!max.Equals(res_max)) OS::Print("%s\n", max.ToCString()); \ | |
81 } | |
82 | |
83 #define NO_CLAMP(b) (b) | |
84 #define TEST_RANGE_OP(Op, l_min, l_max, r_min, r_max, result_min, result_max) \ | |
85 TEST_RANGE_OP_(Op, l_min, l_max, r_min, r_max, \ | |
86 NO_CLAMP, result_min, result_max) | |
87 | |
88 #define CLAMP_TO_SMI(b) (b.Clamp(RangeBoundary::kRangeBoundarySmi)) | |
89 #define TEST_RANGE_OP_SMI(Op, l_min, l_max, r_min, r_max, res_min, res_max) \ | |
90 TEST_RANGE_OP_(Op, l_min, l_max, r_min, r_max, \ | |
91 CLAMP_TO_SMI, res_min, res_max) | |
92 | |
93 TEST_RANGE_OP(Range::Shl, -15, 100, 0, 2, | |
94 RangeBoundary(-60), RangeBoundary(400)); | |
95 TEST_RANGE_OP(Range::Shl, -15, 100, -2, 2, | |
96 RangeBoundary(-60), RangeBoundary(400)); | |
97 TEST_RANGE_OP(Range::Shl, -15, -10, 1, 2, | |
98 RangeBoundary(-60), RangeBoundary(-20)); | |
99 TEST_RANGE_OP(Range::Shl, 5, 10, -2, 2, | |
100 RangeBoundary(5), RangeBoundary(40)); | |
101 TEST_RANGE_OP(Range::Shl, -15, 100, 0, 64, | |
102 RangeBoundary::NegativeInfinity(), | |
103 RangeBoundary::PositiveInfinity()); | |
104 TEST_RANGE_OP(Range::Shl, -1, 1, 63, 63, | |
105 RangeBoundary(kMinInt64), | |
106 RangeBoundary::PositiveInfinity()); | |
107 if (kBitsPerWord == 64) { | |
108 TEST_RANGE_OP_SMI(Range::Shl, -1, 1, 62, 62, | |
109 RangeBoundary(kSmiMin), | |
110 RangeBoundary(kSmiMax)); | |
111 TEST_RANGE_OP_SMI(Range::Shl, -1, 1, 30, 30, | |
112 RangeBoundary(-1 << 30), | |
113 RangeBoundary(1 << 30)); | |
114 } else { | |
115 TEST_RANGE_OP_SMI(Range::Shl, -1, 1, 30, 30, | |
116 RangeBoundary(kSmiMin), | |
117 RangeBoundary(kSmiMax)); | |
118 TEST_RANGE_OP_SMI(Range::Shl, -1, 1, 62, 62, | |
119 RangeBoundary(kSmiMin), | |
120 RangeBoundary(kSmiMax)); | |
121 } | |
122 TEST_RANGE_OP(Range::Shl, 0, 100, 0, 64, | |
123 RangeBoundary(0), RangeBoundary::PositiveInfinity()); | |
124 TEST_RANGE_OP(Range::Shl, -100, 0, 0, 64, | |
125 RangeBoundary::NegativeInfinity(), RangeBoundary(0)); | |
126 | |
127 TEST_RANGE_OP(Range::Shr, -8, 8, 1, 2, RangeBoundary(-4), RangeBoundary(4)); | |
128 TEST_RANGE_OP(Range::Shr, 1, 8, 1, 2, RangeBoundary(0), RangeBoundary(4)); | |
129 TEST_RANGE_OP(Range::Shr, -16, -8, 1, 2, | |
130 RangeBoundary(-8), RangeBoundary(-2)); | |
131 TEST_RANGE_OP(Range::Shr, 2, 4, -1, 1, RangeBoundary(1), RangeBoundary(4)); | |
132 TEST_RANGE_OP(Range::Shr, kMaxInt64, kMaxInt64, 0, 1, | |
133 RangeBoundary(kMaxInt64 >> 1), RangeBoundary(kMaxInt64)); | |
134 TEST_RANGE_OP(Range::Shr, kMinInt64, kMinInt64, 0, 1, | |
135 RangeBoundary(kMinInt64), RangeBoundary(kMinInt64 >> 1)); | |
136 #undef TEST_RANGE_OP | |
137 } | |
138 | |
139 | |
140 TEST_CASE(RangeTestsInfinity) { | |
141 // +/- inf overflowed. | |
142 EXPECT(RangeBoundary::NegativeInfinity().OverflowedSmi()); | |
143 EXPECT(RangeBoundary::PositiveInfinity().OverflowedSmi()); | |
144 | |
145 EXPECT(RangeBoundary::NegativeInfinity().OverflowedMint()); | |
146 EXPECT(RangeBoundary::PositiveInfinity().OverflowedMint()); | |
147 | |
148 Range* all = new Range(RangeBoundary::NegativeInfinity(), | |
149 RangeBoundary::PositiveInfinity()); | |
150 EXPECT(all->Overlaps(0, 0)); | |
151 EXPECT(all->Overlaps(-1, 1)); | |
152 EXPECT(!all->IsWithin(0, 100)); | |
153 Range* positive = new Range(RangeBoundary::FromConstant(0), | |
154 RangeBoundary::PositiveInfinity()); | |
155 EXPECT(positive->IsPositive()); | |
156 EXPECT(positive->Overlaps(0, 1)); | |
157 EXPECT(positive->Overlaps(1, 100)); | |
158 EXPECT(positive->Overlaps(-1, 0)); | |
159 EXPECT(!positive->Overlaps(-2, -1)); | |
160 Range* negative = new Range(RangeBoundary::NegativeInfinity(), | |
161 RangeBoundary::FromConstant(-1)); | |
162 EXPECT(!negative->IsPositive()); | |
163 EXPECT(!negative->Overlaps(0, 1)); | |
164 EXPECT(!negative->Overlaps(1, 100)); | |
165 EXPECT(negative->Overlaps(-1, 0)); | |
166 EXPECT(negative->Overlaps(-2, -1)); | |
167 Range* negpos = new Range(RangeBoundary::NegativeInfinity(), | |
168 RangeBoundary::FromConstant(0)); | |
169 EXPECT(!negpos->IsPositive()); | |
170 | |
171 Range* a = new Range(RangeBoundary::NegativeInfinity(), | |
172 RangeBoundary::FromConstant(1)); | |
173 | |
174 Range* b = new Range(RangeBoundary::NegativeInfinity(), | |
175 RangeBoundary::FromConstant(31)); | |
176 | |
177 Range* c = new Range(RangeBoundary::NegativeInfinity(), | |
178 RangeBoundary::FromConstant(32)); | |
179 | |
180 EXPECT(a->OnlyLessThanOrEqualTo(31)); | |
181 EXPECT(b->OnlyLessThanOrEqualTo(31)); | |
182 EXPECT(!c->OnlyLessThanOrEqualTo(31)); | |
183 | |
184 Range* unsatisfiable = new Range(RangeBoundary::PositiveInfinity(), | |
185 RangeBoundary::NegativeInfinity()); | |
186 EXPECT(unsatisfiable->IsUnsatisfiable()); | |
187 | |
188 Range* unsatisfiable_right = new Range(RangeBoundary::PositiveInfinity(), | |
189 RangeBoundary::FromConstant(0)); | |
190 EXPECT(unsatisfiable_right->IsUnsatisfiable()); | |
191 | |
192 Range* unsatisfiable_left = new Range(RangeBoundary::FromConstant(0), | |
193 RangeBoundary::NegativeInfinity()); | |
194 EXPECT(unsatisfiable_left->IsUnsatisfiable()); | |
195 } | |
196 | |
197 | |
198 TEST_CASE(RangeUtils) { | |
199 // [-inf, +inf]. | |
200 const Range& range_0 = *(new Range(RangeBoundary::NegativeInfinity(), | |
201 RangeBoundary::PositiveInfinity())); | |
202 // [-inf, -1]. | |
203 const Range& range_a = *(new Range(RangeBoundary::NegativeInfinity(), | |
204 RangeBoundary::FromConstant(-1))); | |
205 // [-inf, 0]. | |
206 const Range& range_b = *(new Range(RangeBoundary::NegativeInfinity(), | |
207 RangeBoundary::FromConstant(0))); | |
208 // [-inf, 1]. | |
209 const Range& range_c = *(new Range(RangeBoundary::NegativeInfinity(), | |
210 RangeBoundary::FromConstant(1))); | |
211 // [-1, +inf] | |
212 const Range& range_d = *(new Range(RangeBoundary::FromConstant(-1), | |
213 RangeBoundary::PositiveInfinity())); | |
214 // [0, +inf] | |
215 const Range& range_e = *(new Range(RangeBoundary::FromConstant(0), | |
216 RangeBoundary::PositiveInfinity())); | |
217 // [1, +inf]. | |
218 const Range& range_f = *(new Range(RangeBoundary::FromConstant(1), | |
219 RangeBoundary::PositiveInfinity())); | |
220 // [1, 2]. | |
221 const Range& range_g = *(new Range(RangeBoundary::FromConstant(1), | |
222 RangeBoundary::FromConstant(2))); | |
223 // [-1, -2]. | |
224 const Range& range_h = *(new Range(RangeBoundary::FromConstant(-1), | |
225 RangeBoundary::FromConstant(-2))); | |
226 // [-1, 1]. | |
227 const Range& range_i = *(new Range(RangeBoundary::FromConstant(-1), | |
228 RangeBoundary::FromConstant(1))); | |
229 | |
230 // OnlyPositiveOrZero. | |
231 EXPECT(!Range::OnlyPositiveOrZero(range_a, range_b)); | |
232 EXPECT(!Range::OnlyPositiveOrZero(range_b, range_c)); | |
233 EXPECT(!Range::OnlyPositiveOrZero(range_c, range_d)); | |
234 EXPECT(!Range::OnlyPositiveOrZero(range_d, range_e)); | |
235 EXPECT(Range::OnlyPositiveOrZero(range_e, range_f)); | |
236 EXPECT(!Range::OnlyPositiveOrZero(range_d, range_d)); | |
237 EXPECT(Range::OnlyPositiveOrZero(range_e, range_e)); | |
238 EXPECT(Range::OnlyPositiveOrZero(range_f, range_g)); | |
239 EXPECT(!Range::OnlyPositiveOrZero(range_g, range_h)); | |
240 EXPECT(!Range::OnlyPositiveOrZero(range_i, range_i)); | |
241 | |
242 // OnlyNegativeOrZero. | |
243 EXPECT(Range::OnlyNegativeOrZero(range_a, range_b)); | |
244 EXPECT(!Range::OnlyNegativeOrZero(range_b, range_c)); | |
245 EXPECT(Range::OnlyNegativeOrZero(range_b, range_b)); | |
246 EXPECT(!Range::OnlyNegativeOrZero(range_c, range_c)); | |
247 EXPECT(!Range::OnlyNegativeOrZero(range_c, range_d)); | |
248 EXPECT(!Range::OnlyNegativeOrZero(range_d, range_e)); | |
249 EXPECT(!Range::OnlyNegativeOrZero(range_e, range_f)); | |
250 EXPECT(!Range::OnlyNegativeOrZero(range_f, range_g)); | |
251 EXPECT(!Range::OnlyNegativeOrZero(range_g, range_h)); | |
252 EXPECT(Range::OnlyNegativeOrZero(range_h, range_h)); | |
253 EXPECT(!Range::OnlyNegativeOrZero(range_i, range_i)); | |
254 | |
255 // [-inf, +inf]. | |
256 EXPECT(!Range::OnlyNegativeOrZero(range_0, range_0)); | |
257 EXPECT(!Range::OnlyPositiveOrZero(range_0, range_0)); | |
258 | |
259 EXPECT(Range::ConstantAbsMax(&range_0) == RangeBoundary::kMax); | |
260 EXPECT(Range::ConstantAbsMax(&range_h) == 2); | |
261 EXPECT(Range::ConstantAbsMax(&range_i) == 1); | |
262 | |
263 // RangeBOundary.Equals. | |
264 EXPECT(RangeBoundary::FromConstant(1).Equals( | |
265 RangeBoundary::FromConstant(1))); | |
266 EXPECT(!RangeBoundary::FromConstant(2).Equals( | |
267 RangeBoundary::FromConstant(1))); | |
268 EXPECT(RangeBoundary::PositiveInfinity().Equals( | |
269 RangeBoundary::PositiveInfinity())); | |
270 EXPECT(!RangeBoundary::PositiveInfinity().Equals( | |
271 RangeBoundary::NegativeInfinity())); | |
272 EXPECT(RangeBoundary::NegativeInfinity().Equals( | |
273 RangeBoundary::NegativeInfinity())); | |
274 EXPECT(!RangeBoundary::NegativeInfinity().Equals( | |
275 RangeBoundary::PositiveInfinity())); | |
276 EXPECT(!RangeBoundary::FromConstant(1).Equals( | |
277 RangeBoundary::NegativeInfinity())); | |
278 EXPECT(!RangeBoundary::FromConstant(1).Equals( | |
279 RangeBoundary::NegativeInfinity())); | |
280 EXPECT(!RangeBoundary::FromConstant(2).Equals( | |
281 RangeBoundary::PositiveInfinity())); | |
282 } | |
283 | |
284 | |
285 TEST_CASE(RangeBinaryOp) { | |
286 Range* range_a = new Range(RangeBoundary::FromConstant(-1), | |
287 RangeBoundary::PositiveInfinity()); | |
288 range_a->Clamp(RangeBoundary::kRangeBoundaryInt64); | |
289 EXPECT(range_a->min().ConstantValue() == -1); | |
290 EXPECT(range_a->max().ConstantValue() == RangeBoundary::kMax); | |
291 Range* range_b = new Range(RangeBoundary::NegativeInfinity(), | |
292 RangeBoundary::FromConstant(1)); | |
293 range_b->Clamp(RangeBoundary::kRangeBoundaryInt64); | |
294 EXPECT(range_b->min().ConstantValue() == RangeBoundary::kMin); | |
295 EXPECT(range_b->max().ConstantValue() == 1); | |
296 Range* result = Range::BinaryOp(Token::kADD, | |
297 range_a, | |
298 range_b, | |
299 NULL); | |
300 ASSERT(result != NULL); | |
301 EXPECT(result->min().IsNegativeInfinity()); | |
302 EXPECT(result->max().IsPositiveInfinity()); | |
303 | |
304 // Test that [5, 10] + [0, 5] = [5, 15]. | |
305 Range* range_c = new Range(RangeBoundary::FromConstant(5), | |
306 RangeBoundary::FromConstant(10)); | |
307 Range* range_d = new Range(RangeBoundary::FromConstant(0), | |
308 RangeBoundary::FromConstant(5)); | |
309 result = Range::BinaryOp(Token::kADD, | |
310 range_c, | |
311 range_d, | |
312 NULL); | |
313 ASSERT(result != NULL); | |
314 EXPECT(result->min().ConstantValue() == 5); | |
315 EXPECT(result->max().ConstantValue() == 15); | |
316 | |
317 | |
318 // Test that [0xff, 0xfff] & [0xf, 0xf] = [0x0, 0xf]. | |
319 Range* range_e = new Range(RangeBoundary::FromConstant(0xff), | |
320 RangeBoundary::FromConstant(0xfff)); | |
321 Range* range_f = new Range(RangeBoundary::FromConstant(0xf), | |
322 RangeBoundary::FromConstant(0xf)); | |
323 result = Range::BinaryOp(Token::kBIT_AND, | |
324 range_e, | |
325 range_f, | |
326 NULL); | |
327 ASSERT(result != NULL); | |
328 EXPECT(result->min().ConstantValue() == 0x0); | |
329 EXPECT(result->max().ConstantValue() == 0xf); | |
330 } | |
331 | |
332 | |
333 TEST_CASE(RangeAdd) { | |
334 #define TEST_RANGE_ADD(l_min, l_max, r_min, r_max, result_min, result_max) \ | |
335 { \ | |
336 RangeBoundary min, max; \ | |
337 Range* left_range = new Range( \ | |
338 RangeBoundary::FromConstant(l_min), \ | |
339 RangeBoundary::FromConstant(l_max)); \ | |
340 Range* right_range = new Range( \ | |
341 RangeBoundary::FromConstant(r_min), \ | |
342 RangeBoundary::FromConstant(r_max)); \ | |
343 EXPECT(left_range->min().ConstantValue() == l_min); \ | |
344 EXPECT(left_range->max().ConstantValue() == l_max); \ | |
345 EXPECT(right_range->min().ConstantValue() == r_min); \ | |
346 EXPECT(right_range->max().ConstantValue() == r_max); \ | |
347 Range::Add(left_range, right_range, &min, &max, NULL); \ | |
348 EXPECT(min.Equals(result_min)); \ | |
349 if (!min.Equals(result_min)) { \ | |
350 OS::Print("%s != %s\n", min.ToCString(), result_min.ToCString()); \ | |
351 } \ | |
352 EXPECT(max.Equals(result_max)); \ | |
353 if (!max.Equals(result_max)) { \ | |
354 OS::Print("%s != %s\n", max.ToCString(), result_max.ToCString()); \ | |
355 } \ | |
356 } | |
357 | |
358 // [kMaxInt32, kMaxInt32 + 15] + [10, 20] = [kMaxInt32 + 10, kMaxInt32 + 35]. | |
359 TEST_RANGE_ADD(static_cast<int64_t>(kMaxInt32), | |
360 static_cast<int64_t>(kMaxInt32) + 15, | |
361 static_cast<int64_t>(10), | |
362 static_cast<int64_t>(20), | |
363 RangeBoundary(static_cast<int64_t>(kMaxInt32) + 10), | |
364 RangeBoundary(static_cast<int64_t>(kMaxInt32) + 35)); | |
365 | |
366 // [kMaxInt32 - 15, kMaxInt32 + 15] + [15, -15] = [kMaxInt32, kMaxInt32]. | |
367 TEST_RANGE_ADD(static_cast<int64_t>(kMaxInt32) - 15, | |
368 static_cast<int64_t>(kMaxInt32) + 15, | |
369 static_cast<int64_t>(15), | |
370 static_cast<int64_t>(-15), | |
371 RangeBoundary(static_cast<int64_t>(kMaxInt32)), | |
372 RangeBoundary(static_cast<int64_t>(kMaxInt32))); | |
373 | |
374 // [kMaxInt32, kMaxInt32 + 15] + [10, kMaxInt64] = [kMaxInt32 + 10, +inf]. | |
375 TEST_RANGE_ADD(static_cast<int64_t>(kMaxInt32), | |
376 static_cast<int64_t>(kMaxInt32) + 15, | |
377 static_cast<int64_t>(10), | |
378 static_cast<int64_t>(kMaxInt64), | |
379 RangeBoundary(static_cast<int64_t>(kMaxInt32) + 10), | |
380 RangeBoundary::PositiveInfinity()); | |
381 | |
382 // [kMinInt64, kMaxInt32 + 15] + [10, 20] = [kMinInt64 + 10, kMaxInt32 + 35]. | |
383 TEST_RANGE_ADD(static_cast<int64_t>(kMinInt64), | |
384 static_cast<int64_t>(kMaxInt32) + 15, | |
385 static_cast<int64_t>(10), | |
386 static_cast<int64_t>(20), | |
387 RangeBoundary(static_cast<int64_t>(kMinInt64) + 10), | |
388 RangeBoundary(static_cast<int64_t>(kMaxInt32) + 35)); | |
389 | |
390 // [0, 0] + [kMinInt64, kMaxInt64] = [kMinInt64, kMaxInt64]. | |
391 TEST_RANGE_ADD(static_cast<int64_t>(0), | |
392 static_cast<int64_t>(0), | |
393 static_cast<int64_t>(kMinInt64), | |
394 static_cast<int64_t>(kMaxInt64), | |
395 RangeBoundary(kMinInt64), | |
396 RangeBoundary(kMaxInt64)); | |
397 | |
398 // Overflows. | |
399 | |
400 // [-1, 1] + [kMinInt64, kMaxInt64] = [-inf, +inf]. | |
401 TEST_RANGE_ADD(static_cast<int64_t>(-1), | |
402 static_cast<int64_t>(1), | |
403 static_cast<int64_t>(kMinInt64), | |
404 static_cast<int64_t>(kMaxInt64), | |
405 RangeBoundary::NegativeInfinity(), | |
406 RangeBoundary::PositiveInfinity()); | |
407 | |
408 // [kMaxInt64, kMaxInt64] + [kMaxInt64, kMaxInt64] = [-inf, +inf]. | |
409 TEST_RANGE_ADD(static_cast<int64_t>(kMaxInt64), | |
410 static_cast<int64_t>(kMaxInt64), | |
411 static_cast<int64_t>(kMaxInt64), | |
412 static_cast<int64_t>(kMaxInt64), | |
413 RangeBoundary::NegativeInfinity(), | |
414 RangeBoundary::PositiveInfinity()); | |
415 | |
416 // [kMaxInt64, kMaxInt64] + [1, 1] = [-inf, +inf]. | |
417 TEST_RANGE_ADD(static_cast<int64_t>(kMaxInt64), | |
418 static_cast<int64_t>(kMaxInt64), | |
419 static_cast<int64_t>(1), | |
420 static_cast<int64_t>(1), | |
421 RangeBoundary::NegativeInfinity(), | |
422 RangeBoundary::PositiveInfinity()); | |
423 | |
424 #undef TEST_RANGE_ADD | |
425 } | |
426 | |
427 | |
428 TEST_CASE(RangeSub) { | |
429 #define TEST_RANGE_SUB(l_min, l_max, r_min, r_max, result_min, result_max) \ | |
430 { \ | |
431 RangeBoundary min, max; \ | |
432 Range* left_range = new Range( \ | |
433 RangeBoundary::FromConstant(l_min), \ | |
434 RangeBoundary::FromConstant(l_max)); \ | |
435 Range* right_range = new Range( \ | |
436 RangeBoundary::FromConstant(r_min), \ | |
437 RangeBoundary::FromConstant(r_max)); \ | |
438 EXPECT(left_range->min().ConstantValue() == l_min); \ | |
439 EXPECT(left_range->max().ConstantValue() == l_max); \ | |
440 EXPECT(right_range->min().ConstantValue() == r_min); \ | |
441 EXPECT(right_range->max().ConstantValue() == r_max); \ | |
442 Range::Sub(left_range, right_range, &min, &max, NULL); \ | |
443 EXPECT(min.Equals(result_min)); \ | |
444 if (!min.Equals(result_min)) { \ | |
445 OS::Print("%s != %s\n", min.ToCString(), result_min.ToCString()); \ | |
446 } \ | |
447 EXPECT(max.Equals(result_max)); \ | |
448 if (!max.Equals(result_max)) { \ | |
449 OS::Print("%s != %s\n", max.ToCString(), result_max.ToCString()); \ | |
450 } \ | |
451 } | |
452 | |
453 // [kMaxInt32, kMaxInt32 + 15] - [10, 20] = [kMaxInt32 - 20, kMaxInt32 + 5]. | |
454 TEST_RANGE_SUB(static_cast<int64_t>(kMaxInt32), | |
455 static_cast<int64_t>(kMaxInt32) + 15, | |
456 static_cast<int64_t>(10), | |
457 static_cast<int64_t>(20), | |
458 RangeBoundary(static_cast<int64_t>(kMaxInt32) - 20), | |
459 RangeBoundary(static_cast<int64_t>(kMaxInt32) + 5)); | |
460 | |
461 // [kMintInt64, kMintInt64] - [1, 1] = [-inf, +inf]. | |
462 TEST_RANGE_SUB(static_cast<int64_t>(kMinInt64), | |
463 static_cast<int64_t>(kMinInt64), | |
464 static_cast<int64_t>(1), | |
465 static_cast<int64_t>(1), | |
466 RangeBoundary::NegativeInfinity(), | |
467 RangeBoundary::PositiveInfinity()); | |
468 | |
469 // [1, 1] - [kMintInt64, kMintInt64] = [-inf, +inf]. | |
470 TEST_RANGE_SUB(static_cast<int64_t>(1), | |
471 static_cast<int64_t>(1), | |
472 static_cast<int64_t>(kMinInt64), | |
473 static_cast<int64_t>(kMinInt64), | |
474 RangeBoundary::NegativeInfinity(), | |
475 RangeBoundary::PositiveInfinity()); | |
476 | |
477 // [kMaxInt32 + 10, kMaxInt32 + 20] - [-20, -20] = | |
478 // [kMaxInt32 + 30, kMaxInt32 + 40]. | |
479 TEST_RANGE_SUB(static_cast<int64_t>(kMaxInt32) + 10, | |
480 static_cast<int64_t>(kMaxInt32) + 20, | |
481 static_cast<int64_t>(-20), | |
482 static_cast<int64_t>(-20), | |
483 RangeBoundary(static_cast<int64_t>(kMaxInt32) + 30), | |
484 RangeBoundary(static_cast<int64_t>(kMaxInt32) + 40)); | |
485 | |
486 | |
487 #undef TEST_RANGE_SUB | |
488 } | |
489 | |
490 | |
491 TEST_CASE(RangeAnd) { | |
492 #define TEST_RANGE_AND(l_min, l_max, r_min, r_max, result_min, result_max) \ | |
493 { \ | |
494 RangeBoundary min, max; \ | |
495 Range* left_range = new Range( \ | |
496 RangeBoundary::FromConstant(l_min), \ | |
497 RangeBoundary::FromConstant(l_max)); \ | |
498 Range* right_range = new Range( \ | |
499 RangeBoundary::FromConstant(r_min), \ | |
500 RangeBoundary::FromConstant(r_max)); \ | |
501 EXPECT(left_range->min().ConstantValue() == l_min); \ | |
502 EXPECT(left_range->max().ConstantValue() == l_max); \ | |
503 EXPECT(right_range->min().ConstantValue() == r_min); \ | |
504 EXPECT(right_range->max().ConstantValue() == r_max); \ | |
505 Range::And(left_range, right_range, &min, &max); \ | |
506 EXPECT(min.Equals(result_min)); \ | |
507 if (!min.Equals(result_min)) { \ | |
508 OS::Print("%s != %s\n", min.ToCString(), result_min.ToCString()); \ | |
509 } \ | |
510 EXPECT(max.Equals(result_max)); \ | |
511 if (!max.Equals(result_max)) { \ | |
512 OS::Print("%s != %s\n", max.ToCString(), result_max.ToCString()); \ | |
513 } \ | |
514 } | |
515 | |
516 // [0xff, 0xfff] & [0xf, 0xf] = [0x0, 0xf]. | |
517 TEST_RANGE_AND(static_cast<int64_t>(0xff), | |
518 static_cast<int64_t>(0xfff), | |
519 static_cast<int64_t>(0xf), | |
520 static_cast<int64_t>(0xf), | |
521 RangeBoundary(0), | |
522 RangeBoundary(0xf)); | |
523 | |
524 // [0xffffffff, 0xffffffff] & [0xfffffffff, 0xfffffffff] = [0x0, 0xfffffffff]. | |
525 TEST_RANGE_AND(static_cast<int64_t>(0xffffffff), | |
526 static_cast<int64_t>(0xffffffff), | |
527 static_cast<int64_t>(0xfffffffff), | |
528 static_cast<int64_t>(0xfffffffff), | |
529 RangeBoundary(0), | |
530 RangeBoundary(static_cast<int64_t>(0xfffffffff))); | |
531 | |
532 // [0xffffffff, 0xffffffff] & [-20, 20] = [0x0, 0xffffffff]. | |
533 TEST_RANGE_AND(static_cast<int64_t>(0xffffffff), | |
534 static_cast<int64_t>(0xffffffff), | |
535 static_cast<int64_t>(-20), | |
536 static_cast<int64_t>(20), | |
537 RangeBoundary(0), | |
538 RangeBoundary(static_cast<int64_t>(0xffffffff))); | |
539 | |
540 // [-20, 20] & [0xffffffff, 0xffffffff] = [0x0, 0xffffffff]. | |
541 TEST_RANGE_AND(static_cast<int64_t>(-20), | |
542 static_cast<int64_t>(20), | |
543 static_cast<int64_t>(0xffffffff), | |
544 static_cast<int64_t>(0xffffffff), | |
545 RangeBoundary(0), | |
546 RangeBoundary(static_cast<int64_t>(0xffffffff))); | |
547 | |
548 // Test that [-20, 20] & [-20, 20] = [Unknown, Unknown]. | |
549 TEST_RANGE_AND(static_cast<int64_t>(-20), | |
550 static_cast<int64_t>(20), | |
551 static_cast<int64_t>(-20), | |
552 static_cast<int64_t>(20), | |
553 RangeBoundary(), | |
554 RangeBoundary()); | |
555 | |
556 #undef TEST_RANGE_AND | |
557 } | |
558 | |
559 | |
560 TEST_CASE(RangeMinMax) { | |
561 // Constants. | |
562 // MIN(0, 1) == 0 | |
563 EXPECT(RangeBoundary::Min( | |
564 RangeBoundary::FromConstant(0), | |
565 RangeBoundary::FromConstant(1), | |
566 RangeBoundary::kRangeBoundaryInt64).ConstantValue() == 0); | |
567 // MIN(0, -1) == -1 | |
568 EXPECT(RangeBoundary::Min( | |
569 RangeBoundary::FromConstant(0), | |
570 RangeBoundary::FromConstant(-1), | |
571 RangeBoundary::kRangeBoundaryInt64).ConstantValue() == -1); | |
572 | |
573 // MIN(1, 0) == 0 | |
574 EXPECT(RangeBoundary::Min( | |
575 RangeBoundary::FromConstant(1), | |
576 RangeBoundary::FromConstant(0), | |
577 RangeBoundary::kRangeBoundaryInt64).ConstantValue() == 0); | |
578 // MIN(-1, 0) == -1 | |
579 EXPECT(RangeBoundary::Min( | |
580 RangeBoundary::FromConstant(-1), | |
581 RangeBoundary::FromConstant(0), | |
582 RangeBoundary::kRangeBoundaryInt64).ConstantValue() == -1); | |
583 | |
584 // MAX(0, 1) == 1 | |
585 EXPECT(RangeBoundary::Max( | |
586 RangeBoundary::FromConstant(0), | |
587 RangeBoundary::FromConstant(1), | |
588 RangeBoundary::kRangeBoundaryInt64).ConstantValue() == 1); | |
589 | |
590 // MAX(0, -1) == 0 | |
591 EXPECT(RangeBoundary::Max( | |
592 RangeBoundary::FromConstant(0), | |
593 RangeBoundary::FromConstant(-1), | |
594 RangeBoundary::kRangeBoundaryInt64).ConstantValue() == 0); | |
595 | |
596 // MAX(1, 0) == 1 | |
597 EXPECT(RangeBoundary::Max( | |
598 RangeBoundary::FromConstant(1), | |
599 RangeBoundary::FromConstant(0), | |
600 RangeBoundary::kRangeBoundaryInt64).ConstantValue() == 1); | |
601 // MAX(-1, 0) == 0 | |
602 EXPECT(RangeBoundary::Max( | |
603 RangeBoundary::FromConstant(-1), | |
604 RangeBoundary::FromConstant(0), | |
605 RangeBoundary::kRangeBoundaryInt64).ConstantValue() == 0); | |
606 | |
607 RangeBoundary n_infinity = RangeBoundary::NegativeInfinity(); | |
608 RangeBoundary p_infinity = RangeBoundary::PositiveInfinity(); | |
609 | |
610 // Constants vs. infinity. | |
611 EXPECT(RangeBoundary::Max( | |
612 n_infinity, | |
613 RangeBoundary::FromConstant(-1), | |
614 RangeBoundary::kRangeBoundaryInt64).ConstantValue() == -1); | |
615 | |
616 EXPECT(RangeBoundary::Max( | |
617 RangeBoundary::FromConstant(-1), | |
618 n_infinity, | |
619 RangeBoundary::kRangeBoundaryInt64).ConstantValue() == -1); | |
620 | |
621 EXPECT(RangeBoundary::Max( | |
622 RangeBoundary::FromConstant(1), | |
623 n_infinity, | |
624 RangeBoundary::kRangeBoundaryInt64).ConstantValue() == 1); | |
625 | |
626 EXPECT(RangeBoundary::Max( | |
627 n_infinity, | |
628 RangeBoundary::FromConstant(1), | |
629 RangeBoundary::kRangeBoundaryInt64).ConstantValue() == 1); | |
630 | |
631 EXPECT(RangeBoundary::Min( | |
632 p_infinity, | |
633 RangeBoundary::FromConstant(-1), | |
634 RangeBoundary::kRangeBoundaryInt64).ConstantValue() == -1); | |
635 | |
636 EXPECT(RangeBoundary::Min( | |
637 RangeBoundary::FromConstant(-1), | |
638 p_infinity, | |
639 RangeBoundary::kRangeBoundaryInt64).ConstantValue() == -1); | |
640 | |
641 EXPECT(RangeBoundary::Min( | |
642 RangeBoundary::FromConstant(1), | |
643 p_infinity, | |
644 RangeBoundary::kRangeBoundaryInt64).ConstantValue() == 1); | |
645 | |
646 EXPECT(RangeBoundary::Min( | |
647 p_infinity, | |
648 RangeBoundary::FromConstant(1), | |
649 RangeBoundary::kRangeBoundaryInt64).ConstantValue() == 1); | |
650 | |
651 // 64-bit values. | |
652 EXPECT(RangeBoundary::Min( | |
653 RangeBoundary(static_cast<int64_t>(kMinInt64)), | |
654 RangeBoundary(static_cast<int64_t>(kMinInt32)), | |
655 RangeBoundary::kRangeBoundaryInt64).ConstantValue() == kMinInt64); | |
656 | |
657 EXPECT(RangeBoundary::Max( | |
658 RangeBoundary(static_cast<int64_t>(kMinInt64)), | |
659 RangeBoundary(static_cast<int64_t>(kMinInt32)), | |
660 RangeBoundary::kRangeBoundaryInt64).ConstantValue() == kMinInt32); | |
661 | |
662 EXPECT(RangeBoundary::Min( | |
663 RangeBoundary(static_cast<int64_t>(kMaxInt64)), | |
664 RangeBoundary(static_cast<int64_t>(kMaxInt32)), | |
665 RangeBoundary::kRangeBoundaryInt64).ConstantValue() == kMaxInt32); | |
666 | |
667 EXPECT(RangeBoundary::Max( | |
668 RangeBoundary(static_cast<int64_t>(kMaxInt64)), | |
669 RangeBoundary(static_cast<int64_t>(kMaxInt32)), | |
670 RangeBoundary::kRangeBoundaryInt64).ConstantValue() == kMaxInt64); | |
671 } | |
672 | |
673 } // namespace dart | 43 } // namespace dart |
OLD | NEW |