summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/optimizing/loop_optimization.cc5
-rw-r--r--test/623-checker-loop-regressions/src/Main.java24
2 files changed, 28 insertions, 1 deletions
diff --git a/compiler/optimizing/loop_optimization.cc b/compiler/optimizing/loop_optimization.cc
index 4710b32e9c..8e88c1ec7f 100644
--- a/compiler/optimizing/loop_optimization.cc
+++ b/compiler/optimizing/loop_optimization.cc
@@ -1082,7 +1082,10 @@ bool HLoopOptimization::TrySetSimpleLoopHeader(HBasicBlock* block) {
HInstruction* s = block->GetFirstInstruction();
if (s != nullptr && s->IsSuspendCheck()) {
HInstruction* c = s->GetNext();
- if (c != nullptr && c->IsCondition() && c->GetUses().HasExactlyOneElement()) {
+ if (c != nullptr &&
+ c->IsCondition() &&
+ c->GetUses().HasExactlyOneElement() && // only used for termination
+ !c->HasEnvironmentUses()) { // unlikely, but not impossible
HInstruction* i = c->GetNext();
if (i != nullptr && i->IsIf() && i->InputAt(0) == c) {
iset_->insert(c);
diff --git a/test/623-checker-loop-regressions/src/Main.java b/test/623-checker-loop-regressions/src/Main.java
index f0b327840c..2b30986ab3 100644
--- a/test/623-checker-loop-regressions/src/Main.java
+++ b/test/623-checker-loop-regressions/src/Main.java
@@ -288,6 +288,28 @@ public class Main {
}
}
+ // A strange function that does not inline.
+ private static void $noinline$foo(boolean x, int n) {
+ if (n < 0)
+ throw new Error("oh no");
+ if (n > 100) {
+ $noinline$foo(!x, n - 1);
+ $noinline$foo(!x, n - 2);
+ $noinline$foo(!x, n - 3);
+ $noinline$foo(!x, n - 4);
+ }
+ }
+
+ // A loop with environment uses of x (the terminating condition). As exposed by bug
+ // b/37247891, the loop can be unrolled, but should handle the (unlikely, but clearly
+ // not impossible) environment uses of the terminating condition in a correct manner.
+ private static void envUsesInCond() {
+ boolean x = false;
+ for (int i = 0; !(x = i >= 1); i++) {
+ $noinline$foo(true, i);
+ }
+ }
+
public static void main(String[] args) {
expectEquals(10, earlyExitFirst(-1));
for (int i = 0; i <= 10; i++) {
@@ -369,6 +391,8 @@ public class Main {
expectEquals(aa[i], bb.charAt(i));
}
+ envUsesInCond();
+
System.out.println("passed");
}