/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <functional>

#include "arch/x86/instruction_set_features_x86.h"
#include "code_generator_x86.h"
#include "constant_folding.h"
#include "dead_code_elimination.h"
#include "driver/compiler_options.h"
#include "graph_checker.h"
#include "optimizing_unit_test.h"
#include "pretty_printer.h"

#include "gtest/gtest.h"

namespace art {

/**
 * Fixture class for the constant folding and dce tests.
 */
class ConstantFoldingTest : public CommonCompilerTest {
 public:
  ConstantFoldingTest() : pool_(), allocator_(&pool_) {
    graph_ = CreateGraph(&allocator_);
  }

  void TestCode(const uint16_t* data,
                const std::string& expected_before,
                const std::string& expected_after_cf,
                const std::string& expected_after_dce,
                std::function<void(HGraph*)> check_after_cf,
                Primitive::Type return_type = Primitive::kPrimInt) {
    graph_ = CreateCFG(&allocator_, data, return_type);
    TestCodeOnReadyGraph(expected_before,
                         expected_after_cf,
                         expected_after_dce,
                         check_after_cf);
  }

  void TestCodeOnReadyGraph(const std::string& expected_before,
                            const std::string& expected_after_cf,
                            const std::string& expected_after_dce,
                            std::function<void(HGraph*)> check_after_cf) {
    ASSERT_NE(graph_, nullptr);

    StringPrettyPrinter printer_before(graph_);
    printer_before.VisitInsertionOrder();
    std::string actual_before = printer_before.str();
    EXPECT_EQ(expected_before, actual_before);

    std::unique_ptr<const X86InstructionSetFeatures> features_x86(
        X86InstructionSetFeatures::FromCppDefines());
    x86::CodeGeneratorX86 codegenX86(graph_, *features_x86.get(), CompilerOptions());
    HConstantFolding(graph_).Run();
    GraphChecker graph_checker_cf(graph_);
    graph_checker_cf.Run();
    ASSERT_TRUE(graph_checker_cf.IsValid());

    StringPrettyPrinter printer_after_cf(graph_);
    printer_after_cf.VisitInsertionOrder();
    std::string actual_after_cf = printer_after_cf.str();
    EXPECT_EQ(expected_after_cf, actual_after_cf);

    check_after_cf(graph_);

    HDeadCodeElimination(graph_).Run();
    GraphChecker graph_checker_dce(graph_);
    graph_checker_dce.Run();
    ASSERT_TRUE(graph_checker_dce.IsValid());

    StringPrettyPrinter printer_after_dce(graph_);
    printer_after_dce.VisitInsertionOrder();
    std::string actual_after_dce = printer_after_dce.str();
    EXPECT_EQ(expected_after_dce, actual_after_dce);
  }

  ArenaPool pool_;
  ArenaAllocator allocator_;
  HGraph* graph_;
};

/**
 * Tiny three-register program exercising int constant folding on negation.
 *
 *                              16-bit
 *                              offset
 *                              ------
 *     v0 <- 1                  0.      const/4 v0, #+1
 *     v1 <- -v0                1.      neg-int v1, v0
 *     return v1                2.      return v1
 */
TEST_F(ConstantFoldingTest, IntConstantFoldingNegation) {
  const uint16_t data[] = TWO_REGISTERS_CODE_ITEM(
    Instruction::CONST_4 | 0 << 8 | 1 << 12,
    Instruction::NEG_INT | 1 << 8 | 0 << 12,
    Instruction::RETURN | 1 << 8);

  std::string expected_before =
      "BasicBlock 0, succ: 1\n"
      "  2: IntConstant [5]\n"
      "  10: SuspendCheck\n"
      "  11: Goto 1\n"
      "BasicBlock 1, pred: 0, succ: 2\n"
      "  5: Neg(2) [8]\n"
      "  8: Return(5)\n"
      "BasicBlock 2, pred: 1\n"
      "  9: Exit\n";

  // Expected difference after constant folding.
  diff_t expected_cf_diff = {
    { "  2: IntConstant [5]\n", "  2: IntConstant\n" },
    { "  10: SuspendCheck\n",   "  10: SuspendCheck\n"
                                "  12: IntConstant [8]\n" },
    { "  5: Neg(2) [8]\n",      removed },
    { "  8: Return(5)\n",       "  8: Return(12)\n" }
  };
  std::string expected_after_cf = Patch(expected_before, expected_cf_diff);

  // Check the value of the computed constant.
  auto check_after_cf = [](HGraph* graph) {
    HInstruction* inst = graph->GetBlocks()[1]->GetFirstInstruction()->InputAt(0);
    ASSERT_TRUE(inst->IsIntConstant());
    ASSERT_EQ(inst->AsIntConstant()->GetValue(), -1);
  };

  // Expected difference after dead code elimination.
  diff_t expected_dce_diff = {
    { "  2: IntConstant\n", removed },
  };
  std::string expected_after_dce = Patch(expected_after_cf, expected_dce_diff);

  TestCode(data,
           expected_before,
           expected_after_cf,
           expected_after_dce,
           check_after_cf);
}

/**
 * Tiny three-register program exercising long constant folding on negation.
 *
 *                              16-bit
 *                              offset
 *                              ------
 *     (v0, v1) <- 4294967296   0.      const-wide v0 #+4294967296
 *     (v2, v3) <- -(v0, v1)    1.      neg-long v2, v0
 *     return (v2, v3)          2.      return-wide v2
 */
TEST_F(ConstantFoldingTest, LongConstantFoldingNegation) {
  const int64_t input = INT64_C(4294967296);             // 2^32
  const uint16_t word0 = Low16Bits(Low32Bits(input));    // LSW.
  const uint16_t word1 = High16Bits(Low32Bits(input));
  const uint16_t word2 = Low16Bits(High32Bits(input));
  const uint16_t word3 = High16Bits(High32Bits(input));  // MSW.
  const uint16_t data[] = FOUR_REGISTERS_CODE_ITEM(
    Instruction::CONST_WIDE | 0 << 8, word0, word1, word2, word3,
    Instruction::NEG_LONG | 2 << 8 | 0 << 12,
    Instruction::RETURN_WIDE | 2 << 8);

  std::string expected_before =
      "BasicBlock 0, succ: 1\n"
      "  4: LongConstant [7]\n"
      "  12: SuspendCheck\n"
      "  13: Goto 1\n"
      "BasicBlock 1, pred: 0, succ: 2\n"
      "  7: Neg(4) [10]\n"
      "  10: Return(7)\n"
      "BasicBlock 2, pred: 1\n"
      "  11: Exit\n";

  // Expected difference after constant folding.
  diff_t expected_cf_diff = {
    { "  4: LongConstant [7]\n", "  4: LongConstant\n" },
    { "  12: SuspendCheck\n",    "  12: SuspendCheck\n"
                                 "  14: LongConstant [10]\n" },
    { "  7: Neg(4) [10]\n",      removed },
    { "  10: Return(7)\n",       "  10: Return(14)\n" }
  };
  std::string expected_after_cf = Patch(expected_before, expected_cf_diff);

  // Check the value of the computed constant.
  auto check_after_cf = [](HGraph* graph) {
    HInstruction* inst = graph->GetBlocks()[1]->GetFirstInstruction()->InputAt(0);
    ASSERT_TRUE(inst->IsLongConstant());
    ASSERT_EQ(inst->AsLongConstant()->GetValue(), INT64_C(-4294967296));
  };

  // Expected difference after dead code elimination.
  diff_t expected_dce_diff = {
    { "  4: LongConstant\n", removed },
  };
  std::string expected_after_dce = Patch(expected_after_cf, expected_dce_diff);

  TestCode(data,
           expected_before,
           expected_after_cf,
           expected_after_dce,
           check_after_cf,
           Primitive::kPrimLong);
}

/**
 * Tiny three-register program exercising int constant folding on addition.
 *
 *                              16-bit
 *                              offset
 *                              ------
 *     v0 <- 1                  0.      const/4 v0, #+1
 *     v1 <- 2                  1.      const/4 v1, #+2
 *     v2 <- v0 + v1            2.      add-int v2, v0, v1
 *     return v2                4.      return v2
 */
TEST_F(ConstantFoldingTest, IntConstantFoldingOnAddition1) {
  const uint16_t data[] = THREE_REGISTERS_CODE_ITEM(
    Instruction::CONST_4 | 0 << 8 | 1 << 12,
    Instruction::CONST_4 | 1 << 8 | 2 << 12,
    Instruction::ADD_INT | 2 << 8, 0 | 1 << 8,
    Instruction::RETURN | 2 << 8);

  std::string expected_before =
    "BasicBlock 0, succ: 1\n"
    "  3: IntConstant [9]\n"
    "  5: IntConstant [9]\n"
    "  14: SuspendCheck\n"
    "  15: Goto 1\n"
    "BasicBlock 1, pred: 0, succ: 2\n"
    "  9: Add(3, 5) [12]\n"
    "  12: Return(9)\n"
    "BasicBlock 2, pred: 1\n"
    "  13: Exit\n";

  // Expected difference after constant folding.
  diff_t expected_cf_diff = {
    { "  3: IntConstant [9]\n", "  3: IntConstant\n" },
    { "  5: IntConstant [9]\n", "  5: IntConstant\n" },
    { "  14: SuspendCheck\n",   "  14: SuspendCheck\n"
                                "  16: IntConstant [12]\n" },
    { "  9: Add(3, 5) [12]\n",  removed },
    { "  12: Return(9)\n",      "  12: Return(16)\n" }
  };
  std::string expected_after_cf = Patch(expected_before, expected_cf_diff);

  // Check the value of the computed constant.
  auto check_after_cf = [](HGraph* graph) {
    HInstruction* inst = graph->GetBlocks()[1]->GetFirstInstruction()->InputAt(0);
    ASSERT_TRUE(inst->IsIntConstant());
    ASSERT_EQ(inst->AsIntConstant()->GetValue(), 3);
  };

  // Expected difference after dead code elimination.
  diff_t expected_dce_diff = {
    { "  3: IntConstant\n", removed },
    { "  5: IntConstant\n", removed }
  };
  std::string expected_after_dce = Patch(expected_after_cf, expected_dce_diff);

  TestCode(data,
           expected_before,
           expected_after_cf,
           expected_after_dce,
           check_after_cf);
}

/**
 * Small three-register program exercising int constant folding on addition.
 *
 *                              16-bit
 *                              offset
 *                              ------
 *     v0 <- 1                  0.      const/4 v0, #+1
 *     v1 <- 2                  1.      const/4 v1, #+2
 *     v0 <- v0 + v1            2.      add-int/2addr v0, v1
 *     v1 <- 4                  3.      const/4 v1, #+4
 *     v2 <- 5                  4.      const/4 v2, #+5
 *     v1 <- v1 + v2            5.      add-int/2addr v1, v2
 *     v2 <- v0 + v1            6.      add-int v2, v0, v1
 *     return v2                8.      return v2
 */
TEST_F(ConstantFoldingTest, IntConstantFoldingOnAddition2) {
  const uint16_t data[] = THREE_REGISTERS_CODE_ITEM(
    Instruction::CONST_4 | 0 << 8 | 1 << 12,
    Instruction::CONST_4 | 1 << 8 | 2 << 12,
    Instruction::ADD_INT_2ADDR | 0 << 8 | 1 << 12,
    Instruction::CONST_4 | 1 << 8 | 4 << 12,
    Instruction::CONST_4 | 2 << 8 | 5 << 12,
    Instruction::ADD_INT_2ADDR | 1 << 8 | 2 << 12,
    Instruction::ADD_INT | 2 << 8, 0 | 1 << 8,
    Instruction::RETURN | 2 << 8);

  std::string expected_before =
    "BasicBlock 0, succ: 1\n"
    "  3: IntConstant [9]\n"
    "  5: IntConstant [9]\n"
    "  11: IntConstant [17]\n"
    "  13: IntConstant [17]\n"
    "  26: SuspendCheck\n"
    "  27: Goto 1\n"
    "BasicBlock 1, pred: 0, succ: 2\n"
    "  9: Add(3, 5) [21]\n"
    "  17: Add(11, 13) [21]\n"
    "  21: Add(9, 17) [24]\n"
    "  24: Return(21)\n"
    "BasicBlock 2, pred: 1\n"
    "  25: Exit\n";

  // Expected difference after constant folding.
  diff_t expected_cf_diff = {
    { "  3: IntConstant [9]\n",   "  3: IntConstant\n" },
    { "  5: IntConstant [9]\n",   "  5: IntConstant\n" },
    { "  11: IntConstant [17]\n", "  11: IntConstant\n" },
    { "  13: IntConstant [17]\n", "  13: IntConstant\n" },
    { "  26: SuspendCheck\n",     "  26: SuspendCheck\n"
                                  "  28: IntConstant\n"
                                  "  29: IntConstant\n"
                                  "  30: IntConstant [24]\n" },
    { "  9: Add(3, 5) [21]\n",    removed },
    { "  17: Add(11, 13) [21]\n", removed },
    { "  21: Add(9, 17) [24]\n",  removed  },
    { "  24: Return(21)\n",       "  24: Return(30)\n" }
  };
  std::string expected_after_cf = Patch(expected_before, expected_cf_diff);

  // Check the values of the computed constants.
  auto check_after_cf = [](HGraph* graph) {
    HInstruction* inst1 = graph->GetBlocks()[1]->GetFirstInstruction()->InputAt(0);
    ASSERT_TRUE(inst1->IsIntConstant());
    ASSERT_EQ(inst1->AsIntConstant()->GetValue(), 12);
    HInstruction* inst2 = inst1->GetPrevious();
    ASSERT_TRUE(inst2->IsIntConstant());
    ASSERT_EQ(inst2->AsIntConstant()->GetValue(), 9);
    HInstruction* inst3 = inst2->GetPrevious();
    ASSERT_TRUE(inst3->IsIntConstant());
    ASSERT_EQ(inst3->AsIntConstant()->GetValue(), 3);
  };

  // Expected difference after dead code elimination.
  diff_t expected_dce_diff = {
    { "  3: IntConstant\n",  removed },
    { "  5: IntConstant\n",  removed },
    { "  11: IntConstant\n", removed },
    { "  13: IntConstant\n", removed },
    { "  28: IntConstant\n", removed },
    { "  29: IntConstant\n", removed }
  };
  std::string expected_after_dce = Patch(expected_after_cf, expected_dce_diff);

  TestCode(data,
           expected_before,
           expected_after_cf,
           expected_after_dce,
           check_after_cf);
}

/**
 * Tiny three-register program exercising int constant folding on subtraction.
 *
 *                              16-bit
 *                              offset
 *                              ------
 *     v0 <- 3                  0.      const/4 v0, #+3
 *     v1 <- 2                  1.      const/4 v1, #+2
 *     v2 <- v0 - v1            2.      sub-int v2, v0, v1
 *     return v2                4.      return v2
 */
TEST_F(ConstantFoldingTest, IntConstantFoldingOnSubtraction) {
  const uint16_t data[] = THREE_REGISTERS_CODE_ITEM(
    Instruction::CONST_4 | 0 << 8 | 3 << 12,
    Instruction::CONST_4 | 1 << 8 | 2 << 12,
    Instruction::SUB_INT | 2 << 8, 0 | 1 << 8,
    Instruction::RETURN | 2 << 8);

  std::string expected_before =
    "BasicBlock 0, succ: 1\n"
    "  3: IntConstant [9]\n"
    "  5: IntConstant [9]\n"
    "  14: SuspendCheck\n"
    "  15: Goto 1\n"
    "BasicBlock 1, pred: 0, succ: 2\n"
    "  9: Sub(3, 5) [12]\n"
    "  12: Return(9)\n"
    "BasicBlock 2, pred: 1\n"
    "  13: Exit\n";

  // Expected difference after constant folding.
  diff_t expected_cf_diff = {
    { "  3: IntConstant [9]\n", "  3: IntConstant\n" },
    { "  5: IntConstant [9]\n", "  5: IntConstant\n" },
    { "  14: SuspendCheck\n",   "  14: SuspendCheck\n"
                                "  16: IntConstant [12]\n" },
    { "  9: Sub(3, 5) [12]\n",  removed },
    { "  12: Return(9)\n",      "  12: Return(16)\n" }
  };
  std::string expected_after_cf = Patch(expected_before, expected_cf_diff);

  // Check the value of the computed constant.
  auto check_after_cf = [](HGraph* graph) {
    HInstruction* inst = graph->GetBlocks()[1]->GetFirstInstruction()->InputAt(0);
    ASSERT_TRUE(inst->IsIntConstant());
    ASSERT_EQ(inst->AsIntConstant()->GetValue(), 1);
  };

  // Expected difference after dead code elimination.
  diff_t expected_dce_diff = {
    { "  3: IntConstant\n", removed },
    { "  5: IntConstant\n", removed }
  };
  std::string expected_after_dce = Patch(expected_after_cf, expected_dce_diff);

  TestCode(data,
           expected_before,
           expected_after_cf,
           expected_after_dce,
           check_after_cf);
}

/**
 * Tiny three-register-pair program exercising long constant folding
 * on addition.
 *
 *                              16-bit
 *                              offset
 *                              ------
 *     (v0, v1) <- 1            0.      const-wide/16 v0, #+1
 *     (v2, v3) <- 2            2.      const-wide/16 v2, #+2
 *     (v4, v5) <-
 *       (v0, v1) + (v1, v2)    4.      add-long v4, v0, v2
 *     return (v4, v5)          6.      return-wide v4
 */
TEST_F(ConstantFoldingTest, LongConstantFoldingOnAddition) {
  const uint16_t data[] = SIX_REGISTERS_CODE_ITEM(
    Instruction::CONST_WIDE_16 | 0 << 8, 1,
    Instruction::CONST_WIDE_16 | 2 << 8, 2,
    Instruction::ADD_LONG | 4 << 8, 0 | 2 << 8,
    Instruction::RETURN_WIDE | 4 << 8);

  std::string expected_before =
    "BasicBlock 0, succ: 1\n"
    "  6: LongConstant [12]\n"
    "  8: LongConstant [12]\n"
    "  17: SuspendCheck\n"
    "  18: Goto 1\n"
    "BasicBlock 1, pred: 0, succ: 2\n"
    "  12: Add(6, 8) [15]\n"
    "  15: Return(12)\n"
    "BasicBlock 2, pred: 1\n"
    "  16: Exit\n";

  // Expected difference after constant folding.
  diff_t expected_cf_diff = {
    { "  6: LongConstant [12]\n", "  6: LongConstant\n" },
    { "  8: LongConstant [12]\n", "  8: LongConstant\n" },
    { "  17: SuspendCheck\n",     "  17: SuspendCheck\n"
                                  "  19: LongConstant [15]\n" },
    { "  12: Add(6, 8) [15]\n",   removed },
    { "  15: Return(12)\n",       "  15: Return(19)\n" }
  };
  std::string expected_after_cf = Patch(expected_before, expected_cf_diff);

  // Check the value of the computed constant.
  auto check_after_cf = [](HGraph* graph) {
    HInstruction* inst = graph->GetBlocks()[1]->GetFirstInstruction()->InputAt(0);
    ASSERT_TRUE(inst->IsLongConstant());
    ASSERT_EQ(inst->AsLongConstant()->GetValue(), 3);
  };

  // Expected difference after dead code elimination.
  diff_t expected_dce_diff = {
    { "  6: LongConstant\n", removed },
    { "  8: LongConstant\n", removed }
  };
  std::string expected_after_dce = Patch(expected_after_cf, expected_dce_diff);

  TestCode(data,
           expected_before,
           expected_after_cf,
           expected_after_dce,
           check_after_cf,
           Primitive::kPrimLong);
}

/**
 * Tiny three-register-pair program exercising long constant folding
 * on subtraction.
 *
 *                              16-bit
 *                              offset
 *                              ------
 *     (v0, v1) <- 3            0.      const-wide/16 v0, #+3
 *     (v2, v3) <- 2            2.      const-wide/16 v2, #+2
 *     (v4, v5) <-
 *       (v0, v1) - (v1, v2)    4.      sub-long v4, v0, v2
 *     return (v4, v5)          6.      return-wide v4
 */
TEST_F(ConstantFoldingTest, LongConstantFoldingOnSubtraction) {
  const uint16_t data[] = SIX_REGISTERS_CODE_ITEM(
    Instruction::CONST_WIDE_16 | 0 << 8, 3,
    Instruction::CONST_WIDE_16 | 2 << 8, 2,
    Instruction::SUB_LONG | 4 << 8, 0 | 2 << 8,
    Instruction::RETURN_WIDE | 4 << 8);

  std::string expected_before =
    "BasicBlock 0, succ: 1\n"
    "  6: LongConstant [12]\n"
    "  8: LongConstant [12]\n"
    "  17: SuspendCheck\n"
    "  18: Goto 1\n"
    "BasicBlock 1, pred: 0, succ: 2\n"
    "  12: Sub(6, 8) [15]\n"
    "  15: Return(12)\n"
    "BasicBlock 2, pred: 1\n"
    "  16: Exit\n";

  // Expected difference after constant folding.
  diff_t expected_cf_diff = {
    { "  6: LongConstant [12]\n", "  6: LongConstant\n" },
    { "  8: LongConstant [12]\n", "  8: LongConstant\n" },
    { "  17: SuspendCheck\n",     "  17: SuspendCheck\n"
                                  "  19: LongConstant [15]\n" },
    { "  12: Sub(6, 8) [15]\n",   removed },
    { "  15: Return(12)\n",       "  15: Return(19)\n" }
  };
  std::string expected_after_cf = Patch(expected_before, expected_cf_diff);

  // Check the value of the computed constant.
  auto check_after_cf = [](HGraph* graph) {
    HInstruction* inst = graph->GetBlocks()[1]->GetFirstInstruction()->InputAt(0);
    ASSERT_TRUE(inst->IsLongConstant());
    ASSERT_EQ(inst->AsLongConstant()->GetValue(), 1);
  };

  // Expected difference after dead code elimination.
  diff_t expected_dce_diff = {
    { "  6: LongConstant\n", removed },
    { "  8: LongConstant\n", removed }
  };
  std::string expected_after_dce = Patch(expected_after_cf, expected_dce_diff);

  TestCode(data,
           expected_before,
           expected_after_cf,
           expected_after_dce,
           check_after_cf,
           Primitive::kPrimLong);
}

/**
 * Three-register program with jumps leading to the creation of many
 * blocks.
 *
 * The intent of this test is to ensure that all constant expressions
 * are actually evaluated at compile-time, thanks to the reverse
 * (forward) post-order traversal of the the dominator tree.
 *
 *                              16-bit
 *                              offset
 *                              ------
 *     v0 <- 1                   0.     const/4 v0, #+1
 *     v1 <- 2                   1.     const/4 v1, #+2
 *     v2 <- v0 + v1             2.     add-int v2, v0, v1
 *     goto L2                   4.     goto +4
 * L1: v1 <- v0 + 5              5.     add-int/lit16 v1, v0, #+5
 *     goto L3                   7.     goto +4
 * L2: v0 <- v2 + 4              8.     add-int/lit16 v0, v2, #+4
 *     goto L1                  10.     goto +(-5)
 * L3: v2 <- v1 + 8             11.     add-int/lit16 v2, v1, #+8
 *     return v2                13.     return v2
 */
TEST_F(ConstantFoldingTest, IntConstantFoldingAndJumps) {
  const uint16_t data[] = THREE_REGISTERS_CODE_ITEM(
    Instruction::CONST_4 | 0 << 8 | 1 << 12,
    Instruction::CONST_4 | 1 << 8 | 2 << 12,
    Instruction::ADD_INT | 2 << 8, 0 | 1 << 8,
    Instruction::GOTO | 4 << 8,
    Instruction::ADD_INT_LIT16 | 1 << 8 | 0 << 12, 5,
    Instruction::GOTO | 4 << 8,
    Instruction::ADD_INT_LIT16 | 0 << 8 | 2 << 12, 4,
    static_cast<uint16_t>(Instruction::GOTO | 0xFFFFFFFB << 8),
    Instruction::ADD_INT_LIT16 | 2 << 8 | 1 << 12, 8,
    Instruction::RETURN | 2 << 8);

  std::string expected_before =
    "BasicBlock 0, succ: 1\n"
    "  3: IntConstant [9]\n"            // v0 <- 1
    "  5: IntConstant [9]\n"            // v1 <- 2
    "  13: IntConstant [14]\n"          // const 5
    "  18: IntConstant [19]\n"          // const 4
    "  23: IntConstant [24]\n"          // const 8
    "  29: SuspendCheck\n"
    "  30: Goto 1\n"
    "BasicBlock 1, pred: 0, succ: 3\n"
    "  9: Add(3, 5) [19]\n"             // v2 <- v0 + v1 = 1 + 2 = 3
    "  11: Goto 3\n"                    // goto L2
    "BasicBlock 2, pred: 3, succ: 4\n"  // L1:
    "  14: Add(19, 13) [24]\n"          // v1 <- v0 + 3 = 7 + 5 = 12
    "  16: Goto 4\n"                    // goto L3
    "BasicBlock 3, pred: 1, succ: 2\n"  // L2:
    "  19: Add(9, 18) [14]\n"           // v0 <- v2 + 2 = 3 + 4 = 7
    "  21: Goto 2\n"                    // goto L1
    "BasicBlock 4, pred: 2, succ: 5\n"  // L3:
    "  24: Add(14, 23) [27]\n"          // v2 <- v1 + 4 = 12 + 8 = 20
    "  27: Return(24)\n"                // return v2
    "BasicBlock 5, pred: 4\n"
    "  28: Exit\n";

  // Expected difference after constant folding.
  diff_t expected_cf_diff = {
    { "  3: IntConstant [9]\n",   "  3: IntConstant\n" },
    { "  5: IntConstant [9]\n",   "  5: IntConstant\n" },
    { "  13: IntConstant [14]\n", "  13: IntConstant\n" },
    { "  18: IntConstant [19]\n", "  18: IntConstant\n" },
    { "  23: IntConstant [24]\n", "  23: IntConstant\n" },
    { "  29: SuspendCheck\n",     "  29: SuspendCheck\n"
                                  "  31: IntConstant\n"
                                  "  32: IntConstant\n"
                                  "  33: IntConstant\n"
                                  "  34: IntConstant [27]\n" },
    { "  9: Add(3, 5) [19]\n",    removed },
    { "  14: Add(19, 13) [24]\n", removed },
    { "  19: Add(9, 18) [14]\n",  removed },
    { "  24: Add(14, 23) [27]\n", removed },
    { "  27: Return(24)\n",       "  27: Return(34)\n"}
  };
  std::string expected_after_cf = Patch(expected_before, expected_cf_diff);

  // Check the values of the computed constants.
  auto check_after_cf = [](HGraph* graph) {
    HInstruction* inst1 = graph->GetBlocks()[4]->GetFirstInstruction()->InputAt(0);
    ASSERT_TRUE(inst1->IsIntConstant());
    ASSERT_EQ(inst1->AsIntConstant()->GetValue(), 20);
    HInstruction* inst2 = inst1->GetPrevious();
    ASSERT_TRUE(inst2->IsIntConstant());
    ASSERT_EQ(inst2->AsIntConstant()->GetValue(), 12);
    HInstruction* inst3 = inst2->GetPrevious();
    ASSERT_TRUE(inst3->IsIntConstant());
    ASSERT_EQ(inst3->AsIntConstant()->GetValue(), 7);
    HInstruction* inst4 = inst3->GetPrevious();
    ASSERT_TRUE(inst4->IsIntConstant());
    ASSERT_EQ(inst4->AsIntConstant()->GetValue(), 3);
  };

  // Expected difference after dead code elimination.
  std::string expected_after_dce =
    "BasicBlock 0, succ: 1\n"
    "  29: SuspendCheck\n"
    "  34: IntConstant [27]\n"
    "  30: Goto 1\n"
    "BasicBlock 1, pred: 0, succ: 5\n"
    "  27: Return(34)\n"
    "BasicBlock 5, pred: 1\n"
    "  28: Exit\n";

  TestCode(data,
           expected_before,
           expected_after_cf,
           expected_after_dce,
           check_after_cf);
}

/**
 * Three-register program with a constant (static) condition.
 *
 *                              16-bit
 *                              offset
 *                              ------
 *     v1 <- 1                  0.      const/4 v1, #+1
 *     v0 <- 0                  1.      const/4 v0, #+0
 *     if v1 >= 0 goto L1       2.      if-gez v1, +3
 *     v0 <- v1                 4.      move v0, v1
 * L1: v2 <- v0 + v1            5.      add-int v2, v0, v1
 *     return-void              7.      return
 */
TEST_F(ConstantFoldingTest, ConstantCondition) {
  const uint16_t data[] = THREE_REGISTERS_CODE_ITEM(
    Instruction::CONST_4 | 1 << 8 | 1 << 12,
    Instruction::CONST_4 | 0 << 8 | 0 << 12,
    Instruction::IF_GEZ | 1 << 8, 3,
    Instruction::MOVE | 0 << 8 | 1 << 12,
    Instruction::ADD_INT | 2 << 8, 0 | 1 << 8,
    Instruction::RETURN_VOID);

  std::string expected_before =
    "BasicBlock 0, succ: 1\n"
    "  3: IntConstant [15, 22, 8]\n"
    "  5: IntConstant [22, 8]\n"
    "  19: SuspendCheck\n"
    "  20: Goto 1\n"
    "BasicBlock 1, pred: 0, succ: 5, 2\n"
    "  8: GreaterThanOrEqual(3, 5) [9]\n"
    "  9: If(8)\n"
    "BasicBlock 2, pred: 1, succ: 3\n"
    "  12: Goto 3\n"
    "BasicBlock 3, pred: 5, 2, succ: 4\n"
    "  22: Phi(5, 3) [15]\n"
    "  15: Add(22, 3)\n"
    "  17: ReturnVoid\n"
    "BasicBlock 4, pred: 3\n"
    "  18: Exit\n"
    "BasicBlock 5, pred: 1, succ: 3\n"
    "  21: Goto 3\n";

  // Expected difference after constant folding.
  diff_t expected_cf_diff = {
    { "  3: IntConstant [15, 22, 8]\n",      "  3: IntConstant [9, 15, 22]\n" },
    { "  5: IntConstant [22, 8]\n",          "  5: IntConstant [22]\n" },
    { "  8: GreaterThanOrEqual(3, 5) [9]\n", removed },
    { "  9: If(8)\n",                        "  9: If(3)\n" }
  };
  std::string expected_after_cf = Patch(expected_before, expected_cf_diff);

  // Check the values of the computed constants.
  auto check_after_cf = [](HGraph* graph) {
    HInstruction* inst = graph->GetBlocks()[1]->GetFirstInstruction()->InputAt(0);
    ASSERT_TRUE(inst->IsIntConstant());
    ASSERT_EQ(inst->AsIntConstant()->GetValue(), 1);
  };

  // Expected graph after dead code elimination.
  std::string expected_after_dce =
    "BasicBlock 0, succ: 1\n"
    "  19: SuspendCheck\n"
    "  20: Goto 1\n"
    "BasicBlock 1, pred: 0, succ: 4\n"
    "  17: ReturnVoid\n"
    "BasicBlock 4, pred: 1\n"
    "  18: Exit\n";

  TestCode(data,
           expected_before,
           expected_after_cf,
           expected_after_dce,
           check_after_cf);
}

/**
 * Unsigned comparisons with zero. Since these instructions are not present
 * in the bytecode, we need to set up the graph explicitly.
 */
TEST_F(ConstantFoldingTest, UnsignedComparisonsWithZero) {
  graph_ = CreateGraph(&allocator_);
  HBasicBlock* entry_block = new (&allocator_) HBasicBlock(graph_);
  graph_->AddBlock(entry_block);
  graph_->SetEntryBlock(entry_block);
  HBasicBlock* block = new (&allocator_) HBasicBlock(graph_);
  graph_->AddBlock(block);
  HBasicBlock* exit_block = new (&allocator_) HBasicBlock(graph_);
  graph_->AddBlock(exit_block);
  graph_->SetExitBlock(exit_block);
  entry_block->AddSuccessor(block);
  block->AddSuccessor(exit_block);

  // Make various unsigned comparisons with zero against a parameter.
  HInstruction* parameter = new (&allocator_) HParameterValue(
      graph_->GetDexFile(), 0, 0, Primitive::kPrimInt, true);
  entry_block->AddInstruction(parameter);
  HInstruction* zero = graph_->GetIntConstant(0);
  HInstruction* last;
  block->AddInstruction(last = new (&allocator_) HAbove(zero, parameter));
  block->AddInstruction(new (&allocator_) HSelect(last, parameter, parameter, 0));
  block->AddInstruction(last = new (&allocator_) HAbove(parameter, zero));
  block->AddInstruction(new (&allocator_) HSelect(last, parameter, parameter, 0));
  block->AddInstruction(last = new (&allocator_) HAboveOrEqual(zero, parameter));
  block->AddInstruction(new (&allocator_) HSelect(last, parameter, parameter, 0));
  block->AddInstruction(last = new (&allocator_) HAboveOrEqual(parameter, zero));
  block->AddInstruction(new (&allocator_) HSelect(last, parameter, parameter, 0));
  block->AddInstruction(last = new (&allocator_) HBelow(zero, parameter));
  block->AddInstruction(new (&allocator_) HSelect(last, parameter, parameter, 0));
  block->AddInstruction(last = new (&allocator_) HBelow(parameter, zero));
  block->AddInstruction(new (&allocator_) HSelect(last, parameter, parameter, 0));
  block->AddInstruction(last = new (&allocator_) HBelowOrEqual(zero, parameter));
  block->AddInstruction(new (&allocator_) HSelect(last, parameter, parameter, 0));
  block->AddInstruction(last = new (&allocator_) HBelowOrEqual(parameter, zero));
  block->AddInstruction(new (&allocator_) HSelect(last, parameter, parameter, 0));

  entry_block->AddInstruction(new (&allocator_) HGoto());
  block->AddInstruction(new (&allocator_) HReturn(zero));
  exit_block->AddInstruction(new (&allocator_) HExit());

  graph_->BuildDominatorTree();

  const std::string expected_before =
      "BasicBlock 0, succ: 1\n"
      "  0: ParameterValue [17, 17, 16, 15, 15, 14, 13, 13, 12, 11, 11, 10, 9, 9, "
                           "8, 7, 7, 6, 5, 5, 4, 3, 3, 2]\n"
      "  1: IntConstant [19, 16, 14, 12, 10, 8, 6, 4, 2]\n"
      "  18: Goto 1\n"
      "BasicBlock 1, pred: 0, succ: 2\n"
      "  2: Above(1, 0) [3]\n"
      "  3: Select(0, 0, 2)\n"
      "  4: Above(0, 1) [5]\n"
      "  5: Select(0, 0, 4)\n"
      "  6: AboveOrEqual(1, 0) [7]\n"
      "  7: Select(0, 0, 6)\n"
      "  8: AboveOrEqual(0, 1) [9]\n"
      "  9: Select(0, 0, 8)\n"
      "  10: Below(1, 0) [11]\n"
      "  11: Select(0, 0, 10)\n"
      "  12: Below(0, 1) [13]\n"
      "  13: Select(0, 0, 12)\n"
      "  14: BelowOrEqual(1, 0) [15]\n"
      "  15: Select(0, 0, 14)\n"
      "  16: BelowOrEqual(0, 1) [17]\n"
      "  17: Select(0, 0, 16)\n"
      "  19: Return(1)\n"
      "BasicBlock 2, pred: 1\n"
      "  20: Exit\n";

  const std::string expected_after_cf =
      "BasicBlock 0, succ: 1\n"
      "  0: ParameterValue [17, 17, 16, 15, 15, 13, 13, 11, 11, 10, 9, 9, 7, 7, 6, 5, 5, 4, 3, 3]\n"
      "  1: IntConstant [13, 3, 19, 16, 10, 6, 4]\n"
      "  21: IntConstant [15, 9]\n"
      "  18: Goto 1\n"
      "BasicBlock 1, pred: 0, succ: 2\n"
      "  3: Select(0, 0, 1)\n"
      "  4: Above(0, 1) [5]\n"
      "  5: Select(0, 0, 4)\n"
      "  6: AboveOrEqual(1, 0) [7]\n"
      "  7: Select(0, 0, 6)\n"
      "  9: Select(0, 0, 21)\n"
      "  10: Below(1, 0) [11]\n"
      "  11: Select(0, 0, 10)\n"
      "  13: Select(0, 0, 1)\n"
      "  15: Select(0, 0, 21)\n"
      "  16: BelowOrEqual(0, 1) [17]\n"
      "  17: Select(0, 0, 16)\n"
      "  19: Return(1)\n"
      "BasicBlock 2, pred: 1\n"
      "  20: Exit\n";

  const std::string expected_after_dce =
      "BasicBlock 0, succ: 1\n"
      "  0: ParameterValue\n"
      "  1: IntConstant [19]\n"
      "  18: Goto 1\n"
      "BasicBlock 1, pred: 0, succ: 2\n"
      "  19: Return(1)\n"
      "BasicBlock 2, pred: 1\n"
      "  20: Exit\n";

  auto check_after_cf = [](HGraph* graph) {
    CHECK(graph != nullptr);
  };

  TestCodeOnReadyGraph(expected_before,
                       expected_after_cf,
                       expected_after_dce,
                       check_after_cf);
}

}  // namespace art
