ssa_test.cc revision 4833f5a1990c76bc2be89504225fb13cca22bedf
1c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray/*
2c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray * Copyright (C) 2014 The Android Open Source Project
3c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray *
4c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray * Licensed under the Apache License, Version 2.0 (the "License");
5c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray * you may not use this file except in compliance with the License.
6c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray * You may obtain a copy of the License at
7c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray *
8c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray *      http://www.apache.org/licenses/LICENSE-2.0
9c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray *
10c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray * Unless required by applicable law or agreed to in writing, software
11c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray * distributed under the License is distributed on an "AS IS" BASIS,
12c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray * See the License for the specific language governing permissions and
14c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray * limitations under the License.
15c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray */
16c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
17b666f4805c8ae707ea6fd7f6c7f375e0b000dba8Mathieu Chartier#include "base/arena_allocator.h"
18c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray#include "base/stringprintf.h"
19c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray#include "builder.h"
20c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray#include "dex_file.h"
21c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray#include "dex_instruction.h"
22c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray#include "nodes.h"
23c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray#include "optimizing_unit_test.h"
24c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray#include "pretty_printer.h"
25c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray#include "ssa_builder.h"
26c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
27c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray#include "gtest/gtest.h"
28c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
29c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffraynamespace art {
30c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
314833f5a1990c76bc2be89504225fb13cca22bedfDavid Brazdilclass SsaTest : public CommonCompilerTest {};
324833f5a1990c76bc2be89504225fb13cca22bedfDavid Brazdil
330d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffrayclass SsaPrettyPrinter : public HPrettyPrinter {
34c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray public:
350d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray  explicit SsaPrettyPrinter(HGraph* graph) : HPrettyPrinter(graph), str_("") {}
36c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
372ed20afc6a1032e9e0cf919cb8d1b2b41e147182Alexandre Rames  void PrintInt(int value) OVERRIDE {
38c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    str_ += StringPrintf("%d", value);
39c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  }
40c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
412ed20afc6a1032e9e0cf919cb8d1b2b41e147182Alexandre Rames  void PrintString(const char* value) OVERRIDE {
42c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    str_ += value;
43c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  }
44c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
452ed20afc6a1032e9e0cf919cb8d1b2b41e147182Alexandre Rames  void PrintNewLine() OVERRIDE {
46c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    str_ += '\n';
47c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  }
48c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
49c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  void Clear() { str_.clear(); }
50c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
51c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  std::string str() const { return str_; }
52c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
532ed20afc6a1032e9e0cf919cb8d1b2b41e147182Alexandre Rames  void VisitIntConstant(HIntConstant* constant) OVERRIDE {
54c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    PrintPreInstruction(constant);
55c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    str_ += constant->DebugName();
56c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    str_ += " ";
57c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    PrintInt(constant->GetValue());
58c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    PrintPostInstruction(constant);
59c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  }
60c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
61c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray private:
62c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  std::string str_;
63c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
640d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray  DISALLOW_COPY_AND_ASSIGN(SsaPrettyPrinter);
65c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray};
66c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
67c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffraystatic void ReNumberInstructions(HGraph* graph) {
68c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  int id = 0;
69fa6b93c4b69e6d7ddfa2a4ed0aff01b0608c5a3aVladimir Marko  for (HBasicBlock* block : graph->GetBlocks()) {
70f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    for (HInstructionIterator it(block->GetPhis()); !it.Done(); it.Advance()) {
71c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray      it.Current()->SetId(id++);
72c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    }
73f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    for (HInstructionIterator it(block->GetInstructions()); !it.Done(); it.Advance()) {
74c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray      it.Current()->SetId(id++);
75c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    }
76c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  }
77c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray}
78c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
79c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffraystatic void TestCode(const uint16_t* data, const char* expected) {
80c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  ArenaPool pool;
81c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  ArenaAllocator allocator(&pool);
820a23d74dc2751440822960eab218be4cb8843647Nicolas Geoffray  HGraph* graph = CreateGraph(&allocator);
835e8b137d28c840b128e2488f954cccee3e86db14David Brazdil  HGraphBuilder builder(graph);
84c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  const DexFile::CodeItem* item = reinterpret_cast<const DexFile::CodeItem*>(data);
855e8b137d28c840b128e2488f954cccee3e86db14David Brazdil  bool graph_built = builder.BuildGraph(*item);
865e8b137d28c840b128e2488f954cccee3e86db14David Brazdil  ASSERT_TRUE(graph_built);
870d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray
884833f5a1990c76bc2be89504225fb13cca22bedfDavid Brazdil  TransformToSsa(graph);
89fbc695f9b8e2084697e19c1355ab925f99f0d235Nicolas Geoffray  // Suspend checks implementation may change in the future, and this test relies
90fbc695f9b8e2084697e19c1355ab925f99f0d235Nicolas Geoffray  // on how instructions are ordered.
91fbc695f9b8e2084697e19c1355ab925f99f0d235Nicolas Geoffray  RemoveSuspendChecks(graph);
92c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  ReNumberInstructions(graph);
93c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
94184d640d2a3ac86d871dab58386a50cc9bb973f9Nicolas Geoffray  // Test that phis had their type set.
95fa6b93c4b69e6d7ddfa2a4ed0aff01b0608c5a3aVladimir Marko  for (HBasicBlock* block : graph->GetBlocks()) {
96fa6b93c4b69e6d7ddfa2a4ed0aff01b0608c5a3aVladimir Marko    for (HInstructionIterator it(block->GetPhis()); !it.Done(); it.Advance()) {
97184d640d2a3ac86d871dab58386a50cc9bb973f9Nicolas Geoffray      ASSERT_NE(it.Current()->GetType(), Primitive::kPrimVoid);
98184d640d2a3ac86d871dab58386a50cc9bb973f9Nicolas Geoffray    }
99184d640d2a3ac86d871dab58386a50cc9bb973f9Nicolas Geoffray  }
100184d640d2a3ac86d871dab58386a50cc9bb973f9Nicolas Geoffray
1010d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray  SsaPrettyPrinter printer(graph);
102c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  printer.VisitInsertionOrder();
103c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
104c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  ASSERT_STREQ(expected, printer.str().c_str());
105c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray}
106c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
1074833f5a1990c76bc2be89504225fb13cca22bedfDavid BrazdilTEST_F(SsaTest, CFG1) {
108c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  // Test that we get rid of loads and stores.
109c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  const char* expected =
110c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 0, succ: 1\n"
111c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  0: IntConstant 0 [2, 2]\n"
112c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  1: Goto\n"
113ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray    "BasicBlock 1, pred: 0, succ: 5, 2\n"
114c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  2: Equal(0, 0) [3]\n"
115c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  3: If(2)\n"
116c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 2, pred: 1, succ: 3\n"
117c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  4: Goto\n"
1188b20f88b0a8d1b374dd5eaae289d19734c77b8f8Nicolas Geoffray    "BasicBlock 3, pred: 5, 2, succ: 4\n"
119c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  5: ReturnVoid\n"
120c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 4, pred: 3\n"
121622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray    "  6: Exit\n"
122622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray    // Synthesized block to avoid critical edge.
123622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray    "BasicBlock 5, pred: 1, succ: 3\n"
124622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray    "  7: Goto\n";
125c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
126c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
127c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::CONST_4 | 0 | 0,
128c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::IF_EQ, 3,
129c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::GOTO | 0x100,
130c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::RETURN_VOID);
131c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
132c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  TestCode(data, expected);
133c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray}
134c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
1354833f5a1990c76bc2be89504225fb13cca22bedfDavid BrazdilTEST_F(SsaTest, CFG2) {
136c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  // Test that we create a phi for the join block of an if control flow instruction
137c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  // when there is only code in the else branch.
138c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  const char* expected =
139c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 0, succ: 1\n"
140c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  0: IntConstant 0 [6, 3, 3]\n"
141c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  1: IntConstant 4 [6]\n"
142c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  2: Goto\n"
143ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray    "BasicBlock 1, pred: 0, succ: 5, 2\n"
144c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  3: Equal(0, 0) [4]\n"
145c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  4: If(3)\n"
146c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 2, pred: 1, succ: 3\n"
147c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  5: Goto\n"
1488b20f88b0a8d1b374dd5eaae289d19734c77b8f8Nicolas Geoffray    "BasicBlock 3, pred: 5, 2, succ: 4\n"
1498b20f88b0a8d1b374dd5eaae289d19734c77b8f8Nicolas Geoffray    "  6: Phi(0, 1) [7]\n"
150c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  7: Return(6)\n"
151c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 4, pred: 3\n"
152622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray    "  8: Exit\n"
153622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray    // Synthesized block to avoid critical edge.
154622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray    "BasicBlock 5, pred: 1, succ: 3\n"
155622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray    "  9: Goto\n";
156c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
157c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
158c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::CONST_4 | 0 | 0,
159c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::IF_EQ, 3,
160c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::CONST_4 | 4 << 12 | 0,
161c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::RETURN | 0 << 8);
162c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
163c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  TestCode(data, expected);
164c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray}
165c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
1664833f5a1990c76bc2be89504225fb13cca22bedfDavid BrazdilTEST_F(SsaTest, CFG3) {
167c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  // Test that we create a phi for the join block of an if control flow instruction
168804d09372cc3d80d537da1489da4a45e0e19aa5dNicolas Geoffray  // when both branches update a local.
169c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  const char* expected =
170c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 0, succ: 1\n"
171c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  0: IntConstant 0 [4, 4]\n"
172c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  1: IntConstant 4 [8]\n"
173c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  2: IntConstant 5 [8]\n"
174c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  3: Goto\n"
175c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 1, pred: 0, succ: 3, 2\n"
176c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  4: Equal(0, 0) [5]\n"
177c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  5: If(4)\n"
178c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 2, pred: 1, succ: 4\n"
179c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  6: Goto\n"
180c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 3, pred: 1, succ: 4\n"
181c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  7: Goto\n"
182c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 4, pred: 2, 3, succ: 5\n"
183c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  8: Phi(1, 2) [9]\n"
184c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  9: Return(8)\n"
185c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 5, pred: 4\n"
186c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  10: Exit\n";
187c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
188c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
189c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::CONST_4 | 0 | 0,
190c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::IF_EQ, 4,
191c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::CONST_4 | 4 << 12 | 0,
192c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::GOTO | 0x200,
193c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::CONST_4 | 5 << 12 | 0,
194c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::RETURN | 0 << 8);
195c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
196c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  TestCode(data, expected);
197c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray}
198c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
1994833f5a1990c76bc2be89504225fb13cca22bedfDavid BrazdilTEST_F(SsaTest, Loop1) {
200c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  // Test that we create a phi for an initialized local at entry of a loop.
201c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  const char* expected =
202c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 0, succ: 1\n"
203a3c00e54f9b711bf3fc55ce5e7d4f8765e2ea9faNicolas Geoffray    "  0: IntConstant 0 [6, 3, 3]\n"
204a3c00e54f9b711bf3fc55ce5e7d4f8765e2ea9faNicolas Geoffray    "  1: IntConstant 4 [6]\n"
205a3c00e54f9b711bf3fc55ce5e7d4f8765e2ea9faNicolas Geoffray    "  2: Goto\n"
206a3c00e54f9b711bf3fc55ce5e7d4f8765e2ea9faNicolas Geoffray    "BasicBlock 1, pred: 0, succ: 4, 2\n"
207a3c00e54f9b711bf3fc55ce5e7d4f8765e2ea9faNicolas Geoffray    "  3: Equal(0, 0) [4]\n"
208a3c00e54f9b711bf3fc55ce5e7d4f8765e2ea9faNicolas Geoffray    "  4: If(3)\n"
209a3c00e54f9b711bf3fc55ce5e7d4f8765e2ea9faNicolas Geoffray    "BasicBlock 2, pred: 1, succ: 3\n"
210c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  5: Goto\n"
211a3c00e54f9b711bf3fc55ce5e7d4f8765e2ea9faNicolas Geoffray    "BasicBlock 3, pred: 2, 4, succ: 5\n"
212a3c00e54f9b711bf3fc55ce5e7d4f8765e2ea9faNicolas Geoffray    "  6: Phi(1, 0) [9]\n"
213c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  7: Goto\n"
214a3c00e54f9b711bf3fc55ce5e7d4f8765e2ea9faNicolas Geoffray    "BasicBlock 4, pred: 1, succ: 3\n"
215622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray    "  8: Goto\n"
216a3c00e54f9b711bf3fc55ce5e7d4f8765e2ea9faNicolas Geoffray    "BasicBlock 5, pred: 3, succ: 6\n"
217a3c00e54f9b711bf3fc55ce5e7d4f8765e2ea9faNicolas Geoffray    "  9: Return(6)\n"
218a3c00e54f9b711bf3fc55ce5e7d4f8765e2ea9faNicolas Geoffray    "BasicBlock 6, pred: 5\n"
219a3c00e54f9b711bf3fc55ce5e7d4f8765e2ea9faNicolas Geoffray    "  10: Exit\n";
220c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
221c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
222c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::CONST_4 | 0 | 0,
223a3c00e54f9b711bf3fc55ce5e7d4f8765e2ea9faNicolas Geoffray    Instruction::IF_EQ, 4,
224a3c00e54f9b711bf3fc55ce5e7d4f8765e2ea9faNicolas Geoffray    Instruction::CONST_4 | 4 << 12 | 0,
225a3c00e54f9b711bf3fc55ce5e7d4f8765e2ea9faNicolas Geoffray    Instruction::GOTO | 0x200,
226a3c00e54f9b711bf3fc55ce5e7d4f8765e2ea9faNicolas Geoffray    Instruction::GOTO | 0xFF00,
227a3c00e54f9b711bf3fc55ce5e7d4f8765e2ea9faNicolas Geoffray    Instruction::RETURN | 0 << 8);
228c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
229c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  TestCode(data, expected);
230c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray}
231c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
2324833f5a1990c76bc2be89504225fb13cca22bedfDavid BrazdilTEST_F(SsaTest, Loop2) {
233c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  // Simple loop with one preheader and one back edge.
234c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  const char* expected =
235c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 0, succ: 1\n"
236c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  0: IntConstant 0 [4]\n"
237c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  1: IntConstant 4 [4]\n"
238c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  2: Goto\n"
239c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 1, pred: 0, succ: 2\n"
240c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  3: Goto\n"
241c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 2, pred: 1, 3, succ: 4, 3\n"
242c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  4: Phi(0, 1) [5, 5]\n"
243c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  5: Equal(4, 4) [6]\n"
244c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  6: If(5)\n"
245c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 3, pred: 2, succ: 2\n"
246c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  7: Goto\n"
247c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 4, pred: 2, succ: 5\n"
248c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  8: ReturnVoid\n"
249c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 5, pred: 4\n"
250c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  9: Exit\n";
251c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
252c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
253c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::CONST_4 | 0 | 0,
254c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::IF_EQ, 4,
255c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::CONST_4 | 4 << 12 | 0,
256c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::GOTO | 0xFD00,
257c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::RETURN_VOID);
258c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
259c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  TestCode(data, expected);
260c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray}
261c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
2624833f5a1990c76bc2be89504225fb13cca22bedfDavid BrazdilTEST_F(SsaTest, Loop3) {
263c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  // Test that a local not yet defined at the entry of a loop is handled properly.
264c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  const char* expected =
265c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 0, succ: 1\n"
266c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  0: IntConstant 0 [5]\n"
267c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  1: IntConstant 4 [5]\n"
268c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  2: IntConstant 5 [9]\n"
269c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  3: Goto\n"
270c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 1, pred: 0, succ: 2\n"
271c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  4: Goto\n"
272c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 2, pred: 1, 3, succ: 4, 3\n"
273c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  5: Phi(0, 1) [6, 6]\n"
274c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  6: Equal(5, 5) [7]\n"
275c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  7: If(6)\n"
276c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 3, pred: 2, succ: 2\n"
277c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  8: Goto\n"
278c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 4, pred: 2, succ: 5\n"
279c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  9: Return(2)\n"
280c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 5, pred: 4\n"
281c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  10: Exit\n";
282c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
283c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  const uint16_t data[] = TWO_REGISTERS_CODE_ITEM(
284c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::CONST_4 | 0 | 0,
285c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::IF_EQ, 4,
286c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::CONST_4 | 4 << 12 | 0,
287c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::GOTO | 0xFD00,
288c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::CONST_4 | 5 << 12 | 1 << 8,
289c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::RETURN | 1 << 8);
290c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
291c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  TestCode(data, expected);
292c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray}
293c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
2944833f5a1990c76bc2be89504225fb13cca22bedfDavid BrazdilTEST_F(SsaTest, Loop4) {
295c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  // Make sure we support a preheader of a loop not being the first predecessor
296c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  // in the predecessor list of the header.
297c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  const char* expected =
298c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 0, succ: 1\n"
299c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  0: IntConstant 0 [4]\n"
300c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  1: IntConstant 4 [4]\n"
301c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  2: Goto\n"
302c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 1, pred: 0, succ: 4\n"
303c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  3: Goto\n"
304c83d441a722f0afb510c9cd0e69e09d65652143cNicolas Geoffray    "BasicBlock 2, pred: 4, 3, succ: 5, 3\n"
305c83d441a722f0afb510c9cd0e69e09d65652143cNicolas Geoffray    "  4: Phi(0, 1) [9, 5, 5]\n"
306c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  5: Equal(4, 4) [6]\n"
307c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  6: If(5)\n"
308c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 3, pred: 2, succ: 2\n"
309c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  7: Goto\n"
310c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 4, pred: 1, succ: 2\n"
311c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  8: Goto\n"
312c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 5, pred: 2, succ: 6\n"
313c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  9: Return(4)\n"
314c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 6, pred: 5\n"
315c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  10: Exit\n";
316c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
317c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
318c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::CONST_4 | 0 | 0,
319c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::GOTO | 0x500,
320c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::IF_EQ, 5,
321c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::CONST_4 | 4 << 12 | 0,
322c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::GOTO | 0xFD00,
323c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::GOTO | 0xFC00,
324c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::RETURN | 0 << 8);
325c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
326c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  TestCode(data, expected);
327c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray}
328c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
3294833f5a1990c76bc2be89504225fb13cca22bedfDavid BrazdilTEST_F(SsaTest, Loop5) {
330c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  // Make sure we create a preheader of a loop when a header originally has two
331c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  // incoming blocks and one back edge.
332c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  const char* expected =
333c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 0, succ: 1\n"
334c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  0: IntConstant 0 [4, 4]\n"
3353afca781086699e60a8941fb9474d4607c5909cbNicolas Geoffray    "  1: IntConstant 4 [13]\n"
3363afca781086699e60a8941fb9474d4607c5909cbNicolas Geoffray    "  2: IntConstant 5 [13]\n"
337c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  3: Goto\n"
338c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 1, pred: 0, succ: 3, 2\n"
339c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  4: Equal(0, 0) [5]\n"
340c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  5: If(4)\n"
341c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 2, pred: 1, succ: 8\n"
342c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  6: Goto\n"
343c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 3, pred: 1, succ: 8\n"
344c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  7: Goto\n"
345c83d441a722f0afb510c9cd0e69e09d65652143cNicolas Geoffray    "BasicBlock 4, pred: 8, 5, succ: 6, 5\n"
3463afca781086699e60a8941fb9474d4607c5909cbNicolas Geoffray    "  8: Equal(13, 13) [9]\n"
3473afca781086699e60a8941fb9474d4607c5909cbNicolas Geoffray    "  9: If(8)\n"
348c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 5, pred: 4, succ: 4\n"
3493afca781086699e60a8941fb9474d4607c5909cbNicolas Geoffray    "  10: Goto\n"
350c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 6, pred: 4, succ: 7\n"
3513afca781086699e60a8941fb9474d4607c5909cbNicolas Geoffray    "  11: Return(13)\n"
352c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 7, pred: 6\n"
3533afca781086699e60a8941fb9474d4607c5909cbNicolas Geoffray    "  12: Exit\n"
354c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 8, pred: 2, 3, succ: 4\n"
3553afca781086699e60a8941fb9474d4607c5909cbNicolas Geoffray    "  13: Phi(1, 2) [8, 8, 11]\n"
3563afca781086699e60a8941fb9474d4607c5909cbNicolas Geoffray    "  14: Goto\n";
357c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
358c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
359c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::CONST_4 | 0 | 0,
360c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::IF_EQ, 4,
361c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::CONST_4 | 4 << 12 | 0,
362c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::GOTO | 0x200,
363c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::CONST_4 | 5 << 12 | 0,
364c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::IF_EQ, 3,
365c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::GOTO | 0xFE00,
366c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::RETURN | 0 << 8);
367c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
368c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  TestCode(data, expected);
369c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray}
370c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
3714833f5a1990c76bc2be89504225fb13cca22bedfDavid BrazdilTEST_F(SsaTest, Loop6) {
372c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  // Test a loop with one preheader and two back edges (e.g. continue).
373c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  const char* expected =
374c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 0, succ: 1\n"
375c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  0: IntConstant 0 [5]\n"
376db216f4d49ea1561a74261c29f1264952232728aNicolas Geoffray    "  1: IntConstant 4 [5, 8, 8]\n"
377db216f4d49ea1561a74261c29f1264952232728aNicolas Geoffray    "  2: IntConstant 5 [5]\n"
378c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  3: Goto\n"
379c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 1, pred: 0, succ: 2\n"
380c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  4: Goto\n"
381db216f4d49ea1561a74261c29f1264952232728aNicolas Geoffray    "BasicBlock 2, pred: 1, 4, 5, succ: 6, 3\n"
382db216f4d49ea1561a74261c29f1264952232728aNicolas Geoffray    "  5: Phi(0, 2, 1) [12, 6, 6]\n"
383c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  6: Equal(5, 5) [7]\n"
384c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  7: If(6)\n"
385c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 3, pred: 2, succ: 5, 4\n"
386c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  8: Equal(1, 1) [9]\n"
387c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  9: If(8)\n"
388db216f4d49ea1561a74261c29f1264952232728aNicolas Geoffray    "BasicBlock 4, pred: 3, succ: 2\n"
389c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  10: Goto\n"
390db216f4d49ea1561a74261c29f1264952232728aNicolas Geoffray    "BasicBlock 5, pred: 3, succ: 2\n"
391c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  11: Goto\n"
392c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 6, pred: 2, succ: 7\n"
393c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  12: Return(5)\n"
394c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 7, pred: 6\n"
395db216f4d49ea1561a74261c29f1264952232728aNicolas Geoffray    "  13: Exit\n";
396c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
397c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
398c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::CONST_4 | 0 | 0,
399c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::IF_EQ, 8,
400c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::CONST_4 | 4 << 12 | 0,
401c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::IF_EQ, 4,
402c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::CONST_4 | 5 << 12 | 0,
403c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::GOTO | 0xFA00,
404c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::GOTO | 0xF900,
405c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::RETURN | 0 << 8);
406c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
407c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  TestCode(data, expected);
408c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray}
409c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
4104833f5a1990c76bc2be89504225fb13cca22bedfDavid BrazdilTEST_F(SsaTest, Loop7) {
411c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  // Test a loop with one preheader, one back edge, and two exit edges (e.g. break).
412c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  const char* expected =
413c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 0, succ: 1\n"
414c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  0: IntConstant 0 [5]\n"
415c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  1: IntConstant 4 [5, 8, 8]\n"
416c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  2: IntConstant 5 [12]\n"
417c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  3: Goto\n"
418c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 1, pred: 0, succ: 2\n"
419c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  4: Goto\n"
420ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray    "BasicBlock 2, pred: 1, 5, succ: 8, 3\n"
421c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  5: Phi(0, 1) [12, 6, 6]\n"
422c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  6: Equal(5, 5) [7]\n"
423c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  7: If(6)\n"
424c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 3, pred: 2, succ: 5, 4\n"
425c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  8: Equal(1, 1) [9]\n"
426c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  9: If(8)\n"
427c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 4, pred: 3, succ: 6\n"
428c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  10: Goto\n"
429c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 5, pred: 3, succ: 2\n"
430c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  11: Goto\n"
4318b20f88b0a8d1b374dd5eaae289d19734c77b8f8Nicolas Geoffray    "BasicBlock 6, pred: 8, 4, succ: 7\n"
4328b20f88b0a8d1b374dd5eaae289d19734c77b8f8Nicolas Geoffray    "  12: Phi(5, 2) [13]\n"
433c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  13: Return(12)\n"
434c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 7, pred: 6\n"
435622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray    "  14: Exit\n"
436622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray    "BasicBlock 8, pred: 2, succ: 6\n"
437622d9c31febd950255b36a48b47e1f630197c5feNicolas Geoffray    "  15: Goto\n";
438c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
439c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
440c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::CONST_4 | 0 | 0,
441c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::IF_EQ, 8,
442c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::CONST_4 | 4 << 12 | 0,
443c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::IF_EQ, 4,
444c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::CONST_4 | 5 << 12 | 0,
445c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::GOTO | 0x0200,
446c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::GOTO | 0xF900,
447c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::RETURN | 0 << 8);
448c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
449c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  TestCode(data, expected);
450c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray}
451c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
4524833f5a1990c76bc2be89504225fb13cca22bedfDavid BrazdilTEST_F(SsaTest, DeadLocal) {
453c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  // Test that we correctly handle a local not being used.
454c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  const char* expected =
455c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 0, succ: 1\n"
456c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  0: IntConstant 0\n"
457c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  1: Goto\n"
458c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 1, pred: 0, succ: 2\n"
459c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  2: ReturnVoid\n"
460c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "BasicBlock 2, pred: 1\n"
461c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    "  3: Exit\n";
462c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
463c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
464c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::CONST_4 | 0 | 0,
465c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray    Instruction::RETURN_VOID);
466c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
467c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray  TestCode(data, expected);
468c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray}
469c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray
4704833f5a1990c76bc2be89504225fb13cca22bedfDavid BrazdilTEST_F(SsaTest, LocalInIf) {
4717c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray  // Test that we do not create a phi in the join block when one predecessor
4727c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray  // does not update the local.
4737c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray  const char* expected =
4747c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray    "BasicBlock 0, succ: 1\n"
4757c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray    "  0: IntConstant 0 [3, 3]\n"
4767c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray    "  1: IntConstant 4\n"
4777c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray    "  2: Goto\n"
478ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray    "BasicBlock 1, pred: 0, succ: 5, 2\n"
4797c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray    "  3: Equal(0, 0) [4]\n"
4807c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray    "  4: If(3)\n"
4817c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray    "BasicBlock 2, pred: 1, succ: 3\n"
4827c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray    "  5: Goto\n"
4838b20f88b0a8d1b374dd5eaae289d19734c77b8f8Nicolas Geoffray    "BasicBlock 3, pred: 5, 2, succ: 4\n"
4847c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray    "  6: ReturnVoid\n"
4857c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray    "BasicBlock 4, pred: 3\n"
4867c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray    "  7: Exit\n"
4877c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray    // Synthesized block to avoid critical edge.
4887c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray    "BasicBlock 5, pred: 1, succ: 3\n"
4897c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray    "  8: Goto\n";
4907c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray
4917c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray  const uint16_t data[] = TWO_REGISTERS_CODE_ITEM(
4927c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray    Instruction::CONST_4 | 0 | 0,
4937c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray    Instruction::IF_EQ, 3,
4947c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray    Instruction::CONST_4 | 4 << 12 | 1 << 8,
4957c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray    Instruction::RETURN_VOID);
4967c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray
4977c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray  TestCode(data, expected);
4987c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray}
4997c3560f2ce0ec9484004d05a94bfaa6e02f5a96aNicolas Geoffray
5004833f5a1990c76bc2be89504225fb13cca22bedfDavid BrazdilTEST_F(SsaTest, MultiplePredecessors) {
501ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray  // Test that we do not create a phi when one predecessor
502ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray  // does not update the local.
503ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray  const char* expected =
504ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray    "BasicBlock 0, succ: 1\n"
505ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray    "  0: IntConstant 0 [4, 8, 6, 6, 2, 2, 8, 4]\n"
506ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray    "  1: Goto\n"
507ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray    "BasicBlock 1, pred: 0, succ: 3, 2\n"
508ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray    "  2: Equal(0, 0) [3]\n"
509ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray    "  3: If(2)\n"
510ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray    "BasicBlock 2, pred: 1, succ: 5\n"
511ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray    "  4: Add(0, 0)\n"
512ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray    "  5: Goto\n"
513ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray    "BasicBlock 3, pred: 1, succ: 7, 4\n"
514ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray    "  6: Equal(0, 0) [7]\n"
515ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray    "  7: If(6)\n"
516ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray    "BasicBlock 4, pred: 3, succ: 5\n"
517ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray    "  8: Add(0, 0)\n"
518ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray    "  9: Goto\n"
519ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray    // This block should not get a phi for local 1.
5208b20f88b0a8d1b374dd5eaae289d19734c77b8f8Nicolas Geoffray    "BasicBlock 5, pred: 2, 7, 4, succ: 6\n"
521ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray    "  10: ReturnVoid\n"
522ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray    "BasicBlock 6, pred: 5\n"
523ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray    "  11: Exit\n"
524ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray    "BasicBlock 7, pred: 3, succ: 5\n"
525ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray    "  12: Goto\n";
526ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray
527ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray  const uint16_t data[] = TWO_REGISTERS_CODE_ITEM(
528ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray    Instruction::CONST_4 | 0 | 0,
529ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray    Instruction::IF_EQ, 5,
530ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray    Instruction::ADD_INT_LIT8 | 1 << 8, 0 << 8,
531ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray    Instruction::GOTO | 0x0500,
532ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray    Instruction::IF_EQ, 4,
533ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray    Instruction::ADD_INT_LIT8 | 1 << 8, 0 << 8,
534ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray    Instruction::RETURN_VOID);
535ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray
536ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray  TestCode(data, expected);
537ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray}
538ec7e4727e99aa1416398ac5a684f5024817a25c7Nicolas Geoffray
539c32e770f21540e4e9eda6dc7f770e745d33f1b9fNicolas Geoffray}  // namespace art
540