1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2014 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file.
4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/change-lowering.h"
6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/compiler-test-utils.h"
7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/graph-unittest.h"
8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/js-graph.h"
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/node-properties-inl.h"
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/simplified-operator.h"
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/typer.h"
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "testing/gmock-support.h"
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochusing testing::_;
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochusing testing::AllOf;
16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochusing testing::Capture;
17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochusing testing::CaptureEq;
18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 {
20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal {
21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace compiler {
22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// TODO(bmeurer): Find a new home for these functions.
24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochinline std::ostream& operator<<(std::ostream& os, const MachineType& type) {
25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  OStringStream ost;
26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ost << type;
27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return os << ost.c_str();
28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass ChangeLoweringTest : public GraphTest {
32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ChangeLoweringTest() : simplified_(zone()) {}
34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual ~ChangeLoweringTest() {}
35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual MachineType WordRepresentation() const = 0;
37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected:
39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int HeapNumberValueOffset() const {
40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    STATIC_ASSERT(HeapNumber::kValueOffset % kApiPointerSize == 0);
41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return (HeapNumber::kValueOffset / kApiPointerSize) * PointerSize() -
42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           kHeapObjectTag;
43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool Is32() const { return WordRepresentation() == kRepWord32; }
45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int PointerSize() const {
46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    switch (WordRepresentation()) {
47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case kRepWord32:
48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return 4;
49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case kRepWord64:
50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return 8;
51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      default:
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        break;
53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    UNREACHABLE();
55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return 0;
56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int SmiMaxValue() const { return -(SmiMinValue() + 1); }
58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int SmiMinValue() const {
59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return static_cast<int>(0xffffffffu << (SmiValueSize() - 1));
60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int SmiShiftAmount() const { return kSmiTagSize + SmiShiftSize(); }
62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int SmiShiftSize() const {
63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Is32() ? SmiTagging<4>::SmiShiftSize()
64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  : SmiTagging<8>::SmiShiftSize();
65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int SmiValueSize() const {
67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Is32() ? SmiTagging<4>::SmiValueSize()
68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  : SmiTagging<8>::SmiValueSize();
69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* Parameter(int32_t index = 0) {
72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return graph()->NewNode(common()->Parameter(index), graph()->start());
73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Reduction Reduce(Node* node) {
76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Typer typer(zone());
77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    MachineOperatorBuilder machine(WordRepresentation());
78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    JSOperatorBuilder javascript(zone());
79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    JSGraph jsgraph(graph(), common(), &javascript, &typer, &machine);
80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CompilationInfo info(isolate(), zone());
81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Linkage linkage(&info);
82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ChangeLowering reducer(&jsgraph, &linkage);
83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return reducer.Reduce(node);
84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SimplifiedOperatorBuilder* simplified() { return &simplified_; }
87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Matcher<Node*> IsAllocateHeapNumber(const Matcher<Node*>& effect_matcher,
89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                      const Matcher<Node*>& control_matcher) {
90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return IsCall(
91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        _, IsHeapConstant(Unique<HeapObject>::CreateImmovable(
92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch               CEntryStub(isolate(), 1).GetCode())),
93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        IsExternalConstant(ExternalReference(
94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            Runtime::FunctionForId(Runtime::kAllocateHeapNumber), isolate())),
95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        IsInt32Constant(0), IsNumberConstant(0.0), effect_matcher,
96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        control_matcher);
97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Matcher<Node*> IsWordEqual(const Matcher<Node*>& lhs_matcher,
99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                             const Matcher<Node*>& rhs_matcher) {
100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Is32() ? IsWord32Equal(lhs_matcher, rhs_matcher)
101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  : IsWord64Equal(lhs_matcher, rhs_matcher);
102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SimplifiedOperatorBuilder simplified_;
106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// -----------------------------------------------------------------------------
110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Common.
111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass ChangeLoweringCommonTest
114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    : public ChangeLoweringTest,
115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      public ::testing::WithParamInterface<MachineType> {
116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual ~ChangeLoweringCommonTest() {}
118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual MachineType WordRepresentation() const FINAL OVERRIDE {
120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return GetParam();
121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTARGET_TEST_P(ChangeLoweringCommonTest, ChangeBitToBool) {
126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* val = Parameter(0);
127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* node = graph()->NewNode(simplified()->ChangeBitToBool(), val);
128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Reduction reduction = Reduce(node);
129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ASSERT_TRUE(reduction.Changed());
130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* phi = reduction.replacement();
132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Capture<Node*> branch;
133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_THAT(phi,
134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              IsPhi(static_cast<MachineType>(kTypeBool | kRepTagged),
135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    IsTrueConstant(), IsFalseConstant(),
136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    IsMerge(IsIfTrue(AllOf(CaptureEq(&branch),
137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                           IsBranch(val, graph()->start()))),
138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                            IsIfFalse(CaptureEq(&branch)))));
139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTARGET_TEST_P(ChangeLoweringCommonTest, ChangeBoolToBit) {
143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* val = Parameter(0);
144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* node = graph()->NewNode(simplified()->ChangeBoolToBit(), val);
145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Reduction reduction = Reduce(node);
146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ASSERT_TRUE(reduction.Changed());
147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_THAT(reduction.replacement(), IsWordEqual(val, IsTrueConstant()));
149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTARGET_TEST_P(ChangeLoweringCommonTest, ChangeFloat64ToTagged) {
153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* val = Parameter(0);
154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* node = graph()->NewNode(simplified()->ChangeFloat64ToTagged(), val);
155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Reduction reduction = Reduce(node);
156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ASSERT_TRUE(reduction.Changed());
157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* finish = reduction.replacement();
159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Capture<Node*> heap_number;
160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_THAT(
161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      finish,
162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      IsFinish(
163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          AllOf(CaptureEq(&heap_number),
164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                IsAllocateHeapNumber(IsValueEffect(val), graph()->start())),
165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          IsStore(kMachFloat64, kNoWriteBarrier, CaptureEq(&heap_number),
166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  IsInt32Constant(HeapNumberValueOffset()), val,
167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  CaptureEq(&heap_number), graph()->start())));
168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTARGET_TEST_P(ChangeLoweringCommonTest, StringAdd) {
172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* node =
173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      graph()->NewNode(simplified()->StringAdd(), Parameter(0), Parameter(1));
174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Reduction reduction = Reduce(node);
175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_FALSE(reduction.Changed());
176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochINSTANTIATE_TEST_CASE_P(ChangeLoweringTest, ChangeLoweringCommonTest,
180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        ::testing::Values(kRepWord32, kRepWord64));
181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// -----------------------------------------------------------------------------
184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 32-bit
185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass ChangeLowering32Test : public ChangeLoweringTest {
188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual ~ChangeLowering32Test() {}
190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual MachineType WordRepresentation() const FINAL OVERRIDE {
191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return kRepWord32;
192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTARGET_TEST_F(ChangeLowering32Test, ChangeInt32ToTagged) {
197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* val = Parameter(0);
198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* node = graph()->NewNode(simplified()->ChangeInt32ToTagged(), val);
199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Reduction reduction = Reduce(node);
200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ASSERT_TRUE(reduction.Changed());
201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* phi = reduction.replacement();
203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Capture<Node*> add, branch, heap_number, if_true;
204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_THAT(
205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      phi,
206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      IsPhi(kMachAnyTagged,
207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            IsFinish(
208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                AllOf(CaptureEq(&heap_number),
209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                      IsAllocateHeapNumber(_, CaptureEq(&if_true))),
210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                IsStore(kMachFloat64, kNoWriteBarrier, CaptureEq(&heap_number),
211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        IsInt32Constant(HeapNumberValueOffset()),
212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        IsChangeInt32ToFloat64(val), CaptureEq(&heap_number),
213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        CaptureEq(&if_true))),
214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            IsProjection(
215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                0, AllOf(CaptureEq(&add), IsInt32AddWithOverflow(val, val))),
216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            IsMerge(AllOf(CaptureEq(&if_true), IsIfTrue(CaptureEq(&branch))),
217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    IsIfFalse(AllOf(CaptureEq(&branch),
218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    IsBranch(IsProjection(1, CaptureEq(&add)),
219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                             graph()->start()))))));
220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTARGET_TEST_F(ChangeLowering32Test, ChangeTaggedToFloat64) {
224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STATIC_ASSERT(kSmiTag == 0);
225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STATIC_ASSERT(kSmiTagSize == 1);
226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* val = Parameter(0);
228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* node = graph()->NewNode(simplified()->ChangeTaggedToFloat64(), val);
229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Reduction reduction = Reduce(node);
230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ASSERT_TRUE(reduction.Changed());
231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* phi = reduction.replacement();
233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Capture<Node*> branch, if_true;
234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_THAT(
235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      phi,
236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      IsPhi(
237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          kMachFloat64,
238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          IsLoad(kMachFloat64, val, IsInt32Constant(HeapNumberValueOffset()),
239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                 IsControlEffect(CaptureEq(&if_true))),
240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          IsChangeInt32ToFloat64(
241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              IsWord32Sar(val, IsInt32Constant(SmiShiftAmount()))),
242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          IsMerge(
243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              AllOf(CaptureEq(&if_true),
244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    IsIfTrue(AllOf(
245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        CaptureEq(&branch),
246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        IsBranch(IsWord32And(val, IsInt32Constant(kSmiTagMask)),
247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 graph()->start())))),
248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              IsIfFalse(CaptureEq(&branch)))));
249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTARGET_TEST_F(ChangeLowering32Test, ChangeTaggedToInt32) {
253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STATIC_ASSERT(kSmiTag == 0);
254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STATIC_ASSERT(kSmiTagSize == 1);
255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* val = Parameter(0);
257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* node = graph()->NewNode(simplified()->ChangeTaggedToInt32(), val);
258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Reduction reduction = Reduce(node);
259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ASSERT_TRUE(reduction.Changed());
260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* phi = reduction.replacement();
262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Capture<Node*> branch, if_true;
263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_THAT(
264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      phi,
265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      IsPhi(kMachInt32,
266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            IsChangeFloat64ToInt32(IsLoad(
267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                kMachFloat64, val, IsInt32Constant(HeapNumberValueOffset()),
268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                IsControlEffect(CaptureEq(&if_true)))),
269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            IsWord32Sar(val, IsInt32Constant(SmiShiftAmount())),
270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            IsMerge(AllOf(CaptureEq(&if_true), IsIfTrue(CaptureEq(&branch))),
271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    IsIfFalse(AllOf(
272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        CaptureEq(&branch),
273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        IsBranch(IsWord32And(val, IsInt32Constant(kSmiTagMask)),
274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 graph()->start()))))));
275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTARGET_TEST_F(ChangeLowering32Test, ChangeTaggedToUint32) {
279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STATIC_ASSERT(kSmiTag == 0);
280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STATIC_ASSERT(kSmiTagSize == 1);
281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* val = Parameter(0);
283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* node = graph()->NewNode(simplified()->ChangeTaggedToUint32(), val);
284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Reduction reduction = Reduce(node);
285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ASSERT_TRUE(reduction.Changed());
286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* phi = reduction.replacement();
288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Capture<Node*> branch, if_true;
289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_THAT(
290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      phi,
291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      IsPhi(kMachUint32,
292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            IsChangeFloat64ToUint32(IsLoad(
293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                kMachFloat64, val, IsInt32Constant(HeapNumberValueOffset()),
294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                IsControlEffect(CaptureEq(&if_true)))),
295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            IsWord32Sar(val, IsInt32Constant(SmiShiftAmount())),
296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            IsMerge(AllOf(CaptureEq(&if_true), IsIfTrue(CaptureEq(&branch))),
297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    IsIfFalse(AllOf(
298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        CaptureEq(&branch),
299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        IsBranch(IsWord32And(val, IsInt32Constant(kSmiTagMask)),
300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 graph()->start()))))));
301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTARGET_TEST_F(ChangeLowering32Test, ChangeUint32ToTagged) {
305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STATIC_ASSERT(kSmiTag == 0);
306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STATIC_ASSERT(kSmiTagSize == 1);
307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* val = Parameter(0);
309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* node = graph()->NewNode(simplified()->ChangeUint32ToTagged(), val);
310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Reduction reduction = Reduce(node);
311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ASSERT_TRUE(reduction.Changed());
312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* phi = reduction.replacement();
314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Capture<Node*> branch, heap_number, if_false;
315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_THAT(
316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      phi,
317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      IsPhi(
318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          kMachAnyTagged, IsWord32Shl(val, IsInt32Constant(SmiShiftAmount())),
319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          IsFinish(
320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              AllOf(CaptureEq(&heap_number),
321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    IsAllocateHeapNumber(_, CaptureEq(&if_false))),
322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              IsStore(kMachFloat64, kNoWriteBarrier, CaptureEq(&heap_number),
323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                      IsInt32Constant(HeapNumberValueOffset()),
324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                      IsChangeUint32ToFloat64(val), CaptureEq(&heap_number),
325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                      CaptureEq(&if_false))),
326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          IsMerge(
327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              IsIfTrue(AllOf(CaptureEq(&branch),
328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                             IsBranch(IsUint32LessThanOrEqual(
329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                          val, IsInt32Constant(SmiMaxValue())),
330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                      graph()->start()))),
331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              AllOf(CaptureEq(&if_false), IsIfFalse(CaptureEq(&branch))))));
332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// -----------------------------------------------------------------------------
336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 64-bit
337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass ChangeLowering64Test : public ChangeLoweringTest {
340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual ~ChangeLowering64Test() {}
342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual MachineType WordRepresentation() const FINAL OVERRIDE {
343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return kRepWord64;
344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTARGET_TEST_F(ChangeLowering64Test, ChangeInt32ToTagged) {
349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* val = Parameter(0);
350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* node = graph()->NewNode(simplified()->ChangeInt32ToTagged(), val);
351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Reduction reduction = Reduce(node);
352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ASSERT_TRUE(reduction.Changed());
353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_THAT(reduction.replacement(),
355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              IsWord64Shl(IsChangeInt32ToInt64(val),
356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          IsInt32Constant(SmiShiftAmount())));
357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTARGET_TEST_F(ChangeLowering64Test, ChangeTaggedToFloat64) {
361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STATIC_ASSERT(kSmiTag == 0);
362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STATIC_ASSERT(kSmiTagSize == 1);
363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* val = Parameter(0);
365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* node = graph()->NewNode(simplified()->ChangeTaggedToFloat64(), val);
366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Reduction reduction = Reduce(node);
367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ASSERT_TRUE(reduction.Changed());
368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* phi = reduction.replacement();
370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Capture<Node*> branch, if_true;
371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_THAT(
372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      phi,
373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      IsPhi(
374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          kMachFloat64,
375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          IsLoad(kMachFloat64, val, IsInt32Constant(HeapNumberValueOffset()),
376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                 IsControlEffect(CaptureEq(&if_true))),
377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          IsChangeInt32ToFloat64(IsTruncateInt64ToInt32(
378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              IsWord64Sar(val, IsInt32Constant(SmiShiftAmount())))),
379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          IsMerge(
380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              AllOf(CaptureEq(&if_true),
381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    IsIfTrue(AllOf(
382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        CaptureEq(&branch),
383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        IsBranch(IsWord64And(val, IsInt32Constant(kSmiTagMask)),
384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 graph()->start())))),
385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              IsIfFalse(CaptureEq(&branch)))));
386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTARGET_TEST_F(ChangeLowering64Test, ChangeTaggedToInt32) {
390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STATIC_ASSERT(kSmiTag == 0);
391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STATIC_ASSERT(kSmiTagSize == 1);
392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* val = Parameter(0);
394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* node = graph()->NewNode(simplified()->ChangeTaggedToInt32(), val);
395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Reduction reduction = Reduce(node);
396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ASSERT_TRUE(reduction.Changed());
397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* phi = reduction.replacement();
399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Capture<Node*> branch, if_true;
400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_THAT(
401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      phi,
402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      IsPhi(kMachInt32,
403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            IsChangeFloat64ToInt32(IsLoad(
404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                kMachFloat64, val, IsInt32Constant(HeapNumberValueOffset()),
405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                IsControlEffect(CaptureEq(&if_true)))),
406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            IsTruncateInt64ToInt32(
407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                IsWord64Sar(val, IsInt32Constant(SmiShiftAmount()))),
408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            IsMerge(AllOf(CaptureEq(&if_true), IsIfTrue(CaptureEq(&branch))),
409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    IsIfFalse(AllOf(
410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        CaptureEq(&branch),
411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        IsBranch(IsWord64And(val, IsInt32Constant(kSmiTagMask)),
412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 graph()->start()))))));
413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTARGET_TEST_F(ChangeLowering64Test, ChangeTaggedToUint32) {
417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STATIC_ASSERT(kSmiTag == 0);
418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STATIC_ASSERT(kSmiTagSize == 1);
419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* val = Parameter(0);
421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* node = graph()->NewNode(simplified()->ChangeTaggedToUint32(), val);
422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Reduction reduction = Reduce(node);
423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ASSERT_TRUE(reduction.Changed());
424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* phi = reduction.replacement();
426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Capture<Node*> branch, if_true;
427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_THAT(
428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      phi,
429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      IsPhi(kMachUint32,
430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            IsChangeFloat64ToUint32(IsLoad(
431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                kMachFloat64, val, IsInt32Constant(HeapNumberValueOffset()),
432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                IsControlEffect(CaptureEq(&if_true)))),
433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            IsTruncateInt64ToInt32(
434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                IsWord64Sar(val, IsInt32Constant(SmiShiftAmount()))),
435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            IsMerge(AllOf(CaptureEq(&if_true), IsIfTrue(CaptureEq(&branch))),
436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    IsIfFalse(AllOf(
437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        CaptureEq(&branch),
438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        IsBranch(IsWord64And(val, IsInt32Constant(kSmiTagMask)),
439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 graph()->start()))))));
440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTARGET_TEST_F(ChangeLowering64Test, ChangeUint32ToTagged) {
444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STATIC_ASSERT(kSmiTag == 0);
445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STATIC_ASSERT(kSmiTagSize == 1);
446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* val = Parameter(0);
448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* node = graph()->NewNode(simplified()->ChangeUint32ToTagged(), val);
449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Reduction reduction = Reduce(node);
450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ASSERT_TRUE(reduction.Changed());
451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* phi = reduction.replacement();
453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Capture<Node*> branch, heap_number, if_false;
454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_THAT(
455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      phi,
456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      IsPhi(
457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          kMachAnyTagged, IsWord64Shl(IsChangeUint32ToUint64(val),
458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                      IsInt32Constant(SmiShiftAmount())),
459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          IsFinish(
460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              AllOf(CaptureEq(&heap_number),
461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    IsAllocateHeapNumber(_, CaptureEq(&if_false))),
462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              IsStore(kMachFloat64, kNoWriteBarrier, CaptureEq(&heap_number),
463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                      IsInt32Constant(HeapNumberValueOffset()),
464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                      IsChangeUint32ToFloat64(val), CaptureEq(&heap_number),
465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                      CaptureEq(&if_false))),
466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          IsMerge(
467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              IsIfTrue(AllOf(CaptureEq(&branch),
468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                             IsBranch(IsUint32LessThanOrEqual(
469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                          val, IsInt32Constant(SmiMaxValue())),
470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                      graph()->start()))),
471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              AllOf(CaptureEq(&if_false), IsIfFalse(CaptureEq(&branch))))));
472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace compiler
475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace internal
476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace v8
477