constant_folding_test.cc revision 96709f17347cb7a6aae15816244d2200ca95a649
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 */ 3596709f17347cb7a6aae15816244d2200ca95a649Aart Bikclass ConstantFoldingTest : public testing::Test { 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, 4596709f17347cb7a6aae15816244d2200ca95a649Aart Bik 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, 5796709f17347cb7a6aae15816244d2200ca95a649Aart Bik std::function<void(HGraph*)> check_after_cf) { 5896709f17347cb7a6aae15816244d2200ca95a649Aart Bik ASSERT_NE(graph_, nullptr); 5996709f17347cb7a6aae15816244d2200ca95a649Aart Bik graph_->TryBuildingSsa(); 6096709f17347cb7a6aae15816244d2200ca95a649Aart Bik 6196709f17347cb7a6aae15816244d2200ca95a649Aart Bik StringPrettyPrinter printer_before(graph_); 6296709f17347cb7a6aae15816244d2200ca95a649Aart Bik printer_before.VisitInsertionOrder(); 6396709f17347cb7a6aae15816244d2200ca95a649Aart Bik std::string actual_before = printer_before.str(); 6496709f17347cb7a6aae15816244d2200ca95a649Aart Bik EXPECT_EQ(expected_before, actual_before); 6596709f17347cb7a6aae15816244d2200ca95a649Aart Bik 6696709f17347cb7a6aae15816244d2200ca95a649Aart Bik std::unique_ptr<const X86InstructionSetFeatures> features_x86( 6796709f17347cb7a6aae15816244d2200ca95a649Aart Bik X86InstructionSetFeatures::FromCppDefines()); 6896709f17347cb7a6aae15816244d2200ca95a649Aart Bik x86::CodeGeneratorX86 codegenX86(graph_, *features_x86.get(), CompilerOptions()); 6996709f17347cb7a6aae15816244d2200ca95a649Aart Bik HConstantFolding(graph_).Run(); 7096709f17347cb7a6aae15816244d2200ca95a649Aart Bik SSAChecker ssa_checker_cf(graph_); 7196709f17347cb7a6aae15816244d2200ca95a649Aart Bik ssa_checker_cf.Run(); 7296709f17347cb7a6aae15816244d2200ca95a649Aart Bik ASSERT_TRUE(ssa_checker_cf.IsValid()); 7396709f17347cb7a6aae15816244d2200ca95a649Aart Bik 7496709f17347cb7a6aae15816244d2200ca95a649Aart Bik StringPrettyPrinter printer_after_cf(graph_); 7596709f17347cb7a6aae15816244d2200ca95a649Aart Bik printer_after_cf.VisitInsertionOrder(); 7696709f17347cb7a6aae15816244d2200ca95a649Aart Bik std::string actual_after_cf = printer_after_cf.str(); 7796709f17347cb7a6aae15816244d2200ca95a649Aart Bik EXPECT_EQ(expected_after_cf, actual_after_cf); 7896709f17347cb7a6aae15816244d2200ca95a649Aart Bik 7996709f17347cb7a6aae15816244d2200ca95a649Aart Bik check_after_cf(graph_); 8096709f17347cb7a6aae15816244d2200ca95a649Aart Bik 8196709f17347cb7a6aae15816244d2200ca95a649Aart Bik HDeadCodeElimination(graph_).Run(); 8296709f17347cb7a6aae15816244d2200ca95a649Aart Bik SSAChecker ssa_checker_dce(graph_); 8396709f17347cb7a6aae15816244d2200ca95a649Aart Bik ssa_checker_dce.Run(); 8496709f17347cb7a6aae15816244d2200ca95a649Aart Bik ASSERT_TRUE(ssa_checker_dce.IsValid()); 8596709f17347cb7a6aae15816244d2200ca95a649Aart Bik 8696709f17347cb7a6aae15816244d2200ca95a649Aart Bik StringPrettyPrinter printer_after_dce(graph_); 8796709f17347cb7a6aae15816244d2200ca95a649Aart Bik printer_after_dce.VisitInsertionOrder(); 8896709f17347cb7a6aae15816244d2200ca95a649Aart Bik std::string actual_after_dce = printer_after_dce.str(); 8996709f17347cb7a6aae15816244d2200ca95a649Aart Bik EXPECT_EQ(expected_after_dce, actual_after_dce); 9096709f17347cb7a6aae15816244d2200ca95a649Aart Bik } 9196709f17347cb7a6aae15816244d2200ca95a649Aart Bik 9296709f17347cb7a6aae15816244d2200ca95a649Aart Bik ArenaPool pool_; 9396709f17347cb7a6aae15816244d2200ca95a649Aart Bik ArenaAllocator allocator_; 9496709f17347cb7a6aae15816244d2200ca95a649Aart Bik HGraph* graph_; 9596709f17347cb7a6aae15816244d2200ca95a649Aart Bik}; 96556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 97556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain/** 989240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain * Tiny three-register program exercising int constant folding on negation. 999240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain * 1009240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain * 16-bit 1019240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain * offset 1029240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain * ------ 1039240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain * v0 <- 1 0. const/4 v0, #+1 104c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain * v1 <- -v0 1. neg-int v1, v0 1059240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain * return v1 2. return v1 1069240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain */ 10796709f17347cb7a6aae15816244d2200ca95a649Aart BikTEST_F(ConstantFoldingTest, IntConstantFoldingNegation) { 1089240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain const uint16_t data[] = TWO_REGISTERS_CODE_ITEM( 1099240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain Instruction::CONST_4 | 0 << 8 | 1 << 12, 1109240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain Instruction::NEG_INT | 1 << 8 | 0 << 12, 1119240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain Instruction::RETURN | 1 << 8); 1129240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain 1139240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain std::string expected_before = 1149240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain "BasicBlock 0, succ: 1\n" 1159240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain " 2: IntConstant [5]\n" 1169240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain " 10: SuspendCheck\n" 1179240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain " 11: Goto 1\n" 1189240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain "BasicBlock 1, pred: 0, succ: 2\n" 1199240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain " 5: Neg(2) [8]\n" 1209240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain " 8: Return(5)\n" 1219240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain "BasicBlock 2, pred: 1\n" 1229240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain " 9: Exit\n"; 1239240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain 1249240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain // Expected difference after constant folding. 1259240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain diff_t expected_cf_diff = { 1269240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain { " 2: IntConstant [5]\n", " 2: IntConstant\n" }, 1278d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil { " 10: SuspendCheck\n", " 10: SuspendCheck\n" 1288d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil " 12: IntConstant [8]\n" }, 1298d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil { " 5: Neg(2) [8]\n", removed }, 1309240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain { " 8: Return(5)\n", " 8: Return(12)\n" } 1319240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain }; 1329240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain std::string expected_after_cf = Patch(expected_before, expected_cf_diff); 1339240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain 1349240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain // Check the value of the computed constant. 1359240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain auto check_after_cf = [](HGraph* graph) { 136ec7802a102d49ab5c17495118d4fe0bcc7287bebVladimir Marko HInstruction* inst = graph->GetBlocks()[1]->GetFirstInstruction()->InputAt(0); 1379240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain ASSERT_TRUE(inst->IsIntConstant()); 1389240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain ASSERT_EQ(inst->AsIntConstant()->GetValue(), -1); 1399240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain }; 1409240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain 1419240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain // Expected difference after dead code elimination. 1429240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain diff_t expected_dce_diff = { 1439240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain { " 2: IntConstant\n", removed }, 1449240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain }; 1459240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain std::string expected_after_dce = Patch(expected_after_cf, expected_dce_diff); 1469240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain 1479240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain TestCode(data, 1489240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain expected_before, 1499240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain expected_after_cf, 1509240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain expected_after_dce, 1519240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain check_after_cf); 1529240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain} 1539240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain 1549240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain/** 155c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain * Tiny three-register program exercising long constant folding on negation. 156c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain * 157c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain * 16-bit 158c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain * offset 159c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain * ------ 160c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain * (v0, v1) <- 4294967296 0. const-wide v0 #+4294967296 161c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain * (v2, v3) <- -(v0, v1) 1. neg-long v2, v0 162c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain * return (v2, v3) 2. return-wide v2 163c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain */ 16496709f17347cb7a6aae15816244d2200ca95a649Aart BikTEST_F(ConstantFoldingTest, LongConstantFoldingNegation) { 165c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain const int64_t input = INT64_C(4294967296); // 2^32 166c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain const uint16_t word0 = Low16Bits(Low32Bits(input)); // LSW. 167c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain const uint16_t word1 = High16Bits(Low32Bits(input)); 168c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain const uint16_t word2 = Low16Bits(High32Bits(input)); 169c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain const uint16_t word3 = High16Bits(High32Bits(input)); // MSW. 170c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain const uint16_t data[] = FOUR_REGISTERS_CODE_ITEM( 171c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain Instruction::CONST_WIDE | 0 << 8, word0, word1, word2, word3, 172c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain Instruction::NEG_LONG | 2 << 8 | 0 << 12, 173c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain Instruction::RETURN_WIDE | 2 << 8); 174c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain 175c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain std::string expected_before = 176c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain "BasicBlock 0, succ: 1\n" 177c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain " 4: LongConstant [7]\n" 178c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain " 12: SuspendCheck\n" 179c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain " 13: Goto 1\n" 180c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain "BasicBlock 1, pred: 0, succ: 2\n" 181c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain " 7: Neg(4) [10]\n" 182c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain " 10: Return(7)\n" 183c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain "BasicBlock 2, pred: 1\n" 184c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain " 11: Exit\n"; 185c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain 186c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain // Expected difference after constant folding. 187c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain diff_t expected_cf_diff = { 188c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain { " 4: LongConstant [7]\n", " 4: LongConstant\n" }, 189c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain { " 12: SuspendCheck\n", " 12: SuspendCheck\n" 190c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain " 14: LongConstant [10]\n" }, 191c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain { " 7: Neg(4) [10]\n", removed }, 192c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain { " 10: Return(7)\n", " 10: Return(14)\n" } 193c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain }; 194c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain std::string expected_after_cf = Patch(expected_before, expected_cf_diff); 195c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain 196c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain // Check the value of the computed constant. 197c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain auto check_after_cf = [](HGraph* graph) { 198ec7802a102d49ab5c17495118d4fe0bcc7287bebVladimir Marko HInstruction* inst = graph->GetBlocks()[1]->GetFirstInstruction()->InputAt(0); 199c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain ASSERT_TRUE(inst->IsLongConstant()); 200c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain ASSERT_EQ(inst->AsLongConstant()->GetValue(), INT64_C(-4294967296)); 201c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain }; 202c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain 203c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain // Expected difference after dead code elimination. 204c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain diff_t expected_dce_diff = { 205c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain { " 4: LongConstant\n", removed }, 206c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain }; 207c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain std::string expected_after_dce = Patch(expected_after_cf, expected_dce_diff); 208c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain 209c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain TestCode(data, 210c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain expected_before, 211c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain expected_after_cf, 212c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain expected_after_dce, 213c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain check_after_cf, 214c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain Primitive::kPrimLong); 215c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain} 216c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain 217c90bc7c07f9bd24b5424cfb1e3f064fbae5334d6Roland Levillain/** 218556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * Tiny three-register program exercising int constant folding on addition. 219556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * 220556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * 16-bit 221556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * offset 222556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * ------ 223556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * v0 <- 1 0. const/4 v0, #+1 224556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * v1 <- 2 1. const/4 v1, #+2 225556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * v2 <- v0 + v1 2. add-int v2, v0, v1 226556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * return v2 4. return v2 227556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain */ 22896709f17347cb7a6aae15816244d2200ca95a649Aart BikTEST_F(ConstantFoldingTest, IntConstantFoldingOnAddition1) { 229556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain const uint16_t data[] = THREE_REGISTERS_CODE_ITEM( 230556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::CONST_4 | 0 << 8 | 1 << 12, 231556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::CONST_4 | 1 << 8 | 2 << 12, 232556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::ADD_INT | 2 << 8, 0 | 1 << 8, 233556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::RETURN | 2 << 8); 234556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 235556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain std::string expected_before = 236556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain "BasicBlock 0, succ: 1\n" 237556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 3: IntConstant [9]\n" 238556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 5: IntConstant [9]\n" 239556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 14: SuspendCheck\n" 240556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 15: Goto 1\n" 241556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain "BasicBlock 1, pred: 0, succ: 2\n" 242556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 9: Add(3, 5) [12]\n" 243556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 12: Return(9)\n" 244556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain "BasicBlock 2, pred: 1\n" 245556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 13: Exit\n"; 246556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 24775be28332b278cff9039b54bfb228ac72f539cccRoland Levillain // Expected difference after constant folding. 24875be28332b278cff9039b54bfb228ac72f539cccRoland Levillain diff_t expected_cf_diff = { 249556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 3: IntConstant [9]\n", " 3: IntConstant\n" }, 250556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 5: IntConstant [9]\n", " 5: IntConstant\n" }, 2518d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil { " 14: SuspendCheck\n", " 14: SuspendCheck\n" 2528d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil " 16: IntConstant [12]\n" }, 2538d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil { " 9: Add(3, 5) [12]\n", removed }, 254556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 12: Return(9)\n", " 12: Return(16)\n" } 255556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain }; 25675be28332b278cff9039b54bfb228ac72f539cccRoland Levillain std::string expected_after_cf = Patch(expected_before, expected_cf_diff); 257556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 25893445689c714e53cabf347da4321ecf3023e926cRoland Levillain // Check the value of the computed constant. 25975be28332b278cff9039b54bfb228ac72f539cccRoland Levillain auto check_after_cf = [](HGraph* graph) { 260ec7802a102d49ab5c17495118d4fe0bcc7287bebVladimir Marko HInstruction* inst = graph->GetBlocks()[1]->GetFirstInstruction()->InputAt(0); 26193445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_TRUE(inst->IsIntConstant()); 26293445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_EQ(inst->AsIntConstant()->GetValue(), 3); 26393445689c714e53cabf347da4321ecf3023e926cRoland Levillain }; 26493445689c714e53cabf347da4321ecf3023e926cRoland Levillain 265556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain // Expected difference after dead code elimination. 266556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain diff_t expected_dce_diff = { 267556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 3: IntConstant\n", removed }, 268556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 5: IntConstant\n", removed } 269556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain }; 27075be28332b278cff9039b54bfb228ac72f539cccRoland Levillain std::string expected_after_dce = Patch(expected_after_cf, expected_dce_diff); 271556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 27293445689c714e53cabf347da4321ecf3023e926cRoland Levillain TestCode(data, 27393445689c714e53cabf347da4321ecf3023e926cRoland Levillain expected_before, 27475be28332b278cff9039b54bfb228ac72f539cccRoland Levillain expected_after_cf, 27593445689c714e53cabf347da4321ecf3023e926cRoland Levillain expected_after_dce, 27675be28332b278cff9039b54bfb228ac72f539cccRoland Levillain check_after_cf); 277556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain} 278556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 279556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain/** 280556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * Small three-register program exercising int constant folding on addition. 281556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * 282556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * 16-bit 283556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * offset 284556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * ------ 285556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * v0 <- 1 0. const/4 v0, #+1 286556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * v1 <- 2 1. const/4 v1, #+2 287556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * v0 <- v0 + v1 2. add-int/2addr v0, v1 2888d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil * v1 <- 4 3. const/4 v1, #+4 2898d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil * v2 <- 5 4. const/4 v2, #+5 290556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * v1 <- v1 + v2 5. add-int/2addr v1, v2 291556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * v2 <- v0 + v1 6. add-int v2, v0, v1 292556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * return v2 8. return v2 293556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain */ 29496709f17347cb7a6aae15816244d2200ca95a649Aart BikTEST_F(ConstantFoldingTest, IntConstantFoldingOnAddition2) { 295556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain const uint16_t data[] = THREE_REGISTERS_CODE_ITEM( 296556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::CONST_4 | 0 << 8 | 1 << 12, 297556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::CONST_4 | 1 << 8 | 2 << 12, 298556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::ADD_INT_2ADDR | 0 << 8 | 1 << 12, 2998d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil Instruction::CONST_4 | 1 << 8 | 4 << 12, 3008d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil Instruction::CONST_4 | 2 << 8 | 5 << 12, 301556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::ADD_INT_2ADDR | 1 << 8 | 2 << 12, 302556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::ADD_INT | 2 << 8, 0 | 1 << 8, 303556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::RETURN | 2 << 8); 304556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 305556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain std::string expected_before = 306556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain "BasicBlock 0, succ: 1\n" 307556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 3: IntConstant [9]\n" 308556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 5: IntConstant [9]\n" 309556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 11: IntConstant [17]\n" 310556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 13: IntConstant [17]\n" 311556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 26: SuspendCheck\n" 312556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 27: Goto 1\n" 313556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain "BasicBlock 1, pred: 0, succ: 2\n" 314556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 9: Add(3, 5) [21]\n" 315556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 17: Add(11, 13) [21]\n" 316556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 21: Add(9, 17) [24]\n" 317556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 24: Return(21)\n" 318556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain "BasicBlock 2, pred: 1\n" 319556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 25: Exit\n"; 320556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 32175be28332b278cff9039b54bfb228ac72f539cccRoland Levillain // Expected difference after constant folding. 32275be28332b278cff9039b54bfb228ac72f539cccRoland Levillain diff_t expected_cf_diff = { 323556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 3: IntConstant [9]\n", " 3: IntConstant\n" }, 324556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 5: IntConstant [9]\n", " 5: IntConstant\n" }, 325556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 11: IntConstant [17]\n", " 11: IntConstant\n" }, 326556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 13: IntConstant [17]\n", " 13: IntConstant\n" }, 3278d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil { " 26: SuspendCheck\n", " 26: SuspendCheck\n" 3288d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil " 28: IntConstant\n" 3298d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil " 29: IntConstant\n" 3308d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil " 30: IntConstant [24]\n" }, 3318d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil { " 9: Add(3, 5) [21]\n", removed }, 3328d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil { " 17: Add(11, 13) [21]\n", removed }, 3338d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil { " 21: Add(9, 17) [24]\n", removed }, 334556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 24: Return(21)\n", " 24: Return(30)\n" } 335556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain }; 33675be28332b278cff9039b54bfb228ac72f539cccRoland Levillain std::string expected_after_cf = Patch(expected_before, expected_cf_diff); 337556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 33893445689c714e53cabf347da4321ecf3023e926cRoland Levillain // Check the values of the computed constants. 33975be28332b278cff9039b54bfb228ac72f539cccRoland Levillain auto check_after_cf = [](HGraph* graph) { 340ec7802a102d49ab5c17495118d4fe0bcc7287bebVladimir Marko HInstruction* inst1 = graph->GetBlocks()[1]->GetFirstInstruction()->InputAt(0); 34193445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_TRUE(inst1->IsIntConstant()); 3428d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil ASSERT_EQ(inst1->AsIntConstant()->GetValue(), 12); 3438d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil HInstruction* inst2 = inst1->GetPrevious(); 34493445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_TRUE(inst2->IsIntConstant()); 3458d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil ASSERT_EQ(inst2->AsIntConstant()->GetValue(), 9); 3468d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil HInstruction* inst3 = inst2->GetPrevious(); 34793445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_TRUE(inst3->IsIntConstant()); 3488d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil ASSERT_EQ(inst3->AsIntConstant()->GetValue(), 3); 34993445689c714e53cabf347da4321ecf3023e926cRoland Levillain }; 35093445689c714e53cabf347da4321ecf3023e926cRoland Levillain 351556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain // Expected difference after dead code elimination. 352556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain diff_t expected_dce_diff = { 353556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 3: IntConstant\n", removed }, 354556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 5: IntConstant\n", removed }, 355556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 11: IntConstant\n", removed }, 356556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 13: IntConstant\n", removed }, 357556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 28: IntConstant\n", removed }, 358556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 29: IntConstant\n", removed } 359556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain }; 36075be28332b278cff9039b54bfb228ac72f539cccRoland Levillain std::string expected_after_dce = Patch(expected_after_cf, expected_dce_diff); 361556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 36293445689c714e53cabf347da4321ecf3023e926cRoland Levillain TestCode(data, 36393445689c714e53cabf347da4321ecf3023e926cRoland Levillain expected_before, 36475be28332b278cff9039b54bfb228ac72f539cccRoland Levillain expected_after_cf, 36593445689c714e53cabf347da4321ecf3023e926cRoland Levillain expected_after_dce, 36675be28332b278cff9039b54bfb228ac72f539cccRoland Levillain check_after_cf); 367556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain} 368556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 369556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain/** 370556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * Tiny three-register program exercising int constant folding on subtraction. 371556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * 372556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * 16-bit 373556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * offset 374556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * ------ 375556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * v0 <- 3 0. const/4 v0, #+3 376556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * v1 <- 2 1. const/4 v1, #+2 377556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * v2 <- v0 - v1 2. sub-int v2, v0, v1 378556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * return v2 4. return v2 379556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain */ 38096709f17347cb7a6aae15816244d2200ca95a649Aart BikTEST_F(ConstantFoldingTest, IntConstantFoldingOnSubtraction) { 381556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain const uint16_t data[] = THREE_REGISTERS_CODE_ITEM( 382556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::CONST_4 | 0 << 8 | 3 << 12, 383556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::CONST_4 | 1 << 8 | 2 << 12, 384556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::SUB_INT | 2 << 8, 0 | 1 << 8, 385556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::RETURN | 2 << 8); 386556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 387556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain std::string expected_before = 388556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain "BasicBlock 0, succ: 1\n" 389556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 3: IntConstant [9]\n" 390556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 5: IntConstant [9]\n" 391556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 14: SuspendCheck\n" 392556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 15: Goto 1\n" 393556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain "BasicBlock 1, pred: 0, succ: 2\n" 394556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 9: Sub(3, 5) [12]\n" 395556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 12: Return(9)\n" 396556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain "BasicBlock 2, pred: 1\n" 397556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 13: Exit\n"; 398556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 39975be28332b278cff9039b54bfb228ac72f539cccRoland Levillain // Expected difference after constant folding. 40075be28332b278cff9039b54bfb228ac72f539cccRoland Levillain diff_t expected_cf_diff = { 401556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 3: IntConstant [9]\n", " 3: IntConstant\n" }, 402556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 5: IntConstant [9]\n", " 5: IntConstant\n" }, 4038d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil { " 14: SuspendCheck\n", " 14: SuspendCheck\n" 4048d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil " 16: IntConstant [12]\n" }, 4058d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil { " 9: Sub(3, 5) [12]\n", removed }, 406556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 12: Return(9)\n", " 12: Return(16)\n" } 407556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain }; 40875be28332b278cff9039b54bfb228ac72f539cccRoland Levillain std::string expected_after_cf = Patch(expected_before, expected_cf_diff); 409556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 41093445689c714e53cabf347da4321ecf3023e926cRoland Levillain // Check the value of the computed constant. 41175be28332b278cff9039b54bfb228ac72f539cccRoland Levillain auto check_after_cf = [](HGraph* graph) { 412ec7802a102d49ab5c17495118d4fe0bcc7287bebVladimir Marko HInstruction* inst = graph->GetBlocks()[1]->GetFirstInstruction()->InputAt(0); 41393445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_TRUE(inst->IsIntConstant()); 41493445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_EQ(inst->AsIntConstant()->GetValue(), 1); 41593445689c714e53cabf347da4321ecf3023e926cRoland Levillain }; 41693445689c714e53cabf347da4321ecf3023e926cRoland Levillain 417556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain // Expected difference after dead code elimination. 418556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain diff_t expected_dce_diff = { 419556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 3: IntConstant\n", removed }, 420556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 5: IntConstant\n", removed } 421556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain }; 42275be28332b278cff9039b54bfb228ac72f539cccRoland Levillain std::string expected_after_dce = Patch(expected_after_cf, expected_dce_diff); 423556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 42493445689c714e53cabf347da4321ecf3023e926cRoland Levillain TestCode(data, 42593445689c714e53cabf347da4321ecf3023e926cRoland Levillain expected_before, 42675be28332b278cff9039b54bfb228ac72f539cccRoland Levillain expected_after_cf, 42793445689c714e53cabf347da4321ecf3023e926cRoland Levillain expected_after_dce, 42875be28332b278cff9039b54bfb228ac72f539cccRoland Levillain check_after_cf); 429556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain} 430556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 431556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain/** 432556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * Tiny three-register-pair program exercising long constant folding 433556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * on addition. 434556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * 435556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * 16-bit 436556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * offset 437556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * ------ 438556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * (v0, v1) <- 1 0. const-wide/16 v0, #+1 439556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * (v2, v3) <- 2 2. const-wide/16 v2, #+2 440556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * (v4, v5) <- 441556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * (v0, v1) + (v1, v2) 4. add-long v4, v0, v2 442556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * return (v4, v5) 6. return-wide v4 443556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain */ 44496709f17347cb7a6aae15816244d2200ca95a649Aart BikTEST_F(ConstantFoldingTest, LongConstantFoldingOnAddition) { 445556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain const uint16_t data[] = SIX_REGISTERS_CODE_ITEM( 446556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::CONST_WIDE_16 | 0 << 8, 1, 447556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::CONST_WIDE_16 | 2 << 8, 2, 448556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::ADD_LONG | 4 << 8, 0 | 2 << 8, 449556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::RETURN_WIDE | 4 << 8); 450556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 451556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain std::string expected_before = 452556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain "BasicBlock 0, succ: 1\n" 453556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 6: LongConstant [12]\n" 454556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 8: LongConstant [12]\n" 455556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 17: SuspendCheck\n" 456556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 18: Goto 1\n" 457556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain "BasicBlock 1, pred: 0, succ: 2\n" 458556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 12: Add(6, 8) [15]\n" 459556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 15: Return(12)\n" 460556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain "BasicBlock 2, pred: 1\n" 461556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 16: Exit\n"; 462556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 46375be28332b278cff9039b54bfb228ac72f539cccRoland Levillain // Expected difference after constant folding. 46475be28332b278cff9039b54bfb228ac72f539cccRoland Levillain diff_t expected_cf_diff = { 465556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 6: LongConstant [12]\n", " 6: LongConstant\n" }, 466556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 8: LongConstant [12]\n", " 8: LongConstant\n" }, 4678d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil { " 17: SuspendCheck\n", " 17: SuspendCheck\n" 4688d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil " 19: LongConstant [15]\n" }, 4698d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil { " 12: Add(6, 8) [15]\n", removed }, 470556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 15: Return(12)\n", " 15: Return(19)\n" } 471556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain }; 47275be28332b278cff9039b54bfb228ac72f539cccRoland Levillain std::string expected_after_cf = Patch(expected_before, expected_cf_diff); 473556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 47493445689c714e53cabf347da4321ecf3023e926cRoland Levillain // Check the value of the computed constant. 47575be28332b278cff9039b54bfb228ac72f539cccRoland Levillain auto check_after_cf = [](HGraph* graph) { 476ec7802a102d49ab5c17495118d4fe0bcc7287bebVladimir Marko HInstruction* inst = graph->GetBlocks()[1]->GetFirstInstruction()->InputAt(0); 47793445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_TRUE(inst->IsLongConstant()); 47893445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_EQ(inst->AsLongConstant()->GetValue(), 3); 47993445689c714e53cabf347da4321ecf3023e926cRoland Levillain }; 48093445689c714e53cabf347da4321ecf3023e926cRoland Levillain 481556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain // Expected difference after dead code elimination. 482556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain diff_t expected_dce_diff = { 483556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 6: LongConstant\n", removed }, 484556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 8: LongConstant\n", removed } 485556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain }; 48675be28332b278cff9039b54bfb228ac72f539cccRoland Levillain std::string expected_after_dce = Patch(expected_after_cf, expected_dce_diff); 487556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 48893445689c714e53cabf347da4321ecf3023e926cRoland Levillain TestCode(data, 48993445689c714e53cabf347da4321ecf3023e926cRoland Levillain expected_before, 49075be28332b278cff9039b54bfb228ac72f539cccRoland Levillain expected_after_cf, 49193445689c714e53cabf347da4321ecf3023e926cRoland Levillain expected_after_dce, 49275be28332b278cff9039b54bfb228ac72f539cccRoland Levillain check_after_cf, 49393445689c714e53cabf347da4321ecf3023e926cRoland Levillain Primitive::kPrimLong); 494556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain} 495556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 496556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain/** 497556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * Tiny three-register-pair program exercising long constant folding 498556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * on subtraction. 499556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * 500556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * 16-bit 501556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * offset 502556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * ------ 503556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * (v0, v1) <- 3 0. const-wide/16 v0, #+3 504556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * (v2, v3) <- 2 2. const-wide/16 v2, #+2 505556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * (v4, v5) <- 506556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * (v0, v1) - (v1, v2) 4. sub-long v4, v0, v2 507556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * return (v4, v5) 6. return-wide v4 508556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain */ 50996709f17347cb7a6aae15816244d2200ca95a649Aart BikTEST_F(ConstantFoldingTest, LongConstantFoldingOnSubtraction) { 510556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain const uint16_t data[] = SIX_REGISTERS_CODE_ITEM( 511556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::CONST_WIDE_16 | 0 << 8, 3, 512556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::CONST_WIDE_16 | 2 << 8, 2, 513556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::SUB_LONG | 4 << 8, 0 | 2 << 8, 514556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::RETURN_WIDE | 4 << 8); 515556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 516556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain std::string expected_before = 517556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain "BasicBlock 0, succ: 1\n" 518556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 6: LongConstant [12]\n" 519556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 8: LongConstant [12]\n" 520556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 17: SuspendCheck\n" 521556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 18: Goto 1\n" 522556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain "BasicBlock 1, pred: 0, succ: 2\n" 523556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 12: Sub(6, 8) [15]\n" 524556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 15: Return(12)\n" 525556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain "BasicBlock 2, pred: 1\n" 526556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 16: Exit\n"; 527556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 52875be28332b278cff9039b54bfb228ac72f539cccRoland Levillain // Expected difference after constant folding. 52975be28332b278cff9039b54bfb228ac72f539cccRoland Levillain diff_t expected_cf_diff = { 530556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 6: LongConstant [12]\n", " 6: LongConstant\n" }, 531556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 8: LongConstant [12]\n", " 8: LongConstant\n" }, 5328d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil { " 17: SuspendCheck\n", " 17: SuspendCheck\n" 5338d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil " 19: LongConstant [15]\n" }, 5348d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil { " 12: Sub(6, 8) [15]\n", removed }, 535556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 15: Return(12)\n", " 15: Return(19)\n" } 536556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain }; 53775be28332b278cff9039b54bfb228ac72f539cccRoland Levillain std::string expected_after_cf = Patch(expected_before, expected_cf_diff); 538556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 53993445689c714e53cabf347da4321ecf3023e926cRoland Levillain // Check the value of the computed constant. 54075be28332b278cff9039b54bfb228ac72f539cccRoland Levillain auto check_after_cf = [](HGraph* graph) { 541ec7802a102d49ab5c17495118d4fe0bcc7287bebVladimir Marko HInstruction* inst = graph->GetBlocks()[1]->GetFirstInstruction()->InputAt(0); 54293445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_TRUE(inst->IsLongConstant()); 54393445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_EQ(inst->AsLongConstant()->GetValue(), 1); 54493445689c714e53cabf347da4321ecf3023e926cRoland Levillain }; 54593445689c714e53cabf347da4321ecf3023e926cRoland Levillain 546556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain // Expected difference after dead code elimination. 547556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain diff_t expected_dce_diff = { 548556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 6: LongConstant\n", removed }, 549556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 8: LongConstant\n", removed } 550556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain }; 55175be28332b278cff9039b54bfb228ac72f539cccRoland Levillain std::string expected_after_dce = Patch(expected_after_cf, expected_dce_diff); 552556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 55393445689c714e53cabf347da4321ecf3023e926cRoland Levillain TestCode(data, 55493445689c714e53cabf347da4321ecf3023e926cRoland Levillain expected_before, 55575be28332b278cff9039b54bfb228ac72f539cccRoland Levillain expected_after_cf, 55693445689c714e53cabf347da4321ecf3023e926cRoland Levillain expected_after_dce, 55775be28332b278cff9039b54bfb228ac72f539cccRoland Levillain check_after_cf, 55893445689c714e53cabf347da4321ecf3023e926cRoland Levillain Primitive::kPrimLong); 559556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain} 560556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 561556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain/** 562556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * Three-register program with jumps leading to the creation of many 563556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * blocks. 564556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * 565556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * The intent of this test is to ensure that all constant expressions 566556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * are actually evaluated at compile-time, thanks to the reverse 567556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * (forward) post-order traversal of the the dominator tree. 568556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * 569556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * 16-bit 570556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * offset 571556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * ------ 5728d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil * v0 <- 1 0. const/4 v0, #+1 5738d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil * v1 <- 2 1. const/4 v1, #+2 574556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * v2 <- v0 + v1 2. add-int v2, v0, v1 575556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * goto L2 4. goto +4 5768d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil * L1: v1 <- v0 + 5 5. add-int/lit16 v1, v0, #+5 577556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * goto L3 7. goto +4 5788d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil * L2: v0 <- v2 + 4 8. add-int/lit16 v0, v2, #+4 579556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * goto L1 10. goto +(-5) 5808d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil * L3: v2 <- v1 + 8 11. add-int/lit16 v2, v1, #+8 581556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * return v2 13. return v2 582556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain */ 58396709f17347cb7a6aae15816244d2200ca95a649Aart BikTEST_F(ConstantFoldingTest, IntConstantFoldingAndJumps) { 584556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain const uint16_t data[] = THREE_REGISTERS_CODE_ITEM( 5858d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil Instruction::CONST_4 | 0 << 8 | 1 << 12, 5868d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil Instruction::CONST_4 | 1 << 8 | 2 << 12, 587556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::ADD_INT | 2 << 8, 0 | 1 << 8, 588556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::GOTO | 4 << 8, 5898d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil Instruction::ADD_INT_LIT16 | 1 << 8 | 0 << 12, 5, 590556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::GOTO | 4 << 8, 5918d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil Instruction::ADD_INT_LIT16 | 0 << 8 | 2 << 12, 4, 59258554b7de4b437ddef7ff550e62c8ec0b16f9264Andreas Gampe static_cast<uint16_t>(Instruction::GOTO | 0xFFFFFFFB << 8), 5938d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil Instruction::ADD_INT_LIT16 | 2 << 8 | 1 << 12, 8, 594556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::RETURN | 2 << 8); 595556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 596556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain std::string expected_before = 597556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain "BasicBlock 0, succ: 1\n" 5988d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil " 3: IntConstant [9]\n" // v0 <- 1 5998d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil " 5: IntConstant [9]\n" // v1 <- 2 6008d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil " 13: IntConstant [14]\n" // const 5 6018d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil " 18: IntConstant [19]\n" // const 4 6028d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil " 24: IntConstant [25]\n" // const 8 603556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 30: SuspendCheck\n" 604556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 31: Goto 1\n" 605556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain "BasicBlock 1, pred: 0, succ: 3\n" 6068d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil " 9: Add(3, 5) [19]\n" // v2 <- v0 + v1 = 1 + 2 = 3 60793445689c714e53cabf347da4321ecf3023e926cRoland Levillain " 11: Goto 3\n" // goto L2 60893445689c714e53cabf347da4321ecf3023e926cRoland Levillain "BasicBlock 2, pred: 3, succ: 4\n" // L1: 6098d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil " 14: Add(19, 13) [25]\n" // v1 <- v0 + 3 = 7 + 5 = 12 61093445689c714e53cabf347da4321ecf3023e926cRoland Levillain " 16: Goto 4\n" // goto L3 61193445689c714e53cabf347da4321ecf3023e926cRoland Levillain "BasicBlock 3, pred: 1, succ: 2\n" // L2: 6128d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil " 19: Add(9, 18) [14]\n" // v0 <- v2 + 2 = 3 + 4 = 7 613556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 21: SuspendCheck\n" 61493445689c714e53cabf347da4321ecf3023e926cRoland Levillain " 22: Goto 2\n" // goto L1 61593445689c714e53cabf347da4321ecf3023e926cRoland Levillain "BasicBlock 4, pred: 2, succ: 5\n" // L3: 6168d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil " 25: Add(14, 24) [28]\n" // v2 <- v1 + 4 = 12 + 8 = 20 61793445689c714e53cabf347da4321ecf3023e926cRoland Levillain " 28: Return(25)\n" // return v2 618556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain "BasicBlock 5, pred: 4\n" 619556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 29: Exit\n"; 620556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 62175be28332b278cff9039b54bfb228ac72f539cccRoland Levillain // Expected difference after constant folding. 62275be28332b278cff9039b54bfb228ac72f539cccRoland Levillain diff_t expected_cf_diff = { 623556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 3: IntConstant [9]\n", " 3: IntConstant\n" }, 624556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 5: IntConstant [9]\n", " 5: IntConstant []\n" }, 625556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 13: IntConstant [14]\n", " 13: IntConstant\n" }, 626556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 18: IntConstant [19]\n", " 18: IntConstant\n" }, 627556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 24: IntConstant [25]\n", " 24: IntConstant\n" }, 6288d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil { " 30: SuspendCheck\n", " 30: SuspendCheck\n" 6298d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil " 32: IntConstant []\n" 6308d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil " 33: IntConstant []\n" 6318d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil " 34: IntConstant\n" 6328d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil " 35: IntConstant [28]\n" }, 6338d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil { " 9: Add(3, 5) [19]\n", removed }, 6348d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil { " 14: Add(19, 13) [25]\n", removed }, 6358d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil { " 19: Add(9, 18) [14]\n", removed }, 6368d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil { " 25: Add(14, 24) [28]\n", removed }, 637556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 28: Return(25)\n", " 28: Return(35)\n"} 638556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain }; 63975be28332b278cff9039b54bfb228ac72f539cccRoland Levillain std::string expected_after_cf = Patch(expected_before, expected_cf_diff); 640556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 64193445689c714e53cabf347da4321ecf3023e926cRoland Levillain // Check the values of the computed constants. 64275be28332b278cff9039b54bfb228ac72f539cccRoland Levillain auto check_after_cf = [](HGraph* graph) { 643ec7802a102d49ab5c17495118d4fe0bcc7287bebVladimir Marko HInstruction* inst1 = graph->GetBlocks()[4]->GetFirstInstruction()->InputAt(0); 64493445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_TRUE(inst1->IsIntConstant()); 6458d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil ASSERT_EQ(inst1->AsIntConstant()->GetValue(), 20); 6468d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil HInstruction* inst2 = inst1->GetPrevious(); 64793445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_TRUE(inst2->IsIntConstant()); 6488d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil ASSERT_EQ(inst2->AsIntConstant()->GetValue(), 12); 6498d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil HInstruction* inst3 = inst2->GetPrevious(); 65093445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_TRUE(inst3->IsIntConstant()); 6518d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil ASSERT_EQ(inst3->AsIntConstant()->GetValue(), 7); 6528d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil HInstruction* inst4 = inst3->GetPrevious(); 65393445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_TRUE(inst4->IsIntConstant()); 6548d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil ASSERT_EQ(inst4->AsIntConstant()->GetValue(), 3); 65593445689c714e53cabf347da4321ecf3023e926cRoland Levillain }; 65693445689c714e53cabf347da4321ecf3023e926cRoland Levillain 657556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain // Expected difference after dead code elimination. 6581c533c17baff841e383a539fdd3c0a65135181b0David Brazdil std::string expected_after_dce = 6591c533c17baff841e383a539fdd3c0a65135181b0David Brazdil "BasicBlock 0, succ: 1\n" 6601c533c17baff841e383a539fdd3c0a65135181b0David Brazdil " 5: IntConstant []\n" 6611c533c17baff841e383a539fdd3c0a65135181b0David Brazdil " 30: SuspendCheck\n" 6621c533c17baff841e383a539fdd3c0a65135181b0David Brazdil " 32: IntConstant []\n" 6631c533c17baff841e383a539fdd3c0a65135181b0David Brazdil " 33: IntConstant []\n" 6641c533c17baff841e383a539fdd3c0a65135181b0David Brazdil " 35: IntConstant [28]\n" 6651c533c17baff841e383a539fdd3c0a65135181b0David Brazdil " 31: Goto 1\n" 6661c533c17baff841e383a539fdd3c0a65135181b0David Brazdil "BasicBlock 1, pred: 0, succ: 5\n" 6671c533c17baff841e383a539fdd3c0a65135181b0David Brazdil " 21: SuspendCheck\n" 6681c533c17baff841e383a539fdd3c0a65135181b0David Brazdil " 28: Return(35)\n" 6691c533c17baff841e383a539fdd3c0a65135181b0David Brazdil "BasicBlock 5, pred: 1\n" 6701c533c17baff841e383a539fdd3c0a65135181b0David Brazdil " 29: Exit\n"; 671556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 67293445689c714e53cabf347da4321ecf3023e926cRoland Levillain TestCode(data, 67393445689c714e53cabf347da4321ecf3023e926cRoland Levillain expected_before, 67475be28332b278cff9039b54bfb228ac72f539cccRoland Levillain expected_after_cf, 67593445689c714e53cabf347da4321ecf3023e926cRoland Levillain expected_after_dce, 67675be28332b278cff9039b54bfb228ac72f539cccRoland Levillain check_after_cf); 677556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain} 678556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 679556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain/** 680556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * Three-register program with a constant (static) condition. 681556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * 682556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * 16-bit 683556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * offset 684556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * ------ 685556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * v1 <- 1 0. const/4 v1, #+1 686556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * v0 <- 0 1. const/4 v0, #+0 687556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * if v1 >= 0 goto L1 2. if-gez v1, +3 688556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * v0 <- v1 4. move v0, v1 689556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * L1: v2 <- v0 + v1 5. add-int v2, v0, v1 690556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * return-void 7. return 691556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain */ 69296709f17347cb7a6aae15816244d2200ca95a649Aart BikTEST_F(ConstantFoldingTest, ConstantCondition) { 693556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain const uint16_t data[] = THREE_REGISTERS_CODE_ITEM( 694556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::CONST_4 | 1 << 8 | 1 << 12, 695556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::CONST_4 | 0 << 8 | 0 << 12, 696556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::IF_GEZ | 1 << 8, 3, 697556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::MOVE | 0 << 8 | 1 << 12, 698556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::ADD_INT | 2 << 8, 0 | 1 << 8, 699556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::RETURN_VOID); 700556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 701556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain std::string expected_before = 702556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain "BasicBlock 0, succ: 1\n" 703556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 3: IntConstant [15, 22, 8]\n" 704556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 5: IntConstant [22, 8]\n" 705556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 19: SuspendCheck\n" 706556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 20: Goto 1\n" 707556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain "BasicBlock 1, pred: 0, succ: 5, 2\n" 708556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 8: GreaterThanOrEqual(3, 5) [9]\n" 709556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 9: If(8)\n" 710556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain "BasicBlock 2, pred: 1, succ: 3\n" 711556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 12: Goto 3\n" 7128b20f88b0a8d1b374dd5eaae289d19734c77b8f8Nicolas Geoffray "BasicBlock 3, pred: 5, 2, succ: 4\n" 7138b20f88b0a8d1b374dd5eaae289d19734c77b8f8Nicolas Geoffray " 22: Phi(5, 3) [15]\n" 714556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 15: Add(22, 3)\n" 715556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 17: ReturnVoid\n" 716556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain "BasicBlock 4, pred: 3\n" 717556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 18: Exit\n" 718556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain "BasicBlock 5, pred: 1, succ: 3\n" 719556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 21: Goto 3\n"; 720556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 72175be28332b278cff9039b54bfb228ac72f539cccRoland Levillain // Expected difference after constant folding. 72275be28332b278cff9039b54bfb228ac72f539cccRoland Levillain diff_t expected_cf_diff = { 7238d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil { " 3: IntConstant [15, 22, 8]\n", " 3: IntConstant [9, 15, 22]\n" }, 724556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 5: IntConstant [22, 8]\n", " 5: IntConstant [22]\n" }, 7258d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil { " 8: GreaterThanOrEqual(3, 5) [9]\n", removed }, 7268d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil { " 9: If(8)\n", " 9: If(3)\n" } 727556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain }; 72875be28332b278cff9039b54bfb228ac72f539cccRoland Levillain std::string expected_after_cf = Patch(expected_before, expected_cf_diff); 729556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 73093445689c714e53cabf347da4321ecf3023e926cRoland Levillain // Check the values of the computed constants. 73175be28332b278cff9039b54bfb228ac72f539cccRoland Levillain auto check_after_cf = [](HGraph* graph) { 732ec7802a102d49ab5c17495118d4fe0bcc7287bebVladimir Marko HInstruction* inst = graph->GetBlocks()[1]->GetFirstInstruction()->InputAt(0); 73393445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_TRUE(inst->IsIntConstant()); 73493445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_EQ(inst->AsIntConstant()->GetValue(), 1); 73593445689c714e53cabf347da4321ecf3023e926cRoland Levillain }; 73693445689c714e53cabf347da4321ecf3023e926cRoland Levillain 7371c533c17baff841e383a539fdd3c0a65135181b0David Brazdil // Expected graph after dead code elimination. 7381c533c17baff841e383a539fdd3c0a65135181b0David Brazdil std::string expected_after_dce = 7391c533c17baff841e383a539fdd3c0a65135181b0David Brazdil "BasicBlock 0, succ: 1\n" 7401c533c17baff841e383a539fdd3c0a65135181b0David Brazdil " 19: SuspendCheck\n" 7411c533c17baff841e383a539fdd3c0a65135181b0David Brazdil " 20: Goto 1\n" 7421c533c17baff841e383a539fdd3c0a65135181b0David Brazdil "BasicBlock 1, pred: 0, succ: 4\n" 7431c533c17baff841e383a539fdd3c0a65135181b0David Brazdil " 17: ReturnVoid\n" 7441c533c17baff841e383a539fdd3c0a65135181b0David Brazdil "BasicBlock 4, pred: 1\n" 7451c533c17baff841e383a539fdd3c0a65135181b0David Brazdil " 18: Exit\n"; 746556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 74793445689c714e53cabf347da4321ecf3023e926cRoland Levillain TestCode(data, 74893445689c714e53cabf347da4321ecf3023e926cRoland Levillain expected_before, 74975be28332b278cff9039b54bfb228ac72f539cccRoland Levillain expected_after_cf, 75093445689c714e53cabf347da4321ecf3023e926cRoland Levillain expected_after_dce, 75175be28332b278cff9039b54bfb228ac72f539cccRoland Levillain check_after_cf); 752556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain} 753556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 75496709f17347cb7a6aae15816244d2200ca95a649Aart Bik/** 75596709f17347cb7a6aae15816244d2200ca95a649Aart Bik * Unsigned comparisons with zero. Since these instructions are not present 75696709f17347cb7a6aae15816244d2200ca95a649Aart Bik * in the bytecode, we need to set up the graph explicitly. 75796709f17347cb7a6aae15816244d2200ca95a649Aart Bik */ 75896709f17347cb7a6aae15816244d2200ca95a649Aart BikTEST_F(ConstantFoldingTest, UnsignedComparisonsWithZero) { 75996709f17347cb7a6aae15816244d2200ca95a649Aart Bik graph_ = CreateGraph(&allocator_); 76096709f17347cb7a6aae15816244d2200ca95a649Aart Bik HBasicBlock* entry_block = new (&allocator_) HBasicBlock(graph_); 76196709f17347cb7a6aae15816244d2200ca95a649Aart Bik graph_->AddBlock(entry_block); 76296709f17347cb7a6aae15816244d2200ca95a649Aart Bik graph_->SetEntryBlock(entry_block); 76396709f17347cb7a6aae15816244d2200ca95a649Aart Bik HBasicBlock* block = new (&allocator_) HBasicBlock(graph_); 76496709f17347cb7a6aae15816244d2200ca95a649Aart Bik graph_->AddBlock(block); 76596709f17347cb7a6aae15816244d2200ca95a649Aart Bik HBasicBlock* exit_block = new (&allocator_) HBasicBlock(graph_); 76696709f17347cb7a6aae15816244d2200ca95a649Aart Bik graph_->AddBlock(exit_block); 76796709f17347cb7a6aae15816244d2200ca95a649Aart Bik graph_->SetExitBlock(exit_block); 76896709f17347cb7a6aae15816244d2200ca95a649Aart Bik entry_block->AddSuccessor(block); 76996709f17347cb7a6aae15816244d2200ca95a649Aart Bik block->AddSuccessor(exit_block); 77096709f17347cb7a6aae15816244d2200ca95a649Aart Bik 77196709f17347cb7a6aae15816244d2200ca95a649Aart Bik // Make various unsigned comparisons with zero against a parameter. 77296709f17347cb7a6aae15816244d2200ca95a649Aart Bik HInstruction* parameter = new (&allocator_) HParameterValue( 77396709f17347cb7a6aae15816244d2200ca95a649Aart Bik graph_->GetDexFile(), 0, 0, Primitive::kPrimInt, true); 77496709f17347cb7a6aae15816244d2200ca95a649Aart Bik entry_block->AddInstruction(parameter); 77596709f17347cb7a6aae15816244d2200ca95a649Aart Bik HInstruction* zero = graph_->GetIntConstant(0); 77696709f17347cb7a6aae15816244d2200ca95a649Aart Bik HInstruction* last; 77796709f17347cb7a6aae15816244d2200ca95a649Aart Bik block->AddInstruction(last = new (&allocator_) HAbove(zero, parameter)); 77896709f17347cb7a6aae15816244d2200ca95a649Aart Bik block->AddInstruction(new (&allocator_) HDeoptimize(last, 0)); 77996709f17347cb7a6aae15816244d2200ca95a649Aart Bik block->AddInstruction(last = new (&allocator_) HAbove(parameter, zero)); 78096709f17347cb7a6aae15816244d2200ca95a649Aart Bik block->AddInstruction(new (&allocator_) HDeoptimize(last, 0)); 78196709f17347cb7a6aae15816244d2200ca95a649Aart Bik block->AddInstruction(last = new (&allocator_) HAboveOrEqual(zero, parameter)); 78296709f17347cb7a6aae15816244d2200ca95a649Aart Bik block->AddInstruction(new (&allocator_) HDeoptimize(last, 0)); 78396709f17347cb7a6aae15816244d2200ca95a649Aart Bik block->AddInstruction(last = new (&allocator_) HAboveOrEqual(parameter, zero)); 78496709f17347cb7a6aae15816244d2200ca95a649Aart Bik block->AddInstruction(new (&allocator_) HDeoptimize(last, 0)); 78596709f17347cb7a6aae15816244d2200ca95a649Aart Bik block->AddInstruction(last = new (&allocator_) HBelow(zero, parameter)); 78696709f17347cb7a6aae15816244d2200ca95a649Aart Bik block->AddInstruction(new (&allocator_) HDeoptimize(last, 0)); 78796709f17347cb7a6aae15816244d2200ca95a649Aart Bik block->AddInstruction(last = new (&allocator_) HBelow(parameter, zero)); 78896709f17347cb7a6aae15816244d2200ca95a649Aart Bik block->AddInstruction(new (&allocator_) HDeoptimize(last, 0)); 78996709f17347cb7a6aae15816244d2200ca95a649Aart Bik block->AddInstruction(last = new (&allocator_) HBelowOrEqual(zero, parameter)); 79096709f17347cb7a6aae15816244d2200ca95a649Aart Bik block->AddInstruction(new (&allocator_) HDeoptimize(last, 0)); 79196709f17347cb7a6aae15816244d2200ca95a649Aart Bik block->AddInstruction(last = new (&allocator_) HBelowOrEqual(parameter, zero)); 79296709f17347cb7a6aae15816244d2200ca95a649Aart Bik block->AddInstruction(new (&allocator_) HDeoptimize(last, 0)); 79396709f17347cb7a6aae15816244d2200ca95a649Aart Bik 79496709f17347cb7a6aae15816244d2200ca95a649Aart Bik entry_block->AddInstruction(new (&allocator_) HGoto()); 79596709f17347cb7a6aae15816244d2200ca95a649Aart Bik block->AddInstruction(new (&allocator_) HReturn(zero)); 79696709f17347cb7a6aae15816244d2200ca95a649Aart Bik exit_block->AddInstruction(new (&allocator_) HExit()); 79796709f17347cb7a6aae15816244d2200ca95a649Aart Bik 79896709f17347cb7a6aae15816244d2200ca95a649Aart Bik const std::string expected_before = 79996709f17347cb7a6aae15816244d2200ca95a649Aart Bik "BasicBlock 0, succ: 1\n" 80096709f17347cb7a6aae15816244d2200ca95a649Aart Bik " 0: ParameterValue [16, 14, 12, 10, 8, 6, 4, 2]\n" 80196709f17347cb7a6aae15816244d2200ca95a649Aart Bik " 1: IntConstant [19, 16, 14, 12, 10, 8, 6, 4, 2]\n" 80296709f17347cb7a6aae15816244d2200ca95a649Aart Bik " 18: Goto 1\n" 80396709f17347cb7a6aae15816244d2200ca95a649Aart Bik "BasicBlock 1, pred: 0, succ: 2\n" 80496709f17347cb7a6aae15816244d2200ca95a649Aart Bik " 2: Above(1, 0) [3]\n" 80596709f17347cb7a6aae15816244d2200ca95a649Aart Bik " 3: Deoptimize(2)\n" 80696709f17347cb7a6aae15816244d2200ca95a649Aart Bik " 4: Above(0, 1) [5]\n" 80796709f17347cb7a6aae15816244d2200ca95a649Aart Bik " 5: Deoptimize(4)\n" 80896709f17347cb7a6aae15816244d2200ca95a649Aart Bik " 6: AboveOrEqual(1, 0) [7]\n" 80996709f17347cb7a6aae15816244d2200ca95a649Aart Bik " 7: Deoptimize(6)\n" 81096709f17347cb7a6aae15816244d2200ca95a649Aart Bik " 8: AboveOrEqual(0, 1) [9]\n" 81196709f17347cb7a6aae15816244d2200ca95a649Aart Bik " 9: Deoptimize(8)\n" 81296709f17347cb7a6aae15816244d2200ca95a649Aart Bik " 10: Below(1, 0) [11]\n" 81396709f17347cb7a6aae15816244d2200ca95a649Aart Bik " 11: Deoptimize(10)\n" 81496709f17347cb7a6aae15816244d2200ca95a649Aart Bik " 12: Below(0, 1) [13]\n" 81596709f17347cb7a6aae15816244d2200ca95a649Aart Bik " 13: Deoptimize(12)\n" 81696709f17347cb7a6aae15816244d2200ca95a649Aart Bik " 14: BelowOrEqual(1, 0) [15]\n" 81796709f17347cb7a6aae15816244d2200ca95a649Aart Bik " 15: Deoptimize(14)\n" 81896709f17347cb7a6aae15816244d2200ca95a649Aart Bik " 16: BelowOrEqual(0, 1) [17]\n" 81996709f17347cb7a6aae15816244d2200ca95a649Aart Bik " 17: Deoptimize(16)\n" 82096709f17347cb7a6aae15816244d2200ca95a649Aart Bik " 19: Return(1)\n" 82196709f17347cb7a6aae15816244d2200ca95a649Aart Bik "BasicBlock 2, pred: 1\n" 82296709f17347cb7a6aae15816244d2200ca95a649Aart Bik " 20: Exit\n"; 82396709f17347cb7a6aae15816244d2200ca95a649Aart Bik 82496709f17347cb7a6aae15816244d2200ca95a649Aart Bik const std::string expected_after_cf = 82596709f17347cb7a6aae15816244d2200ca95a649Aart Bik "BasicBlock 0, succ: 1\n" 82696709f17347cb7a6aae15816244d2200ca95a649Aart Bik " 0: ParameterValue [16, 10, 6, 4]\n" 82796709f17347cb7a6aae15816244d2200ca95a649Aart Bik " 1: IntConstant [13, 3, 19, 16, 10, 6, 4]\n" 82896709f17347cb7a6aae15816244d2200ca95a649Aart Bik " 21: IntConstant [15, 9]\n" 82996709f17347cb7a6aae15816244d2200ca95a649Aart Bik " 18: Goto 1\n" 83096709f17347cb7a6aae15816244d2200ca95a649Aart Bik "BasicBlock 1, pred: 0, succ: 2\n" 83196709f17347cb7a6aae15816244d2200ca95a649Aart Bik " 3: Deoptimize(1)\n" 83296709f17347cb7a6aae15816244d2200ca95a649Aart Bik " 4: Above(0, 1) [5]\n" 83396709f17347cb7a6aae15816244d2200ca95a649Aart Bik " 5: Deoptimize(4)\n" 83496709f17347cb7a6aae15816244d2200ca95a649Aart Bik " 6: AboveOrEqual(1, 0) [7]\n" 83596709f17347cb7a6aae15816244d2200ca95a649Aart Bik " 7: Deoptimize(6)\n" 83696709f17347cb7a6aae15816244d2200ca95a649Aart Bik " 9: Deoptimize(21)\n" 83796709f17347cb7a6aae15816244d2200ca95a649Aart Bik " 10: Below(1, 0) [11]\n" 83896709f17347cb7a6aae15816244d2200ca95a649Aart Bik " 11: Deoptimize(10)\n" 83996709f17347cb7a6aae15816244d2200ca95a649Aart Bik " 13: Deoptimize(1)\n" 84096709f17347cb7a6aae15816244d2200ca95a649Aart Bik " 15: Deoptimize(21)\n" 84196709f17347cb7a6aae15816244d2200ca95a649Aart Bik " 16: BelowOrEqual(0, 1) [17]\n" 84296709f17347cb7a6aae15816244d2200ca95a649Aart Bik " 17: Deoptimize(16)\n" 84396709f17347cb7a6aae15816244d2200ca95a649Aart Bik " 19: Return(1)\n" 84496709f17347cb7a6aae15816244d2200ca95a649Aart Bik "BasicBlock 2, pred: 1\n" 84596709f17347cb7a6aae15816244d2200ca95a649Aart Bik " 20: Exit\n"; 84696709f17347cb7a6aae15816244d2200ca95a649Aart Bik 84796709f17347cb7a6aae15816244d2200ca95a649Aart Bik const std::string expected_after_dce = expected_after_cf; 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