diff options
Diffstat (limited to 'test')
69 files changed, 3463 insertions, 677 deletions
diff --git a/test/003-omnibus-opcodes/src/FloatMath.java b/test/003-omnibus-opcodes/src/FloatMath.java index 96befe9cdc..fcdb4fe305 100644 --- a/test/003-omnibus-opcodes/src/FloatMath.java +++ b/test/003-omnibus-opcodes/src/FloatMath.java @@ -135,7 +135,8 @@ public class FloatMath { static float[] floatOperTest(float x, float y) { System.out.println("FloatMath.floatOperTest"); - float[] results = new float[9]; + float[] results = new float[10]; + float tmp; /* this seems to generate "op-float" instructions */ results[0] = x + y; @@ -145,7 +146,21 @@ public class FloatMath { results[4] = x % -y; /* this seems to generate "op-float/2addr" instructions */ - results[8] = x + (((((x + y) - y) * y) / y) % y); + tmp = x; + tmp += y; + results[5] = tmp; + tmp = x; + tmp -= y; + results[6] = tmp; + tmp = x; + tmp *= y; + results[7] = tmp; + tmp = x; + tmp /= y; + results[8] = tmp; + tmp = x; + tmp %= -y; + results[9] = tmp; return results; } @@ -155,7 +170,11 @@ public class FloatMath { Main.assertTrue(results[2] > -210000.01f && results[2] < -209999.99f); Main.assertTrue(results[3] > -23333.34f && results[3] < -23333.32f); Main.assertTrue(results[4] > 0.999f && results[4] < 1.001f); - Main.assertTrue(results[8] > 70000.99f && results[8] < 70001.01f); + Main.assertTrue(results[5] > 69996.99f && results[5] < 69997.01f); + Main.assertTrue(results[6] > 70002.99f && results[6] < 70003.01f); + Main.assertTrue(results[7] > -210000.01f && results[7] < -209999.99f); + Main.assertTrue(results[8] > -23333.34f && results[8] < -23333.32f); + Main.assertTrue(results[9] > 0.999f && results[9] < 1.001f); } /* @@ -165,7 +184,8 @@ public class FloatMath { static double[] doubleOperTest(double x, double y) { System.out.println("FloatMath.doubleOperTest"); - double[] results = new double[9]; + double[] results = new double[10]; + double tmp; /* this seems to generate "op-double" instructions */ results[0] = x + y; @@ -175,7 +195,21 @@ public class FloatMath { results[4] = x % -y; /* this seems to generate "op-double/2addr" instructions */ - results[8] = x + (((((x + y) - y) * y) / y) % y); + tmp = x; + tmp += y; + results[5] = tmp; + tmp = x; + tmp -= y; + results[6] = tmp; + tmp = x; + tmp *= y; + results[7] = tmp; + tmp = x; + tmp /= y; + results[8] = tmp; + tmp = x; + tmp %= -y; + results[9] = tmp; return results; } @@ -185,7 +219,11 @@ public class FloatMath { Main.assertTrue(results[2] > -210000.01 && results[2] < -209999.99); Main.assertTrue(results[3] > -23333.34 && results[3] < -23333.32); Main.assertTrue(results[4] > 0.999 && results[4] < 1.001); - Main.assertTrue(results[8] > 70000.99 && results[8] < 70001.01); + Main.assertTrue(results[5] > 69996.99 && results[5] < 69997.01); + Main.assertTrue(results[6] > 70002.99 && results[6] < 70003.01); + Main.assertTrue(results[7] > -210000.01 && results[7] < -209999.99); + Main.assertTrue(results[8] > -23333.34 && results[8] < -23333.32); + Main.assertTrue(results[9] > 0.999 && results[9] < 1.001); } /* diff --git a/test/004-checker-UnsafeTest18/src/Main.java b/test/004-checker-UnsafeTest18/src/Main.java index bb020b9b9f..282f9ce0d0 100644 --- a/test/004-checker-UnsafeTest18/src/Main.java +++ b/test/004-checker-UnsafeTest18/src/Main.java @@ -15,6 +15,7 @@ */ import java.lang.reflect.Field; +import java.util.concurrent.atomic.AtomicBoolean; import sun.misc.Unsafe; @@ -31,13 +32,17 @@ public class Main { private static Thread[] sThreads = new Thread[10]; // - // Fields accessed by setters and adders. + // Fields accessed by setters and adders, and by memory fence tests. // public int i = 0; public long l = 0; public Object o = null; + public int x_value; + public int y_value; + public volatile boolean running; + // // Setters. // @@ -128,6 +133,10 @@ public class Main { private static void fork(Runnable r) { for (int i = 0; i < 10; i++) { sThreads[i] = new Thread(r); + } + // Start the threads only after the full array has been written with new threads, + // because one test relies on the contents of this array to be consistent. + for (int i = 0; i < 10; i++) { sThreads[i].start(); } } @@ -167,22 +176,22 @@ public class Main { throw new Error("No offset: " + e); } - // Some sanity within same thread. + // Some sanity on setters and adders within same thread. set32(m, intOffset, 3); - expectEquals32(3, m.i); + expectEqual32(3, m.i); set64(m, longOffset, 7L); - expectEquals64(7L, m.l); + expectEqual64(7L, m.l); setObj(m, objOffset, m); - expectEqualsObj(m, m.o); + expectEqualObj(m, m.o); add32(m, intOffset, 11); - expectEquals32(14, m.i); + expectEqual32(14, m.i); add64(m, longOffset, 13L); - expectEquals64(20L, m.l); + expectEqual64(20L, m.l); // Some sanity on setters within different threads. @@ -193,7 +202,7 @@ public class Main { } }); join(); - expectEquals32(9, m.i); // one thread's last value wins + expectEqual32(9, m.i); // one thread's last value wins fork(new Runnable() { public void run() { @@ -202,7 +211,7 @@ public class Main { } }); join(); - expectEquals64(109L, m.l); // one thread's last value wins + expectEqual64(109L, m.l); // one thread's last value wins fork(new Runnable() { public void run() { @@ -211,7 +220,7 @@ public class Main { } }); join(); - expectEqualsObj(sThreads[9], m.o); // one thread's last value wins + expectEqualObj(sThreads[9], m.o); // one thread's last value wins // Some sanity on adders within different threads. @@ -222,7 +231,7 @@ public class Main { } }); join(); - expectEquals32(559, m.i); // all values accounted for + expectEqual32(559, m.i); // all values accounted for fork(new Runnable() { public void run() { @@ -231,9 +240,101 @@ public class Main { } }); join(); - expectEquals64(659L, m.l); // all values accounted for + expectEqual64(659L, m.l); // all values accounted for + + // Some sanity on fences within same thread. Note that memory fences within one + // thread make little sense, but the sanity check ensures nothing bad happens. + + m.i = -1; + m.l = -2L; + m.o = null; + + load(); + store(); + full(); + + expectEqual32(-1, m.i); + expectEqual64(-2L, m.l); + expectEqualObj(null, m.o); + + // Some sanity on full fence within different threads. We write the non-volatile m.l after + // the fork(), which means there is no happens-before relation in the Java memory model + // with respect to the read in the threads. This relation is enforced by the memory fences + // and the weak-set() -> get() guard. Note that the guard semantics used here are actually + // too strong and already enforce total memory visibility, but this test illustrates what + // should still happen if Java had a true relaxed memory guard. + + final AtomicBoolean guard1 = new AtomicBoolean(); + m.l = 0L; + + fork(new Runnable() { + public void run() { + while (!guard1.get()); // busy-waiting + full(); + expectEqual64(-123456789L, m.l); + } + }); + + m.l = -123456789L; + full(); + while (!guard1.weakCompareAndSet(false, true)); // relaxed memory order + join(); + + // Some sanity on release/acquire fences within different threads. We write the non-volatile + // m.l after the fork(), which means there is no happens-before relation in the Java memory + // model with respect to the read in the threads. This relation is enforced by the memory fences + // and the weak-set() -> get() guard. Note that the guard semantics used here are actually + // too strong and already enforce total memory visibility, but this test illustrates what + // should still happen if Java had a true relaxed memory guard. + + final AtomicBoolean guard2 = new AtomicBoolean(); + m.l = 0L; + + fork(new Runnable() { + public void run() { + while (!guard2.get()); // busy-waiting + load(); + expectEqual64(-987654321L, m.l); + } + }); + + m.l = -987654321L; + store(); + while (!guard2.weakCompareAndSet(false, true)); // relaxed memory order + join(); + + // Some sanity on release/acquire fences within different threads using a test suggested by + // Hans Boehm. Even this test remains with the realm of sanity only, since having the threads + // read the same value consistently would be a valid outcome. - // TODO: the fences + m.x_value = -1; + m.y_value = -1; + m.running = true; + + fork(new Runnable() { + public void run() { + while (m.running) { + for (int few_times = 0; few_times < 1000; few_times++) { + // Read y first, then load fence, then read x. + // They should appear in order, if seen at all. + int local_y = m.y_value; + load(); + int local_x = m.x_value; + expectLessThanOrEqual32(local_y, local_x); + } + } + } + }); + + for (int many_times = 0; many_times < 100000; many_times++) { + m.x_value = many_times; + store(); + m.y_value = many_times; + } + m.running = false; + join(); + + // All done! System.out.println("passed"); } @@ -250,19 +351,25 @@ public class Main { } } - private static void expectEquals32(int expected, int result) { + private static void expectEqual32(int expected, int result) { if (expected != result) { throw new Error("Expected: " + expected + ", found: " + result); } } - private static void expectEquals64(long expected, long result) { + private static void expectLessThanOrEqual32(int val1, int val2) { + if (val1 > val2) { + throw new Error("Expected: " + val1 + " <= " + val2); + } + } + + private static void expectEqual64(long expected, long result) { if (expected != result) { throw new Error("Expected: " + expected + ", found: " + result); } } - private static void expectEqualsObj(Object expected, Object result) { + private static void expectEqualObj(Object expected, Object result) { if (expected != result) { throw new Error("Expected: " + expected + ", found: " + result); } diff --git a/test/064-field-access/expected.txt b/test/064-field-access/expected.txt index 0af56ba52b..69a586c968 100644 --- a/test/064-field-access/expected.txt +++ b/test/064-field-access/expected.txt @@ -1,2 +1,3 @@ good Got expected failure +Got expected failure diff --git a/test/064-field-access/smali/SubClassUsingInaccessibleField.smali b/test/064-field-access/smali/SubClassUsingInaccessibleField.smali new file mode 100644 index 0000000000..224b431e2e --- /dev/null +++ b/test/064-field-access/smali/SubClassUsingInaccessibleField.smali @@ -0,0 +1,32 @@ +# Copyright (C) 2016 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. + +.class public LSubClassUsingInaccessibleField; + +.super Lother/PublicClass; + +.method public constructor <init>()V + .registers 1 + invoke-direct {p0}, Lother/PublicClass;-><init>()V + return-void +.end method + +# Regression test for compiler DCHECK() failure (bogus check) when referencing +# a package-private field from an indirectly inherited package-private class, +# using this very class as the declaring class in the FieldId, bug: 27684368 . +.method public test()I + .registers 2 + iget v0, p0, LSubClassUsingInaccessibleField;->otherProtectedClassPackageIntInstanceField:I + return v0 +.end method diff --git a/test/064-field-access/src/Main.java b/test/064-field-access/src/Main.java index 8dd22bab97..5d90129559 100644 --- a/test/064-field-access/src/Main.java +++ b/test/064-field-access/src/Main.java @@ -16,6 +16,7 @@ import other.PublicClass; import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /* @@ -35,6 +36,20 @@ public class Main { // reference System.out.println("Got expected failure"); } + + try { + Class c = Class.forName("SubClassUsingInaccessibleField"); + Object o = c.newInstance(); + c.getMethod("test").invoke(o, null); + } catch (InvocationTargetException ite) { + if (ite.getCause() instanceof IllegalAccessError) { + System.out.println("Got expected failure"); + } else { + System.out.println("Got unexpected failure " + ite.getCause()); + } + } catch (Exception e) { + System.out.println("Got unexpected failure " + e); + } } /* diff --git a/test/097-duplicate-method/build b/test/097-duplicate-method/build deleted file mode 100644 index 4525549905..0000000000 --- a/test/097-duplicate-method/build +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash -# -# Copyright (C) 2012 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. - -# Stop if something fails. -set -e - -mkdir classes - -if [ ${USE_JACK} = "true" ]; then - ${JACK} --output-jack src.jack src - - ${JASMIN} -d classes src/*.j - jar cf jasmin.jill.jar -C classes . - - # We set jack.import.type.policy=keep-first to consider class definitions from jasmin first. - ${JACK} --import jasmin.jill.jar --import src.jack -D jack.import.type.policy=keep-first --output-dex . -else - ${JAVAC} -d classes src/*.java - ${JASMIN} -d classes src/*.j - - ${DX} --debug --dex --dump-to=classes.lst --output=classes.dex classes -fi -zip $TEST_NAME.jar classes.dex diff --git a/test/097-duplicate-method/classes.dex b/test/097-duplicate-method/classes.dex Binary files differnew file mode 100644 index 0000000000..18f8958cdc --- /dev/null +++ b/test/097-duplicate-method/classes.dex diff --git a/test/097-duplicate-method/info.txt b/test/097-duplicate-method/info.txt index 4e7e0eebb1..ed0daeda9e 100644 --- a/test/097-duplicate-method/info.txt +++ b/test/097-duplicate-method/info.txt @@ -1,2 +1,7 @@ This is a test to verify that duplicate methods in a dex file are handled properly (all but the first are ignored). + +We need to build a dex file with duplicate methods. We cannot do that +with Jack (this is invalid) or smali (it does not keep duplicate +methods, only one is in the dex). Therefore, having a precompiled +dex file allows to run the test on whatever toolchain. diff --git a/test/097-duplicate-method/src/Test.j b/test/097-duplicate-method/src/Test.j deleted file mode 100644 index f96a9a3062..0000000000 --- a/test/097-duplicate-method/src/Test.j +++ /dev/null @@ -1,29 +0,0 @@ -; Copyright (C) 2012 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. - -.class Test -.super java/lang/Object - -.method public static run()Ljava/lang/Object; - .limit stack 2 - new java/lang/Object - dup - invokespecial java/lang/Object/<init>()V - areturn -.end method - -.method public static run()Ljava/lang/Object; - aconst_null - areturn -.end method diff --git a/test/117-nopatchoat/nopatchoat.cc b/test/117-nopatchoat/nopatchoat.cc index 82e1fc8ae5..0dab4007a7 100644 --- a/test/117-nopatchoat/nopatchoat.cc +++ b/test/117-nopatchoat/nopatchoat.cc @@ -54,7 +54,8 @@ class NoPatchoatTest { } const OatFile* oat_file = oat_dex_file->GetOatFile(); - return !oat_file->IsPic() && !oat_file->IsExtractOnly(); + return !oat_file->IsPic() + && CompilerFilter::IsCompilationEnabled(oat_file->GetCompilerFilter()); } }; diff --git a/test/145-alloc-tracking-stress/src/Main.java b/test/145-alloc-tracking-stress/src/Main.java index 418690a2a6..752fdd9135 100644 --- a/test/145-alloc-tracking-stress/src/Main.java +++ b/test/145-alloc-tracking-stress/src/Main.java @@ -1,4 +1,5 @@ /* + * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/431-optimizing-arith-shifts/src/Main.java b/test/431-optimizing-arith-shifts/src/Main.java index 86422bd8e7..b7a112f6a3 100644 --- a/test/431-optimizing-arith-shifts/src/Main.java +++ b/test/431-optimizing-arith-shifts/src/Main.java @@ -29,304 +29,302 @@ public class Main { } public static void main(String[] args) { - shlInt(); - shlLong(); - shrInt(); - shrLong(); - ushrInt(); - ushrLong(); + testShlInt(); + testShlLong(); + testShrInt(); + testShrLong(); + testUShrInt(); + testUShrLong(); } - private static void shlInt() { - expectEquals(48, $opt$ShlConst2(12)); - expectEquals(12, $opt$ShlConst0(12)); - expectEquals(-48, $opt$Shl(-12, 2)); - expectEquals(1024, $opt$Shl(32, 5)); + private static void testShlInt() { + expectEquals(48, $opt$ShlIntConst2(12)); + expectEquals(12, $opt$ShlIntConst0(12)); + expectEquals(-48, $opt$ShlInt(-12, 2)); + expectEquals(1024, $opt$ShlInt(32, 5)); - expectEquals(7, $opt$Shl(7, 0)); - expectEquals(14, $opt$Shl(7, 1)); - expectEquals(0, $opt$Shl(0, 30)); + expectEquals(7, $opt$ShlInt(7, 0)); + expectEquals(14, $opt$ShlInt(7, 1)); + expectEquals(0, $opt$ShlInt(0, 30)); - expectEquals(1073741824L, $opt$Shl(1, 30)); - expectEquals(Integer.MIN_VALUE, $opt$Shl(1, 31)); // overflow - expectEquals(Integer.MIN_VALUE, $opt$Shl(1073741824, 1)); // overflow - expectEquals(1073741824, $opt$Shl(268435456, 2)); + expectEquals(1073741824L, $opt$ShlInt(1, 30)); + expectEquals(Integer.MIN_VALUE, $opt$ShlInt(1, 31)); // overflow + expectEquals(Integer.MIN_VALUE, $opt$ShlInt(1073741824, 1)); // overflow + expectEquals(1073741824, $opt$ShlInt(268435456, 2)); // Only the 5 lower bits should be used for shifting (& 0x1f). - expectEquals(7, $opt$Shl(7, 32)); // 32 & 0x1f = 0 - expectEquals(14, $opt$Shl(7, 33)); // 33 & 0x1f = 1 - expectEquals(32, $opt$Shl(1, 101)); // 101 & 0x1f = 5 + expectEquals(7, $opt$ShlInt(7, 32)); // 32 & 0x1f = 0 + expectEquals(14, $opt$ShlInt(7, 33)); // 33 & 0x1f = 1 + expectEquals(32, $opt$ShlInt(1, 101)); // 101 & 0x1f = 5 - expectEquals(Integer.MIN_VALUE, $opt$Shl(1, -1)); // -1 & 0x1f = 31 - expectEquals(14, $opt$Shl(7, -31)); // -31 & 0x1f = 1 - expectEquals(7, $opt$Shl(7, -32)); // -32 & 0x1f = 0 - expectEquals(-536870912, $opt$Shl(7, -3)); // -3 & 0x1f = 29 + expectEquals(Integer.MIN_VALUE, $opt$ShlInt(1, -1)); // -1 & 0x1f = 31 + expectEquals(14, $opt$ShlInt(7, -31)); // -31 & 0x1f = 1 + expectEquals(7, $opt$ShlInt(7, -32)); // -32 & 0x1f = 0 + expectEquals(-536870912, $opt$ShlInt(7, -3)); // -3 & 0x1f = 29 - expectEquals(Integer.MIN_VALUE, $opt$Shl(7, Integer.MAX_VALUE)); - expectEquals(7, $opt$Shl(7, Integer.MIN_VALUE)); + expectEquals(Integer.MIN_VALUE, $opt$ShlInt(7, Integer.MAX_VALUE)); + expectEquals(7, $opt$ShlInt(7, Integer.MIN_VALUE)); } - private static void shlLong() { - expectEquals(48L, $opt$ShlConst2(12L)); - expectEquals(12L, $opt$ShlConst0(12L)); - expectEquals(-48L, $opt$Shl(-12L, 2L)); - expectEquals(1024L, $opt$Shl(32L, 5L)); + private static void testShlLong() { + expectEquals(48L, $opt$ShlLongConst2(12L)); + expectEquals(12L, $opt$ShlLongConst0(12L)); + expectEquals(-48L, $opt$ShlLong(-12L, 2)); + expectEquals(1024L, $opt$ShlLong(32L, 5)); - expectEquals(7L, $opt$Shl(7L, 0L)); - expectEquals(14L, $opt$Shl(7L, 1L)); - expectEquals(0L, $opt$Shl(0L, 30L)); + expectEquals(7L, $opt$ShlLong(7L, 0)); + expectEquals(14L, $opt$ShlLong(7L, 1)); + expectEquals(0L, $opt$ShlLong(0L, 30)); - expectEquals(1073741824L, $opt$Shl(1L, 30L)); - expectEquals(2147483648L, $opt$Shl(1L, 31L)); - expectEquals(2147483648L, $opt$Shl(1073741824L, 1L)); + expectEquals(1073741824L, $opt$ShlLong(1L, 30)); + expectEquals(2147483648L, $opt$ShlLong(1L, 31)); + expectEquals(2147483648L, $opt$ShlLong(1073741824L, 1)); // Long shifts can use up to 6 lower bits. - expectEquals(4294967296L, $opt$Shl(1L, 32L)); - expectEquals(60129542144L, $opt$Shl(7L, 33L)); - expectEquals(Long.MIN_VALUE, $opt$Shl(1L, 63L)); // overflow + expectEquals(4294967296L, $opt$ShlLong(1L, 32)); + expectEquals(60129542144L, $opt$ShlLong(7L, 33)); + expectEquals(Long.MIN_VALUE, $opt$ShlLong(1L, 63)); // overflow // Only the 6 lower bits should be used for shifting (& 0x3f). - expectEquals(7L, $opt$Shl(7L, 64L)); // 64 & 0x3f = 0 - expectEquals(14L, $opt$Shl(7L, 65L)); // 65 & 0x3f = 1 - expectEquals(137438953472L, $opt$Shl(1L, 101L)); // 101 & 0x3f = 37 + expectEquals(7L, $opt$ShlLong(7L, 64)); // 64 & 0x3f = 0 + expectEquals(14L, $opt$ShlLong(7L, 65)); // 65 & 0x3f = 1 + expectEquals(137438953472L, $opt$ShlLong(1L, 101)); // 101 & 0x3f = 37 - expectEquals(Long.MIN_VALUE, $opt$Shl(1L, -1L)); // -1 & 0x3f = 63 - expectEquals(14L, $opt$Shl(7L, -63L)); // -63 & 0x3f = 1 - expectEquals(7L, $opt$Shl(7L, -64L)); // -64 & 0x3f = 0 - expectEquals(2305843009213693952L, $opt$Shl(1L, -3L)); // -3 & 0x3f = 61 + expectEquals(Long.MIN_VALUE, $opt$ShlLong(1L, -1)); // -1 & 0x3f = 63 + expectEquals(14L, $opt$ShlLong(7L, -63)); // -63 & 0x3f = 1 + expectEquals(7L, $opt$ShlLong(7L, -64)); // -64 & 0x3f = 0 + expectEquals(2305843009213693952L, $opt$ShlLong(1L, -3)); // -3 & 0x3f = 61 - expectEquals(Long.MIN_VALUE, $opt$Shl(7L, Long.MAX_VALUE)); - expectEquals(7L, $opt$Shl(7L, Long.MIN_VALUE)); + expectEquals(Long.MIN_VALUE, $opt$ShlLong(7L, Integer.MAX_VALUE)); + expectEquals(7L, $opt$ShlLong(7L, Integer.MIN_VALUE)); // Exercise some special cases handled by backends/simplifier. - expectEquals(24L, $opt$ShlConst1(12L)); - expectEquals(0x2345678900000000L, $opt$ShlConst32(0x123456789L)); - expectEquals(0x2490249000000000L, $opt$ShlConst33(0x12481248L)); - expectEquals(0x4920492000000000L, $opt$ShlConst34(0x12481248L)); - expectEquals(0x9240924000000000L, $opt$ShlConst35(0x12481248L)); + expectEquals(24L, $opt$ShlLongConst1(12L)); + expectEquals(0x2345678900000000L, $opt$ShlLongConst32(0x123456789L)); + expectEquals(0x2490249000000000L, $opt$ShlLongConst33(0x12481248L)); + expectEquals(0x4920492000000000L, $opt$ShlLongConst34(0x12481248L)); + expectEquals(0x9240924000000000L, $opt$ShlLongConst35(0x12481248L)); } - private static void shrInt() { - expectEquals(3, $opt$ShrConst2(12)); - expectEquals(12, $opt$ShrConst0(12)); - expectEquals(-3, $opt$Shr(-12, 2)); - expectEquals(1, $opt$Shr(32, 5)); + private static void testShrInt() { + expectEquals(3, $opt$ShrIntConst2(12)); + expectEquals(12, $opt$ShrIntConst0(12)); + expectEquals(-3, $opt$ShrInt(-12, 2)); + expectEquals(1, $opt$ShrInt(32, 5)); - expectEquals(7, $opt$Shr(7, 0)); - expectEquals(3, $opt$Shr(7, 1)); - expectEquals(0, $opt$Shr(0, 30)); - expectEquals(0, $opt$Shr(1, 30)); - expectEquals(-1, $opt$Shr(-1, 30)); + expectEquals(7, $opt$ShrInt(7, 0)); + expectEquals(3, $opt$ShrInt(7, 1)); + expectEquals(0, $opt$ShrInt(0, 30)); + expectEquals(0, $opt$ShrInt(1, 30)); + expectEquals(-1, $opt$ShrInt(-1, 30)); - expectEquals(0, $opt$Shr(Integer.MAX_VALUE, 31)); - expectEquals(-1, $opt$Shr(Integer.MIN_VALUE, 31)); + expectEquals(0, $opt$ShrInt(Integer.MAX_VALUE, 31)); + expectEquals(-1, $opt$ShrInt(Integer.MIN_VALUE, 31)); // Only the 5 lower bits should be used for shifting (& 0x1f). - expectEquals(7, $opt$Shr(7, 32)); // 32 & 0x1f = 0 - expectEquals(3, $opt$Shr(7, 33)); // 33 & 0x1f = 1 + expectEquals(7, $opt$ShrInt(7, 32)); // 32 & 0x1f = 0 + expectEquals(3, $opt$ShrInt(7, 33)); // 33 & 0x1f = 1 - expectEquals(0, $opt$Shr(1, -1)); // -1 & 0x1f = 31 - expectEquals(3, $opt$Shr(7, -31)); // -31 & 0x1f = 1 - expectEquals(7, $opt$Shr(7, -32)); // -32 & 0x1f = 0 - expectEquals(-4, $opt$Shr(Integer.MIN_VALUE, -3)); // -3 & 0x1f = 29 + expectEquals(0, $opt$ShrInt(1, -1)); // -1 & 0x1f = 31 + expectEquals(3, $opt$ShrInt(7, -31)); // -31 & 0x1f = 1 + expectEquals(7, $opt$ShrInt(7, -32)); // -32 & 0x1f = 0 + expectEquals(-4, $opt$ShrInt(Integer.MIN_VALUE, -3)); // -3 & 0x1f = 29 - expectEquals(0, $opt$Shr(7, Integer.MAX_VALUE)); - expectEquals(7, $opt$Shr(7, Integer.MIN_VALUE)); + expectEquals(0, $opt$ShrInt(7, Integer.MAX_VALUE)); + expectEquals(7, $opt$ShrInt(7, Integer.MIN_VALUE)); } - private static void shrLong() { - expectEquals(3L, $opt$ShrConst2(12L)); - expectEquals(12L, $opt$ShrConst0(12L)); - expectEquals(-3L, $opt$Shr(-12L, 2L)); - expectEquals(1, $opt$Shr(32, 5)); + private static void testShrLong() { + expectEquals(3L, $opt$ShrLongConst2(12L)); + expectEquals(12L, $opt$ShrLongConst0(12L)); + expectEquals(-3L, $opt$ShrLong(-12L, 2)); + expectEquals(1, $opt$ShrLong(32, 5)); - expectEquals(7L, $opt$Shr(7L, 0L)); - expectEquals(3L, $opt$Shr(7L, 1L)); - expectEquals(0L, $opt$Shr(0L, 30L)); - expectEquals(0L, $opt$Shr(1L, 30L)); - expectEquals(-1L, $opt$Shr(-1L, 30L)); + expectEquals(7L, $opt$ShrLong(7L, 0)); + expectEquals(3L, $opt$ShrLong(7L, 1)); + expectEquals(0L, $opt$ShrLong(0L, 30)); + expectEquals(0L, $opt$ShrLong(1L, 30)); + expectEquals(-1L, $opt$ShrLong(-1L, 30)); - - expectEquals(1L, $opt$Shr(1073741824L, 30L)); - expectEquals(1L, $opt$Shr(2147483648L, 31L)); - expectEquals(1073741824L, $opt$Shr(2147483648L, 1L)); + expectEquals(1L, $opt$ShrLong(1073741824L, 30)); + expectEquals(1L, $opt$ShrLong(2147483648L, 31)); + expectEquals(1073741824L, $opt$ShrLong(2147483648L, 1)); // Long shifts can use up to 6 lower bits. - expectEquals(1L, $opt$Shr(4294967296L, 32L)); - expectEquals(7L, $opt$Shr(60129542144L, 33L)); - expectEquals(0L, $opt$Shr(Long.MAX_VALUE, 63L)); - expectEquals(-1L, $opt$Shr(Long.MIN_VALUE, 63L)); + expectEquals(1L, $opt$ShrLong(4294967296L, 32)); + expectEquals(7L, $opt$ShrLong(60129542144L, 33)); + expectEquals(0L, $opt$ShrLong(Long.MAX_VALUE, 63)); + expectEquals(-1L, $opt$ShrLong(Long.MIN_VALUE, 63)); // Only the 6 lower bits should be used for shifting (& 0x3f). - expectEquals(7L, $opt$Shr(7L, 64L)); // 64 & 0x3f = 0 - expectEquals(3L, $opt$Shr(7L, 65L)); // 65 & 0x3f = 1 + expectEquals(7L, $opt$ShrLong(7L, 64)); // 64 & 0x3f = 0 + expectEquals(3L, $opt$ShrLong(7L, 65)); // 65 & 0x3f = 1 - expectEquals(-1L, $opt$Shr(Long.MIN_VALUE, -1L)); // -1 & 0x3f = 63 - expectEquals(3L, $opt$Shr(7L, -63L)); // -63 & 0x3f = 1 - expectEquals(7L, $opt$Shr(7L, -64L)); // -64 & 0x3f = 0 - expectEquals(1L, $opt$Shr(2305843009213693952L, -3L)); // -3 & 0x3f = 61 - expectEquals(-4L, $opt$Shr(Integer.MIN_VALUE, -3)); // -3 & 0x1f = 29 + expectEquals(-1L, $opt$ShrLong(Long.MIN_VALUE, -1)); // -1 & 0x3f = 63 + expectEquals(3L, $opt$ShrLong(7L, -63)); // -63 & 0x3f = 1 + expectEquals(7L, $opt$ShrLong(7L, -64)); // -64 & 0x3f = 0 + expectEquals(1L, $opt$ShrLong(2305843009213693952L, -3)); // -3 & 0x3f = 61 + expectEquals(-1L, $opt$ShrLong(Integer.MIN_VALUE, -3)); // -3 & 0x1f = 29 - expectEquals(0L, $opt$Shr(7L, Long.MAX_VALUE)); - expectEquals(7L, $opt$Shr(7L, Long.MIN_VALUE)); + expectEquals(0L, $opt$ShrLong(7L, Integer.MAX_VALUE)); + expectEquals(7L, $opt$ShrLong(7L, Integer.MIN_VALUE)); } - private static void ushrInt() { - expectEquals(3, $opt$UShrConst2(12)); - expectEquals(12, $opt$UShrConst0(12)); - expectEquals(1073741821, $opt$UShr(-12, 2)); - expectEquals(1, $opt$UShr(32, 5)); + private static void testUShrInt() { + expectEquals(3, $opt$UShrIntConst2(12)); + expectEquals(12, $opt$UShrIntConst0(12)); + expectEquals(1073741821, $opt$UShrInt(-12, 2)); + expectEquals(1, $opt$UShrInt(32, 5)); - expectEquals(7, $opt$UShr(7, 0)); - expectEquals(3, $opt$UShr(7, 1)); - expectEquals(0, $opt$UShr(0, 30)); - expectEquals(0, $opt$UShr(1, 30)); - expectEquals(3, $opt$UShr(-1, 30)); + expectEquals(7, $opt$UShrInt(7, 0)); + expectEquals(3, $opt$UShrInt(7, 1)); + expectEquals(0, $opt$UShrInt(0, 30)); + expectEquals(0, $opt$UShrInt(1, 30)); + expectEquals(3, $opt$UShrInt(-1, 30)); - expectEquals(0, $opt$UShr(Integer.MAX_VALUE, 31)); - expectEquals(1, $opt$UShr(Integer.MIN_VALUE, 31)); + expectEquals(0, $opt$UShrInt(Integer.MAX_VALUE, 31)); + expectEquals(1, $opt$UShrInt(Integer.MIN_VALUE, 31)); // Only the 5 lower bits should be used for shifting (& 0x1f). - expectEquals(7, $opt$UShr(7, 32)); // 32 & 0x1f = 0 - expectEquals(3, $opt$UShr(7, 33)); // 33 & 0x1f = 1 + expectEquals(7, $opt$UShrInt(7, 32)); // 32 & 0x1f = 0 + expectEquals(3, $opt$UShrInt(7, 33)); // 33 & 0x1f = 1 - expectEquals(0, $opt$UShr(1, -1)); // -1 & 0x1f = 31 - expectEquals(3, $opt$UShr(7, -31)); // -31 & 0x1f = 1 - expectEquals(7, $opt$UShr(7, -32)); // -32 & 0x1f = 0 - expectEquals(4, $opt$UShr(Integer.MIN_VALUE, -3)); // -3 & 0x1f = 29 + expectEquals(0, $opt$UShrInt(1, -1)); // -1 & 0x1f = 31 + expectEquals(3, $opt$UShrInt(7, -31)); // -31 & 0x1f = 1 + expectEquals(7, $opt$UShrInt(7, -32)); // -32 & 0x1f = 0 + expectEquals(4, $opt$UShrInt(Integer.MIN_VALUE, -3)); // -3 & 0x1f = 29 - expectEquals(0, $opt$UShr(7, Integer.MAX_VALUE)); - expectEquals(7, $opt$UShr(7, Integer.MIN_VALUE)); + expectEquals(0, $opt$UShrInt(7, Integer.MAX_VALUE)); + expectEquals(7, $opt$UShrInt(7, Integer.MIN_VALUE)); } - private static void ushrLong() { - expectEquals(3L, $opt$UShrConst2(12L)); - expectEquals(12L, $opt$UShrConst0(12L)); - expectEquals(4611686018427387901L, $opt$UShr(-12L, 2L)); - expectEquals(1, $opt$UShr(32, 5)); - - expectEquals(7L, $opt$UShr(7L, 0L)); - expectEquals(3L, $opt$UShr(7L, 1L)); - expectEquals(0L, $opt$UShr(0L, 30L)); - expectEquals(0L, $opt$UShr(1L, 30L)); - expectEquals(17179869183L, $opt$UShr(-1L, 30L)); + private static void testUShrLong() { + expectEquals(3L, $opt$UShrLongConst2(12L)); + expectEquals(12L, $opt$UShrLongConst0(12L)); + expectEquals(4611686018427387901L, $opt$UShrLong(-12L, 2)); + expectEquals(1, $opt$UShrLong(32, 5)); + expectEquals(7L, $opt$UShrLong(7L, 0)); + expectEquals(3L, $opt$UShrLong(7L, 1)); + expectEquals(0L, $opt$UShrLong(0L, 30)); + expectEquals(0L, $opt$UShrLong(1L, 30)); + expectEquals(17179869183L, $opt$UShrLong(-1L, 30)); - expectEquals(1L, $opt$UShr(1073741824L, 30L)); - expectEquals(1L, $opt$UShr(2147483648L, 31L)); - expectEquals(1073741824L, $opt$UShr(2147483648L, 1L)); + expectEquals(1L, $opt$UShrLong(1073741824L, 30)); + expectEquals(1L, $opt$UShrLong(2147483648L, 31)); + expectEquals(1073741824L, $opt$UShrLong(2147483648L, 1)); // Long shifts can use use up to 6 lower bits. - expectEquals(1L, $opt$UShr(4294967296L, 32L)); - expectEquals(7L, $opt$UShr(60129542144L, 33L)); - expectEquals(0L, $opt$UShr(Long.MAX_VALUE, 63L)); - expectEquals(1L, $opt$UShr(Long.MIN_VALUE, 63L)); + expectEquals(1L, $opt$UShrLong(4294967296L, 32)); + expectEquals(7L, $opt$UShrLong(60129542144L, 33)); + expectEquals(0L, $opt$UShrLong(Long.MAX_VALUE, 63)); + expectEquals(1L, $opt$UShrLong(Long.MIN_VALUE, 63)); // Only the 6 lower bits should be used for shifting (& 0x3f). - expectEquals(7L, $opt$UShr(7L, 64L)); // 64 & 0x3f = 0 - expectEquals(3L, $opt$UShr(7L, 65L)); // 65 & 0x3f = 1 + expectEquals(7L, $opt$UShrLong(7L, 64)); // 64 & 0x3f = 0 + expectEquals(3L, $opt$UShrLong(7L, 65)); // 65 & 0x3f = 1 - expectEquals(1L, $opt$UShr(Long.MIN_VALUE, -1L)); // -1 & 0x3f = 63 - expectEquals(3L, $opt$UShr(7L, -63L)); // -63 & 0x3f = 1 - expectEquals(7L, $opt$UShr(7L, -64L)); // -64 & 0x3f = 0 - expectEquals(1L, $opt$UShr(2305843009213693952L, -3L)); // -3 & 0x3f = 61 - expectEquals(4L, $opt$UShr(Long.MIN_VALUE, -3L)); // -3 & 0x3f = 61 + expectEquals(1L, $opt$UShrLong(Long.MIN_VALUE, -1)); // -1 & 0x3f = 63 + expectEquals(3L, $opt$UShrLong(7L, -63)); // -63 & 0x3f = 1 + expectEquals(7L, $opt$UShrLong(7L, -64)); // -64 & 0x3f = 0 + expectEquals(1L, $opt$UShrLong(2305843009213693952L, -3)); // -3 & 0x3f = 61 + expectEquals(4L, $opt$UShrLong(Long.MIN_VALUE, -3)); // -3 & 0x3f = 61 - expectEquals(0L, $opt$UShr(7L, Long.MAX_VALUE)); - expectEquals(7L, $opt$UShr(7L, Long.MIN_VALUE)); + expectEquals(0L, $opt$UShrLong(7L, Integer.MAX_VALUE)); + expectEquals(7L, $opt$UShrLong(7L, Integer.MIN_VALUE)); } - static int $opt$Shl(int a, int b) { - return a << b; + + static int $opt$ShlInt(int value, int distance) { + return value << distance; } - static long $opt$Shl(long a, long b) { - return a << b; + static long $opt$ShlLong(long value, int distance) { + return value << distance; } - static int $opt$Shr(int a, int b) { - return a >> b; + static int $opt$ShrInt(int value, int distance) { + return value >> distance; } - static long $opt$Shr(long a, long b) { - return a >> b; + static long $opt$ShrLong(long value, int distance) { + return value >> distance; } - static int $opt$UShr(int a, int b) { - return a >>> b; + static int $opt$UShrInt(int value, int distance) { + return value >>> distance; } - static long $opt$UShr(long a, long b) { - return a >>> b; + static long $opt$UShrLong(long value, int distance) { + return value >>> distance; } - static int $opt$ShlConst2(int a) { - return a << 2; + static int $opt$ShlIntConst2(int value) { + return value << 2; } - static long $opt$ShlConst2(long a) { - return a << 2L; + static long $opt$ShlLongConst2(long value) { + return value << 2; } - static int $opt$ShrConst2(int a) { - return a >> 2; + static int $opt$ShrIntConst2(int value) { + return value >> 2; } - static long $opt$ShrConst2(long a) { - return a >> 2L; + static long $opt$ShrLongConst2(long value) { + return value >> 2; } - static int $opt$UShrConst2(int a) { - return a >>> 2; + static int $opt$UShrIntConst2(int value) { + return value >>> 2; } - static long $opt$UShrConst2(long a) { - return a >>> 2L; + static long $opt$UShrLongConst2(long value) { + return value >>> 2; } - static int $opt$ShlConst0(int a) { - return a << 0; + static int $opt$ShlIntConst0(int value) { + return value << 0; } - static long $opt$ShlConst0(long a) { - return a << 0L; + static long $opt$ShlLongConst0(long value) { + return value << 0; } - static int $opt$ShrConst0(int a) { - return a >> 0; + static int $opt$ShrIntConst0(int value) { + return value >> 0; } - static long $opt$ShrConst0(long a) { - return a >> 0L; + static long $opt$ShrLongConst0(long value) { + return value >> 0; } - static int $opt$UShrConst0(int a) { - return a >>> 0; + static int $opt$UShrIntConst0(int value) { + return value >>> 0; } - static long $opt$UShrConst0(long a) { - return a >>> 0L; + static long $opt$UShrLongConst0(long value) { + return value >>> 0; } - static long $opt$ShlConst1(long a) { - return a << 1L; + static long $opt$ShlLongConst1(long value) { + return value << 1; } - static long $opt$ShlConst32(long a) { - return a << 32L; + static long $opt$ShlLongConst32(long value) { + return value << 32; } - static long $opt$ShlConst33(long a) { - return a << 33L; + static long $opt$ShlLongConst33(long value) { + return value << 33; } - static long $opt$ShlConst34(long a) { - return a << 34L; + static long $opt$ShlLongConst34(long value) { + return value << 34; } - static long $opt$ShlConst35(long a) { - return a << 35L; + static long $opt$ShlLongConst35(long value) { + return value << 35; } } - diff --git a/test/469-condition-materialization-regression/expected.txt b/test/469-condition-materialization/expected.txt index e69de29bb2..e69de29bb2 100644 --- a/test/469-condition-materialization-regression/expected.txt +++ b/test/469-condition-materialization/expected.txt diff --git a/test/469-condition-materialization-regression/info.txt b/test/469-condition-materialization/info.txt index 59290f0b50..59290f0b50 100644 --- a/test/469-condition-materialization-regression/info.txt +++ b/test/469-condition-materialization/info.txt diff --git a/test/469-condition-materialization-regression/src/Main.java b/test/469-condition-materialization/src/Main.java index 0be386a38f..0be386a38f 100644 --- a/test/469-condition-materialization-regression/src/Main.java +++ b/test/469-condition-materialization/src/Main.java diff --git a/test/476-clinit-check-inlining-static-invoke/expected.txt b/test/476-clinit-inline-static-invoke/expected.txt index c55bf72369..c55bf72369 100644 --- a/test/476-clinit-check-inlining-static-invoke/expected.txt +++ b/test/476-clinit-inline-static-invoke/expected.txt diff --git a/test/476-clinit-check-inlining-static-invoke/info.txt b/test/476-clinit-inline-static-invoke/info.txt index 1a439fceaf..1a439fceaf 100644 --- a/test/476-clinit-check-inlining-static-invoke/info.txt +++ b/test/476-clinit-inline-static-invoke/info.txt diff --git a/test/476-clinit-check-inlining-static-invoke/src/Main.java b/test/476-clinit-inline-static-invoke/src/Main.java index a7d3bcd2d2..a7d3bcd2d2 100644 --- a/test/476-clinit-check-inlining-static-invoke/src/Main.java +++ b/test/476-clinit-inline-static-invoke/src/Main.java diff --git a/test/529-checker-unresolved/build b/test/529-checker-unresolved/build deleted file mode 100644 index d85035b669..0000000000 --- a/test/529-checker-unresolved/build +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/bash -# -# Copyright (C) 2015 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. - -# Stop if something fails. -set -e - -# We can't use src-ex testing infrastructure because src and src-ex are compiled -# with javac independetely and can't share code (without reflection). - -mkdir classes -${JAVAC} -d classes `find src -name '*.java'` - -mkdir classes-ex -mv classes/UnresolvedClass.class classes-ex -mv classes/UnresolvedInterface.class classes-ex -mv classes/UnresolvedSuperClass.class classes-ex - -if [ ${USE_JACK} = "true" ]; then - jar cf classes.jill.jar -C classes . - jar cf classes-ex.jill.jar -C classes-ex . - - ${JACK} --import classes.jill.jar --output-dex . - zip $TEST_NAME.jar classes.dex - ${JACK} --import classes-ex.jill.jar --output-dex . - zip ${TEST_NAME}-ex.jar classes.dex -else - if [ ${NEED_DEX} = "true" ]; then - ${DX} -JXmx256m --debug --dex --dump-to=classes.lst --output=classes.dex --dump-width=1000 classes - zip $TEST_NAME.jar classes.dex - ${DX} -JXmx256m --debug --dex --dump-to=classes-ex.lst --output=classes.dex --dump-width=1000 classes-ex - zip ${TEST_NAME}-ex.jar classes.dex - fi -fi diff --git a/test/529-checker-unresolved/src/Unresolved.java b/test/529-checker-unresolved/src-dex2oat-unresolved/UnresolvedClass.java index 20ac6e0b89..8b3bb3c7ad 100644 --- a/test/529-checker-unresolved/src/Unresolved.java +++ b/test/529-checker-unresolved/src-dex2oat-unresolved/UnresolvedClass.java @@ -14,17 +14,7 @@ * limitations under the License. */ -interface UnresolvedInterface { - void interfaceMethod(); -} - -class UnresolvedSuperClass { - public void superMethod() { - System.out.println("UnresolvedClass.superMethod()"); - } -} - -class UnresolvedClass extends UnresolvedSuperClass implements UnresolvedInterface { +public class UnresolvedClass extends UnresolvedSuperClass implements UnresolvedInterface { static public void staticMethod() { System.out.println("UnresolvedClass.staticMethod()"); } diff --git a/test/097-duplicate-method/src/Test.java b/test/529-checker-unresolved/src-dex2oat-unresolved/UnresolvedInterface.java index 7dd61e6928..6e6b14bb7c 100644 --- a/test/097-duplicate-method/src/Test.java +++ b/test/529-checker-unresolved/src-dex2oat-unresolved/UnresolvedInterface.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 The Android Open Source Project + * Copyright (C) 2016 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. @@ -14,11 +14,6 @@ * limitations under the License. */ -/** - * This class and method will be overwritten by smali to return non-null. - */ -public class Test { - public static Object run() { - return null; - } +public interface UnresolvedInterface { + void interfaceMethod(); } diff --git a/test/529-checker-unresolved/src-dex2oat-unresolved/UnresolvedSuperClass.java b/test/529-checker-unresolved/src-dex2oat-unresolved/UnresolvedSuperClass.java new file mode 100644 index 0000000000..dd3be00633 --- /dev/null +++ b/test/529-checker-unresolved/src-dex2oat-unresolved/UnresolvedSuperClass.java @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2015 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 UnresolvedSuperClass { + public void superMethod() { + System.out.println("UnresolvedClass.superMethod()"); + } +} diff --git a/test/530-checker-loops1/expected.txt b/test/530-checker-loops1/expected.txt new file mode 100644 index 0000000000..b0aad4deb5 --- /dev/null +++ b/test/530-checker-loops1/expected.txt @@ -0,0 +1 @@ +passed diff --git a/test/530-checker-loops/info.txt b/test/530-checker-loops1/info.txt index f5d334d011..f5d334d011 100644 --- a/test/530-checker-loops/info.txt +++ b/test/530-checker-loops1/info.txt diff --git a/test/530-checker-loops/src/Main.java b/test/530-checker-loops1/src/Main.java index 2e5fd2534a..948a7b7dcc 100644 --- a/test/530-checker-loops/src/Main.java +++ b/test/530-checker-loops1/src/Main.java @@ -454,24 +454,87 @@ public class Main { return result; } - /// CHECK-START: int Main.linearShort() BCE (before) + /// CHECK-START: int Main.linearLong() BCE (before) /// CHECK-DAG: BoundsCheck // - /// CHECK-START: int Main.linearShort() BCE (after) + /// CHECK-START: int Main.linearLong() BCE (after) + /// CHECK-NOT: BoundsCheck + /// CHECK-NOT: Deoptimize + private static int linearLong() { + int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; + int result = 0; + // Induction on constant interval is done in higher precision than necessary, + // but truncated at the use as subscript. + for (long i = 0; i < 10; i++) { + result += x[(int)i]; + } + return result; + } + + /// CHECK-START: int Main.linearLongAlt(int[]) BCE (before) + /// CHECK-DAG: BoundsCheck + // + /// CHECK-START: int Main.linearLongAlt(int[]) BCE (after) + /// CHECK-NOT: BoundsCheck + /// CHECK-NOT: Deoptimize + private static int linearLongAlt(int[] x) { + int result = 0; + // Induction on array length is done in higher precision than necessary, + // but truncated at the use as subscript. + for (long i = 0; i < x.length; i++) { + result += x[(int)i]; + } + return result; + } + + /// CHECK-START: int Main.linearShort() BCE (before) /// CHECK-DAG: BoundsCheck // /// CHECK-START: int Main.linearShort() BCE (after) + /// CHECK-NOT: BoundsCheck /// CHECK-NOT: Deoptimize private static int linearShort() { int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int result = 0; - // TODO: make this work + // Induction is done in short precision, but fits. for (short i = 0; i < 10; i++) { result += x[i]; } return result; } + /// CHECK-START: int Main.linearChar() BCE (before) + /// CHECK-DAG: BoundsCheck + // + /// CHECK-START: int Main.linearChar() BCE (after) + /// CHECK-NOT: BoundsCheck + /// CHECK-NOT: Deoptimize + private static int linearChar() { + int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; + int result = 0; + // Induction is done in char precision, but fits. + for (char i = 0; i < 10; i++) { + result += x[i]; + } + return result; + } + + /// CHECK-START: int Main.linearByte() BCE (before) + /// CHECK-DAG: BoundsCheck + // + /// CHECK-START: int Main.linearByte() BCE (after) + /// CHECK-NOT: BoundsCheck + /// CHECK-NOT: Deoptimize + private static int linearByte() { + int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; + int result = 0; + // Induction is done in byte precision, but fits. + for (byte i = 0; i < 10; i++) { + result += x[i]; + } + return result; + } + /// CHECK-START: int Main.invariantFromPreLoop(int[], int) BCE (before) /// CHECK-DAG: BoundsCheck // @@ -633,6 +696,30 @@ public class Main { } } + /// CHECK-START: int[] Main.linearTriangularOOB() BCE (before) + /// CHECK-DAG: BoundsCheck + // + /// CHECK-START: int[] Main.linearTriangularOOB() BCE (after) + /// CHECK-DAG: BoundsCheck + // + /// CHECK-START: int[] Main.linearTriangularOOB() BCE (after) + /// CHECK-NOT: Deoptimize + private static int[] linearTriangularOOB() { + int[] a = new int[200]; + try { + for (int i = 0; i < 200; i++) { + // Lower bound must be recognized as lower precision induction with arithmetic + // wrap-around to -128 when i exceeds 127. + for (int j = (byte) i; j < 200; j++) { + a[j] += 1; + } + } + } catch (ArrayIndexOutOfBoundsException e) { + return a; + } + return null; // failure if this is reached + } + // // Verifier. // @@ -706,13 +793,25 @@ public class Main { expectEquals(55, linearForNEArrayLengthDown(x)); expectEquals(55, linearDoWhileUp()); expectEquals(55, linearDoWhileDown()); + expectEquals(55, linearLong()); + expectEquals(55, linearLongAlt(x)); expectEquals(55, linearShort()); + expectEquals(55, linearChar()); + expectEquals(55, linearByte()); expectEquals(55, invariantFromPreLoop(x, 1)); linearTriangularOnTwoArrayLengths(10); linearTriangularOnOneArrayLength(10); linearTriangularOnParameter(10); linearTriangularVariationsInnerStrict(10); linearTriangularVariationsInnerNonStrict(10); + { + int[] t = linearTriangularOOB(); + for (int i = 0; i < 200; i++) { + expectEquals(i <= 127 ? i + 1 : 128, t[i]); + } + } + + System.out.println("passed"); } private static void expectEquals(int expected, int result) { diff --git a/test/530-checker-loops2/expected.txt b/test/530-checker-loops2/expected.txt index e69de29bb2..b0aad4deb5 100644 --- a/test/530-checker-loops2/expected.txt +++ b/test/530-checker-loops2/expected.txt @@ -0,0 +1 @@ +passed diff --git a/test/530-checker-loops2/src/Main.java b/test/530-checker-loops2/src/Main.java index 64be1a2be4..c644692f03 100644 --- a/test/530-checker-loops2/src/Main.java +++ b/test/530-checker-loops2/src/Main.java @@ -383,6 +383,55 @@ public class Main { } } + /// CHECK-START: void Main.inductionOOB(int[]) BCE (before) + /// CHECK-DAG: BoundsCheck + // + /// CHECK-START: void Main.inductionOOB(int[]) BCE (after) + /// CHECK-DAG: BoundsCheck + // + /// CHECK-START: void Main.inductionOOB(int[]) BCE (after) + /// CHECK-NOT: Deoptimize + private static void inductionOOB(int[] a) { + // Careless range analysis would remove the bounds check. + // However, the narrower induction b wraps around arithmetically + // before it reaches the end of arrays longer than 127. + byte b = 0; + for (int i = 0; i < a.length; i++) { + a[b++] = i; + } + } + + /// CHECK-START: void Main.controlOOB(int[]) BCE (before) + /// CHECK-DAG: BoundsCheck + // + /// CHECK-START: void Main.controlOOB(int[]) BCE (after) + /// CHECK-DAG: BoundsCheck + // + /// CHECK-START: void Main.controlOOB(int[]) BCE (after) + /// CHECK-NOT: Deoptimize + private static void controlOOB(int[] a) { + // As above, but now the loop control also wraps around. + for (byte i = 0; i < a.length; i++) { + a[i] = -i; + } + } + + /// CHECK-START: void Main.conversionOOB(int[]) BCE (before) + /// CHECK-DAG: BoundsCheck + // + /// CHECK-START: void Main.conversionOOB(int[]) BCE (after) + /// CHECK-DAG: BoundsCheck + // + /// CHECK-START: void Main.conversionOOB(int[]) BCE (after) + /// CHECK-NOT: Deoptimize + private static void conversionOOB(int[] a) { + // As above, but with wrap around caused by an explicit conversion. + for (int i = 0; i < a.length; ) { + a[i] = i; + i = (byte) (i + 1); + } + } + /// CHECK-START: int[] Main.add() BCE (before) /// CHECK-DAG: BoundsCheck // @@ -750,6 +799,8 @@ public class Main { int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; + int[] a200 = new int[200]; + // Sorting. int[] sort = { 5, 4, 1, 9, 10, 2, 7, 6, 3, 8 }; bubble(sort); @@ -884,6 +935,36 @@ public class Main { sResult += 1000; } expectEquals(1111, sResult); + sResult = 0; + try { + inductionOOB(a200); + } catch (ArrayIndexOutOfBoundsException e) { + sResult += 1000; + } + expectEquals(1000, sResult); + for (int i = 0; i < 200; i++) { + expectEquals(i < 128 ? i : 0, a200[i]); + } + sResult = 0; + try { + controlOOB(a200); + } catch (ArrayIndexOutOfBoundsException e) { + sResult += 1000; + } + expectEquals(1000, sResult); + for (int i = 0; i < 200; i++) { + expectEquals(i < 128 ? -i : 0, a200[i]); + } + sResult = 0; + try { + conversionOOB(a200); + } catch (ArrayIndexOutOfBoundsException e) { + sResult += 1000; + } + expectEquals(1000, sResult); + for (int i = 0; i < 200; i++) { + expectEquals(i < 128 ? i : 0, a200[i]); + } // Addition. { @@ -989,6 +1070,8 @@ public class Main { dynamicBCEAndConstantIndicesAllPrimTypes(x, x1, x2, x3, x4, x5, x6, x7, x8, 0, 10)); Integer[] x9 = { 9 }; expectEquals(145, dynamicBCEAndConstantIndexRefType(x, x9, 0, 10)); + + System.out.println("passed"); } private static void expectEquals(int expected, int result) { diff --git a/test/551-checker-shifter-operand/build b/test/551-checker-shifter-operand/build index 18e8c59e91..a78021f349 100644 --- a/test/551-checker-shifter-operand/build +++ b/test/551-checker-shifter-operand/build @@ -58,8 +58,8 @@ EXPERIMENTAL="" # Setup experimental flag mappings in a bash associative array. declare -A JACK_EXPERIMENTAL_ARGS -JACK_EXPERIMENTAL_ARGS["default-methods"]="-D jack.java.source.version=1.8" -JACK_EXPERIMENTAL_ARGS["lambdas"]="-D jack.java.source.version=1.8" +JACK_EXPERIMENTAL_ARGS["default-methods"]="-D jack.java.source.version=1.8 -D jack.android.min-api-level=24" +JACK_EXPERIMENTAL_ARGS["lambdas"]="-D jack.java.source.version=1.8 -D jack.android.min-api-level=24" while true; do if [ "x$1" = "x--dx-option" ]; then diff --git a/test/565-checker-rotate/src/Main.java b/test/565-checker-rotate/src/Main.java index 33bbe0255a..aadb5978e8 100644 --- a/test/565-checker-rotate/src/Main.java +++ b/test/565-checker-rotate/src/Main.java @@ -16,112 +16,619 @@ public class Main { - /// CHECK-START: int Main.rotateLeft32(int, int) intrinsics_recognition (after) - /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerRotateLeft - /// CHECK-DAG: Return [<<Result>>] - private static int rotateLeft32(int x, int y) { - return Integer.rotateLeft(x, y); + /// CHECK-START: int Main.rotateLeftBoolean(boolean, int) intrinsics_recognition (after) + /// CHECK-DAG: <<Method:[ij]\d+>> CurrentMethod + /// CHECK: <<ArgVal:z\d+>> ParameterValue + /// CHECK: <<ArgDist:i\d+>> ParameterValue + /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0 + /// CHECK-DAG: <<One:i\d+>> IntConstant 1 + /// CHECK-DAG: <<Val:i\d+>> Phi [<<One>>,<<Zero>>] + /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect [<<Val>>,<<ArgDist>>,<<Method>>] intrinsic:IntegerRotateLeft + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.rotateLeftBoolean(boolean, int) instruction_simplifier (after) + /// CHECK: <<ArgVal:z\d+>> ParameterValue + /// CHECK: <<ArgDist:i\d+>> ParameterValue + /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0 + /// CHECK-DAG: <<One:i\d+>> IntConstant 1 + /// CHECK-DAG: <<Val:i\d+>> Phi [<<One>>,<<Zero>>] + /// CHECK-DAG: <<NegDist:i\d+>> Neg [<<ArgDist>>] + /// CHECK-DAG: <<Result:i\d+>> Ror [<<Val>>,<<NegDist>>] + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.rotateLeftBoolean(boolean, int) instruction_simplifier (after) + /// CHECK-NOT: InvokeStaticOrDirect + + /// CHECK-START: int Main.rotateLeftBoolean(boolean, int) select_generator (after) + /// CHECK: <<ArgVal:z\d+>> ParameterValue + /// CHECK: <<ArgDist:i\d+>> ParameterValue + /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0 + /// CHECK-DAG: <<One:i\d+>> IntConstant 1 + /// CHECK-DAG: <<SelVal:i\d+>> Select [<<Zero>>,<<One>>,<<ArgVal>>] + /// CHECK-DAG: <<NegDist:i\d+>> Neg [<<ArgDist>>] + /// CHECK-DAG: <<Result:i\d+>> Ror [<<SelVal>>,<<NegDist>>] + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.rotateLeftBoolean(boolean, int) select_generator (after) + /// CHECK-NOT: Phi + + /// CHECK-START: int Main.rotateLeftBoolean(boolean, int) instruction_simplifier_after_bce (after) + /// CHECK: <<ArgVal:z\d+>> ParameterValue + /// CHECK: <<ArgDist:i\d+>> ParameterValue + /// CHECK-DAG: <<NegDist:i\d+>> Neg [<<ArgDist>>] + /// CHECK-DAG: <<Result:i\d+>> Ror [<<ArgVal>>,<<NegDist>>] + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.rotateLeftBoolean(boolean, int) instruction_simplifier_after_bce (after) + /// CHECK-NOT: Select + + private static int rotateLeftBoolean(boolean value, int distance) { + return Integer.rotateLeft(value ? 1 : 0, distance); } - /// CHECK-START: long Main.rotateLeft64(long, int) intrinsics_recognition (after) - /// CHECK-DAG: <<Result:j\d+>> InvokeStaticOrDirect intrinsic:LongRotateLeft - /// CHECK-DAG: Return [<<Result>>] - private static long rotateLeft64(long x, int y) { - return Long.rotateLeft(x, y); + /// CHECK-START: int Main.rotateLeftByte(byte, int) intrinsics_recognition (after) + /// CHECK-DAG: <<Method:[ij]\d+>> CurrentMethod + /// CHECK: <<ArgVal:b\d+>> ParameterValue + /// CHECK: <<ArgDist:i\d+>> ParameterValue + /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect [<<ArgVal>>,<<ArgDist>>,<<Method>>] intrinsic:IntegerRotateLeft + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.rotateLeftByte(byte, int) instruction_simplifier (after) + /// CHECK: <<ArgVal:b\d+>> ParameterValue + /// CHECK: <<ArgDist:i\d+>> ParameterValue + /// CHECK-DAG: <<NegDist:i\d+>> Neg [<<ArgDist>>] + /// CHECK-DAG: <<Result:i\d+>> Ror [<<ArgVal>>,<<NegDist>>] + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.rotateLeftByte(byte, int) instruction_simplifier (after) + /// CHECK-NOT: InvokeStaticOrDirect + + private static int rotateLeftByte(byte value, int distance) { + return Integer.rotateLeft(value, distance); } - /// CHECK-START: int Main.rotateRight32(int, int) intrinsics_recognition (after) - /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerRotateRight - /// CHECK-DAG: Return [<<Result>>] - private static int rotateRight32(int x, int y) { - return Integer.rotateRight(x, y); + /// CHECK-START: int Main.rotateLeftShort(short, int) intrinsics_recognition (after) + /// CHECK-DAG: <<Method:[ij]\d+>> CurrentMethod + /// CHECK: <<ArgVal:s\d+>> ParameterValue + /// CHECK: <<ArgDist:i\d+>> ParameterValue + /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect [<<ArgVal>>,<<ArgDist>>,<<Method>>] intrinsic:IntegerRotateLeft + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.rotateLeftShort(short, int) instruction_simplifier (after) + /// CHECK: <<ArgVal:s\d+>> ParameterValue + /// CHECK: <<ArgDist:i\d+>> ParameterValue + /// CHECK-DAG: <<NegDist:i\d+>> Neg [<<ArgDist>>] + /// CHECK-DAG: <<Result:i\d+>> Ror [<<ArgVal>>,<<NegDist>>] + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.rotateLeftShort(short, int) instruction_simplifier (after) + /// CHECK-NOT: InvokeStaticOrDirect + + private static int rotateLeftShort(short value, int distance) { + return Integer.rotateLeft(value, distance); } - /// CHECK-START: long Main.rotateRight64(long, int) intrinsics_recognition (after) - /// CHECK-DAG: <<Result:j\d+>> InvokeStaticOrDirect intrinsic:LongRotateRight - /// CHECK-DAG: Return [<<Result>>] - private static long rotateRight64(long x, int y) { - return Long.rotateRight(x, y); + /// CHECK-START: int Main.rotateLeftChar(char, int) intrinsics_recognition (after) + /// CHECK-DAG: <<Method:[ij]\d+>> CurrentMethod + /// CHECK: <<ArgVal:c\d+>> ParameterValue + /// CHECK: <<ArgDist:i\d+>> ParameterValue + /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect [<<ArgVal>>,<<ArgDist>>,<<Method>>] intrinsic:IntegerRotateLeft + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.rotateLeftChar(char, int) instruction_simplifier (after) + /// CHECK: <<ArgVal:c\d+>> ParameterValue + /// CHECK: <<ArgDist:i\d+>> ParameterValue + /// CHECK-DAG: <<NegDist:i\d+>> Neg [<<ArgDist>>] + /// CHECK-DAG: <<Result:i\d+>> Ror [<<ArgVal>>,<<NegDist>>] + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.rotateLeftChar(char, int) instruction_simplifier (after) + /// CHECK-NOT: InvokeStaticOrDirect + + private static int rotateLeftChar(char value, int distance) { + return Integer.rotateLeft(value, distance); } - public static void main(String args[]) { - expectEquals32(0x00000001, rotateLeft32(0x00000001, 0)); - expectEquals32(0x00000002, rotateLeft32(0x00000001, 1)); - expectEquals32(0x80000000, rotateLeft32(0x00000001, 31)); - expectEquals32(0x00000001, rotateLeft32(0x00000001, 32)); // overshoot - expectEquals32(0x00000003, rotateLeft32(0x80000001, 1)); - expectEquals32(0x00000006, rotateLeft32(0x80000001, 2)); - expectEquals32(0x23456781, rotateLeft32(0x12345678, 4)); - expectEquals32(0xBCDEF09A, rotateLeft32(0x9ABCDEF0, 8)); + /// CHECK-START: int Main.rotateLeftInt(int, int) intrinsics_recognition (after) + /// CHECK-DAG: <<Method:[ij]\d+>> CurrentMethod + /// CHECK: <<ArgVal:i\d+>> ParameterValue + /// CHECK: <<ArgDist:i\d+>> ParameterValue + /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect [<<ArgVal>>,<<ArgDist>>,<<Method>>] intrinsic:IntegerRotateLeft + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.rotateLeftInt(int, int) instruction_simplifier (after) + /// CHECK: <<ArgVal:i\d+>> ParameterValue + /// CHECK: <<ArgDist:i\d+>> ParameterValue + /// CHECK-DAG: <<NegDist:i\d+>> Neg [<<ArgDist>>] + /// CHECK-DAG: <<Result:i\d+>> Ror [<<ArgVal>>,<<NegDist>>] + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.rotateLeftInt(int, int) instruction_simplifier (after) + /// CHECK-NOT: InvokeStaticOrDirect + + private static int rotateLeftInt(int value, int distance) { + return Integer.rotateLeft(value, distance); + } + + /// CHECK-START: long Main.rotateLeftLong(long, int) intrinsics_recognition (after) + /// CHECK-DAG: <<Method:[ij]\d+>> CurrentMethod + /// CHECK: <<ArgVal:j\d+>> ParameterValue + /// CHECK: <<ArgDist:i\d+>> ParameterValue + /// CHECK-DAG: <<Result:j\d+>> InvokeStaticOrDirect [<<ArgVal>>,<<ArgDist>>,<<Method>>] intrinsic:LongRotateLeft + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: long Main.rotateLeftLong(long, int) instruction_simplifier (after) + /// CHECK: <<ArgVal:j\d+>> ParameterValue + /// CHECK: <<ArgDist:i\d+>> ParameterValue + /// CHECK-DAG: <<NegDist:i\d+>> Neg [<<ArgDist>>] + /// CHECK-DAG: <<Result:j\d+>> Ror [<<ArgVal>>,<<NegDist>>] + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: long Main.rotateLeftLong(long, int) instruction_simplifier (after) + /// CHECK-NOT: InvokeStaticOrDirect + + private static long rotateLeftLong(long value, int distance) { + return Long.rotateLeft(value, distance); + } + + + /// CHECK-START: int Main.rotateRightBoolean(boolean, int) intrinsics_recognition (after) + /// CHECK-DAG: <<Method:[ij]\d+>> CurrentMethod + /// CHECK: <<ArgVal:z\d+>> ParameterValue + /// CHECK: <<ArgDist:i\d+>> ParameterValue + /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0 + /// CHECK-DAG: <<One:i\d+>> IntConstant 1 + /// CHECK-DAG: <<Val:i\d+>> Phi [<<One>>,<<Zero>>] + /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect [<<Val>>,<<ArgDist>>,<<Method>>] intrinsic:IntegerRotateRight + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.rotateRightBoolean(boolean, int) instruction_simplifier (after) + /// CHECK: <<ArgVal:z\d+>> ParameterValue + /// CHECK: <<ArgDist:i\d+>> ParameterValue + /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0 + /// CHECK-DAG: <<One:i\d+>> IntConstant 1 + /// CHECK-DAG: <<Val:i\d+>> Phi [<<One>>,<<Zero>>] + /// CHECK-DAG: <<Result:i\d+>> Ror [<<Val>>,<<ArgDist>>] + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.rotateRightBoolean(boolean, int) instruction_simplifier (after) + /// CHECK-NOT: InvokeStaticOrDirect + + /// CHECK-START: int Main.rotateRightBoolean(boolean, int) select_generator (after) + /// CHECK: <<ArgVal:z\d+>> ParameterValue + /// CHECK: <<ArgDist:i\d+>> ParameterValue + /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0 + /// CHECK-DAG: <<One:i\d+>> IntConstant 1 + /// CHECK-DAG: <<SelVal:i\d+>> Select [<<Zero>>,<<One>>,<<ArgVal>>] + /// CHECK-DAG: <<Result:i\d+>> Ror [<<SelVal>>,<<ArgDist>>] + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.rotateRightBoolean(boolean, int) select_generator (after) + /// CHECK-NOT: Phi + + /// CHECK-START: int Main.rotateRightBoolean(boolean, int) instruction_simplifier_after_bce (after) + /// CHECK: <<ArgVal:z\d+>> ParameterValue + /// CHECK: <<ArgDist:i\d+>> ParameterValue + /// CHECK-DAG: <<Result:i\d+>> Ror [<<ArgVal>>,<<ArgDist>>] + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.rotateRightBoolean(boolean, int) instruction_simplifier_after_bce (after) + /// CHECK-NOT: Select + + private static int rotateRightBoolean(boolean value, int distance) { + return Integer.rotateRight(value ? 1 : 0, distance); + } + + /// CHECK-START: int Main.rotateRightByte(byte, int) intrinsics_recognition (after) + /// CHECK-DAG: <<Method:[ij]\d+>> CurrentMethod + /// CHECK: <<ArgVal:b\d+>> ParameterValue + /// CHECK: <<ArgDist:i\d+>> ParameterValue + /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect [<<ArgVal>>,<<ArgDist>>,<<Method>>] intrinsic:IntegerRotateRight + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.rotateRightByte(byte, int) instruction_simplifier (after) + /// CHECK: <<ArgVal:b\d+>> ParameterValue + /// CHECK: <<ArgDist:i\d+>> ParameterValue + /// CHECK-DAG: <<Result:i\d+>> Ror [<<ArgVal>>,<<ArgDist>>] + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.rotateRightByte(byte, int) instruction_simplifier (after) + /// CHECK-NOT: InvokeStaticOrDirect + + private static int rotateRightByte(byte value, int distance) { + return Integer.rotateRight(value, distance); + } + + /// CHECK-START: int Main.rotateRightShort(short, int) intrinsics_recognition (after) + /// CHECK-DAG: <<Method:[ij]\d+>> CurrentMethod + /// CHECK: <<ArgVal:s\d+>> ParameterValue + /// CHECK: <<ArgDist:i\d+>> ParameterValue + /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect [<<ArgVal>>,<<ArgDist>>,<<Method>>] intrinsic:IntegerRotateRight + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.rotateRightShort(short, int) instruction_simplifier (after) + /// CHECK: <<ArgVal:s\d+>> ParameterValue + /// CHECK: <<ArgDist:i\d+>> ParameterValue + /// CHECK-DAG: <<Result:i\d+>> Ror [<<ArgVal>>,<<ArgDist>>] + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.rotateRightShort(short, int) instruction_simplifier (after) + /// CHECK-NOT: InvokeStaticOrDirect + + private static int rotateRightShort(short value, int distance) { + return Integer.rotateRight(value, distance); + } + + /// CHECK-START: int Main.rotateRightChar(char, int) intrinsics_recognition (after) + /// CHECK-DAG: <<Method:[ij]\d+>> CurrentMethod + /// CHECK: <<ArgVal:c\d+>> ParameterValue + /// CHECK: <<ArgDist:i\d+>> ParameterValue + /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect [<<ArgVal>>,<<ArgDist>>,<<Method>>] intrinsic:IntegerRotateRight + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.rotateRightChar(char, int) instruction_simplifier (after) + /// CHECK: <<ArgVal:c\d+>> ParameterValue + /// CHECK: <<ArgDist:i\d+>> ParameterValue + /// CHECK-DAG: <<Result:i\d+>> Ror [<<ArgVal>>,<<ArgDist>>] + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.rotateRightChar(char, int) instruction_simplifier (after) + /// CHECK-NOT: InvokeStaticOrDirect + + private static int rotateRightChar(char value, int distance) { + return Integer.rotateRight(value, distance); + } + + /// CHECK-START: int Main.rotateRightInt(int, int) intrinsics_recognition (after) + /// CHECK-DAG: <<Method:[ij]\d+>> CurrentMethod + /// CHECK: <<ArgVal:i\d+>> ParameterValue + /// CHECK: <<ArgDist:i\d+>> ParameterValue + /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect [<<ArgVal>>,<<ArgDist>>,<<Method>>] intrinsic:IntegerRotateRight + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.rotateRightInt(int, int) instruction_simplifier (after) + /// CHECK: <<ArgVal:i\d+>> ParameterValue + /// CHECK: <<ArgDist:i\d+>> ParameterValue + /// CHECK-DAG: <<Result:i\d+>> Ror [<<ArgVal>>,<<ArgDist>>] + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.rotateRightInt(int, int) instruction_simplifier (after) + /// CHECK-NOT: InvokeStaticOrDirect + + private static int rotateRightInt(int value, int distance) { + return Integer.rotateRight(value, distance); + } + + /// CHECK-START: long Main.rotateRightLong(long, int) intrinsics_recognition (after) + /// CHECK-DAG: <<Method:[ij]\d+>> CurrentMethod + /// CHECK: <<ArgVal:j\d+>> ParameterValue + /// CHECK: <<ArgDist:i\d+>> ParameterValue + /// CHECK-DAG: <<Result:j\d+>> InvokeStaticOrDirect [<<ArgVal>>,<<ArgDist>>,<<Method>>] intrinsic:LongRotateRight + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: long Main.rotateRightLong(long, int) instruction_simplifier (after) + /// CHECK: <<ArgVal:j\d+>> ParameterValue + /// CHECK: <<ArgDist:i\d+>> ParameterValue + /// CHECK-DAG: <<Result:j\d+>> Ror [<<ArgVal>>,<<ArgDist>>] + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: long Main.rotateRightLong(long, int) instruction_simplifier (after) + /// CHECK-NOT: InvokeStaticOrDirect + + private static long rotateRightLong(long value, int distance) { + return Long.rotateRight(value, distance); + } + + + /// CHECK-START: int Main.rotateLeftIntWithByteDistance(int, byte) intrinsics_recognition (after) + /// CHECK-DAG: <<Method:[ij]\d+>> CurrentMethod + /// CHECK: <<ArgVal:i\d+>> ParameterValue + /// CHECK: <<ArgDist:b\d+>> ParameterValue + /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect [<<ArgVal>>,<<ArgDist>>,<<Method>>] intrinsic:IntegerRotateLeft + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.rotateLeftIntWithByteDistance(int, byte) instruction_simplifier (after) + /// CHECK: <<ArgVal:i\d+>> ParameterValue + /// CHECK: <<ArgDist:b\d+>> ParameterValue + /// CHECK-DAG: <<NegDist:i\d+>> Neg [<<ArgDist>>] + /// CHECK-DAG: <<Result:i\d+>> Ror [<<ArgVal>>,<<NegDist>>] + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.rotateLeftIntWithByteDistance(int, byte) instruction_simplifier (after) + /// CHECK-NOT: InvokeStaticOrDirect + + private static int rotateLeftIntWithByteDistance(int value, byte distance) { + return Integer.rotateLeft(value, distance); + } + + /// CHECK-START: int Main.rotateRightIntWithByteDistance(int, byte) intrinsics_recognition (after) + /// CHECK-DAG: <<Method:[ij]\d+>> CurrentMethod + /// CHECK: <<ArgVal:i\d+>> ParameterValue + /// CHECK: <<ArgDist:b\d+>> ParameterValue + /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect [<<ArgVal>>,<<ArgDist>>,<<Method>>] intrinsic:IntegerRotateRight + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.rotateRightIntWithByteDistance(int, byte) instruction_simplifier (after) + /// CHECK: <<ArgVal:i\d+>> ParameterValue + /// CHECK: <<ArgDist:b\d+>> ParameterValue + /// CHECK-DAG: <<Result:i\d+>> Ror [<<ArgVal>>,<<ArgDist>>] + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.rotateRightIntWithByteDistance(int, byte) instruction_simplifier (after) + /// CHECK-NOT: InvokeStaticOrDirect + + private static int rotateRightIntWithByteDistance(int value, byte distance) { + return Integer.rotateRight(value, distance); + } + + + public static void testRotateLeftBoolean() { + for (int i = 0; i < 40; i++) { // overshoot a bit + int j = i & 31; + expectEqualsInt(0, rotateLeftBoolean(false, i)); + expectEqualsInt(1 << i, rotateLeftBoolean(true, i)); + } + } + + public static void testRotateLeftByte() { + expectEqualsInt(0x00000001, rotateLeftByte((byte)0x01, 0)); + expectEqualsInt(0x00000002, rotateLeftByte((byte)0x01, 1)); + expectEqualsInt(0x80000000, rotateLeftByte((byte)0x01, 31)); + expectEqualsInt(0x00000001, rotateLeftByte((byte)0x01, 32)); // overshoot + expectEqualsInt(0xFFFFFF03, rotateLeftByte((byte)0x81, 1)); + expectEqualsInt(0xFFFFFE07, rotateLeftByte((byte)0x81, 2)); + expectEqualsInt(0x00000120, rotateLeftByte((byte)0x12, 4)); + expectEqualsInt(0xFFFF9AFF, rotateLeftByte((byte)0x9A, 8)); for (int i = 0; i < 40; i++) { // overshoot a bit int j = i & 31; - expectEquals32(0x00000000, rotateLeft32(0x00000000, i)); - expectEquals32(0xFFFFFFFF, rotateLeft32(0xFFFFFFFF, i)); - expectEquals32(1 << j, rotateLeft32(0x00000001, i)); - expectEquals32((0x12345678 << j) | (0x12345678 >>> -j), - rotateLeft32(0x12345678, i)); - } - - expectEquals64(0x0000000000000001L, rotateLeft64(0x0000000000000001L, 0)); - expectEquals64(0x0000000000000002L, rotateLeft64(0x0000000000000001L, 1)); - expectEquals64(0x8000000000000000L, rotateLeft64(0x0000000000000001L, 63)); - expectEquals64(0x0000000000000001L, rotateLeft64(0x0000000000000001L, 64)); // overshoot - expectEquals64(0x0000000000000003L, rotateLeft64(0x8000000000000001L, 1)); - expectEquals64(0x0000000000000006L, rotateLeft64(0x8000000000000001L, 2)); - expectEquals64(0x23456789ABCDEF01L, rotateLeft64(0x123456789ABCDEF0L, 4)); - expectEquals64(0x3456789ABCDEF012L, rotateLeft64(0x123456789ABCDEF0L, 8)); + expectEqualsInt(0x00000000, rotateLeftByte((byte)0x0000, i)); + expectEqualsInt(0xFFFFFFFF, rotateLeftByte((byte)0xFFFF, i)); + expectEqualsInt((1 << j), rotateLeftByte((byte)0x0001, i)); + expectEqualsInt((0x12 << j) | (0x12 >>> -j), rotateLeftByte((byte)0x12, i)); + } + } + + public static void testRotateLeftShort() { + expectEqualsInt(0x00000001, rotateLeftShort((short)0x0001, 0)); + expectEqualsInt(0x00000002, rotateLeftShort((short)0x0001, 1)); + expectEqualsInt(0x80000000, rotateLeftShort((short)0x0001, 31)); + expectEqualsInt(0x00000001, rotateLeftShort((short)0x0001, 32)); // overshoot + expectEqualsInt(0xFFFF0003, rotateLeftShort((short)0x8001, 1)); + expectEqualsInt(0xFFFE0007, rotateLeftShort((short)0x8001, 2)); + expectEqualsInt(0x00012340, rotateLeftShort((short)0x1234, 4)); + expectEqualsInt(0xFF9ABCFF, rotateLeftShort((short)0x9ABC, 8)); + for (int i = 0; i < 40; i++) { // overshoot a bit + int j = i & 31; + expectEqualsInt(0x00000000, rotateLeftShort((short)0x0000, i)); + expectEqualsInt(0xFFFFFFFF, rotateLeftShort((short)0xFFFF, i)); + expectEqualsInt((1 << j), rotateLeftShort((short)0x0001, i)); + expectEqualsInt((0x1234 << j) | (0x1234 >>> -j), rotateLeftShort((short)0x1234, i)); + } + } + + public static void testRotateLeftChar() { + expectEqualsInt(0x00000001, rotateLeftChar((char)0x0001, 0)); + expectEqualsInt(0x00000002, rotateLeftChar((char)0x0001, 1)); + expectEqualsInt(0x80000000, rotateLeftChar((char)0x0001, 31)); + expectEqualsInt(0x00000001, rotateLeftChar((char)0x0001, 32)); // overshoot + expectEqualsInt(0x00010002, rotateLeftChar((char)0x8001, 1)); + expectEqualsInt(0x00020004, rotateLeftChar((char)0x8001, 2)); + expectEqualsInt(0x00012340, rotateLeftChar((char)0x1234, 4)); + expectEqualsInt(0x009ABC00, rotateLeftChar((char)0x9ABC, 8)); + expectEqualsInt(0x00FF0000, rotateLeftChar((char)0xFF00, 8)); + for (int i = 0; i < 40; i++) { // overshoot a bit + int j = i & 31; + expectEqualsInt(0x00000000, rotateLeftChar((char)0x0000, i)); + expectEqualsInt((1 << j), rotateLeftChar((char)0x0001, i)); + expectEqualsInt((0x1234 << j) | (0x1234 >>> -j), rotateLeftChar((char)0x1234, i)); + } + } + + public static void testRotateLeftInt() { + expectEqualsInt(0x00000001, rotateLeftInt(0x00000001, 0)); + expectEqualsInt(0x00000002, rotateLeftInt(0x00000001, 1)); + expectEqualsInt(0x80000000, rotateLeftInt(0x00000001, 31)); + expectEqualsInt(0x00000001, rotateLeftInt(0x00000001, 32)); // overshoot + expectEqualsInt(0x00000003, rotateLeftInt(0x80000001, 1)); + expectEqualsInt(0x00000006, rotateLeftInt(0x80000001, 2)); + expectEqualsInt(0x23456781, rotateLeftInt(0x12345678, 4)); + expectEqualsInt(0xBCDEF09A, rotateLeftInt(0x9ABCDEF0, 8)); + for (int i = 0; i < 40; i++) { // overshoot a bit + int j = i & 31; + expectEqualsInt(0x00000000, rotateLeftInt(0x00000000, i)); + expectEqualsInt(0xFFFFFFFF, rotateLeftInt(0xFFFFFFFF, i)); + expectEqualsInt(1 << j, rotateLeftInt(0x00000001, i)); + expectEqualsInt((0x12345678 << j) | (0x12345678 >>> -j), rotateLeftInt(0x12345678, i)); + } + } + + public static void testRotateLeftLong() { + expectEqualsLong(0x0000000000000001L, rotateLeftLong(0x0000000000000001L, 0)); + expectEqualsLong(0x0000000000000002L, rotateLeftLong(0x0000000000000001L, 1)); + expectEqualsLong(0x8000000000000000L, rotateLeftLong(0x0000000000000001L, 63)); + expectEqualsLong(0x0000000000000001L, rotateLeftLong(0x0000000000000001L, 64)); // overshoot + expectEqualsLong(0x0000000000000003L, rotateLeftLong(0x8000000000000001L, 1)); + expectEqualsLong(0x0000000000000006L, rotateLeftLong(0x8000000000000001L, 2)); + expectEqualsLong(0x23456789ABCDEF01L, rotateLeftLong(0x123456789ABCDEF0L, 4)); + expectEqualsLong(0x3456789ABCDEF012L, rotateLeftLong(0x123456789ABCDEF0L, 8)); for (int i = 0; i < 70; i++) { // overshoot a bit int j = i & 63; - expectEquals64(0x0000000000000000L, rotateLeft64(0x0000000000000000L, i)); - expectEquals64(0xFFFFFFFFFFFFFFFFL, rotateLeft64(0xFFFFFFFFFFFFFFFFL, i)); - expectEquals64(1L << j, rotateLeft64(0x0000000000000001, i)); - expectEquals64((0x123456789ABCDEF0L << j) | (0x123456789ABCDEF0L >>> -j), - rotateLeft64(0x123456789ABCDEF0L, i)); - } - - expectEquals32(0x80000000, rotateRight32(0x80000000, 0)); - expectEquals32(0x40000000, rotateRight32(0x80000000, 1)); - expectEquals32(0x00000001, rotateRight32(0x80000000, 31)); - expectEquals32(0x80000000, rotateRight32(0x80000000, 32)); // overshoot - expectEquals32(0xC0000000, rotateRight32(0x80000001, 1)); - expectEquals32(0x60000000, rotateRight32(0x80000001, 2)); - expectEquals32(0x81234567, rotateRight32(0x12345678, 4)); - expectEquals32(0xF09ABCDE, rotateRight32(0x9ABCDEF0, 8)); + expectEqualsLong(0x0000000000000000L, rotateLeftLong(0x0000000000000000L, i)); + expectEqualsLong(0xFFFFFFFFFFFFFFFFL, rotateLeftLong(0xFFFFFFFFFFFFFFFFL, i)); + expectEqualsLong(1L << j, rotateLeftLong(0x0000000000000001, i)); + expectEqualsLong((0x123456789ABCDEF0L << j) | (0x123456789ABCDEF0L >>> -j), + rotateLeftLong(0x123456789ABCDEF0L, i)); + } + } + + public static void testRotateRightBoolean() { for (int i = 0; i < 40; i++) { // overshoot a bit int j = i & 31; - expectEquals32(0x00000000, rotateRight32(0x00000000, i)); - expectEquals32(0xFFFFFFFF, rotateRight32(0xFFFFFFFF, i)); - expectEquals32(0x80000000 >>> j, rotateRight32(0x80000000, i)); - expectEquals32((0x12345678 >>> j) | (0x12345678 << -j), - rotateRight32(0x12345678, i)); - } - - expectEquals64(0x8000000000000000L, rotateRight64(0x8000000000000000L, 0)); - expectEquals64(0x4000000000000000L, rotateRight64(0x8000000000000000L, 1)); - expectEquals64(0x0000000000000001L, rotateRight64(0x8000000000000000L, 63)); - expectEquals64(0x8000000000000000L, rotateRight64(0x8000000000000000L, 64)); // overshoot - expectEquals64(0xC000000000000000L, rotateRight64(0x8000000000000001L, 1)); - expectEquals64(0x6000000000000000L, rotateRight64(0x8000000000000001L, 2)); - expectEquals64(0x0123456789ABCDEFL, rotateRight64(0x123456789ABCDEF0L, 4)); - expectEquals64(0xF0123456789ABCDEL, rotateRight64(0x123456789ABCDEF0L, 8)); + expectEqualsInt(0, rotateRightBoolean(false, i)); + expectEqualsInt(1 << (32 - i), rotateRightBoolean(true, i)); + } + } + + public static void testRotateRightByte() { + expectEqualsInt(0xFFFFFF80, rotateRightByte((byte)0x80, 0)); + expectEqualsInt(0x7FFFFFC0, rotateRightByte((byte)0x80, 1)); + expectEqualsInt(0xFFFFFF01, rotateRightByte((byte)0x80, 31)); + expectEqualsInt(0xFFFFFF80, rotateRightByte((byte)0x80, 32)); // overshoot + expectEqualsInt(0xFFFFFFC0, rotateRightByte((byte)0x81, 1)); + expectEqualsInt(0x7FFFFFE0, rotateRightByte((byte)0x81, 2)); + expectEqualsInt(0x20000001, rotateRightByte((byte)0x12, 4)); + expectEqualsInt(0x9AFFFFFF, rotateRightByte((byte)0x9A, 8)); + for (int i = 0; i < 40; i++) { // overshoot a bit + int j = i & 31; + expectEqualsInt(0x00000000, rotateRightByte((byte)0x00, i)); + expectEqualsInt(0xFFFFFFFF, rotateRightByte((byte)0xFF, i)); + expectEqualsInt(1 << (32 - j), rotateRightByte((byte)0x01, i)); + expectEqualsInt((0x12 >>> j) | (0x12 << -j), rotateRightByte((byte)0x12, i)); + } + } + + public static void testRotateRightShort() { + expectEqualsInt(0xFFFF8000, rotateRightShort((short)0x8000, 0)); + expectEqualsInt(0x7FFFC000, rotateRightShort((short)0x8000, 1)); + expectEqualsInt(0xFFFF0001, rotateRightShort((short)0x8000, 31)); + expectEqualsInt(0xFFFF8000, rotateRightShort((short)0x8000, 32)); // overshoot + expectEqualsInt(0xFFFFC000, rotateRightShort((short)0x8001, 1)); + expectEqualsInt(0x7FFFE000, rotateRightShort((short)0x8001, 2)); + expectEqualsInt(0x40000123, rotateRightShort((short)0x1234, 4)); + expectEqualsInt(0xBCFFFF9A, rotateRightShort((short)0x9ABC, 8)); + for (int i = 0; i < 40; i++) { // overshoot a bit + int j = i & 31; + expectEqualsInt(0x00000000, rotateRightShort((short)0x0000, i)); + expectEqualsInt(0xFFFFFFFF, rotateRightShort((short)0xFFFF, i)); + expectEqualsInt(1 << (32 - j), rotateRightShort((short)0x0001, i)); + expectEqualsInt((0x1234 >>> j) | (0x1234 << -j), rotateRightShort((short)0x1234, i)); + } + } + + public static void testRotateRightChar() { + expectEqualsInt(0x00008000, rotateRightChar((char)0x8000, 0)); + expectEqualsInt(0x00004000, rotateRightChar((char)0x8000, 1)); + expectEqualsInt(0x00010000, rotateRightChar((char)0x8000, 31)); + expectEqualsInt(0x00008000, rotateRightChar((char)0x8000, 32)); // overshoot + expectEqualsInt(0x80004000, rotateRightChar((char)0x8001, 1)); + expectEqualsInt(0x40002000, rotateRightChar((char)0x8001, 2)); + expectEqualsInt(0x40000123, rotateRightChar((char)0x1234, 4)); + expectEqualsInt(0xBC00009A, rotateRightChar((char)0x9ABC, 8)); + for (int i = 0; i < 40; i++) { // overshoot a bit + int j = i & 31; + expectEqualsInt(0x00000000, rotateRightChar((char)0x0000, i)); + expectEqualsInt(1 << (32 - j), rotateRightChar((char)0x0001, i)); + expectEqualsInt((0x1234 >>> j) | (0x1234 << -j), rotateRightChar((char)0x1234, i)); + } + } + + public static void testRotateRightInt() { + expectEqualsInt(0x80000000, rotateRightInt(0x80000000, 0)); + expectEqualsInt(0x40000000, rotateRightInt(0x80000000, 1)); + expectEqualsInt(0x00000001, rotateRightInt(0x80000000, 31)); + expectEqualsInt(0x80000000, rotateRightInt(0x80000000, 32)); // overshoot + expectEqualsInt(0xC0000000, rotateRightInt(0x80000001, 1)); + expectEqualsInt(0x60000000, rotateRightInt(0x80000001, 2)); + expectEqualsInt(0x81234567, rotateRightInt(0x12345678, 4)); + expectEqualsInt(0xF09ABCDE, rotateRightInt(0x9ABCDEF0, 8)); + for (int i = 0; i < 40; i++) { // overshoot a bit + int j = i & 31; + expectEqualsInt(0x00000000, rotateRightInt(0x00000000, i)); + expectEqualsInt(0xFFFFFFFF, rotateRightInt(0xFFFFFFFF, i)); + expectEqualsInt(0x80000000 >>> j, rotateRightInt(0x80000000, i)); + expectEqualsInt((0x12345678 >>> j) | (0x12345678 << -j), rotateRightInt(0x12345678, i)); + } + } + + public static void testRotateRightLong() { + expectEqualsLong(0x8000000000000000L, rotateRightLong(0x8000000000000000L, 0)); + expectEqualsLong(0x4000000000000000L, rotateRightLong(0x8000000000000000L, 1)); + expectEqualsLong(0x0000000000000001L, rotateRightLong(0x8000000000000000L, 63)); + expectEqualsLong(0x8000000000000000L, rotateRightLong(0x8000000000000000L, 64)); // overshoot + expectEqualsLong(0xC000000000000000L, rotateRightLong(0x8000000000000001L, 1)); + expectEqualsLong(0x6000000000000000L, rotateRightLong(0x8000000000000001L, 2)); + expectEqualsLong(0x0123456789ABCDEFL, rotateRightLong(0x123456789ABCDEF0L, 4)); + expectEqualsLong(0xF0123456789ABCDEL, rotateRightLong(0x123456789ABCDEF0L, 8)); for (int i = 0; i < 70; i++) { // overshoot a bit int j = i & 63; - expectEquals64(0x0000000000000000L, rotateRight64(0x0000000000000000L, i)); - expectEquals64(0xFFFFFFFFFFFFFFFFL, rotateRight64(0xFFFFFFFFFFFFFFFFL, i)); - expectEquals64(0x8000000000000000L >>> j, rotateRight64(0x8000000000000000L, i)); - expectEquals64((0x123456789ABCDEF0L >>> j) | (0x123456789ABCDEF0L << -j), - rotateRight64(0x123456789ABCDEF0L, i)); + expectEqualsLong(0x0000000000000000L, rotateRightLong(0x0000000000000000L, i)); + expectEqualsLong(0xFFFFFFFFFFFFFFFFL, rotateRightLong(0xFFFFFFFFFFFFFFFFL, i)); + expectEqualsLong(0x8000000000000000L >>> j, rotateRightLong(0x8000000000000000L, i)); + expectEqualsLong((0x123456789ABCDEF0L >>> j) | (0x123456789ABCDEF0L << -j), + rotateRightLong(0x123456789ABCDEF0L, i)); } + } + + + public static void testRotateLeftIntWithByteDistance() { + expectEqualsInt(0x00000001, rotateLeftIntWithByteDistance(0x00000001, (byte)0)); + expectEqualsInt(0x00000002, rotateLeftIntWithByteDistance(0x00000001, (byte)1)); + expectEqualsInt(0x80000000, rotateLeftIntWithByteDistance(0x00000001, (byte)31)); + expectEqualsInt(0x00000001, rotateLeftIntWithByteDistance(0x00000001, (byte)32)); // overshoot + expectEqualsInt(0x00000003, rotateLeftIntWithByteDistance(0x80000001, (byte)1)); + expectEqualsInt(0x00000006, rotateLeftIntWithByteDistance(0x80000001, (byte)2)); + expectEqualsInt(0x23456781, rotateLeftIntWithByteDistance(0x12345678, (byte)4)); + expectEqualsInt(0xBCDEF09A, rotateLeftIntWithByteDistance(0x9ABCDEF0, (byte)8)); + for (byte i = 0; i < 40; i++) { // overshoot a bit + byte j = (byte)(i & 31); + expectEqualsInt(0x00000000, rotateLeftIntWithByteDistance(0x00000000, i)); + expectEqualsInt(0xFFFFFFFF, rotateLeftIntWithByteDistance(0xFFFFFFFF, i)); + expectEqualsInt(1 << j, rotateLeftIntWithByteDistance(0x00000001, i)); + expectEqualsInt((0x12345678 << j) | (0x12345678 >>> -j), + rotateLeftIntWithByteDistance(0x12345678, i)); + } + } + + public static void testRotateRightIntWithByteDistance() { + expectEqualsInt(0x80000000, rotateRightIntWithByteDistance(0x80000000, (byte)0)); + expectEqualsInt(0x40000000, rotateRightIntWithByteDistance(0x80000000, (byte)1)); + expectEqualsInt(0x00000001, rotateRightIntWithByteDistance(0x80000000, (byte)31)); + expectEqualsInt(0x80000000, rotateRightIntWithByteDistance(0x80000000, (byte)32)); // overshoot + expectEqualsInt(0xC0000000, rotateRightIntWithByteDistance(0x80000001, (byte)1)); + expectEqualsInt(0x60000000, rotateRightIntWithByteDistance(0x80000001, (byte)2)); + expectEqualsInt(0x81234567, rotateRightIntWithByteDistance(0x12345678, (byte)4)); + expectEqualsInt(0xF09ABCDE, rotateRightIntWithByteDistance(0x9ABCDEF0, (byte)8)); + for (byte i = 0; i < 40; i++) { // overshoot a bit + byte j = (byte)(i & 31); + expectEqualsInt(0x00000000, rotateRightIntWithByteDistance(0x00000000, i)); + expectEqualsInt(0xFFFFFFFF, rotateRightIntWithByteDistance(0xFFFFFFFF, i)); + expectEqualsInt(0x80000000 >>> j, rotateRightIntWithByteDistance(0x80000000, i)); + expectEqualsInt((0x12345678 >>> j) | (0x12345678 << -j), + rotateRightIntWithByteDistance(0x12345678, i)); + } + } + + + public static void main(String args[]) { + testRotateLeftBoolean(); + testRotateLeftByte(); + testRotateLeftShort(); + testRotateLeftChar(); + testRotateLeftInt(); + testRotateLeftLong(); + + testRotateRightBoolean(); + testRotateRightByte(); + testRotateRightShort(); + testRotateRightChar(); + testRotateRightInt(); + testRotateRightLong(); + + // Also exercise distance values with types other than int. + testRotateLeftIntWithByteDistance(); + testRotateRightIntWithByteDistance(); System.out.println("passed"); } - private static void expectEquals32(int expected, int result) { + + private static void expectEqualsInt(int expected, int result) { if (expected != result) { throw new Error("Expected: " + expected + ", found: " + result); } } - private static void expectEquals64(long expected, long result) { + + private static void expectEqualsLong(long expected, long result) { if (expected != result) { throw new Error("Expected: " + expected + ", found: " + result); } diff --git a/test/566-checker-signum/src/Main.java b/test/566-checker-signum/src/Main.java index 0ad0042326..5f2cf3dc95 100644 --- a/test/566-checker-signum/src/Main.java +++ b/test/566-checker-signum/src/Main.java @@ -16,65 +16,213 @@ public class Main { - /// CHECK-START: int Main.sign32(int) intrinsics_recognition (after) - /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerSignum - /// CHECK-DAG: Return [<<Result>>] - private static int sign32(int x) { + /// CHECK-START: int Main.signBoolean(boolean) intrinsics_recognition (after) + /// CHECK-DAG: <<Method:[ij]\d+>> CurrentMethod + /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0 + /// CHECK-DAG: <<One:i\d+>> IntConstant 1 + /// CHECK-DAG: <<Phi:i\d+>> Phi [<<One>>,<<Zero>>] + /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect [<<Phi>>,<<Method>>] intrinsic:IntegerSignum + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.signBoolean(boolean) instruction_simplifier (after) + /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0 + /// CHECK-DAG: <<One:i\d+>> IntConstant 1 + /// CHECK-DAG: <<Phi:i\d+>> Phi [<<One>>,<<Zero>>] + /// CHECK-DAG: <<Result:i\d+>> Compare [<<Phi>>,<<Zero>>] + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.signBoolean(boolean) instruction_simplifier (after) + /// CHECK-NOT: InvokeStaticOrDirect + + /// CHECK-START: int Main.signBoolean(boolean) select_generator (after) + /// CHECK-DAG: <<Arg:z\d+>> ParameterValue + /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0 + /// CHECK-DAG: <<One:i\d+>> IntConstant 1 + /// CHECK-DAG: <<Sel:i\d+>> Select [<<Zero>>,<<One>>,<<Arg>>] + /// CHECK-DAG: <<Result:i\d+>> Compare [<<Sel>>,<<Zero>>] + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.signBoolean(boolean) select_generator (after) + /// CHECK-NOT: Phi + + /// CHECK-START: int Main.signBoolean(boolean) instruction_simplifier_after_bce (after) + /// CHECK-DAG: <<Arg:z\d+>> ParameterValue + /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0 + /// CHECK-DAG: <<Result:i\d+>> Compare [<<Arg>>,<<Zero>>] + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.signBoolean(boolean) instruction_simplifier_after_bce (after) + /// CHECK-NOT: Select + + private static int signBoolean(boolean x) { + return Integer.signum(x ? 1 : 0); + } + + /// CHECK-START: int Main.signByte(byte) intrinsics_recognition (after) + /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerSignum + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.signByte(byte) instruction_simplifier (after) + /// CHECK-DAG: <<Result:i\d+>> Compare + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.signByte(byte) instruction_simplifier (after) + /// CHECK-NOT: InvokeStaticOrDirect + + private static int signByte(byte x) { return Integer.signum(x); } - /// CHECK-START: int Main.sign64(long) intrinsics_recognition (after) - /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:LongSignum - /// CHECK-DAG: Return [<<Result>>] - private static int sign64(long x) { + /// CHECK-START: int Main.signShort(short) intrinsics_recognition (after) + /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerSignum + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.signShort(short) instruction_simplifier (after) + /// CHECK-DAG: <<Result:i\d+>> Compare + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.signShort(short) instruction_simplifier (after) + /// CHECK-NOT: InvokeStaticOrDirect + + private static int signShort(short x) { + return Integer.signum(x); + } + + /// CHECK-START: int Main.signChar(char) intrinsics_recognition (after) + /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerSignum + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.signChar(char) instruction_simplifier (after) + /// CHECK-DAG: <<Result:i\d+>> Compare + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.signChar(char) instruction_simplifier (after) + /// CHECK-NOT: InvokeStaticOrDirect + + private static int signChar(char x) { + return Integer.signum(x); + } + + /// CHECK-START: int Main.signInt(int) intrinsics_recognition (after) + /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerSignum + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.signInt(int) instruction_simplifier (after) + /// CHECK-DAG: <<Result:i\d+>> Compare + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.signInt(int) instruction_simplifier (after) + /// CHECK-NOT: InvokeStaticOrDirect + + private static int signInt(int x) { + return Integer.signum(x); + } + + /// CHECK-START: int Main.signLong(long) intrinsics_recognition (after) + /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:LongSignum + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.signLong(long) instruction_simplifier (after) + /// CHECK-DAG: <<Result:i\d+>> Compare + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.signLong(long) instruction_simplifier (after) + /// CHECK-NOT: InvokeStaticOrDirect + + private static int signLong(long x) { return Long.signum(x); } - public static void main(String args[]) { - expectEquals(-1, sign32(Integer.MIN_VALUE)); - expectEquals(-1, sign32(-12345)); - expectEquals(-1, sign32(-1)); - expectEquals(0, sign32(0)); - expectEquals(1, sign32(1)); - expectEquals(1, sign32(12345)); - expectEquals(1, sign32(Integer.MAX_VALUE)); + + public static void testSignBoolean() { + expectEquals(0, signBoolean(false)); + expectEquals(1, signBoolean(true)); + } + + public static void testSignByte() { + expectEquals(-1, signByte((byte)Byte.MIN_VALUE)); + expectEquals(-1, signByte((byte)-64)); + expectEquals(-1, signByte((byte)-1)); + expectEquals(0, signByte((byte)0)); + expectEquals(1, signByte((byte)1)); + expectEquals(1, signByte((byte)64)); + expectEquals(1, signByte((byte)Byte.MAX_VALUE)); + } + + public static void testSignShort() { + expectEquals(-1, signShort((short)Short.MIN_VALUE)); + expectEquals(-1, signShort((short)-12345)); + expectEquals(-1, signShort((short)-1)); + expectEquals(0, signShort((short)0)); + expectEquals(1, signShort((short)1)); + expectEquals(1, signShort((short)12345)); + expectEquals(1, signShort((short)Short.MAX_VALUE)); + } + + public static void testSignChar() { + expectEquals(0, signChar((char)0)); + expectEquals(1, signChar((char)1)); + expectEquals(1, signChar((char)12345)); + expectEquals(1, signChar((char)Character.MAX_VALUE)); + } + + public static void testSignInt() { + expectEquals(-1, signInt(Integer.MIN_VALUE)); + expectEquals(-1, signInt(-12345)); + expectEquals(-1, signInt(-1)); + expectEquals(0, signInt(0)); + expectEquals(1, signInt(1)); + expectEquals(1, signInt(12345)); + expectEquals(1, signInt(Integer.MAX_VALUE)); for (int i = -11; i <= 11; i++) { int expected = 0; if (i < 0) expected = -1; else if (i > 0) expected = 1; - expectEquals(expected, sign32(i)); + expectEquals(expected, signInt(i)); } + } + + public static void testSignLong() { + expectEquals(-1, signLong(Long.MIN_VALUE)); + expectEquals(-1, signLong(-12345L)); + expectEquals(-1, signLong(-1L)); + expectEquals(0, signLong(0L)); + expectEquals(1, signLong(1L)); + expectEquals(1, signLong(12345L)); + expectEquals(1, signLong(Long.MAX_VALUE)); - expectEquals(-1, sign64(Long.MIN_VALUE)); - expectEquals(-1, sign64(-12345L)); - expectEquals(-1, sign64(-1L)); - expectEquals(0, sign64(0L)); - expectEquals(1, sign64(1L)); - expectEquals(1, sign64(12345L)); - expectEquals(1, sign64(Long.MAX_VALUE)); - - expectEquals(-1, sign64(0x800000007FFFFFFFL)); - expectEquals(-1, sign64(0x80000000FFFFFFFFL)); - expectEquals(1, sign64(0x000000007FFFFFFFL)); - expectEquals(1, sign64(0x00000000FFFFFFFFL)); - expectEquals(1, sign64(0x7FFFFFFF7FFFFFFFL)); - expectEquals(1, sign64(0x7FFFFFFFFFFFFFFFL)); + expectEquals(-1, signLong(0x800000007FFFFFFFL)); + expectEquals(-1, signLong(0x80000000FFFFFFFFL)); + expectEquals(1, signLong(0x000000007FFFFFFFL)); + expectEquals(1, signLong(0x00000000FFFFFFFFL)); + expectEquals(1, signLong(0x7FFFFFFF7FFFFFFFL)); + expectEquals(1, signLong(0x7FFFFFFFFFFFFFFFL)); for (long i = -11L; i <= 11L; i++) { int expected = 0; if (i < 0) expected = -1; else if (i > 0) expected = 1; - expectEquals(expected, sign64(i)); + expectEquals(expected, signLong(i)); } for (long i = Long.MIN_VALUE; i <= Long.MIN_VALUE + 11L; i++) { - expectEquals(-1, sign64(i)); + expectEquals(-1, signLong(i)); } for (long i = Long.MAX_VALUE; i >= Long.MAX_VALUE - 11L; i--) { - expectEquals(1, sign64(i)); + expectEquals(1, signLong(i)); } + } + + + public static void main(String args[]) { + testSignBoolean(); + testSignByte(); + testSignShort(); + testSignChar(); + testSignInt(); + testSignLong(); System.out.println("passed"); } diff --git a/test/567-checker-compare/src/Main.java b/test/567-checker-compare/src/Main.java index 951d2c7510..f95ff1a7db 100644 --- a/test/567-checker-compare/src/Main.java +++ b/test/567-checker-compare/src/Main.java @@ -16,98 +16,902 @@ public class Main { - /// CHECK-START: int Main.compare32(int, int) intrinsics_recognition (after) - /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerCompare - /// CHECK-DAG: Return [<<Result>>] - private static int compare32(int x, int y) { + /// CHECK-START: int Main.compareBooleans(boolean, boolean) intrinsics_recognition (after) + /// CHECK-DAG: <<Method:[ij]\d+>> CurrentMethod + /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0 + /// CHECK-DAG: <<One:i\d+>> IntConstant 1 + /// CHECK-DAG: <<PhiX:i\d+>> Phi [<<One>>,<<Zero>>] + /// CHECK-DAG: <<PhiY:i\d+>> Phi [<<One>>,<<Zero>>] + /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect [<<PhiX>>,<<PhiY>>,<<Method>>] intrinsic:IntegerCompare + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.compareBooleans(boolean, boolean) instruction_simplifier (after) + /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0 + /// CHECK-DAG: <<One:i\d+>> IntConstant 1 + /// CHECK-DAG: <<PhiX:i\d+>> Phi [<<One>>,<<Zero>>] + /// CHECK-DAG: <<PhiY:i\d+>> Phi [<<One>>,<<Zero>>] + /// CHECK-DAG: <<Result:i\d+>> Compare [<<PhiX>>,<<PhiY>>] + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.compareBooleans(boolean, boolean) instruction_simplifier (after) + /// CHECK-NOT: InvokeStaticOrDirect + + /// CHECK-START: int Main.compareBooleans(boolean, boolean) select_generator (after) + /// CHECK: <<ArgX:z\d+>> ParameterValue + /// CHECK: <<ArgY:z\d+>> ParameterValue + /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0 + /// CHECK-DAG: <<One:i\d+>> IntConstant 1 + /// CHECK-DAG: <<SelX:i\d+>> Select [<<Zero>>,<<One>>,<<ArgX>>] + /// CHECK-DAG: <<SelY:i\d+>> Select [<<Zero>>,<<One>>,<<ArgY>>] + /// CHECK-DAG: <<Result:i\d+>> Compare [<<SelX>>,<<SelY>>] + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.compareBooleans(boolean, boolean) select_generator (after) + /// CHECK-NOT: Phi + + /// CHECK-START: int Main.compareBooleans(boolean, boolean) instruction_simplifier_after_bce (after) + /// CHECK: <<ArgX:z\d+>> ParameterValue + /// CHECK: <<ArgY:z\d+>> ParameterValue + /// CHECK-DAG: <<Result:i\d+>> Compare [<<ArgX>>,<<ArgY>>] + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.compareBooleans(boolean, boolean) instruction_simplifier_after_bce (after) + /// CHECK-NOT: Select + + private static int compareBooleans(boolean x, boolean y) { + return Integer.compare((x ? 1 : 0), (y ? 1 : 0)); + } + + /// CHECK-START: int Main.compareBytes(byte, byte) intrinsics_recognition (after) + /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerCompare + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.compareBytes(byte, byte) instruction_simplifier (after) + /// CHECK-DAG: <<Result:i\d+>> Compare + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.compareBytes(byte, byte) instruction_simplifier (after) + /// CHECK-NOT: InvokeStaticOrDirect + + private static int compareBytes(byte x, byte y) { + return Integer.compare(x, y); + } + + /// CHECK-START: int Main.compareShorts(short, short) intrinsics_recognition (after) + /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerCompare + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.compareShorts(short, short) instruction_simplifier (after) + /// CHECK-DAG: <<Result:i\d+>> Compare + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.compareShorts(short, short) instruction_simplifier (after) + /// CHECK-NOT: InvokeStaticOrDirect + + private static int compareShorts(short x, short y) { return Integer.compare(x, y); } - /// CHECK-START: int Main.compare64(long, long) intrinsics_recognition (after) - /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:LongCompare - /// CHECK-DAG: Return [<<Result>>] - private static int compare64(long x, long y) { + /// CHECK-START: int Main.compareChars(char, char) intrinsics_recognition (after) + /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerCompare + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.compareChars(char, char) instruction_simplifier (after) + /// CHECK-DAG: <<Result:i\d+>> Compare + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.compareChars(char, char) instruction_simplifier (after) + /// CHECK-NOT: InvokeStaticOrDirect + + private static int compareChars(char x, char y) { + return Integer.compare(x, y); + } + + /// CHECK-START: int Main.compareInts(int, int) intrinsics_recognition (after) + /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerCompare + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.compareInts(int, int) instruction_simplifier (after) + /// CHECK-DAG: <<Result:i\d+>> Compare + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.compareInts(int, int) instruction_simplifier (after) + /// CHECK-NOT: InvokeStaticOrDirect + + private static int compareInts(int x, int y) { + return Integer.compare(x, y); + } + + /// CHECK-START: int Main.compareLongs(long, long) intrinsics_recognition (after) + /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:LongCompare + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.compareLongs(long, long) instruction_simplifier (after) + /// CHECK-DAG: <<Result:i\d+>> Compare + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.compareLongs(long, long) instruction_simplifier (after) + /// CHECK-NOT: InvokeStaticOrDirect + + private static int compareLongs(long x, long y) { return Long.compare(x, y); } - public static void main(String args[]) { - expectEquals(-1, compare32(Integer.MIN_VALUE, Integer.MIN_VALUE + 1)); - expectEquals(-1, compare32(Integer.MIN_VALUE, -1)); - expectEquals(-1, compare32(Integer.MIN_VALUE, 0)); - expectEquals(-1, compare32(Integer.MIN_VALUE, 1)); - expectEquals(-1, compare32(Integer.MIN_VALUE, Integer.MAX_VALUE)); - expectEquals(-1, compare32(-1, 0)); - expectEquals(-1, compare32(-1, 1)); - expectEquals(-1, compare32(0, 1)); - - expectEquals(0, compare32(Integer.MIN_VALUE, Integer.MIN_VALUE)); - expectEquals(0, compare32(-1, -1)); - expectEquals(0, compare32(0, 0)); - expectEquals(0, compare32(1, 1)); - expectEquals(0, compare32(Integer.MAX_VALUE, Integer.MAX_VALUE)); - - expectEquals(1, compare32(0, -1)); - expectEquals(1, compare32(1, -1)); - expectEquals(1, compare32(1, 0)); - expectEquals(1, compare32(Integer.MAX_VALUE, Integer.MIN_VALUE)); - expectEquals(1, compare32(Integer.MAX_VALUE, -1)); - expectEquals(1, compare32(Integer.MAX_VALUE, 0)); - expectEquals(1, compare32(Integer.MAX_VALUE, 1)); - expectEquals(1, compare32(Integer.MAX_VALUE, Integer.MAX_VALUE - 1)); + + /// CHECK-START: int Main.compareByteShort(byte, short) intrinsics_recognition (after) + /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerCompare + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.compareByteShort(byte, short) instruction_simplifier (after) + /// CHECK-DAG: <<Result:i\d+>> Compare + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.compareByteShort(byte, short) instruction_simplifier (after) + /// CHECK-NOT: InvokeStaticOrDirect + + public static int compareByteShort(byte x, short y) { + return Integer.compare(x, y); + } + + /// CHECK-START: int Main.compareByteChar(byte, char) intrinsics_recognition (after) + /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerCompare + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.compareByteChar(byte, char) instruction_simplifier (after) + /// CHECK-DAG: <<Result:i\d+>> Compare + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.compareByteChar(byte, char) instruction_simplifier (after) + /// CHECK-NOT: InvokeStaticOrDirect + + public static int compareByteChar(byte x, char y) { + return Integer.compare(x, y); + } + + /// CHECK-START: int Main.compareByteInt(byte, int) intrinsics_recognition (after) + /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerCompare + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.compareByteInt(byte, int) instruction_simplifier (after) + /// CHECK-DAG: <<Result:i\d+>> Compare + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.compareByteInt(byte, int) instruction_simplifier (after) + /// CHECK-NOT: InvokeStaticOrDirect + + public static int compareByteInt(byte x, int y) { + return Integer.compare(x, y); + } + + + /// CHECK-START: int Main.compareShortByte(short, byte) intrinsics_recognition (after) + /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerCompare + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.compareShortByte(short, byte) instruction_simplifier (after) + /// CHECK-DAG: <<Result:i\d+>> Compare + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.compareShortByte(short, byte) instruction_simplifier (after) + /// CHECK-NOT: InvokeStaticOrDirect + + public static int compareShortByte(short x, byte y) { + return Integer.compare(x, y); + } + + /// CHECK-START: int Main.compareShortChar(short, char) intrinsics_recognition (after) + /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerCompare + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.compareShortChar(short, char) instruction_simplifier (after) + /// CHECK-DAG: <<Result:i\d+>> Compare + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.compareShortChar(short, char) instruction_simplifier (after) + /// CHECK-NOT: InvokeStaticOrDirect + + public static int compareShortChar(short x, char y) { + return Integer.compare(x, y); + } + + /// CHECK-START: int Main.compareShortInt(short, int) intrinsics_recognition (after) + /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerCompare + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.compareShortInt(short, int) instruction_simplifier (after) + /// CHECK-DAG: <<Result:i\d+>> Compare + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.compareShortInt(short, int) instruction_simplifier (after) + /// CHECK-NOT: InvokeStaticOrDirect + + public static int compareShortInt(short x, int y) { + return Integer.compare(x, y); + } + + + /// CHECK-START: int Main.compareCharByte(char, byte) intrinsics_recognition (after) + /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerCompare + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.compareCharByte(char, byte) instruction_simplifier (after) + /// CHECK-DAG: <<Result:i\d+>> Compare + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.compareCharByte(char, byte) instruction_simplifier (after) + /// CHECK-NOT: InvokeStaticOrDirect + + public static int compareCharByte(char x, byte y) { + return Integer.compare(x, y); + } + + /// CHECK-START: int Main.compareCharShort(char, short) intrinsics_recognition (after) + /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerCompare + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.compareCharShort(char, short) instruction_simplifier (after) + /// CHECK-DAG: <<Result:i\d+>> Compare + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.compareCharShort(char, short) instruction_simplifier (after) + /// CHECK-NOT: InvokeStaticOrDirect + + public static int compareCharShort(char x, short y) { + return Integer.compare(x, y); + } + + /// CHECK-START: int Main.compareCharInt(char, int) intrinsics_recognition (after) + /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerCompare + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.compareCharInt(char, int) instruction_simplifier (after) + /// CHECK-DAG: <<Result:i\d+>> Compare + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.compareCharInt(char, int) instruction_simplifier (after) + /// CHECK-NOT: InvokeStaticOrDirect + + public static int compareCharInt(char x, int y) { + return Integer.compare(x, y); + } + + + /// CHECK-START: int Main.compareIntByte(int, byte) intrinsics_recognition (after) + /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerCompare + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.compareIntByte(int, byte) instruction_simplifier (after) + /// CHECK-DAG: <<Result:i\d+>> Compare + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.compareIntByte(int, byte) instruction_simplifier (after) + /// CHECK-NOT: InvokeStaticOrDirect + + public static int compareIntByte(int x, byte y) { + return Integer.compare(x, y); + } + + /// CHECK-START: int Main.compareIntShort(int, short) intrinsics_recognition (after) + /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerCompare + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.compareIntShort(int, short) instruction_simplifier (after) + /// CHECK-DAG: <<Result:i\d+>> Compare + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.compareIntShort(int, short) instruction_simplifier (after) + /// CHECK-NOT: InvokeStaticOrDirect + + public static int compareIntShort(int x, short y) { + return Integer.compare(x, y); + } + + /// CHECK-START: int Main.compareIntChar(int, char) intrinsics_recognition (after) + /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerCompare + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.compareIntChar(int, char) instruction_simplifier (after) + /// CHECK-DAG: <<Result:i\d+>> Compare + /// CHECK-DAG: Return [<<Result>>] + + /// CHECK-START: int Main.compareIntChar(int, char) instruction_simplifier (after) + /// CHECK-NOT: InvokeStaticOrDirect + + public static int compareIntChar(int x, char y) { + return Integer.compare(x, y); + } + + + public static void testCompareBooleans() { + expectEquals(-1, compareBooleans(false, true)); + + expectEquals(0, compareBooleans(false, false)); + expectEquals(0, compareBooleans(true, true)); + + expectEquals(1, compareBooleans(true, false)); + } + + public static void testCompareBytes() { + expectEquals(-1, compareBytes(Byte.MIN_VALUE, (byte)(Byte.MIN_VALUE + 1))); + expectEquals(-1, compareBytes(Byte.MIN_VALUE, (byte)-1)); + expectEquals(-1, compareBytes(Byte.MIN_VALUE, (byte)0)); + expectEquals(-1, compareBytes(Byte.MIN_VALUE, (byte)1)); + expectEquals(-1, compareBytes(Byte.MIN_VALUE, Byte.MAX_VALUE)); + expectEquals(-1, compareBytes((byte)-1, (byte)0)); + expectEquals(-1, compareBytes((byte)-1, (byte)1)); + expectEquals(-1, compareBytes((byte)0, (byte)1)); + + expectEquals(0, compareBytes(Byte.MIN_VALUE, Byte.MIN_VALUE)); + expectEquals(0, compareBytes((byte)-1, (byte)-1)); + expectEquals(0, compareBytes((byte)0, (byte)0)); + expectEquals(0, compareBytes((byte)1, (byte)1)); + expectEquals(0, compareBytes(Byte.MAX_VALUE, Byte.MAX_VALUE)); + + expectEquals(1, compareBytes((byte)0, (byte)-1)); + expectEquals(1, compareBytes((byte)1, (byte)-1)); + expectEquals(1, compareBytes((byte)1, (byte)0)); + expectEquals(1, compareBytes(Byte.MAX_VALUE, Byte.MIN_VALUE)); + expectEquals(1, compareBytes(Byte.MAX_VALUE, (byte)-1)); + expectEquals(1, compareBytes(Byte.MAX_VALUE, (byte)0)); + expectEquals(1, compareBytes(Byte.MAX_VALUE, (byte)1)); + expectEquals(1, compareBytes(Byte.MAX_VALUE, (byte)(Byte.MAX_VALUE - 1))); + + for (byte i = -11; i <= 11; i++) { + for (byte j = -11; j <= 11; j++) { + int expected = 0; + if (i < j) expected = -1; + else if (i > j) expected = 1; + expectEquals(expected, compareBytes(i, j)); + } + } + } + + public static void testCompareShorts() { + expectEquals(-1, compareShorts(Short.MIN_VALUE, (short)(Short.MIN_VALUE + 1))); + expectEquals(-1, compareShorts(Short.MIN_VALUE, (short)-1)); + expectEquals(-1, compareShorts(Short.MIN_VALUE, (short)0)); + expectEquals(-1, compareShorts(Short.MIN_VALUE, (short)1)); + expectEquals(-1, compareShorts(Short.MIN_VALUE, (short)Short.MAX_VALUE)); + expectEquals(-1, compareShorts((short)-1, (short)0)); + expectEquals(-1, compareShorts((short)-1, (short)1)); + expectEquals(-1, compareShorts((short)0, (short)1)); + + expectEquals(0, compareShorts(Short.MIN_VALUE, Short.MIN_VALUE)); + expectEquals(0, compareShorts((short)-1, (short)-1)); + expectEquals(0, compareShorts((short)0, (short)0)); + expectEquals(0, compareShorts((short)1, (short)1)); + expectEquals(0, compareShorts(Short.MAX_VALUE, Short.MAX_VALUE)); + + expectEquals(1, compareShorts((short)0, (short)-1)); + expectEquals(1, compareShorts((short)1, (short)-1)); + expectEquals(1, compareShorts((short)1, (short)0)); + expectEquals(1, compareShorts(Short.MAX_VALUE, Short.MIN_VALUE)); + expectEquals(1, compareShorts(Short.MAX_VALUE, (short)-1)); + expectEquals(1, compareShorts(Short.MAX_VALUE, (short)0)); + expectEquals(1, compareShorts(Short.MAX_VALUE, (short)1)); + expectEquals(1, compareShorts(Short.MAX_VALUE, (short)(Short.MAX_VALUE - 1))); + + for (short i = -11; i <= 11; i++) { + for (short j = -11; j <= 11; j++) { + int expected = 0; + if (i < j) expected = -1; + else if (i > j) expected = 1; + expectEquals(expected, compareShorts(i, j)); + } + } + } + + public static void testCompareChars() { + expectEquals(-1, compareChars((char)0, Character.MAX_VALUE)); + expectEquals(-1, compareChars((char)0, (char)1)); + + expectEquals(0, compareChars((char)0, (char)0)); + expectEquals(0, compareChars((char)1, (char)1)); + expectEquals(0, compareChars(Character.MAX_VALUE, Character.MAX_VALUE)); + + expectEquals(1, compareChars((char)1, (char)0)); + expectEquals(1, compareChars(Character.MAX_VALUE, (char)0)); + expectEquals(1, compareChars(Character.MAX_VALUE, (char)1)); + expectEquals(1, compareChars(Character.MAX_VALUE, (char)(Character.MAX_VALUE - 1))); + + for (char i = 0; i <= 11; i++) { + for (char j = 0; j <= 11; j++) { + int expected = 0; + if (i < j) expected = -1; + else if (i > j) expected = 1; + expectEquals(expected, compareChars(i, j)); + } + } + } + + public static void testCompareInts() { + expectEquals(-1, compareInts(Integer.MIN_VALUE, Integer.MIN_VALUE + 1)); + expectEquals(-1, compareInts(Integer.MIN_VALUE, -1)); + expectEquals(-1, compareInts(Integer.MIN_VALUE, 0)); + expectEquals(-1, compareInts(Integer.MIN_VALUE, 1)); + expectEquals(-1, compareInts(Integer.MIN_VALUE, Integer.MAX_VALUE)); + expectEquals(-1, compareInts(-1, 0)); + expectEquals(-1, compareInts(-1, 1)); + expectEquals(-1, compareInts(0, 1)); + + expectEquals(0, compareInts(Integer.MIN_VALUE, Integer.MIN_VALUE)); + expectEquals(0, compareInts(-1, -1)); + expectEquals(0, compareInts(0, 0)); + expectEquals(0, compareInts(1, 1)); + expectEquals(0, compareInts(Integer.MAX_VALUE, Integer.MAX_VALUE)); + + expectEquals(1, compareInts(0, -1)); + expectEquals(1, compareInts(1, -1)); + expectEquals(1, compareInts(1, 0)); + expectEquals(1, compareInts(Integer.MAX_VALUE, Integer.MIN_VALUE)); + expectEquals(1, compareInts(Integer.MAX_VALUE, -1)); + expectEquals(1, compareInts(Integer.MAX_VALUE, 0)); + expectEquals(1, compareInts(Integer.MAX_VALUE, 1)); + expectEquals(1, compareInts(Integer.MAX_VALUE, Integer.MAX_VALUE - 1)); for (int i = -11; i <= 11; i++) { for (int j = -11; j <= 11; j++) { int expected = 0; if (i < j) expected = -1; else if (i > j) expected = 1; - expectEquals(expected, compare32(i, j)); + expectEquals(expected, compareInts(i, j)); } } + } - expectEquals(-1, compare64(Long.MIN_VALUE, Long.MIN_VALUE + 1L)); - expectEquals(-1, compare64(Long.MIN_VALUE, -1L)); - expectEquals(-1, compare64(Long.MIN_VALUE, 0L)); - expectEquals(-1, compare64(Long.MIN_VALUE, 1L)); - expectEquals(-1, compare64(Long.MIN_VALUE, Long.MAX_VALUE)); - expectEquals(-1, compare64(-1L, 0L)); - expectEquals(-1, compare64(-1L, 1L)); - expectEquals(-1, compare64(0L, 1L)); + public static void testCompareLongs() { + expectEquals(-1, compareLongs(Long.MIN_VALUE, Long.MIN_VALUE + 1L)); + expectEquals(-1, compareLongs(Long.MIN_VALUE, -1L)); + expectEquals(-1, compareLongs(Long.MIN_VALUE, 0L)); + expectEquals(-1, compareLongs(Long.MIN_VALUE, 1L)); + expectEquals(-1, compareLongs(Long.MIN_VALUE, Long.MAX_VALUE)); + expectEquals(-1, compareLongs(-1L, 0L)); + expectEquals(-1, compareLongs(-1L, 1L)); + expectEquals(-1, compareLongs(0L, 1L)); - expectEquals(0, compare64(Long.MIN_VALUE, Long.MIN_VALUE)); - expectEquals(0, compare64(-1L, -1L)); - expectEquals(0, compare64(0L, 0L)); - expectEquals(0, compare64(1L, 1L)); - expectEquals(0, compare64(Long.MAX_VALUE, Long.MAX_VALUE)); + expectEquals(0, compareLongs(Long.MIN_VALUE, Long.MIN_VALUE)); + expectEquals(0, compareLongs(-1L, -1L)); + expectEquals(0, compareLongs(0L, 0L)); + expectEquals(0, compareLongs(1L, 1L)); + expectEquals(0, compareLongs(Long.MAX_VALUE, Long.MAX_VALUE)); - expectEquals(1, compare64(0L, -1L)); - expectEquals(1, compare64(1L, -1L)); - expectEquals(1, compare64(1L, 0L)); - expectEquals(1, compare64(Long.MAX_VALUE, Long.MIN_VALUE)); - expectEquals(1, compare64(Long.MAX_VALUE, -1L)); - expectEquals(1, compare64(Long.MAX_VALUE, 0L)); - expectEquals(1, compare64(Long.MAX_VALUE, 1L)); - expectEquals(1, compare64(Long.MAX_VALUE, Long.MAX_VALUE - 1L)); + expectEquals(1, compareLongs(0L, -1L)); + expectEquals(1, compareLongs(1L, -1L)); + expectEquals(1, compareLongs(1L, 0L)); + expectEquals(1, compareLongs(Long.MAX_VALUE, Long.MIN_VALUE)); + expectEquals(1, compareLongs(Long.MAX_VALUE, -1L)); + expectEquals(1, compareLongs(Long.MAX_VALUE, 0L)); + expectEquals(1, compareLongs(Long.MAX_VALUE, 1L)); + expectEquals(1, compareLongs(Long.MAX_VALUE, Long.MAX_VALUE - 1L)); - expectEquals(-1, compare64(0x111111117FFFFFFFL, 0x11111111FFFFFFFFL)); - expectEquals(0, compare64(0x111111117FFFFFFFL, 0x111111117FFFFFFFL)); - expectEquals(1, compare64(0x11111111FFFFFFFFL, 0x111111117FFFFFFFL)); + expectEquals(-1, compareLongs(0x111111117FFFFFFFL, 0x11111111FFFFFFFFL)); + expectEquals(0, compareLongs(0x111111117FFFFFFFL, 0x111111117FFFFFFFL)); + expectEquals(1, compareLongs(0x11111111FFFFFFFFL, 0x111111117FFFFFFFL)); for (long i = -11L; i <= 11L; i++) { for (long j = -11L; j <= 11L; j++) { int expected = 0; if (i < j) expected = -1; else if (i > j) expected = 1; - expectEquals(expected, compare64(i, j)); + expectEquals(expected, compareLongs(i, j)); } } for (long i = Long.MIN_VALUE; i <= Long.MIN_VALUE + 11L; i++) { - expectEquals(-1, compare64(i, 0)); + expectEquals(-1, compareLongs(i, 0)); } for (long i = Long.MAX_VALUE; i >= Long.MAX_VALUE - 11L; i--) { - expectEquals(1, compare64(i, 0)); + expectEquals(1, compareLongs(i, 0)); + } + } + + + public static void testCompareByteShort() { + expectEquals(-1, compareByteShort(Byte.MIN_VALUE, (short)-1)); + expectEquals(-1, compareByteShort(Byte.MIN_VALUE, (short)0)); + expectEquals(-1, compareByteShort(Byte.MIN_VALUE, (short)1)); + expectEquals(-1, compareByteShort(Byte.MIN_VALUE, Short.MAX_VALUE)); + expectEquals(-1, compareByteShort((byte)-1, (short)0)); + expectEquals(-1, compareByteShort((byte)-1, (short)1)); + expectEquals(-1, compareByteShort((byte)0, (short)1)); + expectEquals(-1, compareByteShort(Byte.MAX_VALUE, (short)(Short.MAX_VALUE - 1))); + expectEquals(-1, compareByteShort(Byte.MAX_VALUE, Short.MAX_VALUE)); + + expectEquals(0, compareByteShort((byte)-1, (short)-1)); + expectEquals(0, compareByteShort((byte)0, (short)0)); + expectEquals(0, compareByteShort((byte)1, (short)1)); + + expectEquals(1, compareByteShort(Byte.MIN_VALUE, Short.MIN_VALUE)); + expectEquals(1, compareByteShort(Byte.MIN_VALUE, (short)(Short.MIN_VALUE + 1))); + expectEquals(1, compareByteShort((byte)0, (short)-1)); + expectEquals(1, compareByteShort((byte)1, (short)-1)); + expectEquals(1, compareByteShort((byte)1, (short)0)); + expectEquals(1, compareByteShort(Byte.MAX_VALUE, Short.MIN_VALUE)); + expectEquals(1, compareByteShort(Byte.MAX_VALUE, (short)-1)); + expectEquals(1, compareByteShort(Byte.MAX_VALUE, (short)0)); + expectEquals(1, compareByteShort(Byte.MAX_VALUE, (short)1)); + + for (byte i = -11; i <= 11; i++) { + for (short j = -11; j <= 11; j++) { + int expected = 0; + if (i < j) expected = -1; + else if (i > j) expected = 1; + expectEquals(expected, compareByteShort(i, j)); + } + } + } + + public static void testCompareByteChar() { + expectEquals(-1, compareByteChar(Byte.MIN_VALUE, (char)0)); + expectEquals(-1, compareByteChar(Byte.MIN_VALUE, (char)1)); + expectEquals(-1, compareByteChar(Byte.MIN_VALUE, Character.MAX_VALUE)); + expectEquals(-1, compareByteChar((byte)-1, (char)0)); + expectEquals(-1, compareByteChar((byte)-1, (char)1)); + expectEquals(-1, compareByteChar((byte)0, (char)1)); + expectEquals(-1, compareByteChar(Byte.MAX_VALUE, (char)(Character.MAX_VALUE - 1))); + expectEquals(-1, compareByteChar(Byte.MAX_VALUE, Character.MAX_VALUE)); + + expectEquals(0, compareByteChar((byte)0, (char)0)); + expectEquals(0, compareByteChar((byte)1, (char)1)); + + expectEquals(1, compareByteChar((byte)1, (char)0)); + expectEquals(1, compareByteChar(Byte.MAX_VALUE, (char)0)); + expectEquals(1, compareByteChar(Byte.MAX_VALUE, (char)1)); + + for (byte i = -11; i <= 11; i++) { + for (char j = 0; j <= 11; j++) { + int expected = 0; + if (i < j) expected = -1; + else if (i > j) expected = 1; + expectEquals(expected, compareByteChar(i, j)); + } + } + } + + public static void testCompareByteInt() { + expectEquals(-1, compareByteInt(Byte.MIN_VALUE, -1)); + expectEquals(-1, compareByteInt(Byte.MIN_VALUE, 0)); + expectEquals(-1, compareByteInt(Byte.MIN_VALUE, 1)); + expectEquals(-1, compareByteInt(Byte.MIN_VALUE, Integer.MAX_VALUE)); + expectEquals(-1, compareByteInt((byte)-1, 0)); + expectEquals(-1, compareByteInt((byte)-1, 1)); + expectEquals(-1, compareByteInt((byte)0, 1)); + expectEquals(-1, compareByteInt(Byte.MAX_VALUE, Integer.MAX_VALUE - 1)); + expectEquals(-1, compareByteInt(Byte.MAX_VALUE, Integer.MAX_VALUE)); + + expectEquals(0, compareByteInt((byte)-1, -1)); + expectEquals(0, compareByteInt((byte)0, 0)); + expectEquals(0, compareByteInt((byte)1, 1)); + + expectEquals(1, compareByteInt(Byte.MIN_VALUE, Integer.MIN_VALUE)); + expectEquals(1, compareByteInt(Byte.MIN_VALUE, Integer.MIN_VALUE + 1)); + expectEquals(1, compareByteInt((byte)0, -1)); + expectEquals(1, compareByteInt((byte)1, -1)); + expectEquals(1, compareByteInt((byte)1, 0)); + expectEquals(1, compareByteInt(Byte.MAX_VALUE, Integer.MIN_VALUE)); + expectEquals(1, compareByteInt(Byte.MAX_VALUE, -1)); + expectEquals(1, compareByteInt(Byte.MAX_VALUE, 0)); + expectEquals(1, compareByteInt(Byte.MAX_VALUE, 1)); + + for (byte i = -11; i <= 11; i++) { + for (int j = -11; j <= 11; j++) { + int expected = 0; + if (i < j) expected = -1; + else if (i > j) expected = 1; + expectEquals(expected, compareByteInt(i, j)); + } + } + } + + + public static void testCompareShortByte() { + expectEquals(-1, compareShortByte(Short.MIN_VALUE, Byte.MIN_VALUE)); + expectEquals(-1, compareShortByte(Short.MIN_VALUE, (byte)(Byte.MIN_VALUE + 1))); + expectEquals(-1, compareShortByte(Short.MIN_VALUE, (byte)-1)); + expectEquals(-1, compareShortByte(Short.MIN_VALUE, (byte)0)); + expectEquals(-1, compareShortByte(Short.MIN_VALUE, (byte)1)); + expectEquals(-1, compareShortByte(Short.MIN_VALUE, Byte.MAX_VALUE)); + expectEquals(-1, compareShortByte((short)-1, (byte)0)); + expectEquals(-1, compareShortByte((short)-1, (byte)1)); + expectEquals(-1, compareShortByte((short)0, (byte)1)); + + expectEquals(0, compareShortByte((short)-1, (byte)-1)); + expectEquals(0, compareShortByte((short)0, (byte)0)); + expectEquals(0, compareShortByte((short)1, (byte)1)); + + expectEquals(1, compareShortByte((short)0, (byte)-1)); + expectEquals(1, compareShortByte((short)1, (byte)-1)); + expectEquals(1, compareShortByte((short)1, (byte)0)); + expectEquals(1, compareShortByte(Short.MAX_VALUE, Byte.MIN_VALUE)); + expectEquals(1, compareShortByte(Short.MAX_VALUE, (byte)-1)); + expectEquals(1, compareShortByte(Short.MAX_VALUE, (byte)0)); + expectEquals(1, compareShortByte(Short.MAX_VALUE, (byte)1)); + expectEquals(1, compareShortByte(Short.MAX_VALUE, (byte)(Byte.MAX_VALUE - 1))); + expectEquals(1, compareShortByte(Short.MAX_VALUE, Byte.MAX_VALUE)); + + for (short i = -11; i <= 11; i++) { + for (byte j = -11; j <= 11; j++) { + int expected = 0; + if (i < j) expected = -1; + else if (i > j) expected = 1; + expectEquals(expected, compareShortByte(i, j)); + } + } + } + + public static void testCompareShortChar() { + expectEquals(-1, compareShortChar(Short.MIN_VALUE, (char)0)); + expectEquals(-1, compareShortChar(Short.MIN_VALUE, (char)1)); + expectEquals(-1, compareShortChar(Short.MIN_VALUE, Character.MAX_VALUE)); + expectEquals(-1, compareShortChar((short)-1, (char)0)); + expectEquals(-1, compareShortChar((short)-1, (char)1)); + expectEquals(-1, compareShortChar((short)0, (char)1)); + expectEquals(-1, compareShortChar(Short.MAX_VALUE, (char)(Character.MAX_VALUE - 1))); + expectEquals(-1, compareShortChar(Short.MAX_VALUE, Character.MAX_VALUE)); + + expectEquals(0, compareShortChar((short)0, (char)0)); + expectEquals(0, compareShortChar((short)1, (char)1)); + + expectEquals(1, compareShortChar((short)1, (char)0)); + expectEquals(1, compareShortChar(Short.MAX_VALUE, (char)0)); + expectEquals(1, compareShortChar(Short.MAX_VALUE, (char)1)); + + for (short i = -11; i <= 11; i++) { + for (char j = 0; j <= 11; j++) { + int expected = 0; + if (i < j) expected = -1; + else if (i > j) expected = 1; + expectEquals(expected, compareShortChar(i, j)); + } + } + } + + public static void testCompareShortInt() { + expectEquals(-1, compareShortInt(Short.MIN_VALUE, -1)); + expectEquals(-1, compareShortInt(Short.MIN_VALUE, 0)); + expectEquals(-1, compareShortInt(Short.MIN_VALUE, 1)); + expectEquals(-1, compareShortInt(Short.MIN_VALUE, Integer.MAX_VALUE)); + expectEquals(-1, compareShortInt((short)-1, 0)); + expectEquals(-1, compareShortInt((short)-1, 1)); + expectEquals(-1, compareShortInt((short)0, 1)); + expectEquals(-1, compareShortInt(Short.MAX_VALUE, Integer.MAX_VALUE - 1)); + expectEquals(-1, compareShortInt(Short.MAX_VALUE, Integer.MAX_VALUE)); + + expectEquals(0, compareShortInt((short)-1, -1)); + expectEquals(0, compareShortInt((short)0, 0)); + expectEquals(0, compareShortInt((short)1, 1)); + + expectEquals(1, compareShortInt(Short.MIN_VALUE, Integer.MIN_VALUE)); + expectEquals(1, compareShortInt(Short.MIN_VALUE, Integer.MIN_VALUE + 1)); + expectEquals(1, compareShortInt((short)0, -1)); + expectEquals(1, compareShortInt((short)1, -1)); + expectEquals(1, compareShortInt((short)1, 0)); + expectEquals(1, compareShortInt(Short.MAX_VALUE, Integer.MIN_VALUE)); + expectEquals(1, compareShortInt(Short.MAX_VALUE, -1)); + expectEquals(1, compareShortInt(Short.MAX_VALUE, 0)); + expectEquals(1, compareShortInt(Short.MAX_VALUE, 1)); + + for (short i = -11; i <= 11; i++) { + for (int j = -11; j <= 11; j++) { + int expected = 0; + if (i < j) expected = -1; + else if (i > j) expected = 1; + expectEquals(expected, compareShortInt(i, j)); + } } + } + + + public static void testCompareCharByte() { + expectEquals(-1, compareCharByte((char)0, (byte)1)); + expectEquals(-1, compareCharByte((char)0, Byte.MAX_VALUE)); + + expectEquals(0, compareCharByte((char)0, (byte)0)); + expectEquals(0, compareCharByte((char)1, (byte)1)); + + expectEquals(1, compareCharByte((char)0, Byte.MIN_VALUE)); + expectEquals(1, compareCharByte((char)0, (byte)(Byte.MIN_VALUE + 1))); + expectEquals(1, compareCharByte((char)0, (byte)-1)); + expectEquals(1, compareCharByte((char)1, (byte)-1)); + expectEquals(1, compareCharByte((char)1, (byte)0)); + expectEquals(1, compareCharByte(Character.MAX_VALUE, Byte.MIN_VALUE)); + expectEquals(1, compareCharByte(Character.MAX_VALUE, (byte)-1)); + expectEquals(1, compareCharByte(Character.MAX_VALUE, (byte)0)); + expectEquals(1, compareCharByte(Character.MAX_VALUE, (byte)1)); + expectEquals(1, compareCharByte(Character.MAX_VALUE, (byte)(Byte.MAX_VALUE - 1))); + expectEquals(1, compareCharByte(Character.MAX_VALUE, Byte.MAX_VALUE)); + + for (char i = 0; i <= 11; i++) { + for (byte j = -11; j <= 11; j++) { + int expected = 0; + if (i < j) expected = -1; + else if (i > j) expected = 1; + expectEquals(expected, compareCharByte(i, j)); + } + } + } + + public static void testCompareCharShort() { + expectEquals(-1, compareCharShort((char)0, (short)1)); + expectEquals(-1, compareCharShort((char)0, Short.MAX_VALUE)); + + expectEquals(0, compareCharShort((char)0, (short)0)); + expectEquals(0, compareCharShort((char)1, (short)1)); + + expectEquals(1, compareCharShort((char)0, Short.MIN_VALUE)); + expectEquals(1, compareCharShort((char)0, (short)(Short.MIN_VALUE + 1))); + expectEquals(1, compareCharShort((char)0, (short)-1)); + expectEquals(1, compareCharShort((char)1, (short)-1)); + expectEquals(1, compareCharShort((char)1, (short)0)); + expectEquals(1, compareCharShort(Character.MAX_VALUE, Short.MIN_VALUE)); + expectEquals(1, compareCharShort(Character.MAX_VALUE, (short)-1)); + expectEquals(1, compareCharShort(Character.MAX_VALUE, (short)0)); + expectEquals(1, compareCharShort(Character.MAX_VALUE, (short)1)); + expectEquals(1, compareCharShort(Character.MAX_VALUE, (short)(Short.MAX_VALUE - 1))); + expectEquals(1, compareCharShort(Character.MAX_VALUE, Short.MAX_VALUE)); + + for (char i = 0; i <= 11; i++) { + for (short j = -11; j <= 11; j++) { + int expected = 0; + if (i < j) expected = -1; + else if (i > j) expected = 1; + expectEquals(expected, compareCharShort(i, j)); + } + } + } + + public static void testCompareCharInt() { + expectEquals(-1, compareCharInt((char)0, 1)); + expectEquals(-1, compareCharInt((char)0, Integer.MAX_VALUE)); + expectEquals(-1, compareCharInt(Character.MAX_VALUE, Integer.MAX_VALUE - 1)); + expectEquals(-1, compareCharInt(Character.MAX_VALUE, Integer.MAX_VALUE)); + + expectEquals(0, compareCharInt((char)0, 0)); + expectEquals(0, compareCharInt((char)1, 1)); + + expectEquals(1, compareCharInt((char)0, Integer.MIN_VALUE)); + expectEquals(1, compareCharInt((char)0, Integer.MIN_VALUE + 1)); + expectEquals(1, compareCharInt((char)0, -1)); + expectEquals(1, compareCharInt((char)1, -1)); + expectEquals(1, compareCharInt((char)1, 0)); + expectEquals(1, compareCharInt(Character.MAX_VALUE, Integer.MIN_VALUE)); + expectEquals(1, compareCharInt(Character.MAX_VALUE, -1)); + expectEquals(1, compareCharInt(Character.MAX_VALUE, 0)); + expectEquals(1, compareCharInt(Character.MAX_VALUE, 1)); + + for (char i = 0; i <= 11; i++) { + for (int j = -11; j <= 11; j++) { + int expected = 0; + if (i < j) expected = -1; + else if (i > j) expected = 1; + expectEquals(expected, compareCharInt(i, j)); + } + } + } + + + public static void testCompareIntByte() { + expectEquals(-1, compareIntByte(Integer.MIN_VALUE, Byte.MIN_VALUE)); + expectEquals(-1, compareIntByte(Integer.MIN_VALUE, (byte)(Byte.MIN_VALUE + 1))); + expectEquals(-1, compareIntByte(Integer.MIN_VALUE, (byte)-1)); + expectEquals(-1, compareIntByte(Integer.MIN_VALUE, (byte)0)); + expectEquals(-1, compareIntByte(Integer.MIN_VALUE, (byte)1)); + expectEquals(-1, compareIntByte(Integer.MIN_VALUE, Byte.MAX_VALUE)); + expectEquals(-1, compareIntByte(-1, (byte)0)); + expectEquals(-1, compareIntByte(-1, (byte)1)); + expectEquals(-1, compareIntByte(0, (byte)1)); + + expectEquals(0, compareIntByte(-1, (byte)-1)); + expectEquals(0, compareIntByte(0, (byte)0)); + expectEquals(0, compareIntByte(1, (byte)1)); + + expectEquals(1, compareIntByte(0, (byte)-1)); + expectEquals(1, compareIntByte(1, (byte)-1)); + expectEquals(1, compareIntByte(1, (byte)0)); + expectEquals(1, compareIntByte(Integer.MAX_VALUE, Byte.MIN_VALUE)); + expectEquals(1, compareIntByte(Integer.MAX_VALUE, (byte)-1)); + expectEquals(1, compareIntByte(Integer.MAX_VALUE, (byte)0)); + expectEquals(1, compareIntByte(Integer.MAX_VALUE, (byte)1)); + expectEquals(1, compareIntByte(Integer.MAX_VALUE, (byte)(Byte.MAX_VALUE - 1))); + expectEquals(1, compareIntByte(Integer.MAX_VALUE, Byte.MAX_VALUE)); + + for (int i = -11; i <= 11; i++) { + for (byte j = -11; j <= 11; j++) { + int expected = 0; + if (i < j) expected = -1; + else if (i > j) expected = 1; + expectEquals(expected, compareIntByte(i, j)); + } + } + } + + public static void testCompareIntShort() { + expectEquals(-1, compareIntShort(Integer.MIN_VALUE, Short.MIN_VALUE)); + expectEquals(-1, compareIntShort(Integer.MIN_VALUE, (short)(Short.MIN_VALUE + 1))); + expectEquals(-1, compareIntShort(Integer.MIN_VALUE, (short)-1)); + expectEquals(-1, compareIntShort(Integer.MIN_VALUE, (short)0)); + expectEquals(-1, compareIntShort(Integer.MIN_VALUE, (short)1)); + expectEquals(-1, compareIntShort(Integer.MIN_VALUE, Short.MAX_VALUE)); + expectEquals(-1, compareIntShort(-1, (short)0)); + expectEquals(-1, compareIntShort(-1, (short)1)); + expectEquals(-1, compareIntShort(0, (short)1)); + + expectEquals(0, compareIntShort(-1, (short)-1)); + expectEquals(0, compareIntShort(0, (short)0)); + expectEquals(0, compareIntShort(1, (short)1)); + + expectEquals(1, compareIntShort(0, (short)-1)); + expectEquals(1, compareIntShort(1, (short)-1)); + expectEquals(1, compareIntShort(1, (short)0)); + expectEquals(1, compareIntShort(Integer.MAX_VALUE, Short.MIN_VALUE)); + expectEquals(1, compareIntShort(Integer.MAX_VALUE, (short)-1)); + expectEquals(1, compareIntShort(Integer.MAX_VALUE, (short)0)); + expectEquals(1, compareIntShort(Integer.MAX_VALUE, (short)1)); + expectEquals(1, compareIntShort(Integer.MAX_VALUE, (short)(Short.MAX_VALUE - 1))); + expectEquals(1, compareIntShort(Integer.MAX_VALUE, Short.MAX_VALUE)); + + for (int i = -11; i <= 11; i++) { + for (short j = -11; j <= 11; j++) { + int expected = 0; + if (i < j) expected = -1; + else if (i > j) expected = 1; + expectEquals(expected, compareIntShort(i, j)); + } + } + } + + public static void testCompareIntChar() { + expectEquals(-1, compareIntChar(Integer.MIN_VALUE, (char)0)); + expectEquals(-1, compareIntChar(Integer.MIN_VALUE, (char)1)); + expectEquals(-1, compareIntChar(Integer.MIN_VALUE, Character.MAX_VALUE)); + expectEquals(-1, compareIntChar(-1, (char)0)); + expectEquals(-1, compareIntChar(-1, (char)1)); + expectEquals(-1, compareIntChar(0, (char)1)); + + expectEquals(0, compareIntChar(0, (char)0)); + expectEquals(0, compareIntChar(1, (char)1)); + + expectEquals(1, compareIntChar(1, (char)0)); + expectEquals(1, compareIntChar(Integer.MAX_VALUE, (char)0)); + expectEquals(1, compareIntChar(Integer.MAX_VALUE, (char)1)); + expectEquals(1, compareIntChar(Integer.MAX_VALUE, (char)(Character.MAX_VALUE - 1))); + expectEquals(1, compareIntChar(Integer.MAX_VALUE, Character.MAX_VALUE)); + + for (int i = -11; i <= 11; i++) { + for (char j = 0; j <= 11; j++) { + int expected = 0; + if (i < j) expected = -1; + else if (i > j) expected = 1; + expectEquals(expected, compareIntChar(i, j)); + } + } + } + + + public static void main(String args[]) { + testCompareBooleans(); + testCompareBytes(); + testCompareShorts(); + testCompareChars(); + testCompareInts(); + testCompareLongs(); + + testCompareByteShort(); + testCompareByteChar(); + testCompareByteInt(); + + testCompareShortByte(); + testCompareShortChar(); + testCompareShortInt(); + + testCompareCharByte(); + testCompareCharShort(); + testCompareCharInt(); + + testCompareIntByte(); + testCompareIntShort(); + testCompareIntChar(); System.out.println("passed"); } diff --git a/test/530-checker-loops/expected.txt b/test/585-inline-unresolved/expected.txt index e69de29bb2..e69de29bb2 100644 --- a/test/530-checker-loops/expected.txt +++ b/test/585-inline-unresolved/expected.txt diff --git a/test/585-inline-unresolved/info.txt b/test/585-inline-unresolved/info.txt new file mode 100644 index 0000000000..414f638a1c --- /dev/null +++ b/test/585-inline-unresolved/info.txt @@ -0,0 +1,2 @@ +Regression test for optimizing that used to crash when inlining +a method whose return type is unresolved. diff --git a/test/585-inline-unresolved/smali/TestCase.smali b/test/585-inline-unresolved/smali/TestCase.smali new file mode 100644 index 0000000000..f260092847 --- /dev/null +++ b/test/585-inline-unresolved/smali/TestCase.smali @@ -0,0 +1,48 @@ +# Copyright (C) 2016 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. + +.class public LTestCase; + +.super Ljava/lang/Object; + +.field static private test1:Z + +.method public static topLevel()V + .registers 1 + invoke-static {}, LTestCase;->$inline$foo()LUnresolved; + return-void +.end method + +# We need multiple returns to trigger the crash. +.method public static $inline$foo()LUnresolved; + .registers 2 + const v1, 0x0 + sget-boolean v0, LTestCase;->test1:Z + if-eqz v0, :other_return + return-object v1 + :other_return + invoke-static {}, LTestCase;->$noinline$bar()LUnresolved; + move-result-object v0 + return-object v0 +.end method + +.method public static $noinline$bar()LUnresolved; + .registers 2 + const v1, 0x0 + sget-boolean v0, LTestCase;->test1:Z + if-eqz v0, :return + throw v1 + :return + return-object v1 +.end method diff --git a/test/097-duplicate-method/src/Main.java b/test/585-inline-unresolved/src/Main.java index bb3d36ad5b..67ad4d2263 100644 --- a/test/097-duplicate-method/src/Main.java +++ b/test/585-inline-unresolved/src/Main.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 The Android Open Source Project + * Copyright (C) 2016 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. @@ -14,15 +14,9 @@ * limitations under the License. */ -/** - * Certain class files generated by smali can have encoded methods with an - * identical method_idx. In these cases, the behavior should be to only use the - * first one, and to ignore all following duplicates. - */ public class Main { - public static void main(String args[]) { - if (Test.run() != null) { - System.out.println("Success!"); - } - } + public static void main(String[] args) throws Exception { + Class<?> c = Class.forName("TestCase"); + c.getMethod("topLevel").invoke(null); + } } diff --git a/test/586-checker-null-array-get/expected.txt b/test/586-checker-null-array-get/expected.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/586-checker-null-array-get/expected.txt diff --git a/test/586-checker-null-array-get/info.txt b/test/586-checker-null-array-get/info.txt new file mode 100644 index 0000000000..81b42e9789 --- /dev/null +++ b/test/586-checker-null-array-get/info.txt @@ -0,0 +1,3 @@ +Regression test for the load store elimination of optimizing +that used to merge two array gets that have the same inputs but +not the same type. Note that this only happens if the array is null. diff --git a/test/586-checker-null-array-get/src/Main.java b/test/586-checker-null-array-get/src/Main.java new file mode 100644 index 0000000000..332cfb0a53 --- /dev/null +++ b/test/586-checker-null-array-get/src/Main.java @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2016 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 Object[] getObjectArray() { return null; } + public static long[] getLongArray() { return null; } + public static Object getNull() { return null; } + + public static void main(String[] args) { + try { + foo(); + throw new Error("Expected NullPointerException"); + } catch (NullPointerException e) { + // Expected. + } + } + + /// CHECK-START: void Main.foo() load_store_elimination (after) + /// CHECK-DAG: <<Null:l\d+>> NullConstant + /// CHECK-DAG: <<Check:l\d+>> NullCheck [<<Null>>] + /// CHECK-DAG: <<Get1:j\d+>> ArrayGet [<<Check>>,{{i\d+}}] + /// CHECK-DAG: <<Get2:l\d+>> ArrayGet [<<Check>>,{{i\d+}}] + public static void foo() { + longField = getLongArray()[0]; + objectField = getObjectArray()[0]; + } + + /// CHECK-START: void Main.bar() load_store_elimination (after) + /// CHECK-DAG: <<Null:l\d+>> NullConstant + /// CHECK-DAG: <<BoundType:l\d+>> BoundType [<<Null>>] + /// CHECK-DAG: <<CheckL:l\d+>> NullCheck [<<BoundType>>] + /// CHECK-DAG: <<GetL0:l\d+>> ArrayGet [<<CheckL>>,{{i\d+}}] + /// CHECK-DAG: <<GetL1:l\d+>> ArrayGet [<<CheckL>>,{{i\d+}}] + /// CHECK-DAG: <<GetL2:l\d+>> ArrayGet [<<CheckL>>,{{i\d+}}] + /// CHECK-DAG: <<GetL3:l\d+>> ArrayGet [<<CheckL>>,{{i\d+}}] + /// CHECK-DAG: <<CheckJ:l\d+>> NullCheck [<<Null>>] + /// CHECK-DAG: <<GetJ0:j\d+>> ArrayGet [<<CheckJ>>,{{i\d+}}] + /// CHECK-DAG: <<GetJ1:j\d+>> ArrayGet [<<CheckJ>>,{{i\d+}}] + /// CHECK-DAG: <<GetJ2:j\d+>> ArrayGet [<<CheckJ>>,{{i\d+}}] + /// CHECK-DAG: <<GetJ3:j\d+>> ArrayGet [<<CheckJ>>,{{i\d+}}] + public static void bar() { + // We create multiple accesses that will lead the bounds check + // elimination pass to add a HDeoptimize. Not having the bounds check helped + // the load store elimination think it could merge two ArrayGet with different + // types. + String[] array = ((String[])getNull()); + objectField = array[0]; + objectField = array[1]; + objectField = array[2]; + objectField = array[3]; + long[] longArray = getLongArray(); + longField = longArray[0]; + longField = longArray[1]; + longField = longArray[2]; + longField = longArray[3]; + } + + public static long longField; + public static Object objectField; +} diff --git a/test/587-inline-class-error/expected.txt b/test/587-inline-class-error/expected.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/587-inline-class-error/expected.txt diff --git a/test/587-inline-class-error/info.txt b/test/587-inline-class-error/info.txt new file mode 100644 index 0000000000..7f244f673c --- /dev/null +++ b/test/587-inline-class-error/info.txt @@ -0,0 +1,2 @@ +Regression test for the inliner that used to crash while +trying to find a method for an erroneous class. diff --git a/test/587-inline-class-error/smali/SuperVerifyError.smali b/test/587-inline-class-error/smali/SuperVerifyError.smali new file mode 100644 index 0000000000..b63cba0a3b --- /dev/null +++ b/test/587-inline-class-error/smali/SuperVerifyError.smali @@ -0,0 +1,27 @@ +# Copyright (C) 2016 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. + +.class public LSuperVerifyError; + +.super Ljava/lang/Object; + +.method public final foo()V + .registers 1 + return-void +.end method + +.method public bar()V + .registers 1 + return-void +.end method diff --git a/test/587-inline-class-error/smali/TestCase.smali b/test/587-inline-class-error/smali/TestCase.smali new file mode 100644 index 0000000000..7c991ed003 --- /dev/null +++ b/test/587-inline-class-error/smali/TestCase.smali @@ -0,0 +1,33 @@ +# Copyright (C) 2016 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. + +.class public LTestCase; + +.super Ljava/lang/Object; + +.method public static topLevel()V + .registers 2 + const v0, 0x1 + new-array v0, v0, [LVerifyError; + invoke-static {v0}, LTestCase;->test([LVerifyError;)V + return-void +.end method + +.method public static test([LVerifyError;)V + .registers 2 + const v0, 0x0 + aget-object v1, v1, v0 + invoke-virtual {v1}, LSuperVerifyError;->bar()V + return-void +.end method diff --git a/test/587-inline-class-error/smali/VerifyError.smali b/test/587-inline-class-error/smali/VerifyError.smali new file mode 100644 index 0000000000..b821b7132e --- /dev/null +++ b/test/587-inline-class-error/smali/VerifyError.smali @@ -0,0 +1,28 @@ +# Copyright (C) 2016 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. + +.class public final LVerifyError; + +.super LSuperVerifyError; + +# Override a final method to put this class in the error state. +.method public foo()V + .registers 1 + return-void +.end method + +# Having a static field in the class is needed to get the +# right initialization for the embedded vtable length of a +# class. +.field public static i:I diff --git a/test/587-inline-class-error/src/Main.java b/test/587-inline-class-error/src/Main.java new file mode 100644 index 0000000000..3402fabb2c --- /dev/null +++ b/test/587-inline-class-error/src/Main.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2016 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. + */ + +import java.lang.reflect.InvocationTargetException; + +public class Main { + public static void main(String[] args) throws Exception { + try { + Class<?> v = Class.forName("VerifyError"); + throw new Error("Expected LinkageError"); + } catch (LinkageError e) { + // expected + } + + try { + Class.forName("TestCase").getMethod("topLevel").invoke(null); + throw new Error("Expected InvocationTargetException"); + } catch (InvocationTargetException e) { + if (!(e.getCause() instanceof NullPointerException)) { + throw new Error("Expected NullPointerException, got " + e.getCause()); + } + } + } +} diff --git a/test/588-checker-irreducible-lifetime-hole/expected.txt b/test/588-checker-irreducible-lifetime-hole/expected.txt new file mode 100644 index 0000000000..aab200982b --- /dev/null +++ b/test/588-checker-irreducible-lifetime-hole/expected.txt @@ -0,0 +1,2 @@ +42 +1 diff --git a/test/588-checker-irreducible-lifetime-hole/info.txt b/test/588-checker-irreducible-lifetime-hole/info.txt new file mode 100644 index 0000000000..a2861a9fd5 --- /dev/null +++ b/test/588-checker-irreducible-lifetime-hole/info.txt @@ -0,0 +1,3 @@ +Regression test for optimizing that used to have a too +strong DCHECK in the presence of a combination of irreducible loops +and try/catch. diff --git a/test/588-checker-irreducible-lifetime-hole/smali/IrreducibleLoop.smali b/test/588-checker-irreducible-lifetime-hole/smali/IrreducibleLoop.smali new file mode 100644 index 0000000000..7dbd9dae21 --- /dev/null +++ b/test/588-checker-irreducible-lifetime-hole/smali/IrreducibleLoop.smali @@ -0,0 +1,118 @@ +# Copyright (C) 2016 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. + +.class public LIrreducibleLoop; + +.super Ljava/lang/Object; + +## CHECK-START-X86: int IrreducibleLoop.simpleLoop1(int) dead_code_elimination (before) +## CHECK-DAG: <<Method:(i|j)\d+>> CurrentMethod +## CHECK-DAG: <<Constant:i\d+>> IntConstant 42 +## CHECK-DAG: Goto irreducible:true +## CHECK-DAG: InvokeStaticOrDirect [<<Constant>>,<<Method>>] loop:none +## CHECK-DAG: InvokeStaticOrDirect [{{i\d+}},<<Method>>] loop:none +.method public static simpleLoop1(I)I + .registers 3 + const/16 v0, 42 + invoke-static {v0}, LIrreducibleLoop;->$noinline$m(I)V + if-eqz p0, :b22 + goto :b34 + + :b34 + goto :b20 + + :b20 + if-nez p0, :b45 + goto :b46 + + :b46 + goto :b21 + + :b21 + goto :b34 + + :b22 + :try_start + div-int v0, v0, v0 + :try_end + .catchall {:try_start .. :try_end} :b34 + goto :b20 + + :b45 + invoke-static {v0}, LIrreducibleLoop;->$noinline$m(I)V + goto :b26 + + :b26 + return v0 +.end method + +## CHECK-START-X86: int IrreducibleLoop.simpleLoop2(int) dead_code_elimination (before) +## CHECK-DAG: <<Method:(i|j)\d+>> CurrentMethod +## CHECK-DAG: <<Constant:i\d+>> IntConstant 42 +## CHECK-DAG: Goto irreducible:true +## CHECK-DAG: InvokeStaticOrDirect [<<Constant>>,<<Method>>] loop:none +## CHECK-DAG: InvokeStaticOrDirect [{{i\d+}},<<Method>>] loop:none +.method public static simpleLoop2(I)I + .registers 3 + const/16 v0, 42 + + :try_start1 + invoke-static {v0}, LIrreducibleLoop;->$noinline$m(I)V + div-int v0, v0, v0 + :try_end1 + .catchall {:try_start1 .. :try_end1} :b14 + + :try_start2 + invoke-static {v0}, LIrreducibleLoop;->$noinline$m(I)V + div-int v0, v0, v0 + :try_end2 + .catchall {:try_start2 .. :try_end2} :b45 + goto :b49 + + :b14 + goto :b15 + + :b45 + goto :b15 + + :b15 + goto :b16 + + :b16 + goto :b49 + + :b49 + invoke-static {v0}, LIrreducibleLoop;->$noinline$m(I)V + div-int v0, v0, v0 + :try_end3 + .catchall {:b49 .. :try_end3} :b49 + if-eqz p0, :b16 + goto :b26 + + :b26 + return v0 +.end method + +.method public static $noinline$m(I)V + .registers 3 + const/16 v0, 0 + sget-boolean v1,LIrreducibleLoop;->doThrow:Z + if-eqz v1, :exit + # Prevent inlining. + throw v0 + :exit + return-void +.end method + +.field public static doThrow:Z diff --git a/test/588-checker-irreducible-lifetime-hole/src/Main.java b/test/588-checker-irreducible-lifetime-hole/src/Main.java new file mode 100644 index 0000000000..98565b103a --- /dev/null +++ b/test/588-checker-irreducible-lifetime-hole/src/Main.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2016 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. + */ + +import java.lang.reflect.Method; + +public class Main { + // Workaround for b/18051191. + class InnerClass {} + + public static void main(String[] args) throws Exception { + Class<?> c = Class.forName("IrreducibleLoop"); + { + Method m = c.getMethod("simpleLoop1", int.class); + Object[] arguments = { 42 }; + System.out.println(m.invoke(null, arguments)); + } + { + Method m = c.getMethod("simpleLoop2", int.class); + Object[] arguments = { 42 }; + System.out.println(m.invoke(null, arguments)); + } + } +} diff --git a/test/589-super-imt/expected.txt b/test/589-super-imt/expected.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/589-super-imt/expected.txt diff --git a/test/589-super-imt/info.txt b/test/589-super-imt/info.txt new file mode 100644 index 0000000000..c815dc9537 --- /dev/null +++ b/test/589-super-imt/info.txt @@ -0,0 +1,2 @@ +Test what the IMT is properly set for a subclass, and that the +subclass won't use the ImtConflictTable table of its super class. diff --git a/test/589-super-imt/src/Main.java b/test/589-super-imt/src/Main.java new file mode 100644 index 0000000000..e381ca7c93 --- /dev/null +++ b/test/589-super-imt/src/Main.java @@ -0,0 +1,447 @@ +/* + * Copyright (C) 2016 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. + */ + +interface Itf { + public Class<?> method1(); + public Class<?> method2(); + public Class<?> method3(); + public Class<?> method4(); + public Class<?> method5(); + public Class<?> method6(); + public Class<?> method7(); + public Class<?> method8(); + public Class<?> method9(); + public Class<?> method10(); + public Class<?> method11(); + public Class<?> method12(); + public Class<?> method13(); + public Class<?> method14(); + public Class<?> method15(); + public Class<?> method16(); + public Class<?> method17(); + public Class<?> method18(); + public Class<?> method19(); + public Class<?> method20(); + public Class<?> method21(); + public Class<?> method22(); + public Class<?> method23(); + public Class<?> method24(); + public Class<?> method25(); + public Class<?> method26(); + public Class<?> method27(); + public Class<?> method28(); + public Class<?> method29(); + public Class<?> method30(); + public Class<?> method31(); + public Class<?> method32(); + public Class<?> method33(); + public Class<?> method34(); + public Class<?> method35(); + public Class<?> method36(); + public Class<?> method37(); + public Class<?> method38(); + public Class<?> method39(); + public Class<?> method40(); + public Class<?> method41(); + public Class<?> method42(); + public Class<?> method43(); + public Class<?> method44(); + public Class<?> method45(); + public Class<?> method46(); + public Class<?> method47(); + public Class<?> method48(); + public Class<?> method49(); + public Class<?> method50(); + public Class<?> method51(); + public Class<?> method52(); + public Class<?> method53(); + public Class<?> method54(); + public Class<?> method55(); + public Class<?> method56(); + public Class<?> method57(); + public Class<?> method58(); + public Class<?> method59(); + public Class<?> method60(); + public Class<?> method61(); + public Class<?> method62(); + public Class<?> method63(); + public Class<?> method64(); + public Class<?> method65(); + public Class<?> method66(); + public Class<?> method67(); + public Class<?> method68(); + public Class<?> method69(); + public Class<?> method70(); + public Class<?> method71(); + public Class<?> method72(); + public Class<?> method73(); + public Class<?> method74(); + public Class<?> method75(); + public Class<?> method76(); + public Class<?> method77(); + public Class<?> method78(); + public Class<?> method79(); +} + +public class Main implements Itf { + public static Itf main; + public static void main(String[] args) { + main = new Main(); + callMains(); + main = new SubMain(); + callSubMains(); + } + + public static void callMains() { + // We loop to artificially create branches. The compiler will + // not compile this method otherwise. + for (int i = 0; i < 2; ++i) { + expectEquals(main.method1(), Main.class); + expectEquals(main.method2(), Main.class); + expectEquals(main.method3(), Main.class); + expectEquals(main.method4(), Main.class); + expectEquals(main.method5(), Main.class); + expectEquals(main.method6(), Main.class); + expectEquals(main.method7(), Main.class); + expectEquals(main.method8(), Main.class); + expectEquals(main.method9(), Main.class); + expectEquals(main.method10(), Main.class); + expectEquals(main.method11(), Main.class); + expectEquals(main.method12(), Main.class); + expectEquals(main.method13(), Main.class); + expectEquals(main.method14(), Main.class); + expectEquals(main.method15(), Main.class); + expectEquals(main.method16(), Main.class); + expectEquals(main.method17(), Main.class); + expectEquals(main.method18(), Main.class); + expectEquals(main.method19(), Main.class); + expectEquals(main.method20(), Main.class); + expectEquals(main.method21(), Main.class); + expectEquals(main.method22(), Main.class); + expectEquals(main.method23(), Main.class); + expectEquals(main.method24(), Main.class); + expectEquals(main.method25(), Main.class); + expectEquals(main.method26(), Main.class); + expectEquals(main.method27(), Main.class); + expectEquals(main.method28(), Main.class); + expectEquals(main.method29(), Main.class); + expectEquals(main.method30(), Main.class); + expectEquals(main.method31(), Main.class); + expectEquals(main.method32(), Main.class); + expectEquals(main.method33(), Main.class); + expectEquals(main.method34(), Main.class); + expectEquals(main.method35(), Main.class); + expectEquals(main.method36(), Main.class); + expectEquals(main.method37(), Main.class); + expectEquals(main.method38(), Main.class); + expectEquals(main.method39(), Main.class); + expectEquals(main.method40(), Main.class); + expectEquals(main.method41(), Main.class); + expectEquals(main.method42(), Main.class); + expectEquals(main.method43(), Main.class); + expectEquals(main.method44(), Main.class); + expectEquals(main.method45(), Main.class); + expectEquals(main.method46(), Main.class); + expectEquals(main.method47(), Main.class); + expectEquals(main.method48(), Main.class); + expectEquals(main.method49(), Main.class); + expectEquals(main.method50(), Main.class); + expectEquals(main.method51(), Main.class); + expectEquals(main.method52(), Main.class); + expectEquals(main.method53(), Main.class); + expectEquals(main.method54(), Main.class); + expectEquals(main.method55(), Main.class); + expectEquals(main.method56(), Main.class); + expectEquals(main.method57(), Main.class); + expectEquals(main.method58(), Main.class); + expectEquals(main.method59(), Main.class); + expectEquals(main.method60(), Main.class); + expectEquals(main.method61(), Main.class); + expectEquals(main.method62(), Main.class); + expectEquals(main.method63(), Main.class); + expectEquals(main.method64(), Main.class); + expectEquals(main.method65(), Main.class); + expectEquals(main.method66(), Main.class); + expectEquals(main.method67(), Main.class); + expectEquals(main.method68(), Main.class); + expectEquals(main.method69(), Main.class); + expectEquals(main.method70(), Main.class); + expectEquals(main.method71(), Main.class); + expectEquals(main.method72(), Main.class); + expectEquals(main.method73(), Main.class); + expectEquals(main.method74(), Main.class); + expectEquals(main.method75(), Main.class); + expectEquals(main.method76(), Main.class); + expectEquals(main.method77(), Main.class); + expectEquals(main.method78(), Main.class); + expectEquals(main.method79(), Main.class); + } + } + + public static void callSubMains() { + // We loop to artificially create branches. The compiler will + // not compile this method otherwise. + for (int i = 0; i < 2; ++i) { + expectEquals(main.method1(), SubMain.class); + expectEquals(main.method2(), SubMain.class); + expectEquals(main.method3(), SubMain.class); + expectEquals(main.method4(), SubMain.class); + expectEquals(main.method5(), SubMain.class); + expectEquals(main.method6(), SubMain.class); + expectEquals(main.method7(), SubMain.class); + expectEquals(main.method8(), SubMain.class); + expectEquals(main.method9(), SubMain.class); + expectEquals(main.method10(), SubMain.class); + expectEquals(main.method11(), SubMain.class); + expectEquals(main.method12(), SubMain.class); + expectEquals(main.method13(), SubMain.class); + expectEquals(main.method14(), SubMain.class); + expectEquals(main.method15(), SubMain.class); + expectEquals(main.method16(), SubMain.class); + expectEquals(main.method17(), SubMain.class); + expectEquals(main.method18(), SubMain.class); + expectEquals(main.method19(), SubMain.class); + expectEquals(main.method20(), SubMain.class); + expectEquals(main.method21(), SubMain.class); + expectEquals(main.method22(), SubMain.class); + expectEquals(main.method23(), SubMain.class); + expectEquals(main.method24(), SubMain.class); + expectEquals(main.method25(), SubMain.class); + expectEquals(main.method26(), SubMain.class); + expectEquals(main.method27(), SubMain.class); + expectEquals(main.method28(), SubMain.class); + expectEquals(main.method29(), SubMain.class); + expectEquals(main.method30(), SubMain.class); + expectEquals(main.method31(), SubMain.class); + expectEquals(main.method32(), SubMain.class); + expectEquals(main.method33(), SubMain.class); + expectEquals(main.method34(), SubMain.class); + expectEquals(main.method35(), SubMain.class); + expectEquals(main.method36(), SubMain.class); + expectEquals(main.method37(), SubMain.class); + expectEquals(main.method38(), SubMain.class); + expectEquals(main.method39(), SubMain.class); + expectEquals(main.method40(), SubMain.class); + expectEquals(main.method41(), SubMain.class); + expectEquals(main.method42(), SubMain.class); + expectEquals(main.method43(), SubMain.class); + expectEquals(main.method44(), SubMain.class); + expectEquals(main.method45(), SubMain.class); + expectEquals(main.method46(), SubMain.class); + expectEquals(main.method47(), SubMain.class); + expectEquals(main.method48(), SubMain.class); + expectEquals(main.method49(), SubMain.class); + expectEquals(main.method50(), SubMain.class); + expectEquals(main.method51(), SubMain.class); + expectEquals(main.method52(), SubMain.class); + expectEquals(main.method53(), SubMain.class); + expectEquals(main.method54(), SubMain.class); + expectEquals(main.method55(), SubMain.class); + expectEquals(main.method56(), SubMain.class); + expectEquals(main.method57(), SubMain.class); + expectEquals(main.method58(), SubMain.class); + expectEquals(main.method59(), SubMain.class); + expectEquals(main.method60(), SubMain.class); + expectEquals(main.method61(), SubMain.class); + expectEquals(main.method62(), SubMain.class); + expectEquals(main.method63(), SubMain.class); + expectEquals(main.method64(), SubMain.class); + expectEquals(main.method65(), SubMain.class); + expectEquals(main.method66(), SubMain.class); + expectEquals(main.method67(), SubMain.class); + expectEquals(main.method68(), SubMain.class); + expectEquals(main.method69(), SubMain.class); + expectEquals(main.method70(), SubMain.class); + expectEquals(main.method71(), SubMain.class); + expectEquals(main.method72(), SubMain.class); + expectEquals(main.method73(), SubMain.class); + expectEquals(main.method74(), SubMain.class); + expectEquals(main.method75(), SubMain.class); + expectEquals(main.method76(), SubMain.class); + expectEquals(main.method77(), SubMain.class); + expectEquals(main.method78(), SubMain.class); + expectEquals(main.method79(), SubMain.class); + } + } + + public static void expectEquals(Object actual, Object expected) { + if (!actual.equals(expected)) { + throw new Error("Expected " + expected + ", got " + actual); + } + } + + public Class<?> method1() { return Main.class; } + public Class<?> method2() { return Main.class; } + public Class<?> method3() { return Main.class; } + public Class<?> method4() { return Main.class; } + public Class<?> method5() { return Main.class; } + public Class<?> method6() { return Main.class; } + public Class<?> method7() { return Main.class; } + public Class<?> method8() { return Main.class; } + public Class<?> method9() { return Main.class; } + public Class<?> method10() { return Main.class; } + public Class<?> method11() { return Main.class; } + public Class<?> method12() { return Main.class; } + public Class<?> method13() { return Main.class; } + public Class<?> method14() { return Main.class; } + public Class<?> method15() { return Main.class; } + public Class<?> method16() { return Main.class; } + public Class<?> method17() { return Main.class; } + public Class<?> method18() { return Main.class; } + public Class<?> method19() { return Main.class; } + public Class<?> method20() { return Main.class; } + public Class<?> method21() { return Main.class; } + public Class<?> method22() { return Main.class; } + public Class<?> method23() { return Main.class; } + public Class<?> method24() { return Main.class; } + public Class<?> method25() { return Main.class; } + public Class<?> method26() { return Main.class; } + public Class<?> method27() { return Main.class; } + public Class<?> method28() { return Main.class; } + public Class<?> method29() { return Main.class; } + public Class<?> method30() { return Main.class; } + public Class<?> method31() { return Main.class; } + public Class<?> method32() { return Main.class; } + public Class<?> method33() { return Main.class; } + public Class<?> method34() { return Main.class; } + public Class<?> method35() { return Main.class; } + public Class<?> method36() { return Main.class; } + public Class<?> method37() { return Main.class; } + public Class<?> method38() { return Main.class; } + public Class<?> method39() { return Main.class; } + public Class<?> method40() { return Main.class; } + public Class<?> method41() { return Main.class; } + public Class<?> method42() { return Main.class; } + public Class<?> method43() { return Main.class; } + public Class<?> method44() { return Main.class; } + public Class<?> method45() { return Main.class; } + public Class<?> method46() { return Main.class; } + public Class<?> method47() { return Main.class; } + public Class<?> method48() { return Main.class; } + public Class<?> method49() { return Main.class; } + public Class<?> method50() { return Main.class; } + public Class<?> method51() { return Main.class; } + public Class<?> method52() { return Main.class; } + public Class<?> method53() { return Main.class; } + public Class<?> method54() { return Main.class; } + public Class<?> method55() { return Main.class; } + public Class<?> method56() { return Main.class; } + public Class<?> method57() { return Main.class; } + public Class<?> method58() { return Main.class; } + public Class<?> method59() { return Main.class; } + public Class<?> method60() { return Main.class; } + public Class<?> method61() { return Main.class; } + public Class<?> method62() { return Main.class; } + public Class<?> method63() { return Main.class; } + public Class<?> method64() { return Main.class; } + public Class<?> method65() { return Main.class; } + public Class<?> method66() { return Main.class; } + public Class<?> method67() { return Main.class; } + public Class<?> method68() { return Main.class; } + public Class<?> method69() { return Main.class; } + public Class<?> method70() { return Main.class; } + public Class<?> method71() { return Main.class; } + public Class<?> method72() { return Main.class; } + public Class<?> method73() { return Main.class; } + public Class<?> method74() { return Main.class; } + public Class<?> method75() { return Main.class; } + public Class<?> method76() { return Main.class; } + public Class<?> method77() { return Main.class; } + public Class<?> method78() { return Main.class; } + public Class<?> method79() { return Main.class; } +} + +class SubMain extends Main { + public Class<?> method1() { return SubMain.class; } + public Class<?> method2() { return SubMain.class; } + public Class<?> method3() { return SubMain.class; } + public Class<?> method4() { return SubMain.class; } + public Class<?> method5() { return SubMain.class; } + public Class<?> method6() { return SubMain.class; } + public Class<?> method7() { return SubMain.class; } + public Class<?> method8() { return SubMain.class; } + public Class<?> method9() { return SubMain.class; } + public Class<?> method10() { return SubMain.class; } + public Class<?> method11() { return SubMain.class; } + public Class<?> method12() { return SubMain.class; } + public Class<?> method13() { return SubMain.class; } + public Class<?> method14() { return SubMain.class; } + public Class<?> method15() { return SubMain.class; } + public Class<?> method16() { return SubMain.class; } + public Class<?> method17() { return SubMain.class; } + public Class<?> method18() { return SubMain.class; } + public Class<?> method19() { return SubMain.class; } + public Class<?> method20() { return SubMain.class; } + public Class<?> method21() { return SubMain.class; } + public Class<?> method22() { return SubMain.class; } + public Class<?> method23() { return SubMain.class; } + public Class<?> method24() { return SubMain.class; } + public Class<?> method25() { return SubMain.class; } + public Class<?> method26() { return SubMain.class; } + public Class<?> method27() { return SubMain.class; } + public Class<?> method28() { return SubMain.class; } + public Class<?> method29() { return SubMain.class; } + public Class<?> method30() { return SubMain.class; } + public Class<?> method31() { return SubMain.class; } + public Class<?> method32() { return SubMain.class; } + public Class<?> method33() { return SubMain.class; } + public Class<?> method34() { return SubMain.class; } + public Class<?> method35() { return SubMain.class; } + public Class<?> method36() { return SubMain.class; } + public Class<?> method37() { return SubMain.class; } + public Class<?> method38() { return SubMain.class; } + public Class<?> method39() { return SubMain.class; } + public Class<?> method40() { return SubMain.class; } + public Class<?> method41() { return SubMain.class; } + public Class<?> method42() { return SubMain.class; } + public Class<?> method43() { return SubMain.class; } + public Class<?> method44() { return SubMain.class; } + public Class<?> method45() { return SubMain.class; } + public Class<?> method46() { return SubMain.class; } + public Class<?> method47() { return SubMain.class; } + public Class<?> method48() { return SubMain.class; } + public Class<?> method49() { return SubMain.class; } + public Class<?> method50() { return SubMain.class; } + public Class<?> method51() { return SubMain.class; } + public Class<?> method52() { return SubMain.class; } + public Class<?> method53() { return SubMain.class; } + public Class<?> method54() { return SubMain.class; } + public Class<?> method55() { return SubMain.class; } + public Class<?> method56() { return SubMain.class; } + public Class<?> method57() { return SubMain.class; } + public Class<?> method58() { return SubMain.class; } + public Class<?> method59() { return SubMain.class; } + public Class<?> method60() { return SubMain.class; } + public Class<?> method61() { return SubMain.class; } + public Class<?> method62() { return SubMain.class; } + public Class<?> method63() { return SubMain.class; } + public Class<?> method64() { return SubMain.class; } + public Class<?> method65() { return SubMain.class; } + public Class<?> method66() { return SubMain.class; } + public Class<?> method67() { return SubMain.class; } + public Class<?> method68() { return SubMain.class; } + public Class<?> method69() { return SubMain.class; } + public Class<?> method70() { return SubMain.class; } + public Class<?> method71() { return SubMain.class; } + public Class<?> method72() { return SubMain.class; } + public Class<?> method73() { return SubMain.class; } + public Class<?> method74() { return SubMain.class; } + public Class<?> method75() { return SubMain.class; } + public Class<?> method76() { return SubMain.class; } + public Class<?> method77() { return SubMain.class; } + public Class<?> method78() { return SubMain.class; } + public Class<?> method79() { return SubMain.class; } +} diff --git a/test/590-checker-array-set-null-regression/expected.txt b/test/590-checker-array-set-null-regression/expected.txt new file mode 100644 index 0000000000..b0aad4deb5 --- /dev/null +++ b/test/590-checker-array-set-null-regression/expected.txt @@ -0,0 +1 @@ +passed diff --git a/test/590-checker-array-set-null-regression/info.txt b/test/590-checker-array-set-null-regression/info.txt new file mode 100644 index 0000000000..fe173a334d --- /dev/null +++ b/test/590-checker-array-set-null-regression/info.txt @@ -0,0 +1,11 @@ +Regression test for art::PrepareForRegisterAllocation, which replaces + + ArraySet[array, index, BoundType[NullConstant]] + +with + + ArraySet[array, index, NullConstant] + +but used to forget to remove the "need for a type check" bit in the +ArraySet, thus failing "!may_need_runtime_call_for_type_check" +assertions in code generators. diff --git a/test/590-checker-array-set-null-regression/src/Main.java b/test/590-checker-array-set-null-regression/src/Main.java new file mode 100644 index 0000000000..792ee4ecd6 --- /dev/null +++ b/test/590-checker-array-set-null-regression/src/Main.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2016 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[]) { + Element[] elements = new Element[51]; + testArraySetCheckCastNull(elements); + + System.out.println("passed"); + } + + /// CHECK-START: void Main.testArraySetCheckCastNull(Main$Element[]) builder (after) + /// CHECK: <<Array:l\d+>> ParameterValue + /// CHECK-DAG: <<Index:i\d+>> IntConstant 42 + /// CHECK-DAG: <<Null:l\d+>> NullConstant + /// CHECK-DAG: <<Class:l\d+>> LoadClass + /// CHECK-DAG: CheckCast [<<Null>>,<<Class>>] + /// CHECK-DAG: <<CheckedValue:l\d+>> BoundType [<<Null>>] klass:Main$Element can_be_null:true + /// CHECK-DAG: <<CheckedArray:l\d+>> NullCheck [<<Array>>] + /// CHECK-DAG: <<Length:i\d+>> ArrayLength [<<CheckedArray>>] + /// CHECK-DAG: <<CheckedIndex:i\d+>> BoundsCheck [<<Index>>,<<Length>>] + /// CHECK-DAG: <<ArraySet:v\d+>> ArraySet [<<CheckedArray>>,<<CheckedIndex>>,<<CheckedValue>>] needs_type_check:true + + /// CHECK-START: void Main.testArraySetCheckCastNull(Main$Element[]) instruction_simplifier (after) + /// CHECK-NOT: CheckCast + + /// CHECK-START: void Main.testArraySetCheckCastNull(Main$Element[]) prepare_for_register_allocation (before) + /// CHECK: <<Array:l\d+>> ParameterValue + /// CHECK-DAG: <<Index:i\d+>> IntConstant 42 + /// CHECK-DAG: <<Null:l\d+>> NullConstant + /// CHECK-DAG: <<Class:l\d+>> LoadClass + /// CHECK-DAG: <<CheckedValue:l\d+>> BoundType [<<Null>>] + /// CHECK-DAG: <<CheckedArray:l\d+>> NullCheck [<<Array>>] + /// CHECK-DAG: <<Length:i\d+>> ArrayLength [<<CheckedArray>>] + /// CHECK-DAG: <<CheckedIndex:i\d+>> BoundsCheck [<<Index>>,<<Length>>] + /// CHECK-DAG: <<ArraySet:v\d+>> ArraySet [<<CheckedArray>>,<<CheckedIndex>>,<<CheckedValue>>] needs_type_check:true + + /// CHECK-START: void Main.testArraySetCheckCastNull(Main$Element[]) prepare_for_register_allocation (after) + /// CHECK: <<Array:l\d+>> ParameterValue + /// CHECK-DAG: <<Index:i\d+>> IntConstant 42 + /// CHECK-DAG: <<Null:l\d+>> NullConstant + /// CHECK-DAG: <<Class:l\d+>> LoadClass + /// CHECK-DAG: <<Length:i\d+>> ArrayLength [<<Array>>] + /// CHECK-DAG: <<ArraySet:v\d+>> ArraySet [<<Array>>,<<Index>>,<<Null>>] needs_type_check:false + + static void testArraySetCheckCastNull(Element[] elements) { + Object object = null; + Element element = (Element) object; + elements[42] = element; + } + + class Element {} + +} diff --git a/test/590-infinite-loop-with-nop/expected.txt b/test/590-infinite-loop-with-nop/expected.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/590-infinite-loop-with-nop/expected.txt diff --git a/test/590-infinite-loop-with-nop/info.txt b/test/590-infinite-loop-with-nop/info.txt new file mode 100644 index 0000000000..ee0970918b --- /dev/null +++ b/test/590-infinite-loop-with-nop/info.txt @@ -0,0 +1 @@ +Regression test for debug build check failure for infinite loop with NOP. diff --git a/test/590-infinite-loop-with-nop/smali/TestCase.smali b/test/590-infinite-loop-with-nop/smali/TestCase.smali new file mode 100644 index 0000000000..7ea495d00a --- /dev/null +++ b/test/590-infinite-loop-with-nop/smali/TestCase.smali @@ -0,0 +1,28 @@ +# Copyright (C) 2016 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. + +.class LTestCase; + +.super Ljava/lang/Object; + +.method static public infiniteLoop()V + .registers 0 + :infinite_loop + nop + goto :infinite_loop +.end method + +# Add a field to work around +# Failure to verify dex file '...': Offset(208) should be zero when size is zero for field-ids. +.field private a:I diff --git a/test/590-infinite-loop-with-nop/src/Main.java b/test/590-infinite-loop-with-nop/src/Main.java new file mode 100644 index 0000000000..531ff2811a --- /dev/null +++ b/test/590-infinite-loop-with-nop/src/Main.java @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2016 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) { + } +} + diff --git a/test/970-iface-super-resolution-generated/build b/test/970-iface-super-resolution-generated/build index 2d9830b970..fd1b271c1c 100755 --- a/test/970-iface-super-resolution-generated/build +++ b/test/970-iface-super-resolution-generated/build @@ -31,7 +31,7 @@ USES_JAVA_SOURCE="false" if [[ $@ == *"--jvm"* ]]; then USES_JAVA_SOURCE="true" elif [[ "$USE_JACK" == "true" ]]; then - if $JACK -D jack.java.source.version=1.8 2>/dev/null; then + if $JACK -D jack.java.source.version=1.8 -D jack.android.min-api-level=24 2>/dev/null; then USES_JAVA_SOURCE="true" else echo "WARNING: Cannot use jack because it does not support JLS 1.8. Falling back to smali" >&2 diff --git a/test/974-verify-interface-super/expected.txt b/test/974-verify-interface-super/expected.txt new file mode 100644 index 0000000000..7ba7491891 --- /dev/null +++ b/test/974-verify-interface-super/expected.txt @@ -0,0 +1 @@ +OK. No exception before invoke! diff --git a/test/974-verify-interface-super/info.txt b/test/974-verify-interface-super/info.txt new file mode 100644 index 0000000000..c5ff1f69f1 --- /dev/null +++ b/test/974-verify-interface-super/info.txt @@ -0,0 +1,3 @@ +Test that we do the right thing with invoke-super on interfaces when there are +verifier errors. + diff --git a/test/974-verify-interface-super/smali/base.smali b/test/974-verify-interface-super/smali/base.smali new file mode 100644 index 0000000000..c7875de1d3 --- /dev/null +++ b/test/974-verify-interface-super/smali/base.smali @@ -0,0 +1,31 @@ +# Copyright 2016 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. + +.class public LBase; + +.super La/klass/that/does/not/Exist; + +.method public static run()V + .locals 4 + new-instance v0, LBase; + invoke-direct {v0}, LBase;-><init>()V + invoke-virtual {v0}, LBase;->SayHi()V + return-void +.end method + +.method public SayHi()V +.locals 2 + invoke-super {p0}, LIface;->SayHi()V + return-void +.end method diff --git a/test/974-verify-interface-super/smali/iface.smali b/test/974-verify-interface-super/smali/iface.smali new file mode 100644 index 0000000000..89f9c0beba --- /dev/null +++ b/test/974-verify-interface-super/smali/iface.smali @@ -0,0 +1,22 @@ +# Copyright 2016 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. + +.class public abstract interface LIface; + +.super Ljava/lang/Object; + +.method public SayHi()V +.locals 0 + return-void +.end method diff --git a/test/974-verify-interface-super/smali/main.smali b/test/974-verify-interface-super/smali/main.smali new file mode 100644 index 0000000000..be4016c5c1 --- /dev/null +++ b/test/974-verify-interface-super/smali/main.smali @@ -0,0 +1,40 @@ +# Copyright 2016 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. + +.class public LMain; + +.super Ljava/lang/Object; + +.method public static main([Ljava/lang/String;)V + .locals 4 + const-string v0, "OK. No exception before invoke!" + sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream; + invoke-virtual {v1, v0}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + :try_start + invoke-static {}, LBase;->run()V + const-string v0, "FAIL: no exception!" + sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream; + invoke-virtual {v1, v0}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :end + :try_end + .catch Ljava/lang/LinkageError; {:try_start .. :try_end} :end + .catch Ljava/lang/Throwable; {:try_start .. :try_end} :error + :error + move-exception v0 + sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream; + invoke-virtual {v1, v0}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + invoke-virtual {v0}, Ljava/lang/Throwable;->printStackTrace()V + :end + return-void +.end method diff --git a/test/Android.run-test.mk b/test/Android.run-test.mk index 7036bdcaf5..11a38cbd42 100644 --- a/test/Android.run-test.mk +++ b/test/Android.run-test.mk @@ -111,9 +111,6 @@ ifeq ($(ART_TEST_RUN_TEST_NO_DEX2OAT),true) PREBUILD_TYPES += no-dex2oat endif COMPILER_TYPES := -ifeq ($(ART_TEST_DEFAULT_COMPILER),true) - COMPILER_TYPES += default -endif ifeq ($(ART_TEST_INTERPRETER_ACCESS_CHECKS),true) COMPILER_TYPES += interp-ac endif @@ -221,14 +218,9 @@ ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(RUN_TYPES), $(IMAGE_TYPES), $(PICTEST_TYPES), $(DEBUGGABLE_TYPES), $(ART_TEST_RUN_TEST_SKIP), $(ALL_ADDRESS_SIZES)) -# Disable 097-duplicate-method while investigation (broken by latest Jack release, b/27358065) # Disable 137-cfi (b/27391690). -# Disable 536-checker-needs-access-check and 537-checker-inline-and-unverified (b/27425061) # Disable 577-profile-foreign-dex (b/27454772). TEST_ART_BROKEN_ALL_TARGET_TESTS := \ - 097-duplicate-method \ - 536-checker-needs-access-check \ - 537-checker-inline-and-unverified \ 577-profile-foreign-dex \ ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(RUN_TYPES),$(PREBUILD_TYPES), \ @@ -301,9 +293,12 @@ endif TEST_ART_BROKEN_PREBUILD_RUN_TESTS := # 554-jit-profile-file is disabled because it needs a primary oat file to know what it should save. +# 529 and 555: b/27784033 TEST_ART_BROKEN_NO_PREBUILD_TESTS := \ 117-nopatchoat \ - 554-jit-profile-file + 554-jit-profile-file \ + 529-checker-unresolved \ + 555-checker-regression-x86const ifneq (,$(filter no-prebuild,$(PREBUILD_TYPES))) ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(RUN_TYPES),no-prebuild, \ @@ -474,19 +469,6 @@ endif TEST_ART_BROKEN_JIT_RUN_TESTS := -# Known broken tests for the default compiler (Quick). -TEST_ART_BROKEN_DEFAULT_RUN_TESTS := \ - 457-regs \ - 563-checker-fakestring - -ifneq (,$(filter default,$(COMPILER_TYPES))) - ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(RUN_TYPES),$(PREBUILD_TYPES), \ - default,$(RELOCATE_TYPES),$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES), \ - $(IMAGE_TYPES),$(PICTEST_TYPES),$(DEBUGGABLE_TYPES),$(TEST_ART_BROKEN_DEFAULT_RUN_TESTS),$(ALL_ADDRESS_SIZES)) -endif - -TEST_ART_BROKEN_DEFAULT_RUN_TESTS := - # Known broken tests for the mips32 optimizing compiler backend. TEST_ART_BROKEN_OPTIMIZING_MIPS_RUN_TESTS := \ 510-checker-try-catch \ @@ -541,19 +523,9 @@ endif TEST_ART_BROKEN_OPTIMIZING_DEBUGGABLE_RUN_TESTS := # Tests that should fail in the read barrier configuration with the interpreter. -# 145: Test sometimes times out in read barrier configuration (b/27467554). -TEST_ART_BROKEN_INTERPRETER_READ_BARRIER_RUN_TESTS := \ - 145-alloc-tracking-stress - -# Tests that should fail in the read barrier configuration with the default (Quick) compiler (AOT). -# Quick has no support for read barriers and punts to the interpreter, so this list is composed of -# tests expected to fail with the interpreter, both on the concurrent collector and in general. -TEST_ART_BROKEN_DEFAULT_READ_BARRIER_RUN_TESTS := \ - $(TEST_ART_BROKEN_INTERPRETER_READ_BARRIER_RUN_TESTS) \ - $(TEST_ART_BROKEN_INTERPRETER_RUN_TESTS) +TEST_ART_BROKEN_INTERPRETER_READ_BARRIER_RUN_TESTS := # Tests that should fail in the read barrier configuration with the Optimizing compiler (AOT). -# 145: Test sometimes times out in read barrier configuration (b/27467554). # 484: Baker's fast path based read barrier compiler instrumentation generates code containing # more parallel moves on x86, thus some Checker assertions may fail. # 527: On ARM64, the read barrier instrumentation does not support the HArm64IntermediateAddress @@ -561,15 +533,12 @@ TEST_ART_BROKEN_DEFAULT_READ_BARRIER_RUN_TESTS := \ # 537: Expects an array copy to be intrinsified on x86-64, but calling-on-slowpath intrinsics are # not yet handled in the read barrier configuration. TEST_ART_BROKEN_OPTIMIZING_READ_BARRIER_RUN_TESTS := \ - 145-alloc-tracking-stress \ 484-checker-register-hints \ 527-checker-array-access-split \ 537-checker-arraycopy # Tests that should fail in the read barrier configuration with JIT (Optimizing compiler). -# 145: Test sometimes times out in read barrier configuration (b/27467554). -TEST_ART_BROKEN_JIT_READ_BARRIER_RUN_TESTS := \ - 145-alloc-tracking-stress +TEST_ART_BROKEN_JIT_READ_BARRIER_RUN_TESTS := ifeq ($(ART_USE_READ_BARRIER),true) ifneq (,$(filter interpreter,$(COMPILER_TYPES))) @@ -579,13 +548,6 @@ ifeq ($(ART_USE_READ_BARRIER),true) $(TEST_ART_BROKEN_INTERPRETER_READ_BARRIER_RUN_TESTS),$(ALL_ADDRESS_SIZES)) endif - ifneq (,$(filter default,$(COMPILER_TYPES))) - ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(RUN_TYPES), \ - $(PREBUILD_TYPES),default,$(RELOCATE_TYPES),$(TRACE_TYPES),$(GC_TYPES), \ - $(JNI_TYPES),$(IMAGE_TYPES),$(PICTEST_TYPES),$(DEBUGGABLE_TYPES), \ - $(TEST_ART_BROKEN_DEFAULT_READ_BARRIER_RUN_TESTS),$(ALL_ADDRESS_SIZES)) - endif - ifneq (,$(filter optimizing,$(COMPILER_TYPES))) ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(RUN_TYPES), \ $(PREBUILD_TYPES),optimizing,$(RELOCATE_TYPES),$(TRACE_TYPES),$(GC_TYPES), \ @@ -601,30 +563,15 @@ ifeq ($(ART_USE_READ_BARRIER),true) endif endif -TEST_ART_BROKEN_DEFAULT_READ_BARRIER_RUN_TESTS := TEST_ART_BROKEN_OPTIMIZING_READ_BARRIER_RUN_TESTS := TEST_ART_BROKEN_JIT_READ_BARRIER_RUN_TESTS := -# Tests that should fail in the heap poisoning configuration with the default (Quick) compiler. -# 137: Quick has no support for read barriers and punts to the -# interpreter, but CFI unwinding expects managed frames. -# 554: Quick does not support JIT profiling. -TEST_ART_BROKEN_DEFAULT_HEAP_POISONING_RUN_TESTS := \ - 137-cfi \ - 554-jit-profile-file # Tests that should fail in the heap poisoning configuration with the Optimizing compiler. # 055: Exceeds run time limits due to heap poisoning instrumentation (on ARM and ARM64 devices). TEST_ART_BROKEN_OPTIMIZING_HEAP_POISONING_RUN_TESTS := \ 055-enum-performance ifeq ($(ART_HEAP_POISONING),true) - ifneq (,$(filter default,$(COMPILER_TYPES))) - ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(RUN_TYPES), \ - $(PREBUILD_TYPES),default,$(RELOCATE_TYPES),$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES), \ - $(IMAGE_TYPES),$(PICTEST_TYPES),$(DEBUGGABLE_TYPES), \ - $(TEST_ART_BROKEN_DEFAULT_HEAP_POISONING_RUN_TESTS),$(ALL_ADDRESS_SIZES)) - endif - ifneq (,$(filter optimizing,$(COMPILER_TYPES))) ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(RUN_TYPES), \ $(PREBUILD_TYPES),optimizing,$(RELOCATE_TYPES),$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES), \ @@ -633,7 +580,6 @@ ifeq ($(ART_HEAP_POISONING),true) endif endif -TEST_ART_BROKEN_DEFAULT_HEAP_POISONING_RUN_TESTS := TEST_ART_BROKEN_OPTIMIZING_HEAP_POISONING_RUN_TESTS := # Clear variables ahead of appending to them when defining tests. @@ -713,7 +659,7 @@ endif # Create a rule to build and run a tests following the form: # test-art-{1: host or target}-run-test-{2: debug ndebug}-{3: prebuild no-prebuild no-dex2oat}- -# {4: interpreter default optimizing jit interp-ac}- +# {4: interpreter optimizing jit interp-ac}- # {5: relocate nrelocate relocate-npatchoat}- # {6: trace or ntrace}-{7: gcstress gcverify cms}-{8: forcecopy checkjni jni}- # {9: no-image image picimage}-{10: pictest npictest}- @@ -788,16 +734,11 @@ define define-test-art-run-test test_groups += ART_RUN_TEST_$$(uc_host_or_target)_INTERPRETER_ACCESS_CHECKS_RULES run_test_options += --interpreter --verify-soft-fail else - ifeq ($(4),default) - test_groups += ART_RUN_TEST_$$(uc_host_or_target)_DEFAULT_RULES - run_test_options += --quick + ifeq ($(4),jit) + test_groups += ART_RUN_TEST_$$(uc_host_or_target)_JIT_RULES + run_test_options += --jit else - ifeq ($(4),jit) - test_groups += ART_RUN_TEST_$$(uc_host_or_target)_JIT_RULES - run_test_options += --jit - else - $$(error found $(4) expected $(COMPILER_TYPES)) - endif + $$(error found $(4) expected $(COMPILER_TYPES)) endif endif endif diff --git a/test/etc/default-build b/test/etc/default-build index 5f78496c3f..3d84821bf0 100755 --- a/test/etc/default-build +++ b/test/etc/default-build @@ -54,14 +54,20 @@ else HAS_SRC_EX=false fi +if [ -d src-dex2oat-unresolved ]; then + HAS_SRC_DEX2OAT_UNRESOLVED=true +else + HAS_SRC_DEX2OAT_UNRESOLVED=false +fi + DX_FLAGS="" SKIP_DX_MERGER="false" EXPERIMENTAL="" # Setup experimental flag mappings in a bash associative array. declare -A JACK_EXPERIMENTAL_ARGS -JACK_EXPERIMENTAL_ARGS["default-methods"]="-D jack.java.source.version=1.8" -JACK_EXPERIMENTAL_ARGS["lambdas"]="-D jack.java.source.version=1.8" +JACK_EXPERIMENTAL_ARGS["default-methods"]="-D jack.java.source.version=1.8 -D jack.android.min-api-level=24" +JACK_EXPERIMENTAL_ARGS["lambdas"]="-D jack.java.source.version=1.8 -D jack.android.min-api-level=24" while true; do if [ "x$1" = "x--dx-option" ]; then @@ -116,59 +122,80 @@ if ! [ "${HAS_SRC}" = "true" ] && ! [ "${HAS_SRC2}" = "true" ]; then SKIP_DX_MERGER="true" fi -if [ ${USE_JACK} = "true" ]; then - # Jack toolchain - if [ "${HAS_SRC}" = "true" ]; then - if [ "${HAS_SRC_MULTIDEX}" = "true" ]; then - # Compile src and src-multidex in the same .jack file. We will apply multidex partitioning - # when creating the output .dex file. - ${JACK} ${JACK_ARGS} --output-jack src.jack src src src-multidex - jack_extra_args="${jack_extra_args} -D jack.dex.output.policy=minimal-multidex" - jack_extra_args="${jack_extra_args} -D jack.preprocessor=true" - jack_extra_args="${jack_extra_args} -D jack.preprocessor.file=multidex.jpp" - else - ${JACK} ${JACK_ARGS} --output-jack src.jack src +if [ ${HAS_SRC_DEX2OAT_UNRESOLVED} = "true" ]; then + mkdir classes + mkdir classes-ex + ${JAVAC} ${JAVAC_ARGS} -implicit:none -sourcepath src-dex2oat-unresolved -d classes `find src -name '*.java'` + ${JAVAC} ${JAVAC_ARGS} -implicit:none -sourcepath src -d classes-ex `find src-dex2oat-unresolved -name '*.java'` + if [ ${USE_JACK} = "true" ]; then + jar cf classes.jill.jar -C classes . + jar cf classes-ex.jill.jar -C classes-ex . + + ${JACK} --import classes-ex.jill.jar --output-dex . + zip ${TEST_NAME}-ex.jar classes.dex + ${JACK} --import classes.jill.jar --output-dex . + else + if [ ${NEED_DEX} = "true" ]; then + ${DX} -JXmx256m --debug --dex --dump-to=classes-ex.lst --output=classes.dex --dump-width=1000 classes-ex + zip ${TEST_NAME}-ex.jar classes.dex + ${DX} -JXmx256m --debug --dex --dump-to=classes.lst --output=classes.dex --dump-width=1000 classes fi - jack_extra_args="${jack_extra_args} --import src.jack" fi +else + if [ ${USE_JACK} = "true" ]; then + # Jack toolchain + if [ "${HAS_SRC}" = "true" ]; then + if [ "${HAS_SRC_MULTIDEX}" = "true" ]; then + # Compile src and src-multidex in the same .jack file. We will apply multidex partitioning + # when creating the output .dex file. + ${JACK} ${JACK_ARGS} --output-jack src.jack src src src-multidex + jack_extra_args="${jack_extra_args} -D jack.dex.output.policy=minimal-multidex" + jack_extra_args="${jack_extra_args} -D jack.preprocessor=true" + jack_extra_args="${jack_extra_args} -D jack.preprocessor.file=multidex.jpp" + else + ${JACK} ${JACK_ARGS} --output-jack src.jack src + fi + jack_extra_args="${jack_extra_args} --import src.jack" + fi - if [ "${HAS_SRC2}" = "true" ]; then - ${JACK} ${JACK_ARGS} --output-jack src2.jack src2 - # In case of duplicate classes, we want to take into account the classes from src2. Therefore - # we apply the 'keep-first' policy and import src2.jack file *before* the src.jack file. - jack_extra_args="${jack_extra_args} -D jack.import.type.policy=keep-first" - jack_extra_args="--import src2.jack ${jack_extra_args}" - fi + if [ "${HAS_SRC2}" = "true" ]; then + ${JACK} ${JACK_ARGS} --output-jack src2.jack src2 + # In case of duplicate classes, we want to take into account the classes from src2. Therefore + # we apply the 'keep-first' policy and import src2.jack file *before* the src.jack file. + jack_extra_args="${jack_extra_args} -D jack.import.type.policy=keep-first" + jack_extra_args="--import src2.jack ${jack_extra_args}" + fi - # Compile jack files into a DEX file. - if [ "${HAS_SRC}" = "true" ] || [ "${HAS_SRC2}" = "true" ]; then - ${JACK} ${JACK_ARGS} ${jack_extra_args} --output-dex . - fi -else - # Legacy toolchain with javac+dx - if [ "${HAS_SRC}" = "true" ]; then - mkdir classes - ${JAVAC} ${JAVAC_ARGS} -implicit:none -classpath src-multidex -d classes `find src -name '*.java'` - fi + # Compile jack files into a DEX file. + if [ "${HAS_SRC}" = "true" ] || [ "${HAS_SRC2}" = "true" ]; then + ${JACK} ${JACK_ARGS} ${jack_extra_args} --output-dex . + fi + else + # Legacy toolchain with javac+dx + if [ "${HAS_SRC}" = "true" ]; then + mkdir classes + ${JAVAC} ${JAVAC_ARGS} -implicit:none -classpath src-multidex -d classes `find src -name '*.java'` + fi - if [ "${HAS_SRC_MULTIDEX}" = "true" ]; then - mkdir classes2 - ${JAVAC} -implicit:none -classpath src -d classes2 `find src-multidex -name '*.java'` - if [ ${NEED_DEX} = "true" ]; then - ${DX} -JXmx256m --debug --dex --dump-to=classes2.lst --output=classes2.dex \ - --dump-width=1000 ${DX_FLAGS} classes2 + if [ "${HAS_SRC_MULTIDEX}" = "true" ]; then + mkdir classes2 + ${JAVAC} -implicit:none -classpath src -d classes2 `find src-multidex -name '*.java'` + if [ ${NEED_DEX} = "true" ]; then + ${DX} -JXmx256m --debug --dex --dump-to=classes2.lst --output=classes2.dex \ + --dump-width=1000 ${DX_FLAGS} classes2 + fi fi - fi - if [ "${HAS_SRC2}" = "true" ]; then - mkdir -p classes - ${JAVAC} ${JAVAC_ARGS} -d classes `find src2 -name '*.java'` - fi + if [ "${HAS_SRC2}" = "true" ]; then + mkdir -p classes + ${JAVAC} ${JAVAC_ARGS} -d classes `find src2 -name '*.java'` + fi - if [ "${HAS_SRC}" = "true" ] || [ "${HAS_SRC2}" = "true" ]; then - if [ ${NEED_DEX} = "true" -a ${SKIP_DX_MERGER} = "false" ]; then - ${DX} -JXmx256m --debug --dex --dump-to=classes.lst --output=classes.dex \ - --dump-width=1000 ${DX_FLAGS} classes + if [ "${HAS_SRC}" = "true" ] || [ "${HAS_SRC2}" = "true" ]; then + if [ ${NEED_DEX} = "true" -a ${SKIP_DX_MERGER} = "false" ]; then + ${DX} -JXmx256m --debug --dex --dump-to=classes.lst --output=classes.dex \ + --dump-width=1000 ${DX_FLAGS} classes + fi fi fi fi diff --git a/test/etc/run-test-jar b/test/etc/run-test-jar index 2db1e6c947..d13d990700 100755 --- a/test/etc/run-test-jar +++ b/test/etc/run-test-jar @@ -66,6 +66,10 @@ while true; do fi LIB="$1" shift + elif [ "x$1" = "x--gc-stress" ]; then + # Give an extra 5 mins if we are gc-stress. + TIME_OUT_VALUE=$((${TIME_OUT_VALUE} + 300)) + shift elif [ "x$1" = "x--testlib" ]; then shift if [ "x$1" = "x" ]; then @@ -329,9 +333,17 @@ if [ "$JIT" = "y" ]; then INT_OPTS="-Xusejit:true" if [ "$VERIFY" = "y" ] ; then COMPILE_FLAGS="${COMPILE_FLAGS} --compiler-filter=verify-at-runtime" + if [ "$PREBUILD" = "n" ]; then + # Make sure that if we have noprebuild we still JIT as DexClassLoader will + # try to compile the dex file. + INT_OPTS="${INT_OPTS} -Xcompiler-option --compiler-filter=verify-at-runtime" + fi else COMPILE_FLAGS="${COMPILE_FLAGS} --compiler-filter=verify-none" DEX_VERIFY="${DEX_VERIFY} -Xverify:none" + if [ "$PREBUILD" = "n" ]; then + INT_OPTS="${INT_OPTS} -Xcompiler-option --compiler-filter=verify-none" + fi fi fi diff --git a/test/run-all-tests b/test/run-all-tests index 6d5c28c7e0..402c299b55 100755 --- a/test/run-all-tests +++ b/test/run-all-tests @@ -47,9 +47,6 @@ while true; do elif [ "x$1" = "x--no-image" ]; then run_args="${run_args} --no-image" shift - elif [ "x$1" = "x--quick" ]; then - run_args="${run_args} --quick" - shift elif [ "x$1" = "x--optimizing" ]; then run_args="${run_args} --optimizing" shift @@ -181,7 +178,7 @@ if [ "$usage" = "yes" ]; then echo " --trace --no-patchoat --no-dex2oat --use-java-home --pic-image" echo " --pic-test --strace --debuggable --dalvik --dex2oat-swap" echo " --build-only --build-with-jack --build-with-javac-dx" - echo " --never-clean --image --no-image --quick --optimizing" + echo " --never-clean --image --no-image --optimizing" echo " --no-relocate --no-prebuild" echo " Specific Runtime Options:" echo " --seq Run tests one-by-one, avoiding failures caused by busy CPU" diff --git a/test/run-test b/test/run-test index d0f93b9231..01464cd6b6 100755 --- a/test/run-test +++ b/test/run-test @@ -45,7 +45,7 @@ export JAVAC="javac -g -source 1.7 -target 1.7 -Xlint:-options" export RUN="${progdir}/etc/run-test-jar" export DEX_LOCATION=/data/run-test/${test_dir} export NEED_DEX="true" -export USE_JACK="false" +export USE_JACK="true" export SMALI_ARGS="--experimental --api-level 23" # If dx was not set by the environment variable, assume it is in the path. @@ -73,11 +73,6 @@ if [ -z "$JACK" ]; then export JACK="jack" fi -# If the tree is compiled with Jack, build test with Jack by default. -if [ "$ANDROID_COMPILE_WITH_JACK" = "true" ]; then - USE_JACK="true" -fi - # ANDROID_BUILD_TOP is not set in a build environment. if [ -z "$ANDROID_BUILD_TOP" ]; then export ANDROID_BUILD_TOP=$oldwd @@ -246,25 +241,22 @@ while true; do run_args="${run_args} --zygote" shift elif [ "x$1" = "x--interpreter" ]; then - run_args="${run_args} --interpreter" + run_args="${run_args} --interpreter --runtime-option -XOatFileManagerCompilerFilter:verify-at-runtime" image_suffix="-interpreter" shift elif [ "x$1" = "x--jit" ]; then - run_args="${run_args} --jit" + run_args="${run_args} --jit --runtime-option -XOatFileManagerCompilerFilter:verify-at-runtime" image_suffix="-jit" shift elif [ "x$1" = "x--optimizing" ]; then run_args="${run_args} -Xcompiler-option --compiler-backend=Optimizing" image_suffix="-optimizing" shift - elif [ "x$1" = "x--quick" ]; then - run_args="${run_args} -Xcompiler-option --compiler-backend=Quick" - shift elif [ "x$1" = "x--no-verify" ]; then - run_args="${run_args} --no-verify" + run_args="${run_args} --no-verify --runtime-option -XOatFileManagerCompilerFilter:verify-none" shift elif [ "x$1" = "x--verify-soft-fail" ]; then - run_args="${run_args} --verify-soft-fail" + run_args="${run_args} --verify-soft-fail --runtime-option -XOatFileManagerCompilerFilter:verify-at-runtime" image_suffix="-interp-ac" shift elif [ "x$1" = "x--no-optimize" ]; then @@ -394,7 +386,7 @@ if [ "$gc_verify" = "true" ]; then run_args="${run_args} --runtime-option -Xgc:preverify_rosalloc --runtime-option -Xgc:postverify_rosalloc" fi if [ "$gc_stress" = "true" ]; then - run_args="${run_args} --runtime-option -Xgc:SS,gcstress --runtime-option -Xms2m --runtime-option -Xmx16m" + run_args="${run_args} --gc-stress --runtime-option -Xgc:SS,gcstress --runtime-option -Xms2m --runtime-option -Xmx16m" fi if [ "$trace" = "true" ]; then run_args="${run_args} --runtime-option -Xmethod-trace --runtime-option -Xmethod-trace-file-size:2000000" @@ -565,7 +557,6 @@ if [ "$usage" = "yes" ]; then echo " --interpreter Enable interpreter only mode (off by default)." echo " --jit Enable jit (off by default)." echo " --optimizing Enable optimizing compiler (default)." - echo " --quick Use Quick compiler (off by default)." echo " --no-verify Turn off verification (on by default)." echo " --verify-soft-fail Force soft fail verification (off by default)." echo " Verification is enabled if neither --no-verify" |