Fix 697-string-buffer-append under no-image.
We did not account for the environment use of the string buffer coming
from a HLoadClass.
Test: 697-string-buffer-append with --no-image --target --64
Change-Id: I017ed1e5153095be3c1f6e68fe61c86d20cffa8d
diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc
index 3f1f3b0..788dc60 100644
--- a/compiler/optimizing/instruction_simplifier.cc
+++ b/compiler/optimizing/instruction_simplifier.cc
@@ -2778,9 +2778,16 @@
// Accept only calls on the StringBuilder (which shall all be removed).
// TODO: Carve-out for const-string? Or rely on environment pruning (to be implemented)?
if (holder->InputCount() == 0 || holder->InputAt(0) != sb) {
- // When inlining the constructor, we have a NewArray as an environment use.
- if (constructor_inlined && holder == maybe_new_array) {
- continue;
+ // When inlining the constructor, we have a NewArray and may have a LoadClass as an
+ // environment use.
+ if (constructor_inlined) {
+ if (holder == maybe_new_array) {
+ continue;
+ }
+ if (holder == maybe_new_array->InputAt(0)) {
+ DCHECK(holder->IsLoadClass());
+ continue;
+ }
}
return false;
}
@@ -2816,8 +2823,8 @@
block->RemoveInstruction(sb->GetUses().front().GetUser());
}
if (constructor_inlined) {
- // We need to remove the inlined constructor instructions. That also removes all remaining
- // environment uses.
+ // We need to remove the inlined constructor instructions,
+ // and all remaining environment uses (if any).
DCHECK(sb->HasEnvironmentUses());
DCHECK(maybe_new_array != nullptr);
DCHECK(maybe_new_array->IsNewArray());
@@ -2826,6 +2833,21 @@
DCHECK(fence->IsConstructorFence());
block->RemoveInstruction(fence);
block->RemoveInstruction(maybe_new_array);
+ if (sb->HasEnvironmentUses()) {
+ // We know the only remaining uses are from the LoadClass.
+ HInstruction* load_class = maybe_new_array->InputAt(0);
+ DCHECK(load_class->IsLoadClass());
+ for (HEnvironment* env = load_class->GetEnvironment();
+ env != nullptr;
+ env = env->GetParent()) {
+ for (size_t i = 0, size = env->Size(); i != size; ++i) {
+ if (env->GetInstructionAt(i) == sb) {
+ env->RemoveAsUserOfInput(i);
+ env->SetRawEnvAt(i, /*instruction=*/ nullptr);
+ }
+ }
+ }
+ }
}
DCHECK(!sb->HasEnvironmentUses());
block->RemoveInstruction(sb);