summaryrefslogtreecommitdiffstats
path: root/compiler/dex/global_value_numbering_test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/dex/global_value_numbering_test.cc')
-rw-r--r--compiler/dex/global_value_numbering_test.cc43
1 files changed, 43 insertions, 0 deletions
diff --git a/compiler/dex/global_value_numbering_test.cc b/compiler/dex/global_value_numbering_test.cc
index a788129795..7e3b4d8adf 100644
--- a/compiler/dex/global_value_numbering_test.cc
+++ b/compiler/dex/global_value_numbering_test.cc
@@ -134,6 +134,8 @@ class GlobalValueNumberingTest : public testing::Test {
{ bb, opcode, 0u, 0u, 2, { src, src + 1 }, 2, { reg, reg + 1 } }
#define DEF_PHI2(bb, reg, src1, src2) \
{ bb, static_cast<Instruction::Code>(kMirOpPhi), 0, 0u, 2u, { src1, src2 }, 1, { reg } }
+#define DEF_DIV_REM(bb, opcode, result, dividend, divisor) \
+ { bb, opcode, 0u, 0u, 2, { dividend, divisor }, 1, { result } }
void DoPrepareIFields(const IFieldDef* defs, size_t count) {
cu_.mir_graph->ifield_lowering_infos_.clear();
@@ -2222,4 +2224,45 @@ TEST_F(GlobalValueNumberingTest, NormalPathToCatchEntry) {
PerformGVN();
}
+TEST_F(GlobalValueNumberingTestDiamond, DivZeroCheckDiamond) {
+ static const MIRDef mirs[] = {
+ DEF_DIV_REM(3u, Instruction::DIV_INT, 1u, 20u, 21u),
+ DEF_DIV_REM(3u, Instruction::DIV_INT, 2u, 24u, 21u),
+ DEF_DIV_REM(3u, Instruction::DIV_INT, 3u, 20u, 23u),
+ DEF_DIV_REM(4u, Instruction::DIV_INT, 4u, 24u, 22u),
+ DEF_DIV_REM(4u, Instruction::DIV_INT, 9u, 24u, 25u),
+ DEF_DIV_REM(5u, Instruction::DIV_INT, 5u, 24u, 21u),
+ DEF_DIV_REM(5u, Instruction::DIV_INT, 10u, 24u, 26u),
+ DEF_PHI2(6u, 27u, 25u, 26u),
+ DEF_DIV_REM(6u, Instruction::DIV_INT, 12u, 20u, 27u),
+ DEF_DIV_REM(6u, Instruction::DIV_INT, 6u, 24u, 21u),
+ DEF_DIV_REM(6u, Instruction::DIV_INT, 7u, 20u, 23u),
+ DEF_DIV_REM(6u, Instruction::DIV_INT, 8u, 20u, 22u),
+ };
+
+ static const bool expected_ignore_div_zero_check[] = {
+ false, // New divisor seen.
+ true, // Eliminated since it has first divisor as first one.
+ false, // New divisor seen.
+ false, // New divisor seen.
+ false, // New divisor seen.
+ true, // Eliminated in dominating block.
+ false, // New divisor seen.
+ false, // Phi node.
+ true, // Eliminated on both sides of diamond and merged via phi.
+ true, // Eliminated in dominating block.
+ true, // Eliminated in dominating block.
+ false, // Only eliminated on one path of diamond.
+ };
+
+ PrepareMIRs(mirs);
+ PerformGVN();
+ PerformGVNCodeModifications();
+ ASSERT_EQ(arraysize(expected_ignore_div_zero_check), mir_count_);
+ for (size_t i = 0u; i != mir_count_; ++i) {
+ int expected = expected_ignore_div_zero_check[i] ? MIR_IGNORE_DIV_ZERO_CHECK : 0u;
+ EXPECT_EQ(expected, mirs_[i].optimization_flags) << i;
+ }
+}
+
} // namespace art