changeset 5756:f1ceb218882d

Merge.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Tue, 03 Jul 2012 17:50:42 +0200
parents 12e5956a8fdd (current diff) 17d2c3b72762 (diff)
children 0ed5c283c55d
files graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LoopTransformPhase.java
diffstat 11 files changed, 318 insertions(+), 64 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalOptions.java	Tue Jul 03 17:50:34 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalOptions.java	Tue Jul 03 17:50:42 2012 +0200
@@ -98,11 +98,12 @@
     public static float   MinimumUsageProbability            = 0.95f;
 
     //loop transform settings TODO (gd) tune
-    public static float   MinimumPeelProbability             = 0.35f;
+    public static boolean LoopPeeling                        = true;
     public static boolean ReassociateInvariants              = true;
     public static boolean FullUnroll                         = true;
+    public static boolean LoopUnswitch                       = ____;
     public static int     FullUnrollMaxNodes                 = 150;
-    public static boolean LoopUnswitch                       = ____;
+    public static float   MinimumPeelProbability             = 0.35f;
     public static int     LoopUnswitchMaxIncrease            = 50;
     public static int     LoopUnswitchUncertaintyBoost       = 5;
 
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopFragmentWhole.java	Tue Jul 03 17:50:34 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopFragmentWhole.java	Tue Jul 03 17:50:42 2012 +0200
@@ -80,7 +80,8 @@
 
     public FixedNode entryPoint() {
         if (isDuplicate()) {
-            return getDuplicatedNode(original().loop().loopBegin()).forwardEnd();
+            LoopBeginNode newLoopBegin = getDuplicatedNode(original().loop().loopBegin());
+            return newLoopBegin.forwardEnd();
         }
         return loop().entryPoint();
     }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LoopTransformHighPhase.java	Tue Jul 03 17:50:34 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LoopTransformHighPhase.java	Tue Jul 03 17:50:42 2012 +0200
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.compiler.phases;
 
+import com.oracle.graal.compiler.*;
 import com.oracle.graal.compiler.loop.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.nodes.*;
@@ -31,12 +32,14 @@
     @Override
     protected void run(StructuredGraph graph) {
         if (graph.hasLoops()) {
-            LoopsData data = new LoopsData(graph);
-            for (LoopEx loop : data.outterFirst()) {
-                if (LoopPolicies.shouldPeel(loop)) {
-                    Debug.log("Peeling %s", loop);
-                    LoopTransformations.peel(loop);
-                    Debug.dump(graph, "After peeling %s", loop);
+            if (GraalOptions.LoopPeeling) {
+                LoopsData data = new LoopsData(graph);
+                for (LoopEx loop : data.outterFirst()) {
+                    if (LoopPolicies.shouldPeel(loop)) {
+                        Debug.log("Peeling %s", loop);
+                        LoopTransformations.peel(loop);
+                        Debug.dump(graph, "After peeling %s", loop);
+                    }
                 }
             }
         }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LoopTransformPhase.java	Tue Jul 03 17:50:34 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.compiler.phases;
-
-import com.oracle.graal.compiler.*;
-import com.oracle.graal.compiler.loop.*;
-import com.oracle.graal.debug.*;
-import com.oracle.graal.nodes.*;
-
-public class LoopTransformPhase extends Phase {
-
-    @Override
-    protected void run(StructuredGraph graph) {
-        if (graph.hasLoops()) {
-            LoopsData data = new LoopsData(graph);
-            for (LoopEx loop : data.outterFirst()) {
-                double entryProbability = loop.loopBegin().forwardEnd().probability();
-                if (entryProbability > GraalOptions.MinimumPeelProbability
-                                && loop.size() + graph.getNodeCount() < GraalOptions.MaximumDesiredSize) {
-                    Debug.log("Peeling %s", loop);
-                    LoopTransformations.peel(loop);
-                    Debug.dump(graph, "After peeling %s", loop);
-                }
-            }
-        }
-    }
-
-
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ArrayCopySnippets.java	Tue Jul 03 17:50:34 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ArrayCopySnippets.java	Tue Jul 03 17:50:42 2012 +0200
@@ -81,7 +81,7 @@
         long srcOffset = srcPos * arrayIndexScale(baseKind);
         long destOffset = destPos * arrayIndexScale(baseKind);
         if (src == dest && srcPos < destPos) { // bad aliased case
-            for (long i = byteLength - 1; i > byteLength - 1 - nonVectorBytes; i--) {
+            for (long i = byteLength - arrayIndexScale(Kind.Byte); i >= byteLength - nonVectorBytes; i -= arrayIndexScale(Kind.Byte)) {
                 Byte a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Byte);
                 UnsafeStoreNode.store(dest, header, i + destOffset, a.byteValue(), Kind.Byte);
             }
@@ -91,7 +91,7 @@
                 UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND);
             }
         } else {
-            for (long i = 0; i < nonVectorBytes; i++) {
+            for (long i = 0; i < nonVectorBytes; i += arrayIndexScale(Kind.Byte)) {
                 Byte a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Byte);
                 UnsafeStoreNode.store(dest, header, i + destOffset, a.byteValue(), Kind.Byte);
             }
@@ -117,7 +117,7 @@
         long srcOffset = srcPos * arrayIndexScale(baseKind);
         long destOffset = destPos * arrayIndexScale(baseKind);
         if (src == dest && srcPos < destPos) { // bad aliased case
-            for (long i = byteLength - 1; i > byteLength - 1 - nonVectorBytes; i -= arrayIndexScale(Kind.Char)) {
+            for (long i = byteLength - arrayIndexScale(Kind.Char); i >= byteLength - nonVectorBytes; i -= arrayIndexScale(Kind.Char)) {
                 Character a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Char);
                 UnsafeStoreNode.store(dest, header, i + destOffset, a.charValue(), Kind.Char);
             }
@@ -153,7 +153,7 @@
         long srcOffset = srcPos * arrayIndexScale(baseKind);
         long destOffset = destPos * arrayIndexScale(baseKind);
         if (src == dest && srcPos < destPos) { // bad aliased case
-            for (long i = byteLength - 1; i > byteLength - 1 - nonVectorBytes; i -= arrayIndexScale(Kind.Short)) {
+            for (long i = byteLength - arrayIndexScale(Kind.Short); i >= byteLength - nonVectorBytes; i -= arrayIndexScale(Kind.Short)) {
                 Short a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Short);
                 UnsafeStoreNode.store(dest, header, i + destOffset, a.shortValue(), Kind.Short);
             }
@@ -189,7 +189,7 @@
         long srcOffset = srcPos * arrayIndexScale(baseKind);
         long destOffset = destPos * arrayIndexScale(baseKind);
         if (src == dest && srcPos < destPos) { // bad aliased case
-            for (long i = byteLength - 1; i > byteLength - 1 - nonVectorBytes; i -= arrayIndexScale(Kind.Int)) {
+            for (long i = byteLength - arrayIndexScale(Kind.Int); i >= byteLength - nonVectorBytes; i -= arrayIndexScale(Kind.Int)) {
                 Integer a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Int);
                 UnsafeStoreNode.store(dest, header, i + destOffset, a.intValue(), Kind.Int);
             }
@@ -225,7 +225,7 @@
         long srcOffset = srcPos * arrayIndexScale(baseKind);
         long destOffset = destPos * arrayIndexScale(baseKind);
         if (src == dest && srcPos < destPos) { // bad aliased case
-            for (long i = byteLength - 1; i > byteLength - 1 - nonVectorBytes; i -= arrayIndexScale(Kind.Float)) {
+            for (long i = byteLength - arrayIndexScale(Kind.Float); i >= byteLength - nonVectorBytes; i -= arrayIndexScale(Kind.Float)) {
                 Float a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Float);
                 UnsafeStoreNode.store(dest, header, i + destOffset, a.floatValue(), Kind.Float);
             }
--- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/ArrayCopy01.java	Tue Jul 03 17:50:34 2012 +0200
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/ArrayCopy01.java	Tue Jul 03 17:50:42 2012 +0200
@@ -31,6 +31,10 @@
 
     public static Object[] src = new Object[]{null, null};
     public static Object[] dest = new Object[]{null, null};
+    static {
+        // Ensure System is resolved
+        System.arraycopy(src, 0, src, 0, src.length);
+    }
 
     public static int test(int srcPos, int destPos, int length) {
         System.arraycopy(src, srcPos, dest, destPos, length);
--- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/ArrayCopy02.java	Tue Jul 03 17:50:34 2012 +0200
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/ArrayCopy02.java	Tue Jul 03 17:50:42 2012 +0200
@@ -32,6 +32,10 @@
     public static int[] src = new int[]{0, 1, 2, 3, 4, 5};
     public static int[] dest0 = new int[]{5, 4, 3, 2, 1, 0};
     public static int[] dest = new int[]{5, 4, 3, 2, 1, 0};
+    static {
+        // Ensure System is resolved
+        System.arraycopy(src, 0, src, 0, src.length);
+    }
 
     @Before
     public void setUp() {
--- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/ArrayCopy03.java	Tue Jul 03 17:50:34 2012 +0200
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/ArrayCopy03.java	Tue Jul 03 17:50:42 2012 +0200
@@ -32,6 +32,10 @@
     public static byte[] src = new byte[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
     public static byte[] dest0 = new byte[]{10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
     public static byte[] dest = new byte[]{10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
+    static {
+        // Ensure System is resolved
+        System.arraycopy(src, 0, src, 0, src.length);
+    }
 
     @Before
     public void setUp() {
--- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/ArrayCopy04.java	Tue Jul 03 17:50:34 2012 +0200
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/ArrayCopy04.java	Tue Jul 03 17:50:42 2012 +0200
@@ -31,6 +31,10 @@
 
     public static byte[] array = new byte[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
     public static byte[] array0 = new byte[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+    static {
+        // Ensure System is resolved
+        System.arraycopy(array, 0, array, 0, array.length);
+    }
 
     @Before
     public void setUp() {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/ArrayCopy05.java	Tue Jul 03 17:50:42 2012 +0200
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests calls to the array copy method.
+ */
+public class ArrayCopy05 {
+
+    public static char[] array = new char[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+    public static char[] array0 = new char[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+    static {
+        // Ensure System is resolved
+        System.arraycopy(array, 0, array, 0, array.length);
+    }
+
+    @Before
+    public void setUp() {
+        System.currentTimeMillis();
+        for (int i = 0; i < array.length; i++) {
+            array[i] = array0[i];
+        }
+    }
+
+    public static char[] test(int srcPos, int destPos, int length) {
+        System.arraycopy(array, srcPos, array, destPos, length);
+        return array;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertArrayEquals(new char[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, test(0, 0, 0));
+    }
+
+    @Test(expected = java.lang.IndexOutOfBoundsException.class)
+    public void run1() throws Throwable {
+        test(0, 0, -1);
+    }
+
+    @Test(expected = java.lang.IndexOutOfBoundsException.class)
+    public void run2() throws Throwable {
+        test(-1, 0, 0);
+    }
+
+    @Test(expected = java.lang.IndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(0, -1, 0);
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertArrayEquals(new char[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, test(0, 0, 2));
+    }
+
+    @Test(expected = java.lang.IndexOutOfBoundsException.class)
+    public void run5() throws Throwable {
+        test(0, 1, 11);
+    }
+
+    @Test(expected = java.lang.IndexOutOfBoundsException.class)
+    public void run6() throws Throwable {
+        test(1, 0, 11);
+    }
+
+    @Test(expected = java.lang.IndexOutOfBoundsException.class)
+    public void run7() throws Throwable {
+        test(1, 1, -1);
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertArrayEquals(new char[] {0, 0, 1, 3, 4, 5, 6, 7, 8, 9, 10}, test(0, 1, 2));
+    }
+
+    @Test
+    public void run9() throws Throwable {
+        Assert.assertArrayEquals(new char[] {1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10}, test(1, 0, 2));
+    }
+
+    @Test
+    public void run10() throws Throwable {
+        Assert.assertArrayEquals(new char[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, test(1, 1, 2));
+    }
+
+    @Test
+    public void run11() throws Throwable {
+        Assert.assertArrayEquals(new char[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, test(0, 0, 6));
+    }
+
+    @Test
+    public void run12() throws Throwable {
+        Assert.assertArrayEquals(new char[] {0, 0, 1, 2, 3, 4, 6, 7, 8, 9, 10}, test(0, 1, 5));
+    }
+
+    @Test
+    public void run13() throws Throwable {
+        Assert.assertArrayEquals(new char[] {1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10}, test(1, 0, 5));
+    }
+
+    @Test
+    public void run14() throws Throwable {
+        Assert.assertArrayEquals(new char[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, test(1, 1, 5));
+    }
+
+    @Test
+    public void run15() throws Throwable {
+        Assert.assertArrayEquals(new char[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, test(0, 0, 11));
+    }
+
+    @Test
+    public void run16() throws Throwable {
+        Assert.assertArrayEquals(new char[] {0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, test(0, 1, 10));
+    }
+
+    @Test
+    public void run17() throws Throwable {
+        Assert.assertArrayEquals(new char[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10}, test(1, 0, 10));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/ArrayCopy06.java	Tue Jul 03 17:50:42 2012 +0200
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests calls to the array copy method.
+ */
+public class ArrayCopy06 {
+
+    public static short[] array = new short[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+    public static short[] array0 = new short[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+    static {
+        // Ensure System is resolved
+        System.arraycopy(array, 0, array, 0, array.length);
+    }
+
+    @Before
+    public void setUp() {
+        System.currentTimeMillis();
+        for (int i = 0; i < array.length; i++) {
+            array[i] = array0[i];
+        }
+    }
+
+    public static short[] test(int srcPos, int destPos, int length) {
+        System.arraycopy(array, srcPos, array, destPos, length);
+        return array;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertArrayEquals(new short[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, test(0, 0, 0));
+    }
+
+    @Test(expected = java.lang.IndexOutOfBoundsException.class)
+    public void run1() throws Throwable {
+        test(0, 0, -1);
+    }
+
+    @Test(expected = java.lang.IndexOutOfBoundsException.class)
+    public void run2() throws Throwable {
+        test(-1, 0, 0);
+    }
+
+    @Test(expected = java.lang.IndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(0, -1, 0);
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertArrayEquals(new short[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, test(0, 0, 2));
+    }
+
+    @Test(expected = java.lang.IndexOutOfBoundsException.class)
+    public void run5() throws Throwable {
+        test(0, 1, 11);
+    }
+
+    @Test(expected = java.lang.IndexOutOfBoundsException.class)
+    public void run6() throws Throwable {
+        test(1, 0, 11);
+    }
+
+    @Test(expected = java.lang.IndexOutOfBoundsException.class)
+    public void run7() throws Throwable {
+        test(1, 1, -1);
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertArrayEquals(new short[] {0, 0, 1, 3, 4, 5, 6, 7, 8, 9, 10}, test(0, 1, 2));
+    }
+
+    @Test
+    public void run9() throws Throwable {
+        Assert.assertArrayEquals(new short[] {1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10}, test(1, 0, 2));
+    }
+
+    @Test
+    public void run10() throws Throwable {
+        Assert.assertArrayEquals(new short[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, test(1, 1, 2));
+    }
+
+    @Test
+    public void run11() throws Throwable {
+        Assert.assertArrayEquals(new short[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, test(0, 0, 6));
+    }
+
+    @Test
+    public void run12() throws Throwable {
+        Assert.assertArrayEquals(new short[] {0, 0, 1, 2, 3, 4, 6, 7, 8, 9, 10}, test(0, 1, 5));
+    }
+
+    @Test
+    public void run13() throws Throwable {
+        Assert.assertArrayEquals(new short[] {1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10}, test(1, 0, 5));
+    }
+
+    @Test
+    public void run14() throws Throwable {
+        Assert.assertArrayEquals(new short[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, test(1, 1, 5));
+    }
+
+    @Test
+    public void run15() throws Throwable {
+        Assert.assertArrayEquals(new short[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, test(0, 0, 11));
+    }
+
+    @Test
+    public void run16() throws Throwable {
+        Assert.assertArrayEquals(new short[] {0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, test(0, 1, 10));
+    }
+
+    @Test
+    public void run17() throws Throwable {
+        Assert.assertArrayEquals(new short[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10}, test(1, 0, 10));
+    }
+}