summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Santiago Aboy Solanes <solanes@google.com> 2022-08-09 11:54:19 +0000
committer Treehugger Robot <treehugger-gerrit@google.com> 2022-08-09 13:21:11 +0000
commitfa1034c563b44c4f557814c50e2678e14dcd1d13 (patch)
tree6353ca19b0f193183310ad7cd77c199bce64eb18
parent6981ef9238ce2d4ea3f7a86d3faf5d720c8c4641 (diff)
Revert "Propagating values from if clauses to its successors"
This reverts commit c6b816ceb2b35300c937ef2e7d008598b6afba21. Reason for revert: Broke libcore test https://ci.chromium.org/ui/p/art/builders/ci/angler-armv7-ndebug/3179/overview Change-Id: I4f238bd20cc485e49078104e0225c373cac23415
-rw-r--r--compiler/optimizing/constant_folding.cc130
-rw-r--r--compiler/optimizing/constant_folding.h4
-rw-r--r--compiler/optimizing/constant_folding_test.cc2
-rw-r--r--compiler/optimizing/inliner.cc2
-rw-r--r--compiler/optimizing/nodes.cc13
-rw-r--r--compiler/optimizing/nodes.h13
-rw-r--r--compiler/optimizing/optimization.cc2
-rw-r--r--compiler/optimizing/optimizing_compiler_stats.h1
-rw-r--r--test/2042-checker-dce-always-throw/src/Main.java31
-rw-r--r--test/442-checker-constant-folding/src/Main.java378
-rw-r--r--test/449-checker-bce/src/Main.java2
-rw-r--r--test/485-checker-dce-loop-update/smali/TestCase.smali6
-rw-r--r--test/543-checker-dce-trycatch/smali/TestCase.smali6
-rw-r--r--test/559-checker-irreducible-loop/smali/IrreducibleLoop.smali15
-rw-r--r--test/559-checker-irreducible-loop/src/Main.java4
-rw-r--r--test/563-checker-fakestring/smali/TestCase.smali2
-rw-r--r--test/564-checker-inline-loop/src/Main.java17
-rw-r--r--test/596-checker-dead-phi/smali/IrreducibleLoop.smali23
-rw-r--r--test/596-checker-dead-phi/src/Main.java4
19 files changed, 66 insertions, 589 deletions
diff --git a/compiler/optimizing/constant_folding.cc b/compiler/optimizing/constant_folding.cc
index 862abd345d..2031707759 100644
--- a/compiler/optimizing/constant_folding.cc
+++ b/compiler/optimizing/constant_folding.cc
@@ -16,19 +16,14 @@
#include "constant_folding.h"
-#include <algorithm>
-
-#include "optimizing/data_type.h"
-#include "optimizing/nodes.h"
-
namespace art {
// This visitor tries to simplify instructions that can be evaluated
// as constants.
class HConstantFoldingVisitor : public HGraphDelegateVisitor {
public:
- explicit HConstantFoldingVisitor(HGraph* graph, OptimizingCompilerStats* stats)
- : HGraphDelegateVisitor(graph, stats) {}
+ explicit HConstantFoldingVisitor(HGraph* graph)
+ : HGraphDelegateVisitor(graph) {}
private:
void VisitBasicBlock(HBasicBlock* block) override;
@@ -38,9 +33,6 @@ class HConstantFoldingVisitor : public HGraphDelegateVisitor {
void VisitTypeConversion(HTypeConversion* inst) override;
void VisitDivZeroCheck(HDivZeroCheck* inst) override;
- void VisitIf(HIf* inst) override;
-
- void PropagateValue(HBasicBlock* starting_block, HInstruction* variable, HConstant* constant);
DISALLOW_COPY_AND_ASSIGN(HConstantFoldingVisitor);
};
@@ -77,7 +69,7 @@ class InstructionWithAbsorbingInputSimplifier : public HGraphVisitor {
bool HConstantFolding::Run() {
- HConstantFoldingVisitor visitor(graph_, stats_);
+ HConstantFoldingVisitor visitor(graph_);
// Process basic blocks in reverse post-order in the dominator tree,
// so that an instruction turned into a constant, used as input of
// another instruction, may possibly be used to turn that second
@@ -138,122 +130,6 @@ void HConstantFoldingVisitor::VisitDivZeroCheck(HDivZeroCheck* inst) {
}
}
-void HConstantFoldingVisitor::PropagateValue(HBasicBlock* starting_block,
- HInstruction* variable,
- HConstant* constant) {
- const bool recording_stats = stats_ != nullptr;
- size_t uses_before = 0;
- size_t uses_after = 0;
- if (recording_stats) {
- uses_before = variable->GetUses().SizeSlow();
- }
-
- variable->ReplaceUsesDominatedBy(
- starting_block->GetFirstInstruction(), constant, /* strictly_dominated= */ false);
-
- if (recording_stats) {
- uses_after = variable->GetUses().SizeSlow();
- DCHECK_GE(uses_after, 1u) << "we must at least have the use in the if clause.";
- DCHECK_GE(uses_before, uses_after);
- MaybeRecordStat(stats_, MethodCompilationStat::kPropagatedIfValue, uses_before - uses_after);
- }
-}
-
-void HConstantFoldingVisitor::VisitIf(HIf* inst) {
- // Consistency check: the true and false successors do not dominate each other.
- DCHECK(!inst->IfTrueSuccessor()->Dominates(inst->IfFalseSuccessor()) &&
- !inst->IfFalseSuccessor()->Dominates(inst->IfTrueSuccessor()));
-
- HInstruction* if_input = inst->InputAt(0);
-
- // Already a constant.
- if (if_input->IsConstant()) {
- return;
- }
-
- // if (variable) {
- // SSA `variable` guaranteed to be true
- // } else {
- // and here false
- // }
- PropagateValue(inst->IfTrueSuccessor(), if_input, GetGraph()->GetIntConstant(1));
- PropagateValue(inst->IfFalseSuccessor(), if_input, GetGraph()->GetIntConstant(0));
-
- // If the input is a condition, we can propagate the information of the condition itself.
- if (!if_input->IsCondition()) {
- return;
- }
- HCondition* condition = if_input->AsCondition();
-
- // We want either `==` or `!=`, since we cannot make assumptions for other conditions e.g. `>`
- if (!condition->IsEqual() && !condition->IsNotEqual()) {
- return;
- }
-
- HInstruction* left = condition->GetLeft();
- HInstruction* right = condition->GetRight();
-
- // We want one of them to be a constant and not the other.
- if (left->IsConstant() == right->IsConstant()) {
- return;
- }
-
- // At this point we have something like:
- // if (variable == constant) {
- // SSA `variable` guaranteed to be equal to constant here
- // } else {
- // No guarantees can be made here (usually, see boolean case below).
- // }
- // Similarly with variable != constant, except that we can make guarantees in the else case.
-
- HConstant* constant = left->IsConstant() ? left->AsConstant() : right->AsConstant();
- HInstruction* variable = left->IsConstant() ? right : left;
-
- // Sometimes we have an HCompare flowing into an Equals/NonEquals, which can act as a proxy. For
- // example: `Equals(Compare(var, constant), 0)`. This is common for long, float, and double.
- if (variable->IsCompare()) {
- // We only care about equality comparisons so we skip if it is a less or greater comparison.
- if (!constant->IsArithmeticZero()) {
- return;
- }
-
- // Update left and right to be the ones from the HCompare.
- left = variable->AsCompare()->GetLeft();
- right = variable->AsCompare()->GetRight();
-
- // Re-check that one of them to be a constant and not the other.
- if (left->IsConstant() == right->IsConstant()) {
- return;
- }
-
- constant = left->IsConstant() ? left->AsConstant() : right->AsConstant();
- variable = left->IsConstant() ? right : left;
- }
-
- // From this block forward we want to replace the SSA value. We use `starting_block` and not the
- // `if` block as we want to update one of the branches but not the other.
- HBasicBlock* starting_block =
- condition->IsEqual() ? inst->IfTrueSuccessor() : inst->IfFalseSuccessor();
-
- PropagateValue(starting_block, variable, constant);
-
- // Special case for booleans since they have only two values so we know what to propagate in the
- // other branch. However, sometimes our boolean values are not compared to 0 or 1. In those cases
- // we cannot make an assumption for the `else` branch.
- if (variable->GetType() == DataType::Type::kBool &&
- constant->IsIntConstant() &&
- (constant->AsIntConstant()->IsTrue() || constant->AsIntConstant()->IsFalse())) {
- HBasicBlock* other_starting_block =
- condition->IsEqual() ? inst->IfFalseSuccessor() : inst->IfTrueSuccessor();
- DCHECK_NE(other_starting_block, starting_block);
-
- HConstant* other_constant = constant->AsIntConstant()->IsTrue() ?
- GetGraph()->GetIntConstant(0) :
- GetGraph()->GetIntConstant(1);
- DCHECK_NE(other_constant, constant);
- PropagateValue(other_starting_block, variable, other_constant);
- }
-}
void InstructionWithAbsorbingInputSimplifier::VisitShift(HBinaryOperation* instruction) {
DCHECK(instruction->IsShl() || instruction->IsShr() || instruction->IsUShr());
diff --git a/compiler/optimizing/constant_folding.h b/compiler/optimizing/constant_folding.h
index 07388d2e8c..72bd95b3cb 100644
--- a/compiler/optimizing/constant_folding.h
+++ b/compiler/optimizing/constant_folding.h
@@ -19,7 +19,6 @@
#include "nodes.h"
#include "optimization.h"
-#include "optimizing/optimizing_compiler_stats.h"
namespace art {
@@ -40,8 +39,7 @@ namespace art {
*/
class HConstantFolding : public HOptimization {
public:
- HConstantFolding(HGraph* graph, OptimizingCompilerStats* stats, const char* name)
- : HOptimization(graph, name, stats) {}
+ HConstantFolding(HGraph* graph, const char* name) : HOptimization(graph, name) {}
bool Run() override;
diff --git a/compiler/optimizing/constant_folding_test.cc b/compiler/optimizing/constant_folding_test.cc
index 3bcdc1ce40..74d9d3a993 100644
--- a/compiler/optimizing/constant_folding_test.cc
+++ b/compiler/optimizing/constant_folding_test.cc
@@ -58,7 +58,7 @@ class ConstantFoldingTest : public OptimizingUnitTest {
std::string actual_before = printer_before.str();
EXPECT_EQ(expected_before, actual_before);
- HConstantFolding(graph_, /* stats= */ nullptr, "constant_folding").Run();
+ HConstantFolding(graph_, "constant_folding").Run();
GraphChecker graph_checker_cf(graph_);
graph_checker_cf.Run();
ASSERT_TRUE(graph_checker_cf.IsValid());
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc
index cdd8fb2638..3a2f7f2903 100644
--- a/compiler/optimizing/inliner.cc
+++ b/compiler/optimizing/inliner.cc
@@ -2104,7 +2104,7 @@ void HInliner::RunOptimizations(HGraph* callee_graph,
// Note: if the outermost_graph_ is being compiled OSR, we should not run any
// optimization that could lead to a HDeoptimize. The following optimizations do not.
HDeadCodeElimination dce(callee_graph, inline_stats_, "dead_code_elimination$inliner");
- HConstantFolding fold(callee_graph, inline_stats_, "constant_folding$inliner");
+ HConstantFolding fold(callee_graph, "constant_folding$inliner");
InstructionSimplifier simplify(callee_graph, codegen_, inline_stats_);
HOptimization* optimizations[] = {
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc
index 4fbb033c2f..6ac4e07ca7 100644
--- a/compiler/optimizing/nodes.cc
+++ b/compiler/optimizing/nodes.cc
@@ -1477,10 +1477,6 @@ bool HInstructionList::FoundBefore(const HInstruction* instruction1,
UNREACHABLE();
}
-bool HInstruction::Dominates(HInstruction* other_instruction) const {
- return other_instruction == this || StrictlyDominates(other_instruction);
-}
-
bool HInstruction::StrictlyDominates(HInstruction* other_instruction) const {
if (other_instruction == this) {
// An instruction does not strictly dominate itself.
@@ -1540,19 +1536,14 @@ void HInstruction::ReplaceWith(HInstruction* other) {
DCHECK(env_uses_.empty());
}
-void HInstruction::ReplaceUsesDominatedBy(HInstruction* dominator,
- HInstruction* replacement,
- bool strictly_dominated) {
+void HInstruction::ReplaceUsesDominatedBy(HInstruction* dominator, HInstruction* replacement) {
const HUseList<HInstruction*>& uses = GetUses();
for (auto it = uses.begin(), end = uses.end(); it != end; /* ++it below */) {
HInstruction* user = it->GetUser();
size_t index = it->GetIndex();
// Increment `it` now because `*it` may disappear thanks to user->ReplaceInput().
++it;
- const bool dominated =
- strictly_dominated ? dominator->StrictlyDominates(user) : dominator->Dominates(user);
-
- if (dominated) {
+ if (dominator->StrictlyDominates(user)) {
user->ReplaceInput(replacement, index);
} else if (user->IsPhi() && !user->AsPhi()->IsCatchPhi()) {
// If the input flows from a block dominated by `dominator`, we can replace it.
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 103d318710..39cb9275fb 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -2444,12 +2444,9 @@ class HInstruction : public ArenaObject<kArenaAllocInstruction> {
return IsRemovable() && !HasUses();
}
- // Does this instruction dominate `other_instruction`?
- // Aborts if this instruction and `other_instruction` are different phis.
- bool Dominates(HInstruction* other_instruction) const;
-
- // Same but with `strictly dominates` i.e. returns false if this instruction and
- // `other_instruction` are the same.
+ // Does this instruction strictly dominate `other_instruction`?
+ // Returns false if this instruction and `other_instruction` are the same.
+ // Aborts if this instruction and `other_instruction` are both phis.
bool StrictlyDominates(HInstruction* other_instruction) const;
int GetId() const { return id_; }
@@ -2514,9 +2511,7 @@ class HInstruction : public ArenaObject<kArenaAllocInstruction> {
void SetLocations(LocationSummary* locations) { locations_ = locations; }
void ReplaceWith(HInstruction* instruction);
- void ReplaceUsesDominatedBy(HInstruction* dominator,
- HInstruction* replacement,
- bool strictly_dominated = true);
+ void ReplaceUsesDominatedBy(HInstruction* dominator, HInstruction* replacement);
void ReplaceEnvUsesDominatedBy(HInstruction* dominator, HInstruction* replacement);
void ReplaceInput(HInstruction* replacement, size_t index);
diff --git a/compiler/optimizing/optimization.cc b/compiler/optimizing/optimization.cc
index 7bf6dbb741..2cac38b715 100644
--- a/compiler/optimizing/optimization.cc
+++ b/compiler/optimizing/optimization.cc
@@ -221,7 +221,7 @@ ArenaVector<HOptimization*> ConstructOptimizations(
// Regular passes.
//
case OptimizationPass::kConstantFolding:
- opt = new (allocator) HConstantFolding(graph, stats, pass_name);
+ opt = new (allocator) HConstantFolding(graph, pass_name);
break;
case OptimizationPass::kDeadCodeElimination:
opt = new (allocator) HDeadCodeElimination(graph, stats, pass_name);
diff --git a/compiler/optimizing/optimizing_compiler_stats.h b/compiler/optimizing/optimizing_compiler_stats.h
index 5e316ba403..d458e42608 100644
--- a/compiler/optimizing/optimizing_compiler_stats.h
+++ b/compiler/optimizing/optimizing_compiler_stats.h
@@ -73,7 +73,6 @@ enum class MethodCompilationStat {
kLoopVectorizedIdiom,
kSelectGenerated,
kRemovedInstanceOf,
- kPropagatedIfValue,
kInlinedInvokeVirtualOrInterface,
kInlinedLastInvokeVirtualOrInterface,
kImplicitNullCheckGenerated,
diff --git a/test/2042-checker-dce-always-throw/src/Main.java b/test/2042-checker-dce-always-throw/src/Main.java
index bc2e7a11a1..b601f20ebb 100644
--- a/test/2042-checker-dce-always-throw/src/Main.java
+++ b/test/2042-checker-dce-always-throw/src/Main.java
@@ -27,11 +27,11 @@ public class Main {
// Try catch tests
assertEquals(0, $noinline$testDoNotSimplifyInTry(1));
assertEquals(0, $noinline$testSimplifyInCatch(1));
- assertEquals(0, $noinline$testDoNotSimplifyInCatchInOuterTry(1, 1));
+ assertEquals(0, $noinline$testDoNotSimplifyInCatchInOuterTry(1));
// Test that we update the phis correctly after simplifying an always throwing method, and
// recomputing dominance.
- assertEquals(0, $noinline$UpdatePhisCorrectly(1, 1));
+ assertEquals(0, $noinline$UpdatePhisCorrectly(1));
}
private static void alwaysThrows() throws Error {
@@ -251,25 +251,25 @@ public class Main {
}
}
- /// CHECK-START: int Main.$noinline$testDoNotSimplifyInCatchInOuterTry(int, int) dead_code_elimination$after_inlining (before)
+ /// CHECK-START: int Main.$noinline$testDoNotSimplifyInCatchInOuterTry(int) dead_code_elimination$after_inlining (before)
/// CHECK-DAG: InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true
/// CHECK-DAG: Exit block:<<ExitBlock:B\d+>>
/// CHECK-DAG: Goto block:<<InvokeBlock>> target:<<TargetBlock:B\d+>>
/// CHECK-EVAL: "<<ExitBlock>>" != "<<TargetBlock>>"
- /// CHECK-START: int Main.$noinline$testDoNotSimplifyInCatchInOuterTry(int, int) dead_code_elimination$after_inlining (after)
+ /// CHECK-START: int Main.$noinline$testDoNotSimplifyInCatchInOuterTry(int) dead_code_elimination$after_inlining (after)
/// CHECK-DAG: InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true
/// CHECK-DAG: Exit block:<<ExitBlock:B\d+>>
/// CHECK-DAG: Goto block:<<InvokeBlock>> target:<<TargetBlock:B\d+>>
/// CHECK-EVAL: "<<ExitBlock>>" != "<<TargetBlock>>"
// Consistency check to make sure we have the try catches in the graph at this stage.
- /// CHECK-START: int Main.$noinline$testDoNotSimplifyInCatchInOuterTry(int, int) dead_code_elimination$after_inlining (before)
+ /// CHECK-START: int Main.$noinline$testDoNotSimplifyInCatchInOuterTry(int) dead_code_elimination$after_inlining (before)
/// CHECK-DAG: TryBoundary kind:entry
/// CHECK-DAG: TryBoundary kind:entry
// Consistency check to that we do not simplify it by the last DCE pass either
- /// CHECK-START: int Main.$noinline$testDoNotSimplifyInCatchInOuterTry(int, int) dead_code_elimination$final (after)
+ /// CHECK-START: int Main.$noinline$testDoNotSimplifyInCatchInOuterTry(int) dead_code_elimination$final (after)
/// CHECK-DAG: InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true
/// CHECK-DAG: Exit block:<<ExitBlock:B\d+>>
/// CHECK-DAG: Goto block:<<InvokeBlock>> target:<<TargetBlock:B\d+>>
@@ -278,15 +278,13 @@ public class Main {
// Similar to testSimplifyInCatch, but now the throw is in an outer try and we shouldn't simplify
// it. Like in testDoNotSimplifyInTry, we need the help of the inliner to have an invoke followed
// by a Goto.
- private static int $noinline$testDoNotSimplifyInCatchInOuterTry(int num, int other_num) {
+ private static int $noinline$testDoNotSimplifyInCatchInOuterTry(int num) {
try {
try {
throw new Error();
} catch (Error e) {
if (num == 0) {
- // We use `other_num` here because otherwise we propagate the knowledge that `num` equals
- // zero.
- $inline$testDoNotSimplifyInner(other_num);
+ $inline$testDoNotSimplifyInner(num);
}
return 0;
}
@@ -298,7 +296,7 @@ public class Main {
// Check that when we perform SimplifyAlwaysThrows, that the phi for `phi_value` exists, and that
// we correctly update it after running DCE.
- /// CHECK-START: int Main.$noinline$UpdatePhisCorrectly(int, int) dead_code_elimination$after_inlining (before)
+ /// CHECK-START: int Main.$noinline$UpdatePhisCorrectly(int) dead_code_elimination$after_inlining (before)
/// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
/// CHECK-DAG: <<Const5:i\d+>> IntConstant 5
/// CHECK-DAG: <<ReturnValue:i\d+>> Phi [<<Const0>>,<<Const5>>]
@@ -308,24 +306,23 @@ public class Main {
/// CHECK-DAG: Goto block:<<InvokeBlock>> target:<<TargetBlock:B\d+>>
/// CHECK-EVAL: "<<ExitBlock>>" != "<<TargetBlock>>"
- /// CHECK-START: int Main.$noinline$UpdatePhisCorrectly(int, int) dead_code_elimination$after_inlining (after)
+ /// CHECK-START: int Main.$noinline$UpdatePhisCorrectly(int) dead_code_elimination$after_inlining (after)
/// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
/// CHECK-DAG: Return [<<Const0>>]
/// CHECK-DAG: InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true
/// CHECK-DAG: Exit block:<<ExitBlock:B\d+>>
/// CHECK-DAG: Goto block:<<InvokeBlock>> target:<<ExitBlock>>
- /// CHECK-START: int Main.$noinline$UpdatePhisCorrectly(int, int) dead_code_elimination$after_inlining (after)
+ /// CHECK-START: int Main.$noinline$UpdatePhisCorrectly(int) dead_code_elimination$after_inlining (after)
/// CHECK-NOT: Phi
- private static int $noinline$UpdatePhisCorrectly(int num, int other_num) {
+ private static int $noinline$UpdatePhisCorrectly(int num) {
int phi_value = 0;
if (num == 0) {
alwaysThrows();
// This while loop is here so that the `if (num == 0)` will be several blocks instead of
- // just one. We use `other_num` here because otherwise we propagate the knowledge that `num`
- // equals zero.
- while (other_num == 0) {
+ // just one.
+ while (num == 0) {
// Assign to phi_value so that the loop is not empty.
phi_value = 2;
}
diff --git a/test/442-checker-constant-folding/src/Main.java b/test/442-checker-constant-folding/src/Main.java
index 68f9b1f52b..1bdf7b5cc8 100644
--- a/test/442-checker-constant-folding/src/Main.java
+++ b/test/442-checker-constant-folding/src/Main.java
@@ -1577,338 +1577,6 @@ public class Main {
return (double) imm;
}
- /// CHECK-START: int Main.$inline$SpecialCaseForZeroInt(int) constant_folding (before)
- /// CHECK-DAG: Add
- /// CHECK-DAG: Mul
-
- /// CHECK-START: int Main.$inline$SpecialCaseForZeroInt(int) constant_folding (before)
- /// CHECK-NOT: IntConstant 6
-
- /// CHECK-START: int Main.$inline$SpecialCaseForZeroInt(int) constant_folding (after)
- /// CHECK-NOT: Add
-
- /// CHECK-START: int Main.$inline$SpecialCaseForZeroInt(int) constant_folding (after)
- /// CHECK-NOT: Mul
-
- /// CHECK-START: int Main.$inline$SpecialCaseForZeroInt(int) constant_folding (after)
- /// CHECK-DAG: <<Const:i\d+>> IntConstant 6
- /// CHECK-DAG: Return [<<Const>>]
- private static int $inline$SpecialCaseForZeroInt(int value) {
- if (value == 0) {
- return (value + 2) * 3;
- }
- return value;
- }
-
- /// CHECK-START: long Main.$inline$SpecialCaseForZeroLong(long) constant_folding (before)
- /// CHECK-DAG: Add
- /// CHECK-DAG: Mul
-
- /// CHECK-START: long Main.$inline$SpecialCaseForZeroLong(long) constant_folding (before)
- /// CHECK-NOT: LongConstant 6
-
- /// CHECK-START: long Main.$inline$SpecialCaseForZeroLong(long) constant_folding (after)
- /// CHECK-NOT: Add
-
- /// CHECK-START: long Main.$inline$SpecialCaseForZeroLong(long) constant_folding (after)
- /// CHECK-NOT: Mul
-
- /// CHECK-START: long Main.$inline$SpecialCaseForZeroLong(long) constant_folding (after)
- /// CHECK-DAG: <<Const:j\d+>> LongConstant 6
- /// CHECK-DAG: Return [<<Const>>]
- private static long $inline$SpecialCaseForZeroLong(long value) {
- if (value == 0L) {
- return (value + 2) * 3;
- }
- return value;
- }
-
- /// CHECK-START: float Main.$inline$SpecialCaseForZeroFloat(float) constant_folding (before)
- /// CHECK-DAG: Add
- /// CHECK-DAG: Mul
-
- /// CHECK-START: float Main.$inline$SpecialCaseForZeroFloat(float) constant_folding (before)
- /// CHECK-NOT: FloatConstant 6
-
- /// CHECK-START: float Main.$inline$SpecialCaseForZeroFloat(float) constant_folding (after)
- /// CHECK-NOT: Add
-
- /// CHECK-START: float Main.$inline$SpecialCaseForZeroFloat(float) constant_folding (after)
- /// CHECK-NOT: Mul
-
- /// CHECK-START: float Main.$inline$SpecialCaseForZeroFloat(float) constant_folding (after)
- /// CHECK-DAG: <<Const:f\d+>> FloatConstant 6
- /// CHECK-DAG: Return [<<Const>>]
- private static float $inline$SpecialCaseForZeroFloat(float value) {
- if (value == 0F) {
- return (value + 2F) * 3F;
- }
- return value;
- }
-
- /// CHECK-START: double Main.$inline$SpecialCaseForZeroDouble(double) constant_folding (before)
- /// CHECK-DAG: Add
- /// CHECK-DAG: Mul
-
- /// CHECK-START: double Main.$inline$SpecialCaseForZeroDouble(double) constant_folding (before)
- /// CHECK-NOT: DoubleConstant 6
-
- /// CHECK-START: double Main.$inline$SpecialCaseForZeroDouble(double) constant_folding (after)
- /// CHECK-NOT: Add
-
- /// CHECK-START: double Main.$inline$SpecialCaseForZeroDouble(double) constant_folding (after)
- /// CHECK-NOT: Mul
-
- /// CHECK-START: double Main.$inline$SpecialCaseForZeroDouble(double) constant_folding (after)
- /// CHECK-DAG: <<Const:d\d+>> DoubleConstant 6
- /// CHECK-DAG: Return [<<Const>>]
- private static double $inline$SpecialCaseForZeroDouble(double value) {
- if (value == 0D) {
- return (value + 2D) * 3D;
- }
- return value;
- }
-
- // Note that we have Add instead of sub since internally we do `Add(value, -1)`.
- /// CHECK-START: int Main.$noinline$NotEqualsPropagationInt(int) constant_folding (before)
- /// CHECK-DAG: Add
- /// CHECK-DAG: Div
-
- /// CHECK-START: int Main.$noinline$NotEqualsPropagationInt(int) constant_folding (after)
- /// CHECK-NOT: Add
-
- /// CHECK-START: int Main.$noinline$NotEqualsPropagationInt(int) constant_folding (after)
- /// CHECK-NOT: Div
-
- /// CHECK-START: int Main.$noinline$NotEqualsPropagationInt(int) constant_folding (after)
- /// CHECK-DAG: <<Const:i\d+>> IntConstant 1
- /// CHECK-DAG: Return [<<Const>>]
- private static int $noinline$NotEqualsPropagationInt(int value) {
- if (value != 3) {
- return value;
- } else {
- return (value - 1) / 2;
- }
- }
-
- /// CHECK-START: long Main.$noinline$NotEqualsPropagationLong(long) constant_folding (before)
- /// CHECK-DAG: Sub
- /// CHECK-DAG: Div
-
- /// CHECK-START: long Main.$noinline$NotEqualsPropagationLong(long) constant_folding (after)
- /// CHECK-NOT: Sub
-
- /// CHECK-START: long Main.$noinline$NotEqualsPropagationLong(long) constant_folding (after)
- /// CHECK-NOT: Div
-
- /// CHECK-START: long Main.$noinline$NotEqualsPropagationLong(long) constant_folding (after)
- /// CHECK-DAG: <<Const:j\d+>> LongConstant 1
- /// CHECK-DAG: Return [<<Const>>]
- private static long $noinline$NotEqualsPropagationLong(long value) {
- if (value != 3L) {
- return value;
- } else {
- return (value - 1L) / 2L;
- }
- }
-
- /// CHECK-START: float Main.$noinline$NotEqualsPropagationFloat(float) constant_folding (before)
- /// CHECK-DAG: Sub
- /// CHECK-DAG: Div
-
- /// CHECK-START: float Main.$noinline$NotEqualsPropagationFloat(float) constant_folding (after)
- /// CHECK-NOT: Sub
-
- /// CHECK-START: float Main.$noinline$NotEqualsPropagationFloat(float) constant_folding (after)
- /// CHECK-NOT: Div
-
- /// CHECK-START: float Main.$noinline$NotEqualsPropagationFloat(float) constant_folding (after)
- /// CHECK-DAG: <<Const:f\d+>> FloatConstant 1
- /// CHECK-DAG: Return [<<Const>>]
- private static float $noinline$NotEqualsPropagationFloat(float value) {
- if (value != 3F) {
- return value;
- } else {
- return (value - 1F) / 2F;
- }
- }
-
- /// CHECK-START: double Main.$noinline$NotEqualsPropagationDouble(double) constant_folding (before)
- /// CHECK-DAG: Sub
- /// CHECK-DAG: Div
-
- /// CHECK-START: double Main.$noinline$NotEqualsPropagationDouble(double) constant_folding (after)
- /// CHECK-NOT: Sub
-
- /// CHECK-START: double Main.$noinline$NotEqualsPropagationDouble(double) constant_folding (after)
- /// CHECK-NOT: Div
-
- /// CHECK-START: double Main.$noinline$NotEqualsPropagationDouble(double) constant_folding (after)
- /// CHECK-DAG: <<Const:d\d+>> DoubleConstant 1
- /// CHECK-DAG: Return [<<Const>>]
- private static double $noinline$NotEqualsPropagationDouble(double value) {
- if (value != 3D) {
- return value;
- } else {
- return (value - 1D) / 2D;
- }
- }
-
- /// CHECK-START: int Main.$noinline$InlineCaleeWithSpecialCaseForZeroInt(int) inliner (after)
- /// CHECK-NOT: Add
-
- /// CHECK-START: int Main.$noinline$InlineCaleeWithSpecialCaseForZeroInt(int) inliner (after)
- /// CHECK-NOT: Mul
-
- /// CHECK-START: int Main.$noinline$InlineCaleeWithSpecialCaseForZeroInt(int) inliner (after)
- /// CHECK-DAG: <<Const:i\d+>> IntConstant 6
- /// CHECK-DAG: Return [<<Const>>]
- private static int $noinline$InlineCaleeWithSpecialCaseForZeroInt(int value) {
- if (value == 0) {
- return $inline$SpecialCaseForZeroInt(value);
- }
- return value;
- }
-
- /// CHECK-START: long Main.$noinline$InlineCaleeWithSpecialCaseForZeroLong(long) inliner (after)
- /// CHECK-NOT: Add
-
- /// CHECK-START: long Main.$noinline$InlineCaleeWithSpecialCaseForZeroLong(long) inliner (after)
- /// CHECK-NOT: Mul
-
- /// CHECK-START: long Main.$noinline$InlineCaleeWithSpecialCaseForZeroLong(long) inliner (after)
- /// CHECK-DAG: <<Const:j\d+>> LongConstant 6
- /// CHECK-DAG: Return [<<Const>>]
- private static long $noinline$InlineCaleeWithSpecialCaseForZeroLong(long value) {
- if (value == 0L) {
- return $inline$SpecialCaseForZeroLong(value);
- }
- return value;
- }
-
- /// CHECK-START: float Main.$noinline$InlineCaleeWithSpecialCaseForZeroFloat(float) inliner (after)
- /// CHECK-NOT: Add
-
- /// CHECK-START: float Main.$noinline$InlineCaleeWithSpecialCaseForZeroFloat(float) inliner (after)
- /// CHECK-NOT: Mul
-
- /// CHECK-START: float Main.$noinline$InlineCaleeWithSpecialCaseForZeroFloat(float) inliner (after)
- /// CHECK-DAG: <<Const:f\d+>> FloatConstant 6
- /// CHECK-DAG: Return [<<Const>>]
- private static float $noinline$InlineCaleeWithSpecialCaseForZeroFloat(float value) {
- if (value == 0F) {
- return $inline$SpecialCaseForZeroFloat(value);
- }
- return value;
- }
-
- /// CHECK-START: double Main.$noinline$InlineCaleeWithSpecialCaseForZeroDouble(double) inliner (after)
- /// CHECK-NOT: Add
-
- /// CHECK-START: double Main.$noinline$InlineCaleeWithSpecialCaseForZeroDouble(double) inliner (after)
- /// CHECK-NOT: Mul
-
- /// CHECK-START: double Main.$noinline$InlineCaleeWithSpecialCaseForZeroDouble(double) inliner (after)
- /// CHECK-DAG: <<Const:d\d+>> DoubleConstant 6
- /// CHECK-DAG: Return [<<Const>>]
- private static double $noinline$InlineCaleeWithSpecialCaseForZeroDouble(double value) {
- if (value == 0D) {
- return $inline$SpecialCaseForZeroDouble(value);
- }
- return value;
- }
-
- // Check that don't propagate the value == 3 on `if not true` branch, as the `if true` branch also
- // flows into the same block.
- /// CHECK-START: int Main.$noinline$NotEqualsImplicitElseInt(int) constant_folding (before)
- /// CHECK-DAG: Add
- /// CHECK-DAG: Div
-
- /// CHECK-START: int Main.$noinline$NotEqualsImplicitElseInt(int) constant_folding (after)
- /// CHECK-DAG: Add
- /// CHECK-DAG: Div
- private static int $noinline$NotEqualsImplicitElseInt(int value) {
- if (value != 3) {
- value++;
- }
- return (value - 1) / 2;
- }
-
- /// CHECK-START: long Main.$noinline$NotEqualsImplicitElseLong(long) constant_folding (before)
- /// CHECK-DAG: Sub
- /// CHECK-DAG: Div
-
- /// CHECK-START: long Main.$noinline$NotEqualsImplicitElseLong(long) constant_folding (after)
- /// CHECK-DAG: Sub
- /// CHECK-DAG: Div
- private static long $noinline$NotEqualsImplicitElseLong(long value) {
- if (value != 3L) {
- value += 1L;
- }
- return (value - 1L) / 2L;
- }
-
- /// CHECK-START: float Main.$noinline$NotEqualsImplicitElseFloat(float) constant_folding (before)
- /// CHECK-DAG: Sub
- /// CHECK-DAG: Div
-
- /// CHECK-START: float Main.$noinline$NotEqualsImplicitElseFloat(float) constant_folding (after)
- /// CHECK-DAG: Sub
- /// CHECK-DAG: Div
- private static float $noinline$NotEqualsImplicitElseFloat(float value) {
- if (value != 3F) {
- value += 1F;
- }
- return (value - 1F) / 2F;
- }
-
- /// CHECK-START: double Main.$noinline$NotEqualsImplicitElseDouble(double) constant_folding (before)
- /// CHECK-DAG: Sub
- /// CHECK-DAG: Div
-
- /// CHECK-START: double Main.$noinline$NotEqualsImplicitElseDouble(double) constant_folding (after)
- /// CHECK-DAG: Sub
- /// CHECK-DAG: Div
- private static double $noinline$NotEqualsImplicitElseDouble(double value) {
- if (value != 3D) {
- value += 1D;
- }
- return (value - 1D) / 2D;
- }
-
- // By propagating the boolean we can elimniate some equality comparisons as we already know their
- // result. In turn, we also enable DeadCodeElimination to eliminate more code.
- /// CHECK-START: int Main.$noinline$PropagatingParameterValue(boolean) constant_folding (before)
- /// CHECK-DAG: Equal
- /// CHECK-DAG: Equal
- /// CHECK-DAG: Equal
-
- /// CHECK-START: int Main.$noinline$PropagatingParameterValue(boolean) constant_folding (after)
- /// CHECK: Equal
- /// CHECK-NOT: Equal
-
- /// CHECK-START: int Main.$noinline$PropagatingParameterValue(boolean) dead_code_elimination$initial (before)
- /// CHECK-DAG: IntConstant 1
- /// CHECK-DAG: IntConstant 2
- /// CHECK-DAG: IntConstant 3
- /// CHECK-DAG: IntConstant 4
-
- /// CHECK-START: int Main.$noinline$PropagatingParameterValue(boolean) dead_code_elimination$initial (after)
- /// CHECK-DAG: IntConstant 1
- /// CHECK-DAG: IntConstant 4
-
- /// CHECK-START: int Main.$noinline$PropagatingParameterValue(boolean) dead_code_elimination$initial (after)
- /// CHECK-NOT: IntConstant 2
-
- /// CHECK-START: int Main.$noinline$PropagatingParameterValue(boolean) dead_code_elimination$initial (after)
- /// CHECK-NOT: IntConstant 3
- private static int $noinline$PropagatingParameterValue(boolean value) {
- if (value) {
- return value ? 1 : 2;
- } else {
- return value ? 3 : 4;
- }
- }
public static void main(String[] args) throws Exception {
assertIntEquals(-42, IntNegation());
@@ -2040,52 +1708,6 @@ public class Main {
assertDoubleEquals(33, ReturnDouble33());
assertDoubleEquals(34, ReturnDouble34());
assertDoubleEquals(99.25, ReturnDouble99P25());
-
- // Tests for propagating known values due to if clauses.
-
- // Propagating within the same method.
- assertIntEquals(6, $inline$SpecialCaseForZeroInt(0));
- assertIntEquals(3, $inline$SpecialCaseForZeroInt(3));
- assertLongEquals(6L, $inline$SpecialCaseForZeroLong(0L));
- assertLongEquals(3L, $inline$SpecialCaseForZeroLong(3L));
- assertFloatEquals(6F, $inline$SpecialCaseForZeroFloat(0F));
- assertFloatEquals(3F, $inline$SpecialCaseForZeroFloat(3F));
- assertDoubleEquals(6D, $inline$SpecialCaseForZeroDouble(0D));
- assertDoubleEquals(3D, $inline$SpecialCaseForZeroDouble(3D));
-
- // Propagating within the same method, with not equals
- assertIntEquals(0, $noinline$NotEqualsPropagationInt(0));
- assertIntEquals(1, $noinline$NotEqualsPropagationInt(3));
- assertLongEquals(0L, $noinline$NotEqualsPropagationLong(0L));
- assertLongEquals(1L, $noinline$NotEqualsPropagationLong(3L));
- assertFloatEquals(0F, $noinline$NotEqualsPropagationFloat(0F));
- assertFloatEquals(1F, $noinline$NotEqualsPropagationFloat(3F));
- assertDoubleEquals(0D, $noinline$NotEqualsPropagationDouble(0D));
- assertDoubleEquals(1D, $noinline$NotEqualsPropagationDouble(3D));
-
- // Propagating so that the inliner can use it.
- assertIntEquals(6, $noinline$InlineCaleeWithSpecialCaseForZeroInt(0));
- assertIntEquals(3, $noinline$InlineCaleeWithSpecialCaseForZeroInt(3));
- assertLongEquals(6L, $noinline$InlineCaleeWithSpecialCaseForZeroLong(0L));
- assertLongEquals(3L, $noinline$InlineCaleeWithSpecialCaseForZeroLong(3L));
- assertFloatEquals(6F, $noinline$InlineCaleeWithSpecialCaseForZeroFloat(0F));
- assertFloatEquals(3F, $noinline$InlineCaleeWithSpecialCaseForZeroFloat(3F));
- assertDoubleEquals(6D, $noinline$InlineCaleeWithSpecialCaseForZeroDouble(0D));
- assertDoubleEquals(3D, $noinline$InlineCaleeWithSpecialCaseForZeroDouble(3D));
-
- // Propagating within the same method, with not equals
- assertIntEquals(0, $noinline$NotEqualsImplicitElseInt(0));
- assertIntEquals(1, $noinline$NotEqualsImplicitElseInt(3));
- assertLongEquals(0L, $noinline$NotEqualsImplicitElseLong(0L));
- assertLongEquals(1L, $noinline$NotEqualsImplicitElseLong(3L));
- assertFloatEquals(0F, $noinline$NotEqualsImplicitElseFloat(0F));
- assertFloatEquals(1F, $noinline$NotEqualsImplicitElseFloat(3F));
- assertDoubleEquals(0D, $noinline$NotEqualsImplicitElseDouble(0D));
- assertDoubleEquals(1D, $noinline$NotEqualsImplicitElseDouble(3D));
-
- // Propagating parameters.
- assertIntEquals(1, $noinline$PropagatingParameterValue(true));
- assertIntEquals(4, $noinline$PropagatingParameterValue(false));
}
Main() throws ClassNotFoundException {
diff --git a/test/449-checker-bce/src/Main.java b/test/449-checker-bce/src/Main.java
index fbe3586800..1144366dfb 100644
--- a/test/449-checker-bce/src/Main.java
+++ b/test/449-checker-bce/src/Main.java
@@ -1125,7 +1125,7 @@ public class Main {
/// CHECK-DAG: <<Len:i\d+>> ArrayLength [<<Nul>>] loop:none
/// CHECK-DAG: Equal [<<Len>>,<<Val>>] loop:none
/// CHECK-DAG: <<Idx:i\d+>> Phi loop:<<Loop:B\d+>>
- /// CHECK-DAG: BoundsCheck [<<Idx>>,<<Val>>] loop:<<Loop>>
+ /// CHECK-DAG: BoundsCheck [<<Idx>>,<<Len>>] loop:<<Loop>>
//
/// CHECK-START: void Main.lengthAlias4(int[]) BCE (after)
/// CHECK-NOT: BoundsCheck
diff --git a/test/485-checker-dce-loop-update/smali/TestCase.smali b/test/485-checker-dce-loop-update/smali/TestCase.smali
index 3e7bca93c9..5290bad3ed 100644
--- a/test/485-checker-dce-loop-update/smali/TestCase.smali
+++ b/test/485-checker-dce-loop-update/smali/TestCase.smali
@@ -224,7 +224,7 @@
## CHECK-DAG: If [<<ArgY>>] loop:<<HeaderY>>
#
# ### Inner loop ###
-## CHECK-DAG: <<PhiZ2:i\d+>> Phi [<<PhiZ1>>,<<Cst0>>] loop:<<HeaderZ:B\d+>>
+## CHECK-DAG: <<PhiZ2:i\d+>> Phi [<<PhiZ1>>,<<XorZ>>] loop:<<HeaderZ:B\d+>>
## CHECK-DAG: <<XorZ>> Xor [<<PhiZ2>>,<<Cst1>>] loop:<<HeaderZ>>
## CHECK-DAG: <<CondZ:z\d+>> Equal [<<XorZ>>,<<Cst0>>] loop:<<HeaderZ>>
## CHECK-DAG: If [<<CondZ>>] loop:<<HeaderZ>>
@@ -246,8 +246,8 @@
## CHECK-DAG: <<Add7>> Add [<<PhiX>>,<<Cst7>>] loop:<<HeaderY>>
#
# ### Inner loop ###
-## CHECK-DAG: <<PhiZ:i\d+>> Phi [<<ArgZ>>,<<Cst0>>] loop:<<HeaderZ:B\d+>>
-## CHECK-DAG: <<XorZ:i\d+>> Xor [<<PhiZ>>,<<Cst1>>] loop:<<HeaderZ>>
+## CHECK-DAG: <<PhiZ:i\d+>> Phi [<<ArgZ>>,<<XorZ:i\d+>>] loop:<<HeaderZ:B\d+>>
+## CHECK-DAG: <<XorZ>> Xor [<<PhiZ>>,<<Cst1>>] loop:<<HeaderZ>>
## CHECK-DAG: <<CondZ:z\d+>> Equal [<<XorZ>>,<<Cst0>>] loop:<<HeaderZ>>
## CHECK-DAG: If [<<CondZ>>] loop:<<HeaderZ>>
#
diff --git a/test/543-checker-dce-trycatch/smali/TestCase.smali b/test/543-checker-dce-trycatch/smali/TestCase.smali
index 15eaabbc04..7ad9ba8e64 100644
--- a/test/543-checker-dce-trycatch/smali/TestCase.smali
+++ b/test/543-checker-dce-trycatch/smali/TestCase.smali
@@ -206,7 +206,6 @@
## CHECK-START: int TestCase.testCatchPhiInputs_DefinedInTryBlock(int, int, int, int) dead_code_elimination$after_inlining (before)
## CHECK-DAG: <<Arg0:i\d+>> ParameterValue
## CHECK-DAG: <<Arg1:i\d+>> ParameterValue
-## CHECK-DAG: <<Const0x0:i\d+>> IntConstant 0
## CHECK-DAG: <<Const0xa:i\d+>> IntConstant 10
## CHECK-DAG: <<Const0xb:i\d+>> IntConstant 11
## CHECK-DAG: <<Const0xc:i\d+>> IntConstant 12
@@ -216,7 +215,7 @@
## CHECK-DAG: <<Const0x10:i\d+>> IntConstant 16
## CHECK-DAG: <<Const0x11:i\d+>> IntConstant 17
## CHECK-DAG: <<Add:i\d+>> Add [<<Arg0>>,<<Arg1>>]
-## CHECK-DAG: <<Phi:i\d+>> Phi [<<Const0x0>>,<<Const0xf>>] reg:3 is_catch_phi:false
+## CHECK-DAG: <<Phi:i\d+>> Phi [<<Add>>,<<Const0xf>>] reg:3 is_catch_phi:false
## CHECK-DAG: Phi [<<Const0xa>>,<<Const0xb>>,<<Const0xd>>] reg:1 is_catch_phi:true
## CHECK-DAG: Phi [<<Add>>,<<Const0xc>>,<<Const0xe>>] reg:2 is_catch_phi:true
## CHECK-DAG: Phi [<<Phi>>,<<Const0x10>>,<<Const0x11>>] reg:3 is_catch_phi:true
@@ -249,8 +248,7 @@
if-eqz v3, :define_phi
const v3, 0xf
:define_phi
- # v3 = Phi [Add, 0xf] # dead catch phi input, defined in the dead block (HPhi).
- # Note that the Add has to be equal to 0 since we do `if-eqz v3`
+ # v3 = Phi [Add, 0xf] # dead catch phi input, defined in the dead block (HPhi)
div-int/2addr p0, v2
:else
diff --git a/test/559-checker-irreducible-loop/smali/IrreducibleLoop.smali b/test/559-checker-irreducible-loop/smali/IrreducibleLoop.smali
index 493567cac5..a30a11afb7 100644
--- a/test/559-checker-irreducible-loop/smali/IrreducibleLoop.smali
+++ b/test/559-checker-irreducible-loop/smali/IrreducibleLoop.smali
@@ -140,23 +140,24 @@
# other_loop_entry
# i1 = phi(p0, i0)
#
-## CHECK-START: int IrreducibleLoop.liveness(int, int) liveness (after)
+## CHECK-START: int IrreducibleLoop.liveness(int) liveness (after)
## CHECK-DAG: <<Arg:i\d+>> ParameterValue liveness:<<ArgLiv:\d+>> ranges:{[<<ArgLiv>>,<<ArgLoopPhiUse:\d+>>)}
## CHECK-DAG: <<LoopPhi:i\d+>> Phi [<<Arg>>,<<PhiInLoop:i\d+>>] liveness:<<ArgLoopPhiUse>> ranges:{[<<ArgLoopPhiUse>>,<<PhiInLoopUse:\d+>>)}
## CHECK-DAG: <<PhiInLoop>> Phi [<<Arg>>,<<LoopPhi>>] liveness:<<PhiInLoopUse>> ranges:{[<<PhiInLoopUse>>,<<BackEdgeLifetimeEnd:\d+>>)}
## CHECK: Return liveness:<<ReturnLiveness:\d+>>
## CHECK-EVAL: <<ReturnLiveness>> == <<BackEdgeLifetimeEnd>> + 2
-.method public static liveness(II)I
+.method public static liveness(I)I
.registers 2
- if-eq p0, p1, :other_loop_entry
+ const/16 v0, 42
+ if-eq p0, v0, :other_loop_entry
:loop_entry
- add-int p1, p1, p0
- if-ne v0, p1, :exit
+ add-int v0, v0, p0
+ if-ne v1, v0, :exit
:other_loop_entry
- add-int p1, p1, p1
+ add-int v0, v0, v0
goto :loop_entry
:exit
- return p1
+ return v0
.end method
# Check that we don't GVN across irreducible loops:
diff --git a/test/559-checker-irreducible-loop/src/Main.java b/test/559-checker-irreducible-loop/src/Main.java
index b22e9b828e..97165eca6e 100644
--- a/test/559-checker-irreducible-loop/src/Main.java
+++ b/test/559-checker-irreducible-loop/src/Main.java
@@ -38,8 +38,8 @@ public class Main {
}
{
- Method m = c.getMethod("liveness", int.class, int.class);
- Object[] arguments = { 42, 42 };
+ Method m = c.getMethod("liveness", int.class);
+ Object[] arguments = { 42 };
System.out.println(m.invoke(null, arguments));
}
diff --git a/test/563-checker-fakestring/smali/TestCase.smali b/test/563-checker-fakestring/smali/TestCase.smali
index c6561d5386..4721ecaa09 100644
--- a/test/563-checker-fakestring/smali/TestCase.smali
+++ b/test/563-checker-fakestring/smali/TestCase.smali
@@ -310,7 +310,7 @@
## CHECK-NOT: NewInstance
## CHECK-DAG: <<Invoke1:l\d+>> InvokeStaticOrDirect method_name:java.lang.String.<init>
## CHECK-DAG: <<Invoke2:l\d+>> InvokeStaticOrDirect method_name:java.lang.String.<init>
-## CHECK-DAG: <<Phi:l\d+>> Phi [<<Invoke1>>,<<Invoke2>>]
+## CHECK-DAG: <<Phi:l\d+>> Phi [<<Invoke2>>,<<Invoke1>>]
## CHECK-DAG: Return [<<Phi>>]
.method public static loopAndStringInitAndPhi([BZ)Ljava/lang/String;
.registers 4
diff --git a/test/564-checker-inline-loop/src/Main.java b/test/564-checker-inline-loop/src/Main.java
index 41eca3531d..6929913864 100644
--- a/test/564-checker-inline-loop/src/Main.java
+++ b/test/564-checker-inline-loop/src/Main.java
@@ -21,6 +21,9 @@ public class Main {
/// CHECK-DAG: Return [<<Invoke>>]
/// CHECK-START: int Main.inlineLoop() inliner (after)
+ /// CHECK-NOT: InvokeStaticOrDirect
+
+ /// CHECK-START: int Main.inlineLoop() inliner (after)
/// CHECK-DAG: <<Constant:i\d+>> IntConstant 42
/// CHECK-DAG: Return [<<Constant>>]
@@ -28,31 +31,31 @@ public class Main {
/// CHECK: Goto loop:{{B\d+}}
public static int inlineLoop() {
- return $inline$loopMethod();
+ return loopMethod();
}
/// CHECK-START: void Main.inlineWithinLoop() inliner (before)
/// CHECK: InvokeStaticOrDirect
+ /// CHECK-START: void Main.inlineWithinLoop() inliner (after)
+ /// CHECK-NOT: InvokeStaticOrDirect
+
/// CHECK-START: void Main.inlineWithinLoop() licm (after)
/// CHECK-DAG: Goto loop:<<OuterLoop:B\d+>> outer_loop:none
/// CHECK-DAG: Goto outer_loop:<<OuterLoop>>
public static void inlineWithinLoop() {
while (doLoop) {
- $inline$loopMethod();
+ loopMethod();
}
}
- public static int $inline$loopMethod() {
- // We use `otherDoLoop` here so we don't propagate the knowledge that `doLoop` is true when
- // inlining from `inlineWithinLoop`.
- while (otherDoLoop) {}
+ public static int loopMethod() {
+ while (doLoop) {}
return 42;
}
public static boolean doLoop = false;
- public static boolean otherDoLoop = false;
public static void main(String[] args) {
inlineLoop();
diff --git a/test/596-checker-dead-phi/smali/IrreducibleLoop.smali b/test/596-checker-dead-phi/smali/IrreducibleLoop.smali
index 9f822bf19b..bab2ba99cc 100644
--- a/test/596-checker-dead-phi/smali/IrreducibleLoop.smali
+++ b/test/596-checker-dead-phi/smali/IrreducibleLoop.smali
@@ -20,19 +20,18 @@
# not adjacent. This revealed a bug in our SSA builder, where a dead loop phi would
# be replaced by its incoming input during SsaRedundantPhiElimination.
-# Check that the outer loop suspend check environment only has the two parameter vregs.
-## CHECK-START: int IrreducibleLoop.liveness(int, int) builder (after)
-## CHECK-DAG: <<Phi1:i\d+>> Phi reg:3 loop:{{B\d+}} irreducible:false
-## CHECK-DAG: <<Phi2:i\d+>> Phi reg:4 loop:{{B\d+}} irreducible:false
-## CHECK-DAG: SuspendCheck env:[[_,_,_,<<Phi1>>,<<Phi2>>]] loop:{{B\d+}} irreducible:false
+# Check that the outer loop suspend check environment only has the parameter vreg.
+## CHECK-START: int IrreducibleLoop.liveness(int) builder (after)
+## CHECK-DAG: <<Phi:i\d+>> Phi reg:4 loop:{{B\d+}} irreducible:false
+## CHECK-DAG: SuspendCheck env:[[_,_,_,_,<<Phi>>]] loop:{{B\d+}} irreducible:false
# Check that the linear order has non-adjacent loop blocks.
-## CHECK-START: int IrreducibleLoop.liveness(int, int) liveness (after)
+## CHECK-START: int IrreducibleLoop.liveness(int) liveness (after)
## CHECK-DAG: Mul liveness:<<LPreEntry2:\d+>>
## CHECK-DAG: Add liveness:<<LBackEdge1:\d+>>
## CHECK-EVAL: <<LBackEdge1>> < <<LPreEntry2>>
-.method public static liveness(II)I
+.method public static liveness(I)I
.registers 5
const-string v1, "MyString"
@@ -51,9 +50,8 @@
if-ne v2, v3, :pre_header2
:pre_entry2
- # Add a marker on the irreducible loop entry. Here we use p1 because p0 is a
- # known constant and we eliminate the Mul otherwise.
- mul-int/2addr p1, p1
+ # Add a marker on the irreducible loop entry.
+ mul-int/2addr p0, p0
goto :back_edge2
:back_edge2
@@ -63,9 +61,8 @@
if-eqz p0, :back_edge2
:back_edge1
- # Add a marker on the outer loop back edge. Here we use p1 because p0 is a
- # known constant and we eliminate the Add otherwise.
- add-int/2addr p1, p1
+ # Add a marker on the outer loop back edge.
+ add-int/2addr p0, p0
# Set a wide register, to have v1 undefined at the back edge.
const-wide/16 v0, 0x1
goto :header1
diff --git a/test/596-checker-dead-phi/src/Main.java b/test/596-checker-dead-phi/src/Main.java
index c3384adb95..f3a55df46a 100644
--- a/test/596-checker-dead-phi/src/Main.java
+++ b/test/596-checker-dead-phi/src/Main.java
@@ -22,8 +22,8 @@ public class Main {
// Note that we don't actually enter the loops in the 'liveness'
// method, so this is just a verification that that part of the code we
// generated for that method is correct.
- Method m = c.getMethod("liveness", int.class, int.class);
- Object[] arguments = {42, 12};
+ Method m = c.getMethod("liveness", int.class);
+ Object[] arguments = { 42 };
System.out.println(m.invoke(null, arguments));
}
}