constant_folding_test.cc revision fb8d279bc011b31d0765dc7ca59afea324fd0d0c
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 32556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillainstatic void TestCode(const uint16_t* data, 33556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain const std::string& expected_before, 3475be28332b278cff9039b54bfb228ac72f539cccRoland Levillain const std::string& expected_after_cf, 357fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray const std::string& expected_after_dce, 3675be28332b278cff9039b54bfb228ac72f539cccRoland Levillain std::function<void(HGraph*)> check_after_cf, 377fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray Primitive::Type return_type = Primitive::kPrimInt) { 38556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain ArenaPool pool; 39556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain ArenaAllocator allocator(&pool); 407fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray HGraph* graph = CreateCFG(&allocator, data, return_type); 41556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain ASSERT_NE(graph, nullptr); 42556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 43e53798a7e3267305f696bf658e418c92e63e0834Nicolas Geoffray graph->TryBuildingSsa(); 44556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 45556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain StringPrettyPrinter printer_before(graph); 46556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain printer_before.VisitInsertionOrder(); 47556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain std::string actual_before = printer_before.str(); 48556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain ASSERT_EQ(expected_before, actual_before); 49556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 50fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell std::unique_ptr<const X86InstructionSetFeatures> features_x86( 51fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell X86InstructionSetFeatures::FromCppDefines()); 52fb8d279bc011b31d0765dc7ca59afea324fd0d0cMark Mendell x86::CodeGeneratorX86 codegenX86(graph, *features_x86.get(), CompilerOptions()); 535e6916cea259897baaca019c5c7a5d05746306edNicolas Geoffray HConstantFolding(graph).Run(); 54942a3785dca38feaae9d01b35d6bfb09c39315ebNicolas Geoffray SSAChecker ssa_checker_cf(&allocator, graph); 55942a3785dca38feaae9d01b35d6bfb09c39315ebNicolas Geoffray ssa_checker_cf.Run(); 56942a3785dca38feaae9d01b35d6bfb09c39315ebNicolas Geoffray ASSERT_TRUE(ssa_checker_cf.IsValid()); 57556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 5875be28332b278cff9039b54bfb228ac72f539cccRoland Levillain StringPrettyPrinter printer_after_cf(graph); 5975be28332b278cff9039b54bfb228ac72f539cccRoland Levillain printer_after_cf.VisitInsertionOrder(); 6075be28332b278cff9039b54bfb228ac72f539cccRoland Levillain std::string actual_after_cf = printer_after_cf.str(); 6175be28332b278cff9039b54bfb228ac72f539cccRoland Levillain ASSERT_EQ(expected_after_cf, actual_after_cf); 62556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 6375be28332b278cff9039b54bfb228ac72f539cccRoland Levillain check_after_cf(graph); 6493445689c714e53cabf347da4321ecf3023e926cRoland Levillain 655e6916cea259897baaca019c5c7a5d05746306edNicolas Geoffray HDeadCodeElimination(graph).Run(); 66942a3785dca38feaae9d01b35d6bfb09c39315ebNicolas Geoffray SSAChecker ssa_checker_dce(&allocator, graph); 67942a3785dca38feaae9d01b35d6bfb09c39315ebNicolas Geoffray ssa_checker_dce.Run(); 68942a3785dca38feaae9d01b35d6bfb09c39315ebNicolas Geoffray ASSERT_TRUE(ssa_checker_dce.IsValid()); 69556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 70556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain StringPrettyPrinter printer_after_dce(graph); 71556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain printer_after_dce.VisitInsertionOrder(); 72556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain std::string actual_after_dce = printer_after_dce.str(); 73556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain ASSERT_EQ(expected_after_dce, actual_after_dce); 74556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain} 75556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 76556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 77556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain/** 789240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain * Tiny three-register program exercising int constant folding on negation. 799240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain * 809240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain * 16-bit 819240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain * offset 829240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain * ------ 839240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain * v0 <- 1 0. const/4 v0, #+1 849240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain * v1 <- -v0 1. neg-int v0, v1 859240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain * return v1 2. return v1 869240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain */ 879240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland LevillainTEST(ConstantFolding, IntConstantFoldingNegation) { 889240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain const uint16_t data[] = TWO_REGISTERS_CODE_ITEM( 899240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain Instruction::CONST_4 | 0 << 8 | 1 << 12, 909240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain Instruction::NEG_INT | 1 << 8 | 0 << 12, 919240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain Instruction::RETURN | 1 << 8); 929240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain 939240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain std::string expected_before = 949240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain "BasicBlock 0, succ: 1\n" 959240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain " 2: IntConstant [5]\n" 969240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain " 10: SuspendCheck\n" 979240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain " 11: Goto 1\n" 989240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain "BasicBlock 1, pred: 0, succ: 2\n" 999240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain " 5: Neg(2) [8]\n" 1009240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain " 8: Return(5)\n" 1019240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain "BasicBlock 2, pred: 1\n" 1029240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain " 9: Exit\n"; 1039240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain 1049240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain // Expected difference after constant folding. 1059240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain diff_t expected_cf_diff = { 1069240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain { " 2: IntConstant [5]\n", " 2: IntConstant\n" }, 1078d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil { " 10: SuspendCheck\n", " 10: SuspendCheck\n" 1088d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil " 12: IntConstant [8]\n" }, 1098d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil { " 5: Neg(2) [8]\n", removed }, 1109240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain { " 8: Return(5)\n", " 8: Return(12)\n" } 1119240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain }; 1129240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain std::string expected_after_cf = Patch(expected_before, expected_cf_diff); 1139240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain 1149240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain // Check the value of the computed constant. 1159240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain auto check_after_cf = [](HGraph* graph) { 1168d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil HInstruction* inst = graph->GetBlock(1)->GetFirstInstruction()->InputAt(0); 1179240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain ASSERT_TRUE(inst->IsIntConstant()); 1189240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain ASSERT_EQ(inst->AsIntConstant()->GetValue(), -1); 1199240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain }; 1209240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain 1219240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain // Expected difference after dead code elimination. 1229240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain diff_t expected_dce_diff = { 1239240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain { " 2: IntConstant\n", removed }, 1249240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain }; 1259240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain std::string expected_after_dce = Patch(expected_after_cf, expected_dce_diff); 1269240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain 1279240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain TestCode(data, 1289240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain expected_before, 1299240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain expected_after_cf, 1309240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain expected_after_dce, 1319240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain check_after_cf); 1329240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain} 1339240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain 1349240d6a2baa9ed1e18ee08744b461fe49a1ee269Roland Levillain/** 135556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * Tiny three-register program exercising int constant folding on addition. 136556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * 137556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * 16-bit 138556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * offset 139556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * ------ 140556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * v0 <- 1 0. const/4 v0, #+1 141556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * v1 <- 2 1. const/4 v1, #+2 142556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * v2 <- v0 + v1 2. add-int v2, v0, v1 143556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * return v2 4. return v2 144556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain */ 14575be28332b278cff9039b54bfb228ac72f539cccRoland LevillainTEST(ConstantFolding, IntConstantFoldingOnAddition1) { 146556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain const uint16_t data[] = THREE_REGISTERS_CODE_ITEM( 147556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::CONST_4 | 0 << 8 | 1 << 12, 148556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::CONST_4 | 1 << 8 | 2 << 12, 149556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::ADD_INT | 2 << 8, 0 | 1 << 8, 150556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::RETURN | 2 << 8); 151556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 152556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain std::string expected_before = 153556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain "BasicBlock 0, succ: 1\n" 154556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 3: IntConstant [9]\n" 155556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 5: IntConstant [9]\n" 156556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 14: SuspendCheck\n" 157556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 15: Goto 1\n" 158556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain "BasicBlock 1, pred: 0, succ: 2\n" 159556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 9: Add(3, 5) [12]\n" 160556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 12: Return(9)\n" 161556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain "BasicBlock 2, pred: 1\n" 162556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 13: Exit\n"; 163556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 16475be28332b278cff9039b54bfb228ac72f539cccRoland Levillain // Expected difference after constant folding. 16575be28332b278cff9039b54bfb228ac72f539cccRoland Levillain diff_t expected_cf_diff = { 166556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 3: IntConstant [9]\n", " 3: IntConstant\n" }, 167556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 5: IntConstant [9]\n", " 5: IntConstant\n" }, 1688d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil { " 14: SuspendCheck\n", " 14: SuspendCheck\n" 1698d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil " 16: IntConstant [12]\n" }, 1708d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil { " 9: Add(3, 5) [12]\n", removed }, 171556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 12: Return(9)\n", " 12: Return(16)\n" } 172556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain }; 17375be28332b278cff9039b54bfb228ac72f539cccRoland Levillain std::string expected_after_cf = Patch(expected_before, expected_cf_diff); 174556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 17593445689c714e53cabf347da4321ecf3023e926cRoland Levillain // Check the value of the computed constant. 17675be28332b278cff9039b54bfb228ac72f539cccRoland Levillain auto check_after_cf = [](HGraph* graph) { 1778d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil HInstruction* inst = graph->GetBlock(1)->GetFirstInstruction()->InputAt(0); 17893445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_TRUE(inst->IsIntConstant()); 17993445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_EQ(inst->AsIntConstant()->GetValue(), 3); 18093445689c714e53cabf347da4321ecf3023e926cRoland Levillain }; 18193445689c714e53cabf347da4321ecf3023e926cRoland Levillain 182556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain // Expected difference after dead code elimination. 183556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain diff_t expected_dce_diff = { 184556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 3: IntConstant\n", removed }, 185556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 5: IntConstant\n", removed } 186556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain }; 18775be28332b278cff9039b54bfb228ac72f539cccRoland Levillain std::string expected_after_dce = Patch(expected_after_cf, expected_dce_diff); 188556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 18993445689c714e53cabf347da4321ecf3023e926cRoland Levillain TestCode(data, 19093445689c714e53cabf347da4321ecf3023e926cRoland Levillain expected_before, 19175be28332b278cff9039b54bfb228ac72f539cccRoland Levillain expected_after_cf, 19293445689c714e53cabf347da4321ecf3023e926cRoland Levillain expected_after_dce, 19375be28332b278cff9039b54bfb228ac72f539cccRoland Levillain check_after_cf); 194556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain} 195556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 196556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain/** 197556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * Small three-register program exercising int constant folding on addition. 198556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * 199556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * 16-bit 200556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * offset 201556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * ------ 202556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * v0 <- 1 0. const/4 v0, #+1 203556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * v1 <- 2 1. const/4 v1, #+2 204556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * v0 <- v0 + v1 2. add-int/2addr v0, v1 2058d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil * v1 <- 4 3. const/4 v1, #+4 2068d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil * v2 <- 5 4. const/4 v2, #+5 207556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * v1 <- v1 + v2 5. add-int/2addr v1, v2 208556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * v2 <- v0 + v1 6. add-int v2, v0, v1 209556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * return v2 8. return v2 210556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain */ 21175be28332b278cff9039b54bfb228ac72f539cccRoland LevillainTEST(ConstantFolding, IntConstantFoldingOnAddition2) { 212556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain const uint16_t data[] = THREE_REGISTERS_CODE_ITEM( 213556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::CONST_4 | 0 << 8 | 1 << 12, 214556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::CONST_4 | 1 << 8 | 2 << 12, 215556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::ADD_INT_2ADDR | 0 << 8 | 1 << 12, 2168d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil Instruction::CONST_4 | 1 << 8 | 4 << 12, 2178d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil Instruction::CONST_4 | 2 << 8 | 5 << 12, 218556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::ADD_INT_2ADDR | 1 << 8 | 2 << 12, 219556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::ADD_INT | 2 << 8, 0 | 1 << 8, 220556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::RETURN | 2 << 8); 221556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 222556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain std::string expected_before = 223556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain "BasicBlock 0, succ: 1\n" 224556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 3: IntConstant [9]\n" 225556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 5: IntConstant [9]\n" 226556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 11: IntConstant [17]\n" 227556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 13: IntConstant [17]\n" 228556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 26: SuspendCheck\n" 229556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 27: Goto 1\n" 230556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain "BasicBlock 1, pred: 0, succ: 2\n" 231556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 9: Add(3, 5) [21]\n" 232556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 17: Add(11, 13) [21]\n" 233556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 21: Add(9, 17) [24]\n" 234556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 24: Return(21)\n" 235556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain "BasicBlock 2, pred: 1\n" 236556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 25: Exit\n"; 237556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 23875be28332b278cff9039b54bfb228ac72f539cccRoland Levillain // Expected difference after constant folding. 23975be28332b278cff9039b54bfb228ac72f539cccRoland Levillain diff_t expected_cf_diff = { 240556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 3: IntConstant [9]\n", " 3: IntConstant\n" }, 241556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 5: IntConstant [9]\n", " 5: IntConstant\n" }, 242556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 11: IntConstant [17]\n", " 11: IntConstant\n" }, 243556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 13: IntConstant [17]\n", " 13: IntConstant\n" }, 2448d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil { " 26: SuspendCheck\n", " 26: SuspendCheck\n" 2458d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil " 28: IntConstant\n" 2468d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil " 29: IntConstant\n" 2478d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil " 30: IntConstant [24]\n" }, 2488d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil { " 9: Add(3, 5) [21]\n", removed }, 2498d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil { " 17: Add(11, 13) [21]\n", removed }, 2508d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil { " 21: Add(9, 17) [24]\n", removed }, 251556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 24: Return(21)\n", " 24: Return(30)\n" } 252556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain }; 25375be28332b278cff9039b54bfb228ac72f539cccRoland Levillain std::string expected_after_cf = Patch(expected_before, expected_cf_diff); 254556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 25593445689c714e53cabf347da4321ecf3023e926cRoland Levillain // Check the values of the computed constants. 25675be28332b278cff9039b54bfb228ac72f539cccRoland Levillain auto check_after_cf = [](HGraph* graph) { 2578d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil HInstruction* inst1 = graph->GetBlock(1)->GetFirstInstruction()->InputAt(0); 25893445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_TRUE(inst1->IsIntConstant()); 2598d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil ASSERT_EQ(inst1->AsIntConstant()->GetValue(), 12); 2608d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil HInstruction* inst2 = inst1->GetPrevious(); 26193445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_TRUE(inst2->IsIntConstant()); 2628d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil ASSERT_EQ(inst2->AsIntConstant()->GetValue(), 9); 2638d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil HInstruction* inst3 = inst2->GetPrevious(); 26493445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_TRUE(inst3->IsIntConstant()); 2658d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil ASSERT_EQ(inst3->AsIntConstant()->GetValue(), 3); 26693445689c714e53cabf347da4321ecf3023e926cRoland Levillain }; 26793445689c714e53cabf347da4321ecf3023e926cRoland Levillain 268556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain // Expected difference after dead code elimination. 269556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain diff_t expected_dce_diff = { 270556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 3: IntConstant\n", removed }, 271556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 5: IntConstant\n", removed }, 272556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 11: IntConstant\n", removed }, 273556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 13: IntConstant\n", removed }, 274556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 28: IntConstant\n", removed }, 275556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 29: IntConstant\n", removed } 276556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain }; 27775be28332b278cff9039b54bfb228ac72f539cccRoland Levillain std::string expected_after_dce = Patch(expected_after_cf, expected_dce_diff); 278556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 27993445689c714e53cabf347da4321ecf3023e926cRoland Levillain TestCode(data, 28093445689c714e53cabf347da4321ecf3023e926cRoland Levillain expected_before, 28175be28332b278cff9039b54bfb228ac72f539cccRoland Levillain expected_after_cf, 28293445689c714e53cabf347da4321ecf3023e926cRoland Levillain expected_after_dce, 28375be28332b278cff9039b54bfb228ac72f539cccRoland Levillain check_after_cf); 284556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain} 285556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 286556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain/** 287556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * Tiny three-register program exercising int constant folding on subtraction. 288556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * 289556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * 16-bit 290556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * offset 291556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * ------ 292556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * v0 <- 3 0. const/4 v0, #+3 293556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * v1 <- 2 1. const/4 v1, #+2 294556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * v2 <- v0 - v1 2. sub-int v2, v0, v1 295556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * return v2 4. return v2 296556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain */ 29775be28332b278cff9039b54bfb228ac72f539cccRoland LevillainTEST(ConstantFolding, IntConstantFoldingOnSubtraction) { 298556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain const uint16_t data[] = THREE_REGISTERS_CODE_ITEM( 299556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::CONST_4 | 0 << 8 | 3 << 12, 300556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::CONST_4 | 1 << 8 | 2 << 12, 301556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::SUB_INT | 2 << 8, 0 | 1 << 8, 302556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::RETURN | 2 << 8); 303556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 304556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain std::string expected_before = 305556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain "BasicBlock 0, succ: 1\n" 306556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 3: IntConstant [9]\n" 307556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 5: IntConstant [9]\n" 308556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 14: SuspendCheck\n" 309556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 15: Goto 1\n" 310556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain "BasicBlock 1, pred: 0, succ: 2\n" 311556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 9: Sub(3, 5) [12]\n" 312556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 12: Return(9)\n" 313556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain "BasicBlock 2, pred: 1\n" 314556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 13: Exit\n"; 315556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 31675be28332b278cff9039b54bfb228ac72f539cccRoland Levillain // Expected difference after constant folding. 31775be28332b278cff9039b54bfb228ac72f539cccRoland Levillain diff_t expected_cf_diff = { 318556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 3: IntConstant [9]\n", " 3: IntConstant\n" }, 319556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 5: IntConstant [9]\n", " 5: IntConstant\n" }, 3208d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil { " 14: SuspendCheck\n", " 14: SuspendCheck\n" 3218d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil " 16: IntConstant [12]\n" }, 3228d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil { " 9: Sub(3, 5) [12]\n", removed }, 323556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 12: Return(9)\n", " 12: Return(16)\n" } 324556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain }; 32575be28332b278cff9039b54bfb228ac72f539cccRoland Levillain std::string expected_after_cf = Patch(expected_before, expected_cf_diff); 326556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 32793445689c714e53cabf347da4321ecf3023e926cRoland Levillain // Check the value of the computed constant. 32875be28332b278cff9039b54bfb228ac72f539cccRoland Levillain auto check_after_cf = [](HGraph* graph) { 3298d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil HInstruction* inst = graph->GetBlock(1)->GetFirstInstruction()->InputAt(0); 33093445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_TRUE(inst->IsIntConstant()); 33193445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_EQ(inst->AsIntConstant()->GetValue(), 1); 33293445689c714e53cabf347da4321ecf3023e926cRoland Levillain }; 33393445689c714e53cabf347da4321ecf3023e926cRoland Levillain 334556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain // Expected difference after dead code elimination. 335556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain diff_t expected_dce_diff = { 336556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 3: IntConstant\n", removed }, 337556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 5: IntConstant\n", removed } 338556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain }; 33975be28332b278cff9039b54bfb228ac72f539cccRoland Levillain std::string expected_after_dce = Patch(expected_after_cf, expected_dce_diff); 340556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 34193445689c714e53cabf347da4321ecf3023e926cRoland Levillain TestCode(data, 34293445689c714e53cabf347da4321ecf3023e926cRoland Levillain expected_before, 34375be28332b278cff9039b54bfb228ac72f539cccRoland Levillain expected_after_cf, 34493445689c714e53cabf347da4321ecf3023e926cRoland Levillain expected_after_dce, 34575be28332b278cff9039b54bfb228ac72f539cccRoland Levillain check_after_cf); 346556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain} 347556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 348556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain/** 349556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * Tiny three-register-pair program exercising long constant folding 350556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * on addition. 351556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * 352556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * 16-bit 353556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * offset 354556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * ------ 355556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * (v0, v1) <- 1 0. const-wide/16 v0, #+1 356556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * (v2, v3) <- 2 2. const-wide/16 v2, #+2 357556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * (v4, v5) <- 358556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * (v0, v1) + (v1, v2) 4. add-long v4, v0, v2 359556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * return (v4, v5) 6. return-wide v4 360556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain */ 36175be28332b278cff9039b54bfb228ac72f539cccRoland LevillainTEST(ConstantFolding, LongConstantFoldingOnAddition) { 362556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain const uint16_t data[] = SIX_REGISTERS_CODE_ITEM( 363556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::CONST_WIDE_16 | 0 << 8, 1, 364556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::CONST_WIDE_16 | 2 << 8, 2, 365556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::ADD_LONG | 4 << 8, 0 | 2 << 8, 366556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::RETURN_WIDE | 4 << 8); 367556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 368556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain std::string expected_before = 369556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain "BasicBlock 0, succ: 1\n" 370556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 6: LongConstant [12]\n" 371556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 8: LongConstant [12]\n" 372556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 17: SuspendCheck\n" 373556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 18: Goto 1\n" 374556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain "BasicBlock 1, pred: 0, succ: 2\n" 375556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 12: Add(6, 8) [15]\n" 376556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 15: Return(12)\n" 377556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain "BasicBlock 2, pred: 1\n" 378556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 16: Exit\n"; 379556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 38075be28332b278cff9039b54bfb228ac72f539cccRoland Levillain // Expected difference after constant folding. 38175be28332b278cff9039b54bfb228ac72f539cccRoland Levillain diff_t expected_cf_diff = { 382556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 6: LongConstant [12]\n", " 6: LongConstant\n" }, 383556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 8: LongConstant [12]\n", " 8: LongConstant\n" }, 3848d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil { " 17: SuspendCheck\n", " 17: SuspendCheck\n" 3858d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil " 19: LongConstant [15]\n" }, 3868d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil { " 12: Add(6, 8) [15]\n", removed }, 387556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 15: Return(12)\n", " 15: Return(19)\n" } 388556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain }; 38975be28332b278cff9039b54bfb228ac72f539cccRoland Levillain std::string expected_after_cf = Patch(expected_before, expected_cf_diff); 390556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 39193445689c714e53cabf347da4321ecf3023e926cRoland Levillain // Check the value of the computed constant. 39275be28332b278cff9039b54bfb228ac72f539cccRoland Levillain auto check_after_cf = [](HGraph* graph) { 3938d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil HInstruction* inst = graph->GetBlock(1)->GetFirstInstruction()->InputAt(0); 39493445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_TRUE(inst->IsLongConstant()); 39593445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_EQ(inst->AsLongConstant()->GetValue(), 3); 39693445689c714e53cabf347da4321ecf3023e926cRoland Levillain }; 39793445689c714e53cabf347da4321ecf3023e926cRoland Levillain 398556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain // Expected difference after dead code elimination. 399556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain diff_t expected_dce_diff = { 400556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 6: LongConstant\n", removed }, 401556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 8: LongConstant\n", removed } 402556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain }; 40375be28332b278cff9039b54bfb228ac72f539cccRoland Levillain std::string expected_after_dce = Patch(expected_after_cf, expected_dce_diff); 404556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 40593445689c714e53cabf347da4321ecf3023e926cRoland Levillain TestCode(data, 40693445689c714e53cabf347da4321ecf3023e926cRoland Levillain expected_before, 40775be28332b278cff9039b54bfb228ac72f539cccRoland Levillain expected_after_cf, 40893445689c714e53cabf347da4321ecf3023e926cRoland Levillain expected_after_dce, 40975be28332b278cff9039b54bfb228ac72f539cccRoland Levillain check_after_cf, 41093445689c714e53cabf347da4321ecf3023e926cRoland Levillain Primitive::kPrimLong); 411556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain} 412556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 413556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain/** 414556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * Tiny three-register-pair program exercising long constant folding 415556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * on subtraction. 416556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * 417556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * 16-bit 418556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * offset 419556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * ------ 420556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * (v0, v1) <- 3 0. const-wide/16 v0, #+3 421556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * (v2, v3) <- 2 2. const-wide/16 v2, #+2 422556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * (v4, v5) <- 423556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * (v0, v1) - (v1, v2) 4. sub-long v4, v0, v2 424556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * return (v4, v5) 6. return-wide v4 425556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain */ 42675be28332b278cff9039b54bfb228ac72f539cccRoland LevillainTEST(ConstantFolding, LongConstantFoldingOnSubtraction) { 427556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain const uint16_t data[] = SIX_REGISTERS_CODE_ITEM( 428556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::CONST_WIDE_16 | 0 << 8, 3, 429556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::CONST_WIDE_16 | 2 << 8, 2, 430556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::SUB_LONG | 4 << 8, 0 | 2 << 8, 431556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::RETURN_WIDE | 4 << 8); 432556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 433556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain std::string expected_before = 434556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain "BasicBlock 0, succ: 1\n" 435556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 6: LongConstant [12]\n" 436556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 8: LongConstant [12]\n" 437556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 17: SuspendCheck\n" 438556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 18: Goto 1\n" 439556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain "BasicBlock 1, pred: 0, succ: 2\n" 440556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 12: Sub(6, 8) [15]\n" 441556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 15: Return(12)\n" 442556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain "BasicBlock 2, pred: 1\n" 443556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 16: Exit\n"; 444556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 44575be28332b278cff9039b54bfb228ac72f539cccRoland Levillain // Expected difference after constant folding. 44675be28332b278cff9039b54bfb228ac72f539cccRoland Levillain diff_t expected_cf_diff = { 447556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 6: LongConstant [12]\n", " 6: LongConstant\n" }, 448556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 8: LongConstant [12]\n", " 8: LongConstant\n" }, 4498d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil { " 17: SuspendCheck\n", " 17: SuspendCheck\n" 4508d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil " 19: LongConstant [15]\n" }, 4518d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil { " 12: Sub(6, 8) [15]\n", removed }, 452556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 15: Return(12)\n", " 15: Return(19)\n" } 453556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain }; 45475be28332b278cff9039b54bfb228ac72f539cccRoland Levillain std::string expected_after_cf = Patch(expected_before, expected_cf_diff); 455556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 45693445689c714e53cabf347da4321ecf3023e926cRoland Levillain // Check the value of the computed constant. 45775be28332b278cff9039b54bfb228ac72f539cccRoland Levillain auto check_after_cf = [](HGraph* graph) { 4588d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil HInstruction* inst = graph->GetBlock(1)->GetFirstInstruction()->InputAt(0); 45993445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_TRUE(inst->IsLongConstant()); 46093445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_EQ(inst->AsLongConstant()->GetValue(), 1); 46193445689c714e53cabf347da4321ecf3023e926cRoland Levillain }; 46293445689c714e53cabf347da4321ecf3023e926cRoland Levillain 463556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain // Expected difference after dead code elimination. 464556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain diff_t expected_dce_diff = { 465556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 6: LongConstant\n", removed }, 466556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 8: LongConstant\n", removed } 467556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain }; 46875be28332b278cff9039b54bfb228ac72f539cccRoland Levillain std::string expected_after_dce = Patch(expected_after_cf, expected_dce_diff); 469556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 47093445689c714e53cabf347da4321ecf3023e926cRoland Levillain TestCode(data, 47193445689c714e53cabf347da4321ecf3023e926cRoland Levillain expected_before, 47275be28332b278cff9039b54bfb228ac72f539cccRoland Levillain expected_after_cf, 47393445689c714e53cabf347da4321ecf3023e926cRoland Levillain expected_after_dce, 47475be28332b278cff9039b54bfb228ac72f539cccRoland Levillain check_after_cf, 47593445689c714e53cabf347da4321ecf3023e926cRoland Levillain Primitive::kPrimLong); 476556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain} 477556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 478556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain/** 479556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * Three-register program with jumps leading to the creation of many 480556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * blocks. 481556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * 482556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * The intent of this test is to ensure that all constant expressions 483556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * are actually evaluated at compile-time, thanks to the reverse 484556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * (forward) post-order traversal of the the dominator tree. 485556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * 486556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * 16-bit 487556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * offset 488556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * ------ 4898d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil * v0 <- 1 0. const/4 v0, #+1 4908d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil * v1 <- 2 1. const/4 v1, #+2 491556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * v2 <- v0 + v1 2. add-int v2, v0, v1 492556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * goto L2 4. goto +4 4938d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil * L1: v1 <- v0 + 5 5. add-int/lit16 v1, v0, #+5 494556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * goto L3 7. goto +4 4958d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil * L2: v0 <- v2 + 4 8. add-int/lit16 v0, v2, #+4 496556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * goto L1 10. goto +(-5) 4978d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil * L3: v2 <- v1 + 8 11. add-int/lit16 v2, v1, #+8 498556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * return v2 13. return v2 499556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain */ 50075be28332b278cff9039b54bfb228ac72f539cccRoland LevillainTEST(ConstantFolding, IntConstantFoldingAndJumps) { 501556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain const uint16_t data[] = THREE_REGISTERS_CODE_ITEM( 5028d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil Instruction::CONST_4 | 0 << 8 | 1 << 12, 5038d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil Instruction::CONST_4 | 1 << 8 | 2 << 12, 504556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::ADD_INT | 2 << 8, 0 | 1 << 8, 505556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::GOTO | 4 << 8, 5068d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil Instruction::ADD_INT_LIT16 | 1 << 8 | 0 << 12, 5, 507556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::GOTO | 4 << 8, 5088d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil Instruction::ADD_INT_LIT16 | 0 << 8 | 2 << 12, 4, 509556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain static_cast<uint16_t>(Instruction::GOTO | -5 << 8), 5108d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil Instruction::ADD_INT_LIT16 | 2 << 8 | 1 << 12, 8, 511556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::RETURN | 2 << 8); 512556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 513556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain std::string expected_before = 514556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain "BasicBlock 0, succ: 1\n" 5158d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil " 3: IntConstant [9]\n" // v0 <- 1 5168d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil " 5: IntConstant [9]\n" // v1 <- 2 5178d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil " 13: IntConstant [14]\n" // const 5 5188d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil " 18: IntConstant [19]\n" // const 4 5198d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil " 24: IntConstant [25]\n" // const 8 520556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 30: SuspendCheck\n" 521556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 31: Goto 1\n" 522556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain "BasicBlock 1, pred: 0, succ: 3\n" 5238d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil " 9: Add(3, 5) [19]\n" // v2 <- v0 + v1 = 1 + 2 = 3 52493445689c714e53cabf347da4321ecf3023e926cRoland Levillain " 11: Goto 3\n" // goto L2 52593445689c714e53cabf347da4321ecf3023e926cRoland Levillain "BasicBlock 2, pred: 3, succ: 4\n" // L1: 5268d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil " 14: Add(19, 13) [25]\n" // v1 <- v0 + 3 = 7 + 5 = 12 52793445689c714e53cabf347da4321ecf3023e926cRoland Levillain " 16: Goto 4\n" // goto L3 52893445689c714e53cabf347da4321ecf3023e926cRoland Levillain "BasicBlock 3, pred: 1, succ: 2\n" // L2: 5298d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil " 19: Add(9, 18) [14]\n" // v0 <- v2 + 2 = 3 + 4 = 7 530556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 21: SuspendCheck\n" 53193445689c714e53cabf347da4321ecf3023e926cRoland Levillain " 22: Goto 2\n" // goto L1 53293445689c714e53cabf347da4321ecf3023e926cRoland Levillain "BasicBlock 4, pred: 2, succ: 5\n" // L3: 5338d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil " 25: Add(14, 24) [28]\n" // v2 <- v1 + 4 = 12 + 8 = 20 53493445689c714e53cabf347da4321ecf3023e926cRoland Levillain " 28: Return(25)\n" // return v2 535556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain "BasicBlock 5, pred: 4\n" 536556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 29: Exit\n"; 537556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 53875be28332b278cff9039b54bfb228ac72f539cccRoland Levillain // Expected difference after constant folding. 53975be28332b278cff9039b54bfb228ac72f539cccRoland Levillain diff_t expected_cf_diff = { 540556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 3: IntConstant [9]\n", " 3: IntConstant\n" }, 541556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 5: IntConstant [9]\n", " 5: IntConstant []\n" }, 542556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 13: IntConstant [14]\n", " 13: IntConstant\n" }, 543556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 18: IntConstant [19]\n", " 18: IntConstant\n" }, 544556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 24: IntConstant [25]\n", " 24: IntConstant\n" }, 5458d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil { " 30: SuspendCheck\n", " 30: SuspendCheck\n" 5468d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil " 32: IntConstant []\n" 5478d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil " 33: IntConstant []\n" 5488d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil " 34: IntConstant\n" 5498d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil " 35: IntConstant [28]\n" }, 5508d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil { " 9: Add(3, 5) [19]\n", removed }, 5518d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil { " 14: Add(19, 13) [25]\n", removed }, 5528d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil { " 19: Add(9, 18) [14]\n", removed }, 5538d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil { " 25: Add(14, 24) [28]\n", removed }, 554556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 28: Return(25)\n", " 28: Return(35)\n"} 555556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain }; 55675be28332b278cff9039b54bfb228ac72f539cccRoland Levillain std::string expected_after_cf = Patch(expected_before, expected_cf_diff); 557556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 55893445689c714e53cabf347da4321ecf3023e926cRoland Levillain // Check the values of the computed constants. 55975be28332b278cff9039b54bfb228ac72f539cccRoland Levillain auto check_after_cf = [](HGraph* graph) { 5608d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil HInstruction* inst1 = graph->GetBlock(4)->GetFirstInstruction()->InputAt(0); 56193445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_TRUE(inst1->IsIntConstant()); 5628d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil ASSERT_EQ(inst1->AsIntConstant()->GetValue(), 20); 5638d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil HInstruction* inst2 = inst1->GetPrevious(); 56493445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_TRUE(inst2->IsIntConstant()); 5658d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil ASSERT_EQ(inst2->AsIntConstant()->GetValue(), 12); 5668d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil HInstruction* inst3 = inst2->GetPrevious(); 56793445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_TRUE(inst3->IsIntConstant()); 5688d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil ASSERT_EQ(inst3->AsIntConstant()->GetValue(), 7); 5698d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil HInstruction* inst4 = inst3->GetPrevious(); 57093445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_TRUE(inst4->IsIntConstant()); 5718d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil ASSERT_EQ(inst4->AsIntConstant()->GetValue(), 3); 57293445689c714e53cabf347da4321ecf3023e926cRoland Levillain }; 57393445689c714e53cabf347da4321ecf3023e926cRoland Levillain 574556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain // Expected difference after dead code elimination. 575556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain diff_t expected_dce_diff = { 576556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 3: IntConstant\n", removed }, 577556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 13: IntConstant\n", removed }, 578556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 18: IntConstant\n", removed }, 579556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 24: IntConstant\n", removed }, 580556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 34: IntConstant\n", removed }, 581556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain }; 58275be28332b278cff9039b54bfb228ac72f539cccRoland Levillain std::string expected_after_dce = Patch(expected_after_cf, expected_dce_diff); 583556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 58493445689c714e53cabf347da4321ecf3023e926cRoland Levillain TestCode(data, 58593445689c714e53cabf347da4321ecf3023e926cRoland Levillain expected_before, 58675be28332b278cff9039b54bfb228ac72f539cccRoland Levillain expected_after_cf, 58793445689c714e53cabf347da4321ecf3023e926cRoland Levillain expected_after_dce, 58875be28332b278cff9039b54bfb228ac72f539cccRoland Levillain check_after_cf); 589556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain} 590556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 591556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 592556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain/** 593556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * Three-register program with a constant (static) condition. 594556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * 595556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * 16-bit 596556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * offset 597556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * ------ 598556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * v1 <- 1 0. const/4 v1, #+1 599556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * v0 <- 0 1. const/4 v0, #+0 600556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * if v1 >= 0 goto L1 2. if-gez v1, +3 601556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * v0 <- v1 4. move v0, v1 602556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * L1: v2 <- v0 + v1 5. add-int v2, v0, v1 603556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain * return-void 7. return 604556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain */ 60575be28332b278cff9039b54bfb228ac72f539cccRoland LevillainTEST(ConstantFolding, ConstantCondition) { 606556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain const uint16_t data[] = THREE_REGISTERS_CODE_ITEM( 607556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::CONST_4 | 1 << 8 | 1 << 12, 608556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::CONST_4 | 0 << 8 | 0 << 12, 609556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::IF_GEZ | 1 << 8, 3, 610556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::MOVE | 0 << 8 | 1 << 12, 611556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::ADD_INT | 2 << 8, 0 | 1 << 8, 612556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain Instruction::RETURN_VOID); 613556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 614556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain std::string expected_before = 615556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain "BasicBlock 0, succ: 1\n" 616556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 3: IntConstant [15, 22, 8]\n" 617556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 5: IntConstant [22, 8]\n" 618556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 19: SuspendCheck\n" 619556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 20: Goto 1\n" 620556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain "BasicBlock 1, pred: 0, succ: 5, 2\n" 621556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 8: GreaterThanOrEqual(3, 5) [9]\n" 622556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 9: If(8)\n" 623556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain "BasicBlock 2, pred: 1, succ: 3\n" 624556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 12: Goto 3\n" 625556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain "BasicBlock 3, pred: 2, 5, succ: 4\n" 626556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 22: Phi(3, 5) [15]\n" 627556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 15: Add(22, 3)\n" 628556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 17: ReturnVoid\n" 629556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain "BasicBlock 4, pred: 3\n" 630556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 18: Exit\n" 631556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain "BasicBlock 5, pred: 1, succ: 3\n" 632556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain " 21: Goto 3\n"; 633556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 63475be28332b278cff9039b54bfb228ac72f539cccRoland Levillain // Expected difference after constant folding. 63575be28332b278cff9039b54bfb228ac72f539cccRoland Levillain diff_t expected_cf_diff = { 6368d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil { " 3: IntConstant [15, 22, 8]\n", " 3: IntConstant [9, 15, 22]\n" }, 637556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain { " 5: IntConstant [22, 8]\n", " 5: IntConstant [22]\n" }, 6388d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil { " 8: GreaterThanOrEqual(3, 5) [9]\n", removed }, 6398d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil { " 9: If(8)\n", " 9: If(3)\n" } 640556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain }; 64175be28332b278cff9039b54bfb228ac72f539cccRoland Levillain std::string expected_after_cf = Patch(expected_before, expected_cf_diff); 642556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain 64393445689c714e53cabf347da4321ecf3023e926cRoland Levillain // Check the values of the computed constants. 64475be28332b278cff9039b54bfb228ac72f539cccRoland Levillain auto check_after_cf = [](HGraph* graph) { 6458d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil HInstruction* inst = graph->GetBlock(1)->GetFirstInstruction()->InputAt(0); 64693445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_TRUE(inst->IsIntConstant()); 64793445689c714e53cabf347da4321ecf3023e926cRoland Levillain ASSERT_EQ(inst->AsIntConstant()->GetValue(), 1); 64893445689c714e53cabf347da4321ecf3023e926cRoland Levillain }; 64993445689c714e53cabf347da4321ecf3023e926cRoland Levillain 650556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain // Expected difference after dead code elimination. 651556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain diff_t expected_dce_diff = { 6528d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil { " 3: IntConstant [9, 15, 22]\n", " 3: IntConstant [9, 22]\n" }, 6538d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil { " 22: Phi(3, 5) [15]\n", " 22: Phi(3, 5)\n" }, 6548d5b8b295930aaa43255c4f0b74ece3ee8b43a47David Brazdil { " 15: Add(22, 3)\n", removed } 655556c3d193134f6461f3e1fe17c032b087c5931a0Roland Levillain }; 65675be28332b278cff9039b54bfb228ac72f539cccRoland Levillain std::string expected_after_dce = Patch(expected_after_cf, expected_dce_diff); 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} // namespace art 666