diff options
-rw-r--r-- | compiler/optimizing/register_allocator.cc | 4 | ||||
-rw-r--r-- | test/408-move-bug/expected.txt | 0 | ||||
-rw-r--r-- | test/408-move-bug/info.txt | 2 | ||||
-rw-r--r-- | test/408-move-bug/src/Main.java | 69 |
4 files changed, 75 insertions, 0 deletions
diff --git a/compiler/optimizing/register_allocator.cc b/compiler/optimizing/register_allocator.cc index 7862611..9ba75b8 100644 --- a/compiler/optimizing/register_allocator.cc +++ b/compiler/optimizing/register_allocator.cc @@ -796,6 +796,10 @@ void RegisterAllocator::InsertParallelMoveAt(size_t position, // This is a parallel move for connecting siblings in a same block. We need to // differentiate it with moves for connecting blocks, and input moves. if (previous->GetLifetimePosition() != position) { + // If the previous instruction of the previous instruction is not a parallel + // move, we have to insert the new parallel move before the input or connecting + // block moves. + at = previous; previous = previous->GetPrevious(); } } diff --git a/test/408-move-bug/expected.txt b/test/408-move-bug/expected.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/408-move-bug/expected.txt diff --git a/test/408-move-bug/info.txt b/test/408-move-bug/info.txt new file mode 100644 index 0000000..27a3dbc --- /dev/null +++ b/test/408-move-bug/info.txt @@ -0,0 +1,2 @@ +Regression test for the register allocator in the optimizing +compiler. Input moves where being overridden by sibling moves. diff --git a/test/408-move-bug/src/Main.java b/test/408-move-bug/src/Main.java new file mode 100644 index 0000000..420298b --- /dev/null +++ b/test/408-move-bug/src/Main.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +public class Main { + + public static void main(String[] args) { + crash(); + npe(); + } + + static void crash() { + boolean b = baz(); + // Create many objects to starve registers. + Main foo1 = create(); + Main foo2 = create(); + Main foo3 = create(); + Main foo4 = create(); + foo1.otherField = null; + // On X86, we would force b to be in a byte register, which + // would generate moves. This code exposed a bug in the + // register allocator, where an input move was not just before + // the instruction itself, and its destination was overridden + // by another value. + foo1.field = b; + foo2.field = b; + foo3.field = b; + foo4.field = b; + foo1.lastField = b; + } + + // Similar to `crash` but generated an NPE. + static void npe() { + boolean b = baz(); + Main foo1 = create(); + Main foo2 = create(); + Main foo3 = create(); + Main foo4 = create(); + foo1.field = b; + foo2.field = b; + foo3.field = b; + foo4.field = b; + foo1.lastField = b; + } + + static Main create() { + return new Main(); + } + + static boolean baz() { + return false; + } + + boolean field; + Object otherField; + boolean lastField; +} |