diff options
Diffstat (limited to 'test')
21 files changed, 582 insertions, 48 deletions
diff --git a/test/082-inline-execute/src/Main.java b/test/082-inline-execute/src/Main.java index 0e90c4d6a2..4dfa73cbaf 100644 --- a/test/082-inline-execute/src/Main.java +++ b/test/082-inline-execute/src/Main.java @@ -236,15 +236,6 @@ public class Main { String str10 = "abcdefghij"; String str40 = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabc"; - int supplementaryChar = 0x20b9f; - String surrogatePair = "\ud842\udf9f"; - String stringWithSurrogates = "hello " + surrogatePair + " world"; - - Assert.assertEquals(stringWithSurrogates.indexOf(supplementaryChar), "hello ".length()); - Assert.assertEquals(stringWithSurrogates.indexOf(supplementaryChar, 2), "hello ".length()); - Assert.assertEquals(stringWithSurrogates.indexOf(supplementaryChar, 6), 6); - Assert.assertEquals(stringWithSurrogates.indexOf(supplementaryChar, 7), -1); - Assert.assertEquals(str0.indexOf('a'), -1); Assert.assertEquals(str3.indexOf('a'), 0); Assert.assertEquals(str3.indexOf('b'), 1); @@ -269,24 +260,123 @@ public class Main { Assert.assertEquals(str40.indexOf('a',10), 10); Assert.assertEquals(str40.indexOf('b',40), -1); + testIndexOfNull(); + + // Same data as above, but stored so it's not a literal in the next test. -2 stands for + // indexOf(I) instead of indexOf(II). + start--; + int[][] searchData = { + { 'a', -2, -1 }, + { 'a', -2, 0 }, + { 'b', -2, 1 }, + { 'c', -2, 2 }, + { 'j', -2, 9 }, + { 'a', -2, 0 }, + { 'b', -2, 38 }, + { 'c', -2, 39 }, + { 'a', 20, -1 }, + { 'a', 0, -1 }, + { 'a', -1, -1 }, + { '/', ++start, -1 }, + { 'a', negIndex[0], -1 }, + { 'a', 0, 0 }, + { 'a', 1, -1 }, + { 'a', 1234, -1 }, + { 'b', 0, 1 }, + { 'b', 1, 1 }, + { 'c', 2, 2 }, + { 'j', 5, 9 }, + { 'j', 9, 9 }, + { 'a', 10, 10 }, + { 'b', 40, -1 }, + }; + testStringIndexOfChars(searchData); + + testSurrogateIndexOf(); + } + + private static void testStringIndexOfChars(int[][] searchData) { + // Use a try-catch to avoid inlining. + try { + testStringIndexOfCharsImpl(searchData); + } catch (Exception e) { + System.out.println("Unexpected exception"); + } + } + + private static void testStringIndexOfCharsImpl(int[][] searchData) { + String str0 = ""; + String str1 = "/"; + String str3 = "abc"; + String str10 = "abcdefghij"; + String str40 = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabc"; + + Assert.assertEquals(str0.indexOf(searchData[0][0]), searchData[0][2]); + Assert.assertEquals(str3.indexOf(searchData[1][0]), searchData[1][2]); + Assert.assertEquals(str3.indexOf(searchData[2][0]), searchData[2][2]); + Assert.assertEquals(str3.indexOf(searchData[3][0]), searchData[3][2]); + Assert.assertEquals(str10.indexOf(searchData[4][0]), searchData[4][2]); + Assert.assertEquals(str40.indexOf(searchData[5][0]), searchData[5][2]); + Assert.assertEquals(str40.indexOf(searchData[6][0]), searchData[6][2]); + Assert.assertEquals(str40.indexOf(searchData[7][0]), searchData[7][2]); + Assert.assertEquals(str0.indexOf(searchData[8][0], searchData[8][1]), searchData[8][2]); + Assert.assertEquals(str0.indexOf(searchData[9][0], searchData[9][1]), searchData[9][2]); + Assert.assertEquals(str0.indexOf(searchData[10][0], searchData[10][1]), searchData[10][2]); + Assert.assertEquals(str1.indexOf(searchData[11][0], searchData[11][1]), searchData[11][2]); + Assert.assertEquals(str1.indexOf(searchData[12][0], searchData[12][1]), searchData[12][2]); + Assert.assertEquals(str3.indexOf(searchData[13][0], searchData[13][1]), searchData[13][2]); + Assert.assertEquals(str3.indexOf(searchData[14][0], searchData[14][1]), searchData[14][2]); + Assert.assertEquals(str3.indexOf(searchData[15][0], searchData[15][1]), searchData[15][2]); + Assert.assertEquals(str3.indexOf(searchData[16][0], searchData[16][1]), searchData[16][2]); + Assert.assertEquals(str3.indexOf(searchData[17][0], searchData[17][1]), searchData[17][2]); + Assert.assertEquals(str3.indexOf(searchData[18][0], searchData[18][1]), searchData[18][2]); + Assert.assertEquals(str10.indexOf(searchData[19][0], searchData[19][1]), searchData[19][2]); + Assert.assertEquals(str10.indexOf(searchData[20][0], searchData[20][1]), searchData[20][2]); + Assert.assertEquals(str40.indexOf(searchData[21][0], searchData[21][1]), searchData[21][2]); + Assert.assertEquals(str40.indexOf(searchData[22][0], searchData[22][1]), searchData[22][2]); + } + + private static void testSurrogateIndexOf() { + int supplementaryChar = 0x20b9f; + String surrogatePair = "\ud842\udf9f"; + String stringWithSurrogates = "hello " + surrogatePair + " world"; + + Assert.assertEquals(stringWithSurrogates.indexOf(supplementaryChar), "hello ".length()); + Assert.assertEquals(stringWithSurrogates.indexOf(supplementaryChar, 2), "hello ".length()); + Assert.assertEquals(stringWithSurrogates.indexOf(supplementaryChar, 6), 6); + Assert.assertEquals(stringWithSurrogates.indexOf(supplementaryChar, 7), -1); + + Assert.assertEquals(stringWithSurrogates.indexOf(supplementaryChar - 0x10000), -1); + Assert.assertEquals(stringWithSurrogates.indexOf(supplementaryChar | 0x80000000), -1); + } + + private static void testIndexOfNull() { String strNull = null; try { - strNull.indexOf('a'); + testNullIndex(strNull, 'a'); Assert.fail(); } catch (NullPointerException expected) { } try { - strNull.indexOf('a', 0); + testNullIndex(strNull, 'a', 0); Assert.fail(); } catch (NullPointerException expected) { } try { - strNull.indexOf('a', -1); + testNullIndex(strNull, 'a', -1); Assert.fail(); } catch (NullPointerException expected) { } } + private static int testNullIndex(String strNull, int c) { + return strNull.indexOf(c); + } + + private static int testNullIndex(String strNull, int c, int startIndex) { + return strNull.indexOf(c, startIndex); + } + public static void test_String_compareTo() { String test = "0123456789"; String test1 = new String("0123456789"); // different object diff --git a/test/127-secondarydex/expected.txt b/test/127-secondarydex/expected.txt index 29a1411ad3..1c8defb6ec 100644 --- a/test/127-secondarydex/expected.txt +++ b/test/127-secondarydex/expected.txt @@ -1,3 +1,4 @@ testSlowPathDirectInvoke Test Got null pointer exception +Test diff --git a/test/127-secondarydex/src/Main.java b/test/127-secondarydex/src/Main.java index c921c5b0c8..0ede8ed2b2 100644 --- a/test/127-secondarydex/src/Main.java +++ b/test/127-secondarydex/src/Main.java @@ -24,6 +24,7 @@ import java.lang.reflect.Method; public class Main { public static void main(String[] args) { testSlowPathDirectInvoke(); + testString(); } public static void testSlowPathDirectInvoke() { @@ -40,4 +41,11 @@ public class Main { System.out.println("Got unexpected exception " + e); } } + + // For string change, test that String.<init> is compiled properly in + // secondary dex. See http://b/20870917 + public static void testString() { + Test t = new Test(); + System.out.println(t.toString()); + } } diff --git a/test/127-secondarydex/src/Test.java b/test/127-secondarydex/src/Test.java index 82cb901374..8547e791c2 100644 --- a/test/127-secondarydex/src/Test.java +++ b/test/127-secondarydex/src/Test.java @@ -22,4 +22,8 @@ public class Test extends Super { private void print() { System.out.println("Test"); } + + public String toString() { + return new String("Test"); + } } diff --git a/test/431-optimizing-arith-shifts/src/Main.java b/test/431-optimizing-arith-shifts/src/Main.java index d8667c63c5..86422bd8e7 100644 --- a/test/431-optimizing-arith-shifts/src/Main.java +++ b/test/431-optimizing-arith-shifts/src/Main.java @@ -52,7 +52,7 @@ public class Main { expectEquals(Integer.MIN_VALUE, $opt$Shl(1073741824, 1)); // overflow expectEquals(1073741824, $opt$Shl(268435456, 2)); - // othe nly 5 lower bits should be used for shifting (& 0x1f). + // 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 @@ -97,6 +97,13 @@ public class Main { expectEquals(Long.MIN_VALUE, $opt$Shl(7L, Long.MAX_VALUE)); expectEquals(7L, $opt$Shl(7L, Long.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)); } private static void shrInt() { @@ -277,7 +284,7 @@ public class Main { return a >>> 2L; } - static int $opt$ShlConst0(int a) { + static int $opt$ShlConst0(int a) { return a << 0; } @@ -301,5 +308,25 @@ public class Main { return a >>> 0L; } + static long $opt$ShlConst1(long a) { + return a << 1L; + } + + static long $opt$ShlConst32(long a) { + return a << 32L; + } + + static long $opt$ShlConst33(long a) { + return a << 33L; + } + + static long $opt$ShlConst34(long a) { + return a << 34L; + } + + static long $opt$ShlConst35(long a) { + return a << 35L; + } + } diff --git a/test/442-checker-constant-folding/src/Main.java b/test/442-checker-constant-folding/src/Main.java index 6b21fed66c..c89ab4dffe 100644 --- a/test/442-checker-constant-folding/src/Main.java +++ b/test/442-checker-constant-folding/src/Main.java @@ -16,6 +16,12 @@ public class Main { + public static void assertFalse(boolean condition) { + if (condition) { + throw new Error(); + } + } + public static void assertIntEquals(int expected, int result) { if (expected != result) { throw new Error("Expected: " + expected + ", found: " + result); @@ -407,6 +413,54 @@ public class Main { return arg ^ arg; } + // CHECK-START: boolean Main.CmpFloatGreaterThanNaN(float) constant_folding (before) + // CHECK-DAG: [[Arg:f\d+]] ParameterValue + // CHECK-DAG: [[ConstNan:f\d+]] FloatConstant nan + // CHECK-DAG: [[Const0:i\d+]] IntConstant 0 + // CHECK-DAG: IntConstant 1 + // CHECK-DAG: [[Cmp:i\d+]] Compare [ [[Arg]] [[ConstNan]] ] + // CHECK-DAG: [[Le:z\d+]] LessThanOrEqual [ [[Cmp]] [[Const0]] ] + // CHECK-DAG: If [ [[Le]] ] + + // CHECK-START: boolean Main.CmpFloatGreaterThanNaN(float) constant_folding (after) + // CHECK-DAG: ParameterValue + // CHECK-DAG: FloatConstant nan + // CHECK-DAG: IntConstant 0 + // CHECK-DAG: [[Const1:i\d+]] IntConstant 1 + // CHECK-DAG: If [ [[Const1]] ] + + // CHECK-START: boolean Main.CmpFloatGreaterThanNaN(float) constant_folding (after) + // CHECK-NOT: Compare + // CHECK-NOT: LessThanOrEqual + + public static boolean CmpFloatGreaterThanNaN(float arg) { + return arg > Float.NaN; + } + + // CHECK-START: boolean Main.CmpDoubleLessThanNaN(double) constant_folding (before) + // CHECK-DAG: [[Arg:d\d+]] ParameterValue + // CHECK-DAG: [[ConstNan:d\d+]] DoubleConstant nan + // CHECK-DAG: [[Const0:i\d+]] IntConstant 0 + // CHECK-DAG: IntConstant 1 + // CHECK-DAG: [[Cmp:i\d+]] Compare [ [[Arg]] [[ConstNan]] ] + // CHECK-DAG: [[Ge:z\d+]] GreaterThanOrEqual [ [[Cmp]] [[Const0]] ] + // CHECK-DAG: If [ [[Ge]] ] + + // CHECK-START: boolean Main.CmpDoubleLessThanNaN(double) constant_folding (after) + // CHECK-DAG: ParameterValue + // CHECK-DAG: DoubleConstant nan + // CHECK-DAG: IntConstant 0 + // CHECK-DAG: [[Const1:i\d+]] IntConstant 1 + // CHECK-DAG: If [ [[Const1]] ] + + // CHECK-START: boolean Main.CmpDoubleLessThanNaN(double) constant_folding (after) + // CHECK-NOT: Compare + // CHECK-NOT: GreaterThanOrEqual + + public static boolean CmpDoubleLessThanNaN(double arg) { + return arg < Double.NaN; + } + public static void main(String[] args) { assertIntEquals(IntNegation(), -42); assertIntEquals(IntAddition1(), 3); @@ -417,17 +471,19 @@ public class Main { assertIntEquals(StaticCondition(), 5); assertIntEquals(JumpsAndConditionals(true), 7); assertIntEquals(JumpsAndConditionals(false), 3); - int random = 123456; // Chosen randomly. - assertIntEquals(And0(random), 0); - assertLongEquals(Mul0(random), 0); - assertIntEquals(OrAllOnes(random), -1); - assertLongEquals(Rem0(random), 0); - assertIntEquals(Rem1(random), 0); - assertLongEquals(RemN1(random), 0); - assertIntEquals(Shl0(random), 0); - assertLongEquals(Shr0(random), 0); - assertLongEquals(SubSameLong(random), 0); - assertIntEquals(UShr0(random), 0); - assertIntEquals(XorSameInt(random), 0); + int arbitrary = 123456; // Value chosen arbitrarily. + assertIntEquals(And0(arbitrary), 0); + assertLongEquals(Mul0(arbitrary), 0); + assertIntEquals(OrAllOnes(arbitrary), -1); + assertLongEquals(Rem0(arbitrary), 0); + assertIntEquals(Rem1(arbitrary), 0); + assertLongEquals(RemN1(arbitrary), 0); + assertIntEquals(Shl0(arbitrary), 0); + assertLongEquals(Shr0(arbitrary), 0); + assertLongEquals(SubSameLong(arbitrary), 0); + assertIntEquals(UShr0(arbitrary), 0); + assertIntEquals(XorSameInt(arbitrary), 0); + assertFalse(CmpFloatGreaterThanNaN(arbitrary)); + assertFalse(CmpDoubleLessThanNaN(arbitrary)); } } diff --git a/test/454-get-vreg/get_vreg_jni.cc b/test/454-get-vreg/get_vreg_jni.cc index 6b4bc11086..0ef2964e35 100644 --- a/test/454-get-vreg/get_vreg_jni.cc +++ b/test/454-get-vreg/get_vreg_jni.cc @@ -29,7 +29,9 @@ class TestVisitor : public StackVisitor { public: TestVisitor(Thread* thread, Context* context, mirror::Object* this_value) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) - : StackVisitor(thread, context), this_value_(this_value), found_method_index_(0) {} + : StackVisitor(thread, context, StackVisitor::StackWalkKind::kIncludeInlinedFrames), + this_value_(this_value), + found_method_index_(0) {} bool VisitFrame() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { mirror::ArtMethod* m = GetMethod(); diff --git a/test/455-set-vreg/set_vreg_jni.cc b/test/455-set-vreg/set_vreg_jni.cc index 0a83ac0738..dffbfa47d8 100644 --- a/test/455-set-vreg/set_vreg_jni.cc +++ b/test/455-set-vreg/set_vreg_jni.cc @@ -29,7 +29,8 @@ class TestVisitor : public StackVisitor { public: TestVisitor(Thread* thread, Context* context, mirror::Object* this_value) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) - : StackVisitor(thread, context), this_value_(this_value) {} + : StackVisitor(thread, context, StackVisitor::StackWalkKind::kIncludeInlinedFrames), + this_value_(this_value) {} bool VisitFrame() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { mirror::ArtMethod* m = GetMethod(); diff --git a/test/457-regs/regs_jni.cc b/test/457-regs/regs_jni.cc index 1b32348e25..193ab9dc4e 100644 --- a/test/457-regs/regs_jni.cc +++ b/test/457-regs/regs_jni.cc @@ -29,7 +29,7 @@ class TestVisitor : public StackVisitor { public: TestVisitor(Thread* thread, Context* context) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) - : StackVisitor(thread, context) {} + : StackVisitor(thread, context, StackVisitor::StackWalkKind::kIncludeInlinedFrames) {} bool VisitFrame() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { mirror::ArtMethod* m = GetMethod(); diff --git a/test/458-checker-instruction-simplification/src/Main.java b/test/458-checker-instruction-simplification/src/Main.java index 5d5a6b3627..efb7b83e33 100644 --- a/test/458-checker-instruction-simplification/src/Main.java +++ b/test/458-checker-instruction-simplification/src/Main.java @@ -223,6 +223,24 @@ public class Main { return arg << 0; } + // CHECK-START: int Main.Shl1(int) instruction_simplifier (before) + // CHECK-DAG: [[Arg:i\d+]] ParameterValue + // CHECK-DAG: [[Const1:i\d+]] IntConstant 1 + // CHECK-DAG: [[Shl:i\d+]] Shl [ [[Arg]] [[Const1]] ] + // CHECK-DAG: Return [ [[Shl]] ] + + // CHECK-START: int Main.Shl1(int) instruction_simplifier (after) + // CHECK-DAG: [[Arg:i\d+]] ParameterValue + // CHECK-DAG: [[Add:i\d+]] Add [ [[Arg]] [[Arg]] ] + // CHECK-DAG: Return [ [[Add]] ] + + // CHECK-START: int Main.Shl1(int) instruction_simplifier (after) + // CHECK-NOT: Shl + + public static int Shl1(int arg) { + return arg << 1; + } + // CHECK-START: long Main.Shr0(long) instruction_simplifier (before) // CHECK-DAG: [[Arg:j\d+]] ParameterValue // CHECK-DAG: [[Const0:i\d+]] IntConstant 0 @@ -1060,5 +1078,6 @@ public class Main { assertDoubleEquals(Div2(150.0), 75.0); assertFloatEquals(DivMP25(100.0f), -400.0f); assertDoubleEquals(DivMP25(150.0), -600.0); + assertLongEquals(Shl1(100), 200); } } diff --git a/test/461-get-reference-vreg/get_reference_vreg_jni.cc b/test/461-get-reference-vreg/get_reference_vreg_jni.cc index f0b78e1f5e..a8ef684e93 100644 --- a/test/461-get-reference-vreg/get_reference_vreg_jni.cc +++ b/test/461-get-reference-vreg/get_reference_vreg_jni.cc @@ -29,7 +29,9 @@ class TestVisitor : public StackVisitor { public: TestVisitor(Thread* thread, Context* context, mirror::Object* this_value) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) - : StackVisitor(thread, context), this_value_(this_value), found_method_index_(0) {} + : StackVisitor(thread, context, StackVisitor::StackWalkKind::kIncludeInlinedFrames), + this_value_(this_value), + found_method_index_(0) {} bool VisitFrame() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { mirror::ArtMethod* m = GetMethod(); diff --git a/test/466-get-live-vreg/get_live_vreg_jni.cc b/test/466-get-live-vreg/get_live_vreg_jni.cc index 6715ba17e6..4724e8ebe4 100644 --- a/test/466-get-live-vreg/get_live_vreg_jni.cc +++ b/test/466-get-live-vreg/get_live_vreg_jni.cc @@ -28,7 +28,7 @@ namespace { class TestVisitor : public StackVisitor { public: TestVisitor(Thread* thread, Context* context) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) - : StackVisitor(thread, context) {} + : StackVisitor(thread, context, StackVisitor::StackWalkKind::kIncludeInlinedFrames) {} bool VisitFrame() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { mirror::ArtMethod* m = GetMethod(); diff --git a/test/468-checker-bool-simplifier-regression/smali/TestCase.smali b/test/468-checker-bool-simplifier-regression/smali/TestCase.smali index f36304d333..6ff43910d5 100644 --- a/test/468-checker-bool-simplifier-regression/smali/TestCase.smali +++ b/test/468-checker-bool-simplifier-regression/smali/TestCase.smali @@ -18,6 +18,19 @@ .field public static value:Z +# CHECK-START: boolean TestCase.testCase() boolean_simplifier (before) +# CHECK-DAG: [[Const0:i\d+]] IntConstant 0 +# CHECK-DAG: [[Const1:i\d+]] IntConstant 1 +# CHECK-DAG: [[Value:z\d+]] StaticFieldGet +# CHECK-DAG: If [ [[Value]] ] +# CHECK-DAG: [[Phi:i\d+]] Phi [ [[Const1]] [[Const0]] ] +# CHECK-DAG: Return [ [[Phi]] ] + +# CHECK-START: boolean TestCase.testCase() boolean_simplifier (after) +# CHECK-DAG: [[Value:z\d+]] StaticFieldGet +# CHECK-DAG: [[Not:z\d+]] BooleanNot [ [[Value]] ] +# CHECK-DAG: Return [ [[Not]] ] + .method public static testCase()Z .registers 2 sget-boolean v0, LTestCase;->value:Z diff --git a/test/468-checker-bool-simplifier-regression/src/Main.java b/test/468-checker-bool-simplifier-regression/src/Main.java index d45f3bfa16..8fe05c7a8a 100644 --- a/test/468-checker-bool-simplifier-regression/src/Main.java +++ b/test/468-checker-bool-simplifier-regression/src/Main.java @@ -18,19 +18,6 @@ import java.lang.reflect.*; public class Main { - // CHECK-START: boolean TestCase.testCase() boolean_simplifier (before) - // CHECK-DAG: [[Const0:i\d+]] IntConstant 0 - // CHECK-DAG: [[Const1:i\d+]] IntConstant 1 - // CHECK-DAG: [[Value:z\d+]] StaticFieldGet - // CHECK-DAG: If [ [[Value]] ] - // CHECK-DAG: [[Phi:i\d+]] Phi [ [[Const1]] [[Const0]] ] - // CHECK-DAG: Return [ [[Phi]] ] - - // CHECK-START: boolean TestCase.testCase() boolean_simplifier (after) - // CHECK-DAG: [[Value:z\d+]] StaticFieldGet - // CHECK-DAG: [[Not:z\d+]] BooleanNot [ [[Value]] ] - // CHECK-DAG: Return [ [[Not]] ] - public static boolean runTest(boolean input) throws Exception { Class<?> c = Class.forName("TestCase"); Method m = c.getMethod("testCase"); diff --git a/test/485-checker-dce-loop-update/expected.txt b/test/485-checker-dce-loop-update/expected.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/485-checker-dce-loop-update/expected.txt diff --git a/test/485-checker-dce-loop-update/info.txt b/test/485-checker-dce-loop-update/info.txt new file mode 100644 index 0000000000..fccf10cc8e --- /dev/null +++ b/test/485-checker-dce-loop-update/info.txt @@ -0,0 +1,2 @@ +Tests loop information update after DCE because block removal can disconnect loops, leaving other +live blocks outside the loop they had been a member of.
\ No newline at end of file diff --git a/test/485-checker-dce-loop-update/smali/TestCase.smali b/test/485-checker-dce-loop-update/smali/TestCase.smali new file mode 100644 index 0000000000..3873ac50c7 --- /dev/null +++ b/test/485-checker-dce-loop-update/smali/TestCase.smali @@ -0,0 +1,275 @@ +# 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. + +.class public LTestCase; + +.super Ljava/lang/Object; + +.method public static $inline$True()Z + .registers 1 + const/4 v0, 1 + return v0 +.end method + + +# CHECK-START: int TestCase.testSingleExit(int, boolean) dead_code_elimination_final (before) +# CHECK-DAG: [[ArgX:i\d+]] ParameterValue +# CHECK-DAG: [[ArgY:z\d+]] ParameterValue +# CHECK-DAG: [[Cst1:i\d+]] IntConstant 1 +# CHECK-DAG: [[Cst5:i\d+]] IntConstant 5 +# CHECK-DAG: [[Cst7:i\d+]] IntConstant 7 +# CHECK-DAG: [[PhiX:i\d+]] Phi [ [[ArgX]] [[Add5:i\d+]] [[Add7:i\d+]] ] loop_header:[[HeaderY:B\d+]] +# CHECK-DAG: If [ [[ArgY]] ] loop_header:[[HeaderY]] +# CHECK-DAG: If [ [[Cst1]] ] loop_header:[[HeaderY]] +# CHECK-DAG: [[Add5]] Add [ [[PhiX]] [[Cst5]] ] loop_header:[[HeaderY]] +# CHECK-DAG: [[Add7]] Add [ [[PhiX]] [[Cst7]] ] loop_header:[[HeaderY]] +# CHECK-DAG: Return [ [[PhiX]] ] loop_header:null + +# CHECK-START: int TestCase.testSingleExit(int, boolean) dead_code_elimination_final (after) +# CHECK-DAG: [[ArgX:i\d+]] ParameterValue +# CHECK-DAG: [[ArgY:z\d+]] ParameterValue +# CHECK-DAG: [[Cst7:i\d+]] IntConstant 7 +# CHECK-DAG: [[PhiX:i\d+]] Phi [ [[ArgX]] [[AddX:i\d+]] ] loop_header:[[HeaderY:B\d+]] +# CHECK-DAG: If [ [[ArgY]] ] loop_header:[[HeaderY]] +# CHECK-DAG: [[AddX]] Add [ [[PhiX]] [[Cst7]] ] loop_header:[[HeaderY]] +# CHECK-DAG: Return [ [[PhiX]] ] loop_header:null + +.method public static testSingleExit(IZ)I + .registers 3 + + # p0 = int X + # p1 = boolean Y + # v0 = true + + invoke-static {}, LTestCase;->$inline$True()Z + move-result v0 + + :loop_start + if-eqz p1, :loop_body # cannot be determined statically + if-nez v0, :loop_end # will always exit + + # Dead block + add-int/lit8 p0, p0, 5 + goto :loop_start + + # Live block + :loop_body + add-int/lit8 p0, p0, 7 + goto :loop_start + + :loop_end + return p0 +.end method + + +# CHECK-START: int TestCase.testMultipleExits(int, boolean, boolean) dead_code_elimination_final (before) +# CHECK-DAG: [[ArgX:i\d+]] ParameterValue +# CHECK-DAG: [[ArgY:z\d+]] ParameterValue +# CHECK-DAG: [[ArgZ:z\d+]] ParameterValue +# CHECK-DAG: [[Cst1:i\d+]] IntConstant 1 +# CHECK-DAG: [[Cst5:i\d+]] IntConstant 5 +# CHECK-DAG: [[Cst7:i\d+]] IntConstant 7 +# CHECK-DAG: [[PhiX:i\d+]] Phi [ [[ArgX]] [[Add5:i\d+]] [[Add7:i\d+]] ] loop_header:[[HeaderY:B\d+]] +# CHECK-DAG: If [ [[ArgY]] ] loop_header:[[HeaderY]] +# CHECK-DAG: If [ [[ArgZ]] ] loop_header:[[HeaderY]] +# CHECK-DAG: If [ [[Cst1]] ] loop_header:[[HeaderY]] +# CHECK-DAG: [[Add5]] Add [ [[PhiX]] [[Cst5]] ] loop_header:[[HeaderY]] +# CHECK-DAG: [[Add7]] Add [ [[PhiX]] [[Cst7]] ] loop_header:[[HeaderY]] +# CHECK-DAG: Return [ [[PhiX]] ] loop_header:null + +# CHECK-START: int TestCase.testMultipleExits(int, boolean, boolean) dead_code_elimination_final (after) +# CHECK-DAG: [[ArgX:i\d+]] ParameterValue +# CHECK-DAG: [[ArgY:z\d+]] ParameterValue +# CHECK-DAG: [[ArgZ:z\d+]] ParameterValue +# CHECK-DAG: [[Cst7:i\d+]] IntConstant 7 +# CHECK-DAG: [[PhiX:i\d+]] Phi [ [[ArgX]] [[Add7:i\d+]] ] loop_header:[[HeaderY:B\d+]] +# CHECK-DAG: If [ [[ArgY]] ] loop_header:[[HeaderY]] +# CHECK-DAG: [[Add7]] Add [ [[PhiX]] [[Cst7]] ] loop_header:[[HeaderY]] +# CHECK-DAG: If [ [[ArgZ]] ] loop_header:null +# CHECK-DAG: Return [ [[PhiX]] ] loop_header:null + +.method public static testMultipleExits(IZZ)I + .registers 4 + + # p0 = int X + # p1 = boolean Y + # p2 = boolean Z + # v0 = true + + invoke-static {}, LTestCase;->$inline$True()Z + move-result v0 + + :loop_start + if-eqz p1, :loop_body # cannot be determined statically + if-nez p2, :loop_end # may exit + if-nez v0, :loop_end # will always exit + + # Dead block + add-int/lit8 p0, p0, 5 + goto :loop_start + + # Live block + :loop_body + add-int/lit8 p0, p0, 7 + goto :loop_start + + :loop_end + return p0 +.end method + + +# CHECK-START: int TestCase.testExitPredecessors(int, boolean, boolean) dead_code_elimination_final (before) +# CHECK-DAG: [[ArgX:i\d+]] ParameterValue +# CHECK-DAG: [[ArgY:z\d+]] ParameterValue +# CHECK-DAG: [[ArgZ:z\d+]] ParameterValue +# CHECK-DAG: [[Cst1:i\d+]] IntConstant 1 +# CHECK-DAG: [[Cst5:i\d+]] IntConstant 5 +# CHECK-DAG: [[Cst7:i\d+]] IntConstant 7 +# CHECK-DAG: [[Cst9:i\d+]] IntConstant 9 +# CHECK-DAG: [[PhiX1:i\d+]] Phi [ [[ArgX]] [[Add5:i\d+]] [[Add7:i\d+]] ] loop_header:[[HeaderY:B\d+]] +# CHECK-DAG: If [ [[ArgY]] ] loop_header:[[HeaderY]] +# CHECK-DAG: If [ [[ArgZ]] ] loop_header:[[HeaderY]] +# CHECK-DAG: [[Mul9:i\d+]] Mul [ [[PhiX1]] [[Cst9]] ] loop_header:[[HeaderY]] +# CHECK-DAG: [[PhiX2:i\d+]] Phi [ [[Mul9]] [[PhiX1]] ] loop_header:[[HeaderY]] +# CHECK-DAG: If [ [[Cst1]] ] loop_header:[[HeaderY]] +# CHECK-DAG: [[Add5]] Add [ [[PhiX2]] [[Cst5]] ] loop_header:[[HeaderY]] +# CHECK-DAG: [[Add7]] Add [ [[PhiX1]] [[Cst7]] ] loop_header:[[HeaderY]] +# CHECK-DAG: Return [ [[PhiX2]] ] loop_header:null + +# CHECK-START: int TestCase.testExitPredecessors(int, boolean, boolean) dead_code_elimination_final (after) +# CHECK-DAG: [[ArgX:i\d+]] ParameterValue +# CHECK-DAG: [[ArgY:z\d+]] ParameterValue +# CHECK-DAG: [[ArgZ:z\d+]] ParameterValue +# CHECK-DAG: [[Cst7:i\d+]] IntConstant 7 +# CHECK-DAG: [[Cst9:i\d+]] IntConstant 9 +# CHECK-DAG: [[PhiX1:i\d+]] Phi [ [[ArgX]] [[Add7:i\d+]] ] loop_header:[[HeaderY:B\d+]] +# CHECK-DAG: If [ [[ArgY]] ] loop_header:[[HeaderY]] +# CHECK-DAG: [[Add7]] Add [ [[PhiX1]] [[Cst7]] ] loop_header:[[HeaderY]] +# CHECK-DAG: If [ [[ArgZ]] ] loop_header:null +# CHECK-DAG: [[Mul9:i\d+]] Mul [ [[PhiX1]] [[Cst9]] ] loop_header:null +# CHECK-DAG: [[PhiX2:i\d+]] Phi [ [[Mul9]] [[PhiX1]] ] loop_header:null +# CHECK-DAG: Return [ [[PhiX2]] ] loop_header:null + +.method public static testExitPredecessors(IZZ)I + .registers 4 + + # p0 = int X + # p1 = boolean Y + # p2 = boolean Z + # v0 = true + + invoke-static {}, LTestCase;->$inline$True()Z + move-result v0 + + :loop_start + if-eqz p1, :loop_body # cannot be determined statically + + # Additional logic which will end up outside the loop + if-eqz p2, :skip_if + mul-int/lit8 p0, p0, 9 + :skip_if + + if-nez v0, :loop_end # will always take the branch + + # Dead block + add-int/lit8 p0, p0, 5 + goto :loop_start + + # Live block + :loop_body + add-int/lit8 p0, p0, 7 + goto :loop_start + + :loop_end + return p0 +.end method + + +# CHECK-START: int TestCase.testInnerLoop(int, boolean, boolean) dead_code_elimination_final (before) +# CHECK-DAG: [[ArgX:i\d+]] ParameterValue +# CHECK-DAG: [[ArgY:z\d+]] ParameterValue +# CHECK-DAG: [[ArgZ:z\d+]] ParameterValue +# CHECK-DAG: [[Cst0:i\d+]] IntConstant 0 +# CHECK-DAG: [[Cst1:i\d+]] IntConstant 1 +# CHECK-DAG: [[Cst5:i\d+]] IntConstant 5 +# CHECK-DAG: [[Cst7:i\d+]] IntConstant 7 +# +# CHECK-DAG: [[PhiX:i\d+]] Phi [ [[ArgX]] [[Add5:i\d+]] [[Add7:i\d+]] ] loop_header:[[HeaderY:B\d+]] +# CHECK-DAG: [[PhiZ1:i\d+]] Phi [ [[ArgZ]] [[XorZ:i\d+]] [[PhiZ1]] ] loop_header:[[HeaderY]] +# CHECK-DAG: If [ [[ArgY]] ] loop_header:[[HeaderY]] +# +# ### Inner loop ### +# CHECK-DAG: [[PhiZ2:i\d+]] Phi [ [[PhiZ1]] [[XorZ]] ] loop_header:[[HeaderZ:B\d+]] +# CHECK-DAG: [[XorZ]] Xor [ [[PhiZ2]] [[Cst1]] ] loop_header:[[HeaderZ]] +# CHECK-DAG: [[CondZ:z\d+]] Equal [ [[XorZ]] [[Cst0]] ] loop_header:[[HeaderZ]] +# CHECK-DAG: If [ [[CondZ]] ] loop_header:[[HeaderZ]] +# +# CHECK-DAG: [[Add5]] Add [ [[PhiX]] [[Cst5]] ] loop_header:[[HeaderY]] +# CHECK-DAG: [[Add7]] Add [ [[PhiX]] [[Cst7]] ] loop_header:[[HeaderY]] +# CHECK-DAG: Return [ [[PhiX]] ] loop_header:null + +# CHECK-START: int TestCase.testInnerLoop(int, boolean, boolean) dead_code_elimination_final (after) +# CHECK-DAG: [[ArgX:i\d+]] ParameterValue +# CHECK-DAG: [[ArgY:z\d+]] ParameterValue +# CHECK-DAG: [[ArgZ:z\d+]] ParameterValue +# CHECK-DAG: [[Cst0:i\d+]] IntConstant 0 +# CHECK-DAG: [[Cst1:i\d+]] IntConstant 1 +# CHECK-DAG: [[Cst7:i\d+]] IntConstant 7 +# +# CHECK-DAG: [[PhiX:i\d+]] Phi [ [[ArgX]] [[Add7:i\d+]] ] loop_header:[[HeaderY:B\d+]] +# CHECK-DAG: [[PhiZ1:i\d+]] Phi [ [[ArgZ]] [[PhiZ1]] ] loop_header:[[HeaderY]] +# CHECK-DAG: If [ [[ArgY]] ] loop_header:[[HeaderY]] +# CHECK-DAG: [[Add7]] Add [ [[PhiX]] [[Cst7]] ] loop_header:[[HeaderY]] +# +# ### Inner loop ### +# CHECK-DAG: [[PhiZ2:i\d+]] Phi [ [[PhiZ1]] [[XorZ:i\d+]] ] loop_header:[[HeaderZ:B\d+]] +# CHECK-DAG: [[XorZ]] Xor [ [[PhiZ2]] [[Cst1]] ] loop_header:[[HeaderZ]] +# CHECK-DAG: [[CondZ:z\d+]] Equal [ [[XorZ]] [[Cst0]] ] loop_header:[[HeaderZ]] +# CHECK-DAG: If [ [[CondZ]] ] loop_header:[[HeaderZ]] +# +# CHECK-DAG: Return [ [[PhiX]] ] loop_header:null + +.method public static testInnerLoop(IZZ)I + .registers 4 + + # p0 = int X + # p1 = boolean Y + # p2 = boolean Z + # v0 = true + + invoke-static {}, LTestCase;->$inline$True()Z + move-result v0 + + :loop_start + if-eqz p1, :loop_body # cannot be determined statically + + # Inner loop which will end up outside its parent + :inner_loop_start + xor-int/lit8 p2, p2, 1 + if-eqz p2, :inner_loop_start + + if-nez v0, :loop_end # will always take the branch + + # Dead block + add-int/lit8 p0, p0, 5 + goto :loop_start + + # Live block + :loop_body + add-int/lit8 p0, p0, 7 + goto :loop_start + + :loop_end + return p0 +.end method diff --git a/test/485-checker-dce-loop-update/src/Main.java b/test/485-checker-dce-loop-update/src/Main.java new file mode 100644 index 0000000000..6bfe08b0d3 --- /dev/null +++ b/test/485-checker-dce-loop-update/src/Main.java @@ -0,0 +1,27 @@ +/* + * 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. + */ + +import java.lang.reflect.Method; + +public class Main { + + // Workaround for b/18051191. + class InnerClass {} + + public static void main(String[] args) throws Exception { + return; + } +} diff --git a/test/Android.run-test.mk b/test/Android.run-test.mk index 515b8af8ff..07e76205a4 100644 --- a/test/Android.run-test.mk +++ b/test/Android.run-test.mk @@ -385,7 +385,6 @@ TEST_ART_BROKEN_OPTIMIZING_ARM64_RUN_TESTS := # Known broken tests for the optimizing compiler. TEST_ART_BROKEN_OPTIMIZING_RUN_TESTS := -TEST_ART_BROKEN_OPTIMIZING_RUN_TESTS += 472-unreachable-if-regression # b/19988134 ifneq (,$(filter optimizing,$(COMPILER_TYPES))) ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(RUN_TYPES),$(PREBUILD_TYPES), \ @@ -429,8 +428,7 @@ endif TEST_ART_BROKEN_OPTIMIZING_DEBUGGABLE_RUN_TESTS := # Tests that should fail in the read barrier configuration. -TEST_ART_BROKEN_READ_BARRIER_RUN_TESTS := \ - 098-ddmc # b/20720510 +TEST_ART_BROKEN_READ_BARRIER_RUN_TESTS := ifeq ($(ART_USE_READ_BARRIER),true) ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(RUN_TYPES),$(PREBUILD_TYPES), \ diff --git a/test/Instrumentation/Instrumentation.java b/test/Instrumentation/Instrumentation.java new file mode 100644 index 0000000000..09d434213b --- /dev/null +++ b/test/Instrumentation/Instrumentation.java @@ -0,0 +1,22 @@ +/* + * 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 Instrumentation { + // Direct method + private void instanceMethod() { + System.out.println("instanceMethod"); + } +} diff --git a/test/run-test b/test/run-test index 2873a35c83..239681ff4e 100755 --- a/test/run-test +++ b/test/run-test @@ -39,7 +39,7 @@ if [ -z "$TMPDIR" ]; then else tmp_dir="${TMPDIR}/$USER/${test_dir}" fi -checker="${progdir}/../tools/checker.py" +checker="${progdir}/../tools/checker/checker.py" export JAVA="java" export JAVAC="javac -g" |