| 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 |