diff options
| -rw-r--r-- | compiler/optimizing/loop_optimization.cc | 5 | ||||
| -rw-r--r-- | test/623-checker-loop-regressions/src/Main.java | 24 |
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"); } |