1556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain/* 2556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * Copyright (C) 2014 The Android Open Source Project 3556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * 4556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * Licensed under the Apache License, Version 2.0 (the "License"); 5556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * you may not use this file except in compliance with the License. 6556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * You may obtain a copy of the License at 7556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * 8556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * http://www.apache.org/licenses/LICENSE-2.0 9556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * 10556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * Unless required by applicable law or agreed to in writing, software 11556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * distributed under the License is distributed on an "AS IS" BASIS, 12556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * See the License for the specific language governing permissions and 14556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * limitations under the License. 15556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain */ 16556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 1793445689c714e53cabf347da4321ecf3023e926cRoland Levillain#include <functional> 1893445689c714e53cabf347da4321ecf3023e926cRoland Levillain 19fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell#include "arch/x86/instruction_set_features_x86.h" 2075be28332b278cff9039b54bfb228ac72f539cccRoland Levillain#include "code_generator_x86.h" 2175be28332b278cff9039b54bfb228ac72f539cccRoland Levillain#include "constant_folding.h" 22556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain#include "dead_code_elimination.h" 23cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle#include "driver/compiler_options.h" 24556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain#include "graph_checker.h" 25556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain#include "optimizing_unit_test.h" 2675be28332b278cff9039b54bfb228ac72f539cccRoland Levillain#include "pretty_printer.h" 27556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 28556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain#include "gtest/gtest.h" 29556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 30556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillainnamespace art { 31556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 3296709f17347cb7a6aae15816244d2200ca95a649Aart Bik/** 3396709f17347cb7a6aae15816244d2200ca95a649Aart Bik * Fixture class for the constant folding and dce tests. 3496709f17347cb7a6aae15816244d2200ca95a649Aart Bik */ 354833f5a1990c76bc2be89504225fb13cca22bedfDavid Brazdilclass ConstantFoldingTest : public CommonCompilerTest { 3696709f17347cb7a6aae15816244d2200ca95a649Aart Bik public: 3796709f17347cb7a6aae15816244d2200ca95a649Aart Bik ConstantFoldingTest() : pool_(), allocator_(&pool_) { 3896709f17347cb7a6aae15816244d2200ca95a649Aart Bik graph_ = CreateGraph(&allocator_); 3996709f17347cb7a6aae15816244d2200ca95a649Aart Bik } 4096709f17347cb7a6aae15816244d2200ca95a649Aart Bik 4196709f17347cb7a6aae15816244d2200ca95a649Aart Bik void TestCode(const uint16_t* data, 4296709f17347cb7a6aae15816244d2200ca95a649Aart Bik const std::string& expected_before, 4396709f17347cb7a6aae15816244d2200ca95a649Aart Bik const std::string& expected_after_cf, 4496709f17347cb7a6aae15816244d2200ca95a649Aart Bik const std::string& expected_after_dce, 45ca620d7bc03b23a0bcf0ef58df58603ee000dca0Andreas Gampe const std::function<void(HGraph*)>& check_after_cf, 4696709f17347cb7a6aae15816244d2200ca95a649Aart Bik Primitive::Type return_type = Primitive::kPrimInt) { 4796709f17347cb7a6aae15816244d2200ca95a649Aart Bik graph_ = CreateCFG(&allocator_, data, return_type); 4896709f17347cb7a6aae15816244d2200ca95a649Aart Bik TestCodeOnReadyGraph(expected_before, 4996709f17347cb7a6aae15816244d2200ca95a649Aart Bik expected_after_cf, 5096709f17347cb7a6aae15816244d2200ca95a649Aart Bik expected_after_dce, 5196709f17347cb7a6aae15816244d2200ca95a649Aart Bik check_after_cf); 5296709f17347cb7a6aae15816244d2200ca95a649Aart Bik } 5396709f17347cb7a6aae15816244d2200ca95a649Aart Bik 5496709f17347cb7a6aae15816244d2200ca95a649Aart Bik void TestCodeOnReadyGraph(const std::string& expected_before, 5596709f17347cb7a6aae15816244d2200ca95a649Aart Bik const std::string& expected_after_cf, 5696709f17347cb7a6aae15816244d2200ca95a649Aart Bik const std::string& expected_after_dce, 57ca620d7bc03b23a0bcf0ef58df58603ee000dca0Andreas Gampe const std::function<void(HGraph*)>& check_after_cf) { 5896709f17347cb7a6aae15816244d2200ca95a649Aart Bik ASSERT_NE(graph_, nullptr); 5996709f17347cb7a6aae15816244d2200ca95a649Aart Bik 6096709f17347cb7a6aae15816244d2200ca95a649Aart Bik StringPrettyPrinter printer_before(graph_); 6196709f17347cb7a6aae15816244d2200ca95a649Aart Bik printer_before.VisitInsertionOrder(); 6296709f17347cb7a6aae15816244d2200ca95a649Aart Bik std::string actual_before = printer_before.str(); 6396709f17347cb7a6aae15816244d2200ca95a649Aart Bik EXPECT_EQ(expected_before, actual_before); 6496709f17347cb7a6aae15816244d2200ca95a649Aart Bik 6596709f17347cb7a6aae15816244d2200ca95a649Aart Bik std::unique_ptr<const X86InstructionSetFeatures> features_x86( 6696709f17347cb7a6aae15816244d2200ca95a649Aart Bik X86InstructionSetFeatures::FromCppDefines()); 6796709f17347cb7a6aae15816244d2200ca95a649Aart Bik x86::CodeGeneratorX86 codegenX86(graph_, *features_x86.get(), CompilerOptions()); 68ca620d7bc03b23a0bcf0ef58df58603ee000dca0Andreas Gampe HConstantFolding(graph_, "constant_folding").Run(); 69badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil GraphChecker graph_checker_cf(graph_); 70badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil graph_checker_cf.Run(); 71badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil ASSERT_TRUE(graph_checker_cf.IsValid()); 7296709f17347cb7a6aae15816244d2200ca95a649Aart Bik 7396709f17347cb7a6aae15816244d2200ca95a649Aart Bik StringPrettyPrinter printer_after_cf(graph_); 7496709f17347cb7a6aae15816244d2200ca95a649Aart Bik printer_after_cf.VisitInsertionOrder(); 7596709f17347cb7a6aae15816244d2200ca95a649Aart Bik std::string actual_after_cf = printer_after_cf.str(); 7696709f17347cb7a6aae15816244d2200ca95a649Aart Bik EXPECT_EQ(expected_after_cf, actual_after_cf); 7796709f17347cb7a6aae15816244d2200ca95a649Aart Bik 7896709f17347cb7a6aae15816244d2200ca95a649Aart Bik check_after_cf(graph_); 7996709f17347cb7a6aae15816244d2200ca95a649Aart Bik 80ca620d7bc03b23a0bcf0ef58df58603ee000dca0Andreas Gampe HDeadCodeElimination(graph_, nullptr /* stats */, "dead_code_elimination").Run(); 81badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil GraphChecker graph_checker_dce(graph_); 82badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil graph_checker_dce.Run(); 83badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil ASSERT_TRUE(graph_checker_dce.IsValid()); 8496709f17347cb7a6aae15816244d2200ca95a649Aart Bik 8596709f17347cb7a6aae15816244d2200ca95a649Aart Bik StringPrettyPrinter printer_after_dce(graph_); 8696709f17347cb7a6aae15816244d2200ca95a649Aart Bik printer_after_dce.VisitInsertionOrder(); 8796709f17347cb7a6aae15816244d2200ca95a649Aart Bik std::string actual_after_dce = printer_after_dce.str(); 8896709f17347cb7a6aae15816244d2200ca95a649Aart Bik EXPECT_EQ(expected_after_dce, actual_after_dce); 8996709f17347cb7a6aae15816244d2200ca95a649Aart Bik } 9096709f17347cb7a6aae15816244d2200ca95a649Aart Bik 9196709f17347cb7a6aae15816244d2200ca95a649Aart Bik ArenaPool pool_; 9296709f17347cb7a6aae15816244d2200ca95a649Aart Bik ArenaAllocator allocator_; 9396709f17347cb7a6aae15816244d2200ca95a649Aart Bik HGraph* graph_; 9496709f17347cb7a6aae15816244d2200ca95a649Aart Bik}; 95556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 96556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain/** 979240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain * Tiny three-register program exercising int constant folding on negation. 989240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain * 999240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain * 16-bit 1009240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain * offset 1019240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain * ------ 1029240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain * v0 <- 1 0. const/4 v0, #+1 103c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain * v1 <- -v0 1. neg-int v1, v0 1049240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain * return v1 2. return v1 1059240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain */ 10696709f17347cb7a6aae15816244d2200ca95a649Aart BikTEST_F(ConstantFoldingTest, IntConstantFoldingNegation) { 1079240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain const uint16_t data[] = TWO_REGISTERS_CODE_ITEM( 1089240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain Instruction::CONST_4 | 0 << 8 | 1 << 12, 1099240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain Instruction::NEG_INT | 1 << 8 | 0 << 12, 1109240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain Instruction::RETURN | 1 << 8); 1119240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain 1129240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain std::string expected_before = 1139240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain "BasicBlock 0, succ: 1\n" 114dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 2: IntConstant [3]\n" 115dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 0: SuspendCheck\n" 116dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 1: Goto 1\n" 1179240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain "BasicBlock 1, pred: 0, succ: 2\n" 118dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 3: Neg(2) [4]\n" 119dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 4: Return(3)\n" 1209240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain "BasicBlock 2, pred: 1\n" 121dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 5: Exit\n"; 1229240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain 1239240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain // Expected difference after constant folding. 1249240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain diff_t expected_cf_diff = { 125dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 2: IntConstant [3]\n", " 2: IntConstant\n" 126dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 6: IntConstant [4]\n" }, 127dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 3: Neg(2) [4]\n", removed }, 128dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 4: Return(3)\n", " 4: Return(6)\n" } 1299240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain }; 1309240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain std::string expected_after_cf = Patch(expected_before, expected_cf_diff); 1319240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain 1329240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain // Check the value of the computed constant. 1339240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain auto check_after_cf = [](HGraph* graph) { 134ec7802a102d49ab5c17495118d4fe0bcc7287bebVladimir Marko HInstruction* inst = graph->GetBlocks()[1]->GetFirstInstruction()->InputAt(0); 1359240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain ASSERT_TRUE(inst->IsIntConstant()); 1369240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain ASSERT_EQ(inst->AsIntConstant()->GetValue(), -1); 1379240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain }; 1389240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain 1399240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain // Expected difference after dead code elimination. 1409240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain diff_t expected_dce_diff = { 141dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 2: IntConstant\n", removed }, 1429240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain }; 1439240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain std::string expected_after_dce = Patch(expected_after_cf, expected_dce_diff); 1449240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain 1459240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain TestCode(data, 1469240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain expected_before, 1479240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain expected_after_cf, 1489240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain expected_after_dce, 1499240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain check_after_cf); 1509240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain} 1519240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain 1529240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain/** 153c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain * Tiny three-register program exercising long constant folding on negation. 154c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain * 155c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain * 16-bit 156c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain * offset 157c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain * ------ 158c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain * (v0, v1) <- 4294967296 0. const-wide v0 #+4294967296 159c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain * (v2, v3) <- -(v0, v1) 1. neg-long v2, v0 160c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain * return (v2, v3) 2. return-wide v2 161c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain */ 16296709f17347cb7a6aae15816244d2200ca95a649Aart BikTEST_F(ConstantFoldingTest, LongConstantFoldingNegation) { 163c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain const int64_t input = INT64_C(4294967296); // 2^32 164c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain const uint16_t word0 = Low16Bits(Low32Bits(input)); // LSW. 165c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain const uint16_t word1 = High16Bits(Low32Bits(input)); 166c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain const uint16_t word2 = Low16Bits(High32Bits(input)); 167c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain const uint16_t word3 = High16Bits(High32Bits(input)); // MSW. 168c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain const uint16_t data[] = FOUR_REGISTERS_CODE_ITEM( 169c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain Instruction::CONST_WIDE | 0 << 8, word0, word1, word2, word3, 170c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain Instruction::NEG_LONG | 2 << 8 | 0 << 12, 171c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain Instruction::RETURN_WIDE | 2 << 8); 172c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain 173c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain std::string expected_before = 174c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain "BasicBlock 0, succ: 1\n" 175dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 2: LongConstant [3]\n" 176dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 0: SuspendCheck\n" 177dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 1: Goto 1\n" 178c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain "BasicBlock 1, pred: 0, succ: 2\n" 179dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 3: Neg(2) [4]\n" 180dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 4: Return(3)\n" 181c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain "BasicBlock 2, pred: 1\n" 182dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 5: Exit\n"; 183c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain 184c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain // Expected difference after constant folding. 185c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain diff_t expected_cf_diff = { 186dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 2: LongConstant [3]\n", " 2: LongConstant\n" 187dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 6: LongConstant [4]\n" }, 188dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 3: Neg(2) [4]\n", removed }, 189dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 4: Return(3)\n", " 4: Return(6)\n" } 190c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain }; 191c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain std::string expected_after_cf = Patch(expected_before, expected_cf_diff); 192c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain 193c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain // Check the value of the computed constant. 194c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain auto check_after_cf = [](HGraph* graph) { 195ec7802a102d49ab5c17495118d4fe0bcc7287bebVladimir Marko HInstruction* inst = graph->GetBlocks()[1]->GetFirstInstruction()->InputAt(0); 196c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain ASSERT_TRUE(inst->IsLongConstant()); 197c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain ASSERT_EQ(inst->AsLongConstant()->GetValue(), INT64_C(-4294967296)); 198c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain }; 199c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain 200c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain // Expected difference after dead code elimination. 201c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain diff_t expected_dce_diff = { 202dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 2: LongConstant\n", removed }, 203c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain }; 204c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain std::string expected_after_dce = Patch(expected_after_cf, expected_dce_diff); 205c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain 206c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain TestCode(data, 207c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain expected_before, 208c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain expected_after_cf, 209c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain expected_after_dce, 210c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain check_after_cf, 211c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain Primitive::kPrimLong); 212c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain} 213c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain 214c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain/** 215556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * Tiny three-register program exercising int constant folding on addition. 216556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * 217556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * 16-bit 218556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * offset 219556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * ------ 220556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * v0 <- 1 0. const/4 v0, #+1 221556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * v1 <- 2 1. const/4 v1, #+2 222556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * v2 <- v0 + v1 2. add-int v2, v0, v1 223556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * return v2 4. return v2 224556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain */ 22596709f17347cb7a6aae15816244d2200ca95a649Aart BikTEST_F(ConstantFoldingTest, IntConstantFoldingOnAddition1) { 226556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain const uint16_t data[] = THREE_REGISTERS_CODE_ITEM( 227556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::CONST_4 | 0 << 8 | 1 << 12, 228556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::CONST_4 | 1 << 8 | 2 << 12, 229556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::ADD_INT | 2 << 8, 0 | 1 << 8, 230556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::RETURN | 2 << 8); 231556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 232556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain std::string expected_before = 23386ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil "BasicBlock 0, succ: 1\n" 234dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 2: IntConstant [4]\n" 235dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 3: IntConstant [4]\n" 236dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 0: SuspendCheck\n" 237dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 1: Goto 1\n" 23886ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil "BasicBlock 1, pred: 0, succ: 2\n" 239dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 4: Add(2, 3) [5]\n" 240dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 5: Return(4)\n" 24186ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil "BasicBlock 2, pred: 1\n" 242dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 6: Exit\n"; 243556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 24475be28332b278cff9039b54bfb228ac72f539cccRoland Levillain // Expected difference after constant folding. 24575be28332b278cff9039b54bfb228ac72f539cccRoland Levillain diff_t expected_cf_diff = { 246dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 2: IntConstant [4]\n", " 2: IntConstant\n" }, 247dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 3: IntConstant [4]\n", " 3: IntConstant\n" 248dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 7: IntConstant [5]\n" }, 249dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 4: Add(2, 3) [5]\n", removed }, 250dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 5: Return(4)\n", " 5: Return(7)\n" } 251556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain }; 25275be28332b278cff9039b54bfb228ac72f539cccRoland Levillain std::string expected_after_cf = Patch(expected_before, expected_cf_diff); 253556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 25493445689c714e53cabf347da4321ecf3023e926cRoland Levillain // Check the value of the computed constant. 25575be28332b278cff9039b54bfb228ac72f539cccRoland Levillain auto check_after_cf = [](HGraph* graph) { 256ec7802a102d49ab5c17495118d4fe0bcc7287bebVladimir Marko HInstruction* inst = graph->GetBlocks()[1]->GetFirstInstruction()->InputAt(0); 25793445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_TRUE(inst->IsIntConstant()); 25893445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_EQ(inst->AsIntConstant()->GetValue(), 3); 25993445689c714e53cabf347da4321ecf3023e926cRoland Levillain }; 26093445689c714e53cabf347da4321ecf3023e926cRoland Levillain 261556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain // Expected difference after dead code elimination. 262556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain diff_t expected_dce_diff = { 263dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 2: IntConstant\n", removed }, 264dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 3: IntConstant\n", removed } 265556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain }; 26675be28332b278cff9039b54bfb228ac72f539cccRoland Levillain std::string expected_after_dce = Patch(expected_after_cf, expected_dce_diff); 267556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 26893445689c714e53cabf347da4321ecf3023e926cRoland Levillain TestCode(data, 26993445689c714e53cabf347da4321ecf3023e926cRoland Levillain expected_before, 27075be28332b278cff9039b54bfb228ac72f539cccRoland Levillain expected_after_cf, 27193445689c714e53cabf347da4321ecf3023e926cRoland Levillain expected_after_dce, 27275be28332b278cff9039b54bfb228ac72f539cccRoland Levillain check_after_cf); 273556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain} 274556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 275556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain/** 276556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * Small three-register program exercising int constant folding on addition. 277556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * 278556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * 16-bit 279556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * offset 280556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * ------ 281556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * v0 <- 1 0. const/4 v0, #+1 282556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * v1 <- 2 1. const/4 v1, #+2 283556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * v0 <- v0 + v1 2. add-int/2addr v0, v1 2848d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil * v1 <- 4 3. const/4 v1, #+4 2858d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil * v2 <- 5 4. const/4 v2, #+5 286556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * v1 <- v1 + v2 5. add-int/2addr v1, v2 287556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * v2 <- v0 + v1 6. add-int v2, v0, v1 288556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * return v2 8. return v2 289556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain */ 29096709f17347cb7a6aae15816244d2200ca95a649Aart BikTEST_F(ConstantFoldingTest, IntConstantFoldingOnAddition2) { 291556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain const uint16_t data[] = THREE_REGISTERS_CODE_ITEM( 292556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::CONST_4 | 0 << 8 | 1 << 12, 293556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::CONST_4 | 1 << 8 | 2 << 12, 294556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::ADD_INT_2ADDR | 0 << 8 | 1 << 12, 2958d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil Instruction::CONST_4 | 1 << 8 | 4 << 12, 2968d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil Instruction::CONST_4 | 2 << 8 | 5 << 12, 297556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::ADD_INT_2ADDR | 1 << 8 | 2 << 12, 298556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::ADD_INT | 2 << 8, 0 | 1 << 8, 299556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::RETURN | 2 << 8); 300556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 301556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain std::string expected_before = 30286ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil "BasicBlock 0, succ: 1\n" 303dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 2: IntConstant [4]\n" 304dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 3: IntConstant [4]\n" 305dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 5: IntConstant [7]\n" 306dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 6: IntConstant [7]\n" 307dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 0: SuspendCheck\n" 308dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 1: Goto 1\n" 30986ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil "BasicBlock 1, pred: 0, succ: 2\n" 310dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 4: Add(2, 3) [8]\n" 311dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 7: Add(5, 6) [8]\n" 312dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 8: Add(4, 7) [9]\n" 313dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 9: Return(8)\n" 31486ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil "BasicBlock 2, pred: 1\n" 315dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 10: Exit\n"; 316556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 31775be28332b278cff9039b54bfb228ac72f539cccRoland Levillain // Expected difference after constant folding. 31875be28332b278cff9039b54bfb228ac72f539cccRoland Levillain diff_t expected_cf_diff = { 319dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 2: IntConstant [4]\n", " 2: IntConstant\n" }, 320dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 3: IntConstant [4]\n", " 3: IntConstant\n" }, 321dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 5: IntConstant [7]\n", " 5: IntConstant\n" }, 322dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 6: IntConstant [7]\n", " 6: IntConstant\n" 323dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 11: IntConstant\n" 324dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 12: IntConstant\n" 325dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 13: IntConstant [9]\n" }, 326dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 4: Add(2, 3) [8]\n", removed }, 327dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 7: Add(5, 6) [8]\n", removed }, 328dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 8: Add(4, 7) [9]\n", removed }, 329dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 9: Return(8)\n", " 9: Return(13)\n" } 330556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain }; 33175be28332b278cff9039b54bfb228ac72f539cccRoland Levillain std::string expected_after_cf = Patch(expected_before, expected_cf_diff); 332556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 33393445689c714e53cabf347da4321ecf3023e926cRoland Levillain // Check the values of the computed constants. 33475be28332b278cff9039b54bfb228ac72f539cccRoland Levillain auto check_after_cf = [](HGraph* graph) { 335ec7802a102d49ab5c17495118d4fe0bcc7287bebVladimir Marko HInstruction* inst1 = graph->GetBlocks()[1]->GetFirstInstruction()->InputAt(0); 33693445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_TRUE(inst1->IsIntConstant()); 3378d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil ASSERT_EQ(inst1->AsIntConstant()->GetValue(), 12); 3388d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil HInstruction* inst2 = inst1->GetPrevious(); 33993445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_TRUE(inst2->IsIntConstant()); 3408d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil ASSERT_EQ(inst2->AsIntConstant()->GetValue(), 9); 3418d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil HInstruction* inst3 = inst2->GetPrevious(); 34293445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_TRUE(inst3->IsIntConstant()); 3438d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil ASSERT_EQ(inst3->AsIntConstant()->GetValue(), 3); 34493445689c714e53cabf347da4321ecf3023e926cRoland Levillain }; 34593445689c714e53cabf347da4321ecf3023e926cRoland Levillain 346556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain // Expected difference after dead code elimination. 347556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain diff_t expected_dce_diff = { 348dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 2: IntConstant\n", removed }, 349dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 3: IntConstant\n", removed }, 350556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 5: IntConstant\n", removed }, 351dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 6: IntConstant\n", removed }, 352dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 11: IntConstant\n", removed }, 353dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 12: IntConstant\n", removed } 354556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain }; 35575be28332b278cff9039b54bfb228ac72f539cccRoland Levillain std::string expected_after_dce = Patch(expected_after_cf, expected_dce_diff); 356556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 35793445689c714e53cabf347da4321ecf3023e926cRoland Levillain TestCode(data, 35893445689c714e53cabf347da4321ecf3023e926cRoland Levillain expected_before, 35975be28332b278cff9039b54bfb228ac72f539cccRoland Levillain expected_after_cf, 36093445689c714e53cabf347da4321ecf3023e926cRoland Levillain expected_after_dce, 36175be28332b278cff9039b54bfb228ac72f539cccRoland Levillain check_after_cf); 362556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain} 363556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 364556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain/** 365556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * Tiny three-register program exercising int constant folding on subtraction. 366556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * 367556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * 16-bit 368556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * offset 369556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * ------ 370556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * v0 <- 3 0. const/4 v0, #+3 371556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * v1 <- 2 1. const/4 v1, #+2 372556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * v2 <- v0 - v1 2. sub-int v2, v0, v1 373556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * return v2 4. return v2 374556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain */ 37596709f17347cb7a6aae15816244d2200ca95a649Aart BikTEST_F(ConstantFoldingTest, IntConstantFoldingOnSubtraction) { 376556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain const uint16_t data[] = THREE_REGISTERS_CODE_ITEM( 377556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::CONST_4 | 0 << 8 | 3 << 12, 378556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::CONST_4 | 1 << 8 | 2 << 12, 379556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::SUB_INT | 2 << 8, 0 | 1 << 8, 380556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::RETURN | 2 << 8); 381556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 382556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain std::string expected_before = 38386ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil "BasicBlock 0, succ: 1\n" 384dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 2: IntConstant [4]\n" 385dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 3: IntConstant [4]\n" 386dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 0: SuspendCheck\n" 387dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 1: Goto 1\n" 38886ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil "BasicBlock 1, pred: 0, succ: 2\n" 389dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 4: Sub(2, 3) [5]\n" 390dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 5: Return(4)\n" 39186ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil "BasicBlock 2, pred: 1\n" 392dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 6: Exit\n"; 393556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 39475be28332b278cff9039b54bfb228ac72f539cccRoland Levillain // Expected difference after constant folding. 39575be28332b278cff9039b54bfb228ac72f539cccRoland Levillain diff_t expected_cf_diff = { 396dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 2: IntConstant [4]\n", " 2: IntConstant\n" }, 397dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 3: IntConstant [4]\n", " 3: IntConstant\n" 398dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 7: IntConstant [5]\n" }, 399dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 4: Sub(2, 3) [5]\n", removed }, 400dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 5: Return(4)\n", " 5: Return(7)\n" } 401556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain }; 40275be28332b278cff9039b54bfb228ac72f539cccRoland Levillain std::string expected_after_cf = Patch(expected_before, expected_cf_diff); 403556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 40493445689c714e53cabf347da4321ecf3023e926cRoland Levillain // Check the value of the computed constant. 40575be28332b278cff9039b54bfb228ac72f539cccRoland Levillain auto check_after_cf = [](HGraph* graph) { 406ec7802a102d49ab5c17495118d4fe0bcc7287bebVladimir Marko HInstruction* inst = graph->GetBlocks()[1]->GetFirstInstruction()->InputAt(0); 40793445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_TRUE(inst->IsIntConstant()); 40893445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_EQ(inst->AsIntConstant()->GetValue(), 1); 40993445689c714e53cabf347da4321ecf3023e926cRoland Levillain }; 41093445689c714e53cabf347da4321ecf3023e926cRoland Levillain 411556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain // Expected difference after dead code elimination. 412556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain diff_t expected_dce_diff = { 413dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 2: IntConstant\n", removed }, 414dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 3: IntConstant\n", removed } 415556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain }; 41675be28332b278cff9039b54bfb228ac72f539cccRoland Levillain std::string expected_after_dce = Patch(expected_after_cf, expected_dce_diff); 417556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 41893445689c714e53cabf347da4321ecf3023e926cRoland Levillain TestCode(data, 41993445689c714e53cabf347da4321ecf3023e926cRoland Levillain expected_before, 42075be28332b278cff9039b54bfb228ac72f539cccRoland Levillain expected_after_cf, 42193445689c714e53cabf347da4321ecf3023e926cRoland Levillain expected_after_dce, 42275be28332b278cff9039b54bfb228ac72f539cccRoland Levillain check_after_cf); 423556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain} 424556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 425556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain/** 426556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * Tiny three-register-pair program exercising long constant folding 427556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * on addition. 428556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * 429556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * 16-bit 430556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * offset 431556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * ------ 432556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * (v0, v1) <- 1 0. const-wide/16 v0, #+1 433556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * (v2, v3) <- 2 2. const-wide/16 v2, #+2 434556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * (v4, v5) <- 435556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * (v0, v1) + (v1, v2) 4. add-long v4, v0, v2 436556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * return (v4, v5) 6. return-wide v4 437556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain */ 43896709f17347cb7a6aae15816244d2200ca95a649Aart BikTEST_F(ConstantFoldingTest, LongConstantFoldingOnAddition) { 439556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain const uint16_t data[] = SIX_REGISTERS_CODE_ITEM( 440556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::CONST_WIDE_16 | 0 << 8, 1, 441556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::CONST_WIDE_16 | 2 << 8, 2, 442556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::ADD_LONG | 4 << 8, 0 | 2 << 8, 443556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::RETURN_WIDE | 4 << 8); 444556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 445556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain std::string expected_before = 44686ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil "BasicBlock 0, succ: 1\n" 447dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 2: LongConstant [4]\n" 448dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 3: LongConstant [4]\n" 449dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 0: SuspendCheck\n" 450dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 1: Goto 1\n" 45186ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil "BasicBlock 1, pred: 0, succ: 2\n" 452dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 4: Add(2, 3) [5]\n" 453dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 5: Return(4)\n" 45486ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil "BasicBlock 2, pred: 1\n" 455dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 6: Exit\n"; 456556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 45775be28332b278cff9039b54bfb228ac72f539cccRoland Levillain // Expected difference after constant folding. 45875be28332b278cff9039b54bfb228ac72f539cccRoland Levillain diff_t expected_cf_diff = { 459dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 2: LongConstant [4]\n", " 2: LongConstant\n" }, 460dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 3: LongConstant [4]\n", " 3: LongConstant\n" 461dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 7: LongConstant [5]\n" }, 462dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 4: Add(2, 3) [5]\n", removed }, 463dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 5: Return(4)\n", " 5: Return(7)\n" } 464556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain }; 46575be28332b278cff9039b54bfb228ac72f539cccRoland Levillain std::string expected_after_cf = Patch(expected_before, expected_cf_diff); 466556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 46793445689c714e53cabf347da4321ecf3023e926cRoland Levillain // Check the value of the computed constant. 46875be28332b278cff9039b54bfb228ac72f539cccRoland Levillain auto check_after_cf = [](HGraph* graph) { 469ec7802a102d49ab5c17495118d4fe0bcc7287bebVladimir Marko HInstruction* inst = graph->GetBlocks()[1]->GetFirstInstruction()->InputAt(0); 47093445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_TRUE(inst->IsLongConstant()); 47193445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_EQ(inst->AsLongConstant()->GetValue(), 3); 47293445689c714e53cabf347da4321ecf3023e926cRoland Levillain }; 47393445689c714e53cabf347da4321ecf3023e926cRoland Levillain 474556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain // Expected difference after dead code elimination. 475556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain diff_t expected_dce_diff = { 476dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 2: LongConstant\n", removed }, 477dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 3: LongConstant\n", removed } 478556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain }; 47975be28332b278cff9039b54bfb228ac72f539cccRoland Levillain std::string expected_after_dce = Patch(expected_after_cf, expected_dce_diff); 480556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 48193445689c714e53cabf347da4321ecf3023e926cRoland Levillain TestCode(data, 48293445689c714e53cabf347da4321ecf3023e926cRoland Levillain expected_before, 48375be28332b278cff9039b54bfb228ac72f539cccRoland Levillain expected_after_cf, 48493445689c714e53cabf347da4321ecf3023e926cRoland Levillain expected_after_dce, 48575be28332b278cff9039b54bfb228ac72f539cccRoland Levillain check_after_cf, 48693445689c714e53cabf347da4321ecf3023e926cRoland Levillain Primitive::kPrimLong); 487556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain} 488556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 489556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain/** 490556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * Tiny three-register-pair program exercising long constant folding 491556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * on subtraction. 492556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * 493556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * 16-bit 494556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * offset 495556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * ------ 496556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * (v0, v1) <- 3 0. const-wide/16 v0, #+3 497556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * (v2, v3) <- 2 2. const-wide/16 v2, #+2 498556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * (v4, v5) <- 499556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * (v0, v1) - (v1, v2) 4. sub-long v4, v0, v2 500556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * return (v4, v5) 6. return-wide v4 501556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain */ 50296709f17347cb7a6aae15816244d2200ca95a649Aart BikTEST_F(ConstantFoldingTest, LongConstantFoldingOnSubtraction) { 503556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain const uint16_t data[] = SIX_REGISTERS_CODE_ITEM( 504556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::CONST_WIDE_16 | 0 << 8, 3, 505556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::CONST_WIDE_16 | 2 << 8, 2, 506556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::SUB_LONG | 4 << 8, 0 | 2 << 8, 507556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::RETURN_WIDE | 4 << 8); 508556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 509556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain std::string expected_before = 51086ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil "BasicBlock 0, succ: 1\n" 511dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 2: LongConstant [4]\n" 512dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 3: LongConstant [4]\n" 513dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 0: SuspendCheck\n" 514dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 1: Goto 1\n" 51586ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil "BasicBlock 1, pred: 0, succ: 2\n" 516dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 4: Sub(2, 3) [5]\n" 517dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 5: Return(4)\n" 51886ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil "BasicBlock 2, pred: 1\n" 519dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 6: Exit\n"; 520556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 52175be28332b278cff9039b54bfb228ac72f539cccRoland Levillain // Expected difference after constant folding. 52275be28332b278cff9039b54bfb228ac72f539cccRoland Levillain diff_t expected_cf_diff = { 523dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 2: LongConstant [4]\n", " 2: LongConstant\n" }, 524dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 3: LongConstant [4]\n", " 3: LongConstant\n" 525dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 7: LongConstant [5]\n" }, 526dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 4: Sub(2, 3) [5]\n", removed }, 527dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 5: Return(4)\n", " 5: Return(7)\n" } 528556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain }; 52975be28332b278cff9039b54bfb228ac72f539cccRoland Levillain std::string expected_after_cf = Patch(expected_before, expected_cf_diff); 530556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 53193445689c714e53cabf347da4321ecf3023e926cRoland Levillain // Check the value of the computed constant. 53275be28332b278cff9039b54bfb228ac72f539cccRoland Levillain auto check_after_cf = [](HGraph* graph) { 533ec7802a102d49ab5c17495118d4fe0bcc7287bebVladimir Marko HInstruction* inst = graph->GetBlocks()[1]->GetFirstInstruction()->InputAt(0); 53493445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_TRUE(inst->IsLongConstant()); 53593445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_EQ(inst->AsLongConstant()->GetValue(), 1); 53693445689c714e53cabf347da4321ecf3023e926cRoland Levillain }; 53793445689c714e53cabf347da4321ecf3023e926cRoland Levillain 538556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain // Expected difference after dead code elimination. 539556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain diff_t expected_dce_diff = { 540dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 2: LongConstant\n", removed }, 541dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 3: LongConstant\n", removed } 542556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain }; 54375be28332b278cff9039b54bfb228ac72f539cccRoland Levillain std::string expected_after_dce = Patch(expected_after_cf, expected_dce_diff); 544556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 54593445689c714e53cabf347da4321ecf3023e926cRoland Levillain TestCode(data, 54693445689c714e53cabf347da4321ecf3023e926cRoland Levillain expected_before, 54775be28332b278cff9039b54bfb228ac72f539cccRoland Levillain expected_after_cf, 54893445689c714e53cabf347da4321ecf3023e926cRoland Levillain expected_after_dce, 54975be28332b278cff9039b54bfb228ac72f539cccRoland Levillain check_after_cf, 55093445689c714e53cabf347da4321ecf3023e926cRoland Levillain Primitive::kPrimLong); 551556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain} 552556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 553556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain/** 554556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * Three-register program with jumps leading to the creation of many 555556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * blocks. 556556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * 557556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * The intent of this test is to ensure that all constant expressions 558556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * are actually evaluated at compile-time, thanks to the reverse 559556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * (forward) post-order traversal of the the dominator tree. 560556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * 561556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * 16-bit 562556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * offset 563556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * ------ 5648d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil * v0 <- 1 0. const/4 v0, #+1 5658d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil * v1 <- 2 1. const/4 v1, #+2 566556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * v2 <- v0 + v1 2. add-int v2, v0, v1 567556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * goto L2 4. goto +4 5688d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil * L1: v1 <- v0 + 5 5. add-int/lit16 v1, v0, #+5 569556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * goto L3 7. goto +4 5708d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil * L2: v0 <- v2 + 4 8. add-int/lit16 v0, v2, #+4 571556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * goto L1 10. goto +(-5) 5728d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil * L3: v2 <- v1 + 8 11. add-int/lit16 v2, v1, #+8 573556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * return v2 13. return v2 574556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain */ 57596709f17347cb7a6aae15816244d2200ca95a649Aart BikTEST_F(ConstantFoldingTest, IntConstantFoldingAndJumps) { 576556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain const uint16_t data[] = THREE_REGISTERS_CODE_ITEM( 5778d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil Instruction::CONST_4 | 0 << 8 | 1 << 12, 5788d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil Instruction::CONST_4 | 1 << 8 | 2 << 12, 579556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::ADD_INT | 2 << 8, 0 | 1 << 8, 580556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::GOTO | 4 << 8, 5818d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil Instruction::ADD_INT_LIT16 | 1 << 8 | 0 << 12, 5, 582556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::GOTO | 4 << 8, 5838d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil Instruction::ADD_INT_LIT16 | 0 << 8 | 2 << 12, 4, 58458554b7de4b437ddef7ff550e62c8ec0b16f9264Andreas Gampe static_cast<uint16_t>(Instruction::GOTO | 0xFFFFFFFB << 8), 5858d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil Instruction::ADD_INT_LIT16 | 2 << 8 | 1 << 12, 8, 586556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::RETURN | 2 << 8); 587556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 588556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain std::string expected_before = 58986ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil "BasicBlock 0, succ: 1\n" 590dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 2: IntConstant [4]\n" // v0 <- 1 591dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 3: IntConstant [4]\n" // v1 <- 2 592dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 6: IntConstant [7]\n" // const 5 593dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 9: IntConstant [10]\n" // const 4 594dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 12: IntConstant [13]\n" // const 8 595dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 0: SuspendCheck\n" 596dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 1: Goto 1\n" 59786ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil "BasicBlock 1, pred: 0, succ: 3\n" 598dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 4: Add(2, 3) [7]\n" // v2 <- v0 + v1 = 1 + 2 = 3 599dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 5: Goto 3\n" // goto L2 60086ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil "BasicBlock 2, pred: 3, succ: 4\n" // L1: 601dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 10: Add(7, 9) [13]\n" // v1 <- v0 + 3 = 7 + 5 = 12 602dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 11: Goto 4\n" // goto L3 60386ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil "BasicBlock 3, pred: 1, succ: 2\n" // L2: 604dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 7: Add(4, 6) [10]\n" // v0 <- v2 + 2 = 3 + 4 = 7 605dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 8: Goto 2\n" // goto L1 60686ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil "BasicBlock 4, pred: 2, succ: 5\n" // L3: 607dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 13: Add(10, 12) [14]\n" // v2 <- v1 + 4 = 12 + 8 = 20 608dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 14: Return(13)\n" // return v2 60986ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil "BasicBlock 5, pred: 4\n" 610dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 15: Exit\n"; 611556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 61275be28332b278cff9039b54bfb228ac72f539cccRoland Levillain // Expected difference after constant folding. 61375be28332b278cff9039b54bfb228ac72f539cccRoland Levillain diff_t expected_cf_diff = { 614dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 2: IntConstant [4]\n", " 2: IntConstant\n" }, 615dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 3: IntConstant [4]\n", " 3: IntConstant\n" }, 616dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 6: IntConstant [7]\n", " 6: IntConstant\n" }, 617dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 9: IntConstant [10]\n", " 9: IntConstant\n" }, 618dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 12: IntConstant [13]\n", " 12: IntConstant\n" 619dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 16: IntConstant\n" 620dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 17: IntConstant\n" 621dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 18: IntConstant\n" 622dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 19: IntConstant [14]\n" }, 623dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 4: Add(2, 3) [7]\n", removed }, 624dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 10: Add(7, 9) [13]\n", removed }, 625dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 7: Add(4, 6) [10]\n", removed }, 626dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 13: Add(10, 12) [14]\n", removed }, 627dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 14: Return(13)\n", " 14: Return(19)\n"} 628556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain }; 62975be28332b278cff9039b54bfb228ac72f539cccRoland Levillain std::string expected_after_cf = Patch(expected_before, expected_cf_diff); 630556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 63193445689c714e53cabf347da4321ecf3023e926cRoland Levillain // Check the values of the computed constants. 63275be28332b278cff9039b54bfb228ac72f539cccRoland Levillain auto check_after_cf = [](HGraph* graph) { 633ec7802a102d49ab5c17495118d4fe0bcc7287bebVladimir Marko HInstruction* inst1 = graph->GetBlocks()[4]->GetFirstInstruction()->InputAt(0); 63493445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_TRUE(inst1->IsIntConstant()); 6358d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil ASSERT_EQ(inst1->AsIntConstant()->GetValue(), 20); 6368d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil HInstruction* inst2 = inst1->GetPrevious(); 63793445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_TRUE(inst2->IsIntConstant()); 6388d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil ASSERT_EQ(inst2->AsIntConstant()->GetValue(), 12); 6398d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil HInstruction* inst3 = inst2->GetPrevious(); 64093445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_TRUE(inst3->IsIntConstant()); 6418d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil ASSERT_EQ(inst3->AsIntConstant()->GetValue(), 7); 6428d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil HInstruction* inst4 = inst3->GetPrevious(); 64393445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_TRUE(inst4->IsIntConstant()); 6448d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil ASSERT_EQ(inst4->AsIntConstant()->GetValue(), 3); 64593445689c714e53cabf347da4321ecf3023e926cRoland Levillain }; 64693445689c714e53cabf347da4321ecf3023e926cRoland Levillain 647556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain // Expected difference after dead code elimination. 6481c533c17baff841e383a539fdd3c0a65135181b0David Brazdil std::string expected_after_dce = 64986ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil "BasicBlock 0, succ: 1\n" 650dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 19: IntConstant [14]\n" 651dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 0: SuspendCheck\n" 652dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 1: Goto 1\n" 65386ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil "BasicBlock 1, pred: 0, succ: 5\n" 654dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 14: Return(19)\n" 65586ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil "BasicBlock 5, pred: 1\n" 656dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 15: Exit\n"; 657556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 65893445689c714e53cabf347da4321ecf3023e926cRoland Levillain TestCode(data, 65993445689c714e53cabf347da4321ecf3023e926cRoland Levillain expected_before, 66075be28332b278cff9039b54bfb228ac72f539cccRoland Levillain expected_after_cf, 66193445689c714e53cabf347da4321ecf3023e926cRoland Levillain expected_after_dce, 66275be28332b278cff9039b54bfb228ac72f539cccRoland Levillain check_after_cf); 663556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain} 664556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 665556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain/** 666556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * Three-register program with a constant (static) condition. 667556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * 668556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * 16-bit 669556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * offset 670556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * ------ 671556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * v1 <- 1 0. const/4 v1, #+1 672556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * v0 <- 0 1. const/4 v0, #+0 673556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * if v1 >= 0 goto L1 2. if-gez v1, +3 674556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * v0 <- v1 4. move v0, v1 675556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * L1: v2 <- v0 + v1 5. add-int v2, v0, v1 676556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * return-void 7. return 677556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain */ 67896709f17347cb7a6aae15816244d2200ca95a649Aart BikTEST_F(ConstantFoldingTest, ConstantCondition) { 679556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain const uint16_t data[] = THREE_REGISTERS_CODE_ITEM( 680556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::CONST_4 | 1 << 8 | 1 << 12, 681556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::CONST_4 | 0 << 8 | 0 << 12, 682556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::IF_GEZ | 1 << 8, 3, 683556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::MOVE | 0 << 8 | 1 << 12, 684556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::ADD_INT | 2 << 8, 0 | 1 << 8, 685556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::RETURN_VOID); 686556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 687556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain std::string expected_before = 688dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil "BasicBlock 0, succ: 1\n" 689dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 3: IntConstant [9, 8, 5]\n" 690dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 4: IntConstant [8, 5]\n" 691dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 1: SuspendCheck\n" 692dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 2: Goto 1\n" 69386ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil "BasicBlock 1, pred: 0, succ: 5, 2\n" 694dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 5: GreaterThanOrEqual(3, 4) [6]\n" 695dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 6: If(5)\n" 69686ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil "BasicBlock 2, pred: 1, succ: 3\n" 697dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 7: Goto 3\n" 69886ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil "BasicBlock 3, pred: 5, 2, succ: 4\n" 699dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 8: Phi(4, 3) [9]\n" 700dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 9: Add(8, 3)\n" 701dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 10: ReturnVoid\n" 70286ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil "BasicBlock 4, pred: 3\n" 703dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 11: Exit\n" 70486ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil "BasicBlock 5, pred: 1, succ: 3\n" 70586ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil " 0: Goto 3\n"; 706556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 70775be28332b278cff9039b54bfb228ac72f539cccRoland Levillain // Expected difference after constant folding. 70875be28332b278cff9039b54bfb228ac72f539cccRoland Levillain diff_t expected_cf_diff = { 709dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 3: IntConstant [9, 8, 5]\n", " 3: IntConstant [6, 9, 8]\n" }, 710dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 4: IntConstant [8, 5]\n", " 4: IntConstant [8]\n" }, 711dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 5: GreaterThanOrEqual(3, 4) [6]\n", removed }, 712dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil { " 6: If(5)\n", " 6: If(3)\n" } 713556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain }; 71475be28332b278cff9039b54bfb228ac72f539cccRoland Levillain std::string expected_after_cf = Patch(expected_before, expected_cf_diff); 715556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 71693445689c714e53cabf347da4321ecf3023e926cRoland Levillain // Check the values of the computed constants. 71775be28332b278cff9039b54bfb228ac72f539cccRoland Levillain auto check_after_cf = [](HGraph* graph) { 718ec7802a102d49ab5c17495118d4fe0bcc7287bebVladimir Marko HInstruction* inst = graph->GetBlocks()[1]->GetFirstInstruction()->InputAt(0); 71993445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_TRUE(inst->IsIntConstant()); 72093445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_EQ(inst->AsIntConstant()->GetValue(), 1); 72193445689c714e53cabf347da4321ecf3023e926cRoland Levillain }; 72293445689c714e53cabf347da4321ecf3023e926cRoland Levillain 7231c533c17baff841e383a539fdd3c0a65135181b0David Brazdil // Expected graph after dead code elimination. 7241c533c17baff841e383a539fdd3c0a65135181b0David Brazdil std::string expected_after_dce = 72586ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil "BasicBlock 0, succ: 1\n" 726dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 1: SuspendCheck\n" 727dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 2: Goto 1\n" 72886ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil "BasicBlock 1, pred: 0, succ: 4\n" 729dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 10: ReturnVoid\n" 73086ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil "BasicBlock 4, pred: 1\n" 731dee58d6bb6d567fcd0c4f39d8d690c3acaf0e432David Brazdil " 11: Exit\n"; 732556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 73393445689c714e53cabf347da4321ecf3023e926cRoland Levillain TestCode(data, 73493445689c714e53cabf347da4321ecf3023e926cRoland Levillain expected_before, 73575be28332b278cff9039b54bfb228ac72f539cccRoland Levillain expected_after_cf, 73693445689c714e53cabf347da4321ecf3023e926cRoland Levillain expected_after_dce, 73775be28332b278cff9039b54bfb228ac72f539cccRoland Levillain check_after_cf); 738556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain} 739556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 74096709f17347cb7a6aae15816244d2200ca95a649Aart Bik/** 74196709f17347cb7a6aae15816244d2200ca95a649Aart Bik * Unsigned comparisons with zero. Since these instructions are not present 74296709f17347cb7a6aae15816244d2200ca95a649Aart Bik * in the bytecode, we need to set up the graph explicitly. 74396709f17347cb7a6aae15816244d2200ca95a649Aart Bik */ 74496709f17347cb7a6aae15816244d2200ca95a649Aart BikTEST_F(ConstantFoldingTest, UnsignedComparisonsWithZero) { 74596709f17347cb7a6aae15816244d2200ca95a649Aart Bik graph_ = CreateGraph(&allocator_); 74696709f17347cb7a6aae15816244d2200ca95a649Aart Bik HBasicBlock* entry_block = new (&allocator_) HBasicBlock(graph_); 74796709f17347cb7a6aae15816244d2200ca95a649Aart Bik graph_->AddBlock(entry_block); 74896709f17347cb7a6aae15816244d2200ca95a649Aart Bik graph_->SetEntryBlock(entry_block); 74996709f17347cb7a6aae15816244d2200ca95a649Aart Bik HBasicBlock* block = new (&allocator_) HBasicBlock(graph_); 75096709f17347cb7a6aae15816244d2200ca95a649Aart Bik graph_->AddBlock(block); 75196709f17347cb7a6aae15816244d2200ca95a649Aart Bik HBasicBlock* exit_block = new (&allocator_) HBasicBlock(graph_); 75296709f17347cb7a6aae15816244d2200ca95a649Aart Bik graph_->AddBlock(exit_block); 75396709f17347cb7a6aae15816244d2200ca95a649Aart Bik graph_->SetExitBlock(exit_block); 75496709f17347cb7a6aae15816244d2200ca95a649Aart Bik entry_block->AddSuccessor(block); 75596709f17347cb7a6aae15816244d2200ca95a649Aart Bik block->AddSuccessor(exit_block); 75696709f17347cb7a6aae15816244d2200ca95a649Aart Bik 75796709f17347cb7a6aae15816244d2200ca95a649Aart Bik // Make various unsigned comparisons with zero against a parameter. 75896709f17347cb7a6aae15816244d2200ca95a649Aart Bik HInstruction* parameter = new (&allocator_) HParameterValue( 759a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe graph_->GetDexFile(), dex::TypeIndex(0), 0, Primitive::kPrimInt, true); 76096709f17347cb7a6aae15816244d2200ca95a649Aart Bik entry_block->AddInstruction(parameter); 76186ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil entry_block->AddInstruction(new (&allocator_) HGoto()); 76286ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil 76396709f17347cb7a6aae15816244d2200ca95a649Aart Bik HInstruction* zero = graph_->GetIntConstant(0); 76486ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil 76596709f17347cb7a6aae15816244d2200ca95a649Aart Bik HInstruction* last; 76696709f17347cb7a6aae15816244d2200ca95a649Aart Bik block->AddInstruction(last = new (&allocator_) HAbove(zero, parameter)); 767badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil block->AddInstruction(new (&allocator_) HSelect(last, parameter, parameter, 0)); 76896709f17347cb7a6aae15816244d2200ca95a649Aart Bik block->AddInstruction(last = new (&allocator_) HAbove(parameter, zero)); 769badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil block->AddInstruction(new (&allocator_) HSelect(last, parameter, parameter, 0)); 77096709f17347cb7a6aae15816244d2200ca95a649Aart Bik block->AddInstruction(last = new (&allocator_) HAboveOrEqual(zero, parameter)); 771badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil block->AddInstruction(new (&allocator_) HSelect(last, parameter, parameter, 0)); 77296709f17347cb7a6aae15816244d2200ca95a649Aart Bik block->AddInstruction(last = new (&allocator_) HAboveOrEqual(parameter, zero)); 773badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil block->AddInstruction(new (&allocator_) HSelect(last, parameter, parameter, 0)); 77496709f17347cb7a6aae15816244d2200ca95a649Aart Bik block->AddInstruction(last = new (&allocator_) HBelow(zero, parameter)); 775badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil block->AddInstruction(new (&allocator_) HSelect(last, parameter, parameter, 0)); 77696709f17347cb7a6aae15816244d2200ca95a649Aart Bik block->AddInstruction(last = new (&allocator_) HBelow(parameter, zero)); 777badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil block->AddInstruction(new (&allocator_) HSelect(last, parameter, parameter, 0)); 77896709f17347cb7a6aae15816244d2200ca95a649Aart Bik block->AddInstruction(last = new (&allocator_) HBelowOrEqual(zero, parameter)); 779badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil block->AddInstruction(new (&allocator_) HSelect(last, parameter, parameter, 0)); 78096709f17347cb7a6aae15816244d2200ca95a649Aart Bik block->AddInstruction(last = new (&allocator_) HBelowOrEqual(parameter, zero)); 781badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil block->AddInstruction(new (&allocator_) HSelect(last, parameter, parameter, 0)); 78296709f17347cb7a6aae15816244d2200ca95a649Aart Bik block->AddInstruction(new (&allocator_) HReturn(zero)); 78386ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil 78496709f17347cb7a6aae15816244d2200ca95a649Aart Bik exit_block->AddInstruction(new (&allocator_) HExit()); 78596709f17347cb7a6aae15816244d2200ca95a649Aart Bik 786badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil graph_->BuildDominatorTree(); 787badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil 78896709f17347cb7a6aae15816244d2200ca95a649Aart Bik const std::string expected_before = 78996709f17347cb7a6aae15816244d2200ca95a649Aart Bik "BasicBlock 0, succ: 1\n" 79086ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil " 0: ParameterValue [18, 18, 17, 16, 16, 15, 14, 14, 13, 12, 12, 11, 10, 10, 9, " 79186ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil "8, 8, 7, 6, 6, 5, 4, 4, 3]\n" 79286ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil " 2: IntConstant [19, 17, 15, 13, 11, 9, 7, 5, 3]\n" 79386ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil " 1: Goto 1\n" 79496709f17347cb7a6aae15816244d2200ca95a649Aart Bik "BasicBlock 1, pred: 0, succ: 2\n" 79586ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil " 3: Above(2, 0) [4]\n" 79686ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil " 4: Select(0, 0, 3)\n" 79786ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil " 5: Above(0, 2) [6]\n" 79886ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil " 6: Select(0, 0, 5)\n" 79986ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil " 7: AboveOrEqual(2, 0) [8]\n" 80086ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil " 8: Select(0, 0, 7)\n" 80186ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil " 9: AboveOrEqual(0, 2) [10]\n" 80286ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil " 10: Select(0, 0, 9)\n" 80386ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil " 11: Below(2, 0) [12]\n" 80486ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil " 12: Select(0, 0, 11)\n" 80586ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil " 13: Below(0, 2) [14]\n" 80686ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil " 14: Select(0, 0, 13)\n" 80786ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil " 15: BelowOrEqual(2, 0) [16]\n" 80886ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil " 16: Select(0, 0, 15)\n" 80986ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil " 17: BelowOrEqual(0, 2) [18]\n" 81086ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil " 18: Select(0, 0, 17)\n" 81186ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil " 19: Return(2)\n" 81296709f17347cb7a6aae15816244d2200ca95a649Aart Bik "BasicBlock 2, pred: 1\n" 81396709f17347cb7a6aae15816244d2200ca95a649Aart Bik " 20: Exit\n"; 81496709f17347cb7a6aae15816244d2200ca95a649Aart Bik 81596709f17347cb7a6aae15816244d2200ca95a649Aart Bik const std::string expected_after_cf = 81696709f17347cb7a6aae15816244d2200ca95a649Aart Bik "BasicBlock 0, succ: 1\n" 81786ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil " 0: ParameterValue [18, 18, 17, 16, 16, 14, 14, 12, 12, 11, 10, 10, " 81886ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil "8, 8, 7, 6, 6, 5, 4, 4]\n" 81986ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil " 2: IntConstant [14, 4, 19, 17, 11, 7, 5]\n" 82086ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil " 21: IntConstant [16, 10]\n" 82186ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil " 1: Goto 1\n" 82296709f17347cb7a6aae15816244d2200ca95a649Aart Bik "BasicBlock 1, pred: 0, succ: 2\n" 82386ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil " 4: Select(0, 0, 2)\n" 82486ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil " 5: Above(0, 2) [6]\n" 82586ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil " 6: Select(0, 0, 5)\n" 82686ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil " 7: AboveOrEqual(2, 0) [8]\n" 82786ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil " 8: Select(0, 0, 7)\n" 82886ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil " 10: Select(0, 0, 21)\n" 82986ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil " 11: Below(2, 0) [12]\n" 83086ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil " 12: Select(0, 0, 11)\n" 83186ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil " 14: Select(0, 0, 2)\n" 83286ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil " 16: Select(0, 0, 21)\n" 83386ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil " 17: BelowOrEqual(0, 2) [18]\n" 83486ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil " 18: Select(0, 0, 17)\n" 83586ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil " 19: Return(2)\n" 83696709f17347cb7a6aae15816244d2200ca95a649Aart Bik "BasicBlock 2, pred: 1\n" 83796709f17347cb7a6aae15816244d2200ca95a649Aart Bik " 20: Exit\n"; 83896709f17347cb7a6aae15816244d2200ca95a649Aart Bik 839badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil const std::string expected_after_dce = 840badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil "BasicBlock 0, succ: 1\n" 841badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil " 0: ParameterValue\n" 84286ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil " 2: IntConstant [19]\n" 84386ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil " 1: Goto 1\n" 844badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil "BasicBlock 1, pred: 0, succ: 2\n" 84586ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil " 19: Return(2)\n" 846badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil "BasicBlock 2, pred: 1\n" 847badd826664896d4a9628a5a89b78016894aa414bDavid Brazdil " 20: Exit\n"; 84896709f17347cb7a6aae15816244d2200ca95a649Aart Bik 84996709f17347cb7a6aae15816244d2200ca95a649Aart Bik auto check_after_cf = [](HGraph* graph) { 85096709f17347cb7a6aae15816244d2200ca95a649Aart Bik CHECK(graph != nullptr); 85196709f17347cb7a6aae15816244d2200ca95a649Aart Bik }; 85296709f17347cb7a6aae15816244d2200ca95a649Aart Bik 85396709f17347cb7a6aae15816244d2200ca95a649Aart Bik TestCodeOnReadyGraph(expected_before, 85496709f17347cb7a6aae15816244d2200ca95a649Aart Bik expected_after_cf, 85596709f17347cb7a6aae15816244d2200ca95a649Aart Bik expected_after_dce, 85696709f17347cb7a6aae15816244d2200ca95a649Aart Bik check_after_cf); 85796709f17347cb7a6aae15816244d2200ca95a649Aart Bik} 85896709f17347cb7a6aae15816244d2200ca95a649Aart Bik 859556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain} // namespace art 860