29#define TEST_RANGE_OP_(Op, l_min, l_max, r_min, r_max, Clamp, res_min, \
32 RangeBoundary min, max; \
33 Range* left_range = new Range(RangeBoundary::FromConstant(l_min), \
34 RangeBoundary::FromConstant(l_max)); \
35 Range* shift_range = new Range(RangeBoundary::FromConstant(r_min), \
36 RangeBoundary::FromConstant(r_max)); \
37 Op(left_range, shift_range, &min, &max); \
40 EXPECT(min.Equals(res_min)); \
41 if (FLAG_support_il_printer && !min.Equals(res_min)) { \
42 OS::PrintErr("%s\n", min.ToCString()); \
44 EXPECT(max.Equals(res_max)); \
45 if (FLAG_support_il_printer && !max.Equals(res_max)) { \
46 OS::PrintErr("%s\n", max.ToCString()); \
50#define NO_CLAMP(b) (b)
51#define TEST_RANGE_OP(Op, l_min, l_max, r_min, r_max, result_min, result_max) \
52 TEST_RANGE_OP_(Op, l_min, l_max, r_min, r_max, NO_CLAMP, result_min, \
55#define CLAMP_TO_SMI(b) (b.Clamp(RangeBoundary::kRangeBoundarySmi))
56#define TEST_RANGE_OP_SMI(Op, l_min, l_max, r_min, r_max, res_min, res_max) \
57 TEST_RANGE_OP_(Op, l_min, l_max, r_min, r_max, CLAMP_TO_SMI, res_min, res_max)
70 if (compiler::target::kSmiBits == 62) {
77 ASSERT(compiler::target::kSmiBits == 30);
107 EXPECT(all->Equals(&fullInt64Range));
108 EXPECT(all->Overlaps(0, 0));
109 EXPECT(all->Overlaps(-1, 1));
110 EXPECT(!all->IsWithin(0, 100));
142 const Range& range_0 = *(
new Range(negativeInfinity, positiveInfinity));
144 const Range& range_a =
147 const Range& range_b =
150 const Range& range_c =
153 const Range& range_d =
156 const Range& range_e =
159 const Range& range_f =
264#define TEST_RANGE_ADD(l_min, l_max, r_min, r_max, result_min, result_max) \
266 RangeBoundary min, max; \
267 Range* left_range = new Range(RangeBoundary::FromConstant(l_min), \
268 RangeBoundary::FromConstant(l_max)); \
269 Range* right_range = new Range(RangeBoundary::FromConstant(r_min), \
270 RangeBoundary::FromConstant(r_max)); \
271 EXPECT(left_range->min().ConstantValue() == l_min); \
272 EXPECT(left_range->max().ConstantValue() == l_max); \
273 EXPECT(right_range->min().ConstantValue() == r_min); \
274 EXPECT(right_range->max().ConstantValue() == r_max); \
275 Range::Add(left_range, right_range, &min, &max, nullptr); \
276 EXPECT(min.Equals(result_min)); \
277 if (FLAG_support_il_printer && !min.Equals(result_min)) { \
278 OS::PrintErr("%s != %s\n", min.ToCString(), result_min.ToCString()); \
280 EXPECT(max.Equals(result_max)); \
281 if (FLAG_support_il_printer && !max.Equals(result_max)) { \
282 OS::PrintErr("%s != %s\n", max.ToCString(), result_max.ToCString()); \
288 static_cast<int64_t
>(
kMaxInt32) + 15,
static_cast<int64_t
>(10),
289 static_cast<int64_t
>(20),
295 static_cast<int64_t
>(
kMaxInt32) + 15,
static_cast<int64_t
>(15),
296 static_cast<int64_t
>(-15),
302 static_cast<int64_t
>(
kMaxInt32) + 15,
static_cast<int64_t
>(10),
308 static_cast<int64_t
>(
kMaxInt32) + 15,
static_cast<int64_t
>(10),
309 static_cast<int64_t
>(20),
335 static_cast<int64_t
>(
kMaxInt64),
static_cast<int64_t
>(1),
343#define TEST_RANGE_SUB(l_min, l_max, r_min, r_max, result_min, result_max) \
345 RangeBoundary min, max; \
346 Range* left_range = new Range(RangeBoundary::FromConstant(l_min), \
347 RangeBoundary::FromConstant(l_max)); \
348 Range* right_range = new Range(RangeBoundary::FromConstant(r_min), \
349 RangeBoundary::FromConstant(r_max)); \
350 EXPECT(left_range->min().ConstantValue() == l_min); \
351 EXPECT(left_range->max().ConstantValue() == l_max); \
352 EXPECT(right_range->min().ConstantValue() == r_min); \
353 EXPECT(right_range->max().ConstantValue() == r_max); \
354 Range::Sub(left_range, right_range, &min, &max, nullptr); \
355 EXPECT(min.Equals(result_min)); \
356 if (FLAG_support_il_printer && !min.Equals(result_min)) { \
357 OS::PrintErr("%s != %s\n", min.ToCString(), result_min.ToCString()); \
359 EXPECT(max.Equals(result_max)); \
360 if (FLAG_support_il_printer && !max.Equals(result_max)) { \
361 OS::PrintErr("%s != %s\n", max.ToCString(), result_max.ToCString()); \
367 static_cast<int64_t
>(
kMaxInt32) + 15,
static_cast<int64_t
>(10),
368 static_cast<int64_t
>(20),
374 static_cast<int64_t
>(
kMinInt64),
static_cast<int64_t
>(1),
388 static_cast<int64_t
>(-20),
static_cast<int64_t
>(-20),
396#define TEST_RANGE_AND(l_min, l_max, r_min, r_max, result_min, result_max) \
398 RangeBoundary min, max; \
399 Range* left_range = new Range(RangeBoundary::FromConstant(l_min), \
400 RangeBoundary::FromConstant(l_max)); \
401 Range* right_range = new Range(RangeBoundary::FromConstant(r_min), \
402 RangeBoundary::FromConstant(r_max)); \
403 EXPECT(left_range->min().ConstantValue() == l_min); \
404 EXPECT(left_range->max().ConstantValue() == l_max); \
405 EXPECT(right_range->min().ConstantValue() == r_min); \
406 EXPECT(right_range->max().ConstantValue() == r_max); \
407 Range::And(left_range, right_range, &min, &max); \
408 EXPECT(min.Equals(result_min)); \
409 if (FLAG_support_il_printer && !min.Equals(result_min)) { \
410 OS::PrintErr("%s != %s\n", min.ToCString(), result_min.ToCString()); \
412 EXPECT(max.Equals(result_max)); \
413 if (FLAG_support_il_printer && !max.Equals(result_max)) { \
414 OS::PrintErr("%s != %s\n", max.ToCString(), result_max.ToCString()); \
419 TEST_RANGE_AND(
static_cast<int64_t
>(0xff),
static_cast<int64_t
>(0xfff),
420 static_cast<int64_t
>(0xf),
static_cast<int64_t
>(0xf),
425 static_cast<int64_t
>(0xffffffff),
static_cast<int64_t
>(0xffffffff),
426 static_cast<int64_t
>(0xfffffffff),
static_cast<int64_t
>(0xfffffffff),
432 static_cast<int64_t
>(0xffffffff),
static_cast<int64_t
>(-20),
437 TEST_RANGE_AND(
static_cast<int64_t
>(-20),
static_cast<int64_t
>(20),
438 static_cast<int64_t
>(0xffffffff),
439 static_cast<int64_t
>(0xffffffff),
444 TEST_RANGE_AND(
static_cast<int64_t
>(-20),
static_cast<int64_t
>(20),
445 static_cast<int64_t
>(-20),
static_cast<int64_t
>(20),
459 .ConstantValue() == 0);
463 .ConstantValue() == -1);
468 .ConstantValue() == 0);
472 .ConstantValue() == -1);
477 .ConstantValue() == 1);
482 .ConstantValue() == 0);
487 .ConstantValue() == 1);
491 .ConstantValue() == 0);
496 .ConstantValue() == -1);
500 .ConstantValue() == -1);
504 .ConstantValue() == 1);
508 .ConstantValue() == 1);
512 .ConstantValue() == -1);
516 .ConstantValue() == -1);
520 .ConstantValue() == 1);
524 .ConstantValue() == 1);
535 .ConstantValue() == 1);
538 .ConstantValue() == 0);
541 .ConstantValue() == 1);
544 .ConstantValue() == 0);
547 .ConstantValue() == 0);
550 .ConstantValue() == -1);
553 .ConstantValue() == 0);
556 .ConstantValue() == -1);
561 .IsMinimumOrBelow(size));
565 .IsMinimumOrBelow(size));
569 .IsMinimumOrBelow(size));
573 .IsMinimumOrBelow(size));
577 .IsMaximumOrAbove(size));
581 .IsMaximumOrAbove(size));
585 .IsMaximumOrAbove(size));
589 .IsMaximumOrAbove(size));
592#if defined(DART_PRECOMPILER) && defined(TARGET_ARCH_IS_64_BIT)
596 const char* kScript = R
"(
597 @pragma('vm:never-inline')
599 return 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
608 Invoke(root_library,
"main");
612 FlowGraph* flow_graph = pipeline.RunPasses({});
614 auto entry = flow_graph->graph_entry()->normal_entry();
616 ILMatcher cursor(flow_graph, entry,
true,
619 ShiftUint32OpInstr* shift =
nullptr;
623 kMatchAndMoveBinaryUint32Op,
625 {kMatchAndMoveShiftUint32Op, &shift},
627 kMatchAndMoveBinaryUint32Op,
629 kMatchAndMoveBinaryUint32Op,
634 EXPECT(shift->shift_range() !=
nullptr);
635 EXPECT(shift->shift_range()->min().ConstantValue() == 10);
636 EXPECT(shift->shift_range()->max().ConstantValue() == 10);
642 const char* kScript = R
"(
643 @pragma('vm:never-inline')
652 const auto& root_library = Library::Handle(
LoadTestScript(kScript));
653 Invoke(root_library,
"main");
661 ILMatcher cursor(flow_graph, entry,
true,
662 ParallelMovesHandling::kSkip);
668 {kMatchAndMoveLoadClassId, &load_cid},
670 kMatchAndMoveTestRange,
675 EXPECT(load_cid->range() !=
nullptr);
676 EXPECT(kSmiCid < kMintCid);
677 EXPECT(kMintCid < kDoubleCid);
678 EXPECT(load_cid->range()->min().ConstantValue() == kSmiCid);
679 EXPECT(load_cid->range()->max().ConstantValue() == kDoubleCid);
#define RELEASE_ASSERT(cond)
GraphEntryInstr * graph_entry() const
FunctionEntryInstr * normal_entry() const
bool TryMatch(std::initializer_list< MatchCode > match_codes, MatchOpCode insert_before=kInvalidMatchOpCode)
static RangeBoundary MinConstant(RangeSize size)
static constexpr int64_t kMin
static RangeBoundary JoinMax(RangeBoundary a, RangeBoundary b, RangeBoundary::RangeSize size)
static RangeBoundary IntersectionMin(RangeBoundary a, RangeBoundary b)
static RangeBoundary IntersectionMax(RangeBoundary a, RangeBoundary b)
int64_t ConstantValue() const
static RangeBoundary JoinMin(RangeBoundary a, RangeBoundary b, RangeBoundary::RangeSize size)
static constexpr int64_t kMax
static RangeBoundary MaxConstant(RangeSize size)
static RangeBoundary FromConstant(int64_t val)
static int64_t ConstantAbsMax(const Range *range)
static bool OnlyNegativeOrZero(const Range &a, const Range &b)
void set_max(const RangeBoundary &value)
static void Shr(const Range *left_range, const Range *right_range, RangeBoundary *min, RangeBoundary *max)
bool IsWithin(int64_t min_int, int64_t max_int) const
static bool OnlyPositiveOrZero(const Range &a, const Range &b)
static bool IsUnknown(const Range *other)
const RangeBoundary & min() const
static void BinaryOp(const Token::Kind op, const Range *left_range, const Range *right_range, Definition *left_defn, Range *result)
const RangeBoundary & max() const
static Range Full(RangeBoundary::RangeSize size)
void Clamp(RangeBoundary::RangeSize size)
static void Shl(const Range *left_range, const Range *right_range, RangeBoundary *min, RangeBoundary *max)
void set_min(const RangeBoundary &value)
bool OnlyLessThanOrEqualTo(int64_t val) const
bool Overlaps(int64_t min_int, int64_t max_int) const
FlowGraph * RunPasses(std::initializer_list< CompilerPass::Id > passes)
Dart_NativeFunction function
constexpr int64_t kMaxInt64
static bool Equals(const Object &expected, const Object &actual)
constexpr int64_t kMinInt64
LibraryPtr LoadTestScript(const char *script, Dart_NativeEntryResolver resolver, const char *lib_uri)
constexpr int32_t kMinInt32
ObjectPtr Invoke(const Library &lib, const char *name)
FunctionPtr GetFunction(const Library &lib, const char *name)
constexpr int32_t kMaxInt32
#define TEST_RANGE_AND(l_min, l_max, r_min, r_max, result_min, result_max)
#define TEST_RANGE_SUB(l_min, l_max, r_min, r_max, result_min, result_max)
#define TEST_RANGE_ADD(l_min, l_max, r_min, r_max, result_min, result_max)
#define TEST_RANGE_OP(Op, l_min, l_max, r_min, r_max, result_min, result_max)
#define TEST_RANGE_OP_SMI(Op, l_min, l_max, r_min, r_max, res_min, res_max)
#define ISOLATE_UNIT_TEST_CASE(name)