summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/458-checker-instruction-simplification/smali/SmaliTests.smali136
-rw-r--r--test/458-checker-instruction-simplification/src/Main.java122
-rw-r--r--test/478-checker-clinit-check-pruning/src/Main.java53
-rw-r--r--test/530-checker-loops1/src/Main.java36
-rw-r--r--test/530-checker-loops2/src/Main.java133
-rw-r--r--test/548-checker-inlining-and-dce/src/Main.java10
-rw-r--r--test/609-checker-inline-interface/expected.txt0
-rw-r--r--test/609-checker-inline-interface/info.txt2
-rw-r--r--test/609-checker-inline-interface/src/Main.java70
-rw-r--r--test/610-arraycopy/expected.txt0
-rw-r--r--test/610-arraycopy/info.txt2
-rw-r--r--test/610-arraycopy/src/Main.java44
12 files changed, 554 insertions, 54 deletions
diff --git a/test/458-checker-instruction-simplification/smali/SmaliTests.smali b/test/458-checker-instruction-simplification/smali/SmaliTests.smali
index ede599b213..6845961f39 100644
--- a/test/458-checker-instruction-simplification/smali/SmaliTests.smali
+++ b/test/458-checker-instruction-simplification/smali/SmaliTests.smali
@@ -191,3 +191,139 @@
.end method
+## CHECK-START: int SmaliTests.AddSubConst(int) instruction_simplifier (before)
+## CHECK-DAG: <<ArgValue:i\d+>> ParameterValue
+## CHECK-DAG: <<Const7:i\d+>> IntConstant 7
+## CHECK-DAG: <<Const8:i\d+>> IntConstant 8
+## CHECK-DAG: <<Add:i\d+>> Add [<<ArgValue>>,<<Const7>>]
+## CHECK-DAG: <<Sub:i\d+>> Sub [<<Add>>,<<Const8>>]
+## CHECK-DAG: Return [<<Sub>>]
+
+## CHECK-START: int SmaliTests.AddSubConst(int) instruction_simplifier (after)
+## CHECK-DAG: <<ArgValue:i\d+>> ParameterValue
+## CHECK-DAG: <<ConstM1:i\d+>> IntConstant -1
+## CHECK-DAG: <<Add:i\d+>> Add [<<ArgValue>>,<<ConstM1>>]
+## CHECK-DAG: Return [<<Add>>]
+
+.method public static AddSubConst(I)I
+ .registers 3
+
+ .prologue
+ add-int/lit8 v0, p0, 7
+
+ const/16 v1, 8
+
+ sub-int v0, v0, v1
+
+ return v0
+.end method
+
+## CHECK-START: int SmaliTests.SubAddConst(int) instruction_simplifier (before)
+## CHECK-DAG: <<ArgValue:i\d+>> ParameterValue
+## CHECK-DAG: <<Const3:i\d+>> IntConstant 3
+## CHECK-DAG: <<Const4:i\d+>> IntConstant 4
+## CHECK-DAG: <<Sub:i\d+>> Sub [<<ArgValue>>,<<Const3>>]
+## CHECK-DAG: <<Add:i\d+>> Add [<<Sub>>,<<Const4>>]
+## CHECK-DAG: Return [<<Add>>]
+
+## CHECK-START: int SmaliTests.SubAddConst(int) instruction_simplifier (after)
+## CHECK-DAG: <<ArgValue:i\d+>> ParameterValue
+## CHECK-DAG: <<Const1:i\d+>> IntConstant 1
+## CHECK-DAG: <<Add:i\d+>> Add [<<ArgValue>>,<<Const1>>]
+## CHECK-DAG: Return [<<Add>>]
+
+.method public static SubAddConst(I)I
+ .registers 2
+
+ .prologue
+ const/4 v0, 3
+
+ sub-int v0, p0, v0
+
+ add-int/lit8 v0, v0, 4
+
+ return v0
+.end method
+
+## CHECK-START: int SmaliTests.SubSubConst1(int) instruction_simplifier (before)
+## CHECK-DAG: <<ArgValue:i\d+>> ParameterValue
+## CHECK-DAG: <<Const9:i\d+>> IntConstant 9
+## CHECK-DAG: <<Const10:i\d+>> IntConstant 10
+## CHECK-DAG: <<Sub1:i\d+>> Sub [<<ArgValue>>,<<Const9>>]
+## CHECK-DAG: <<Sub2:i\d+>> Sub [<<Sub1>>,<<Const10>>]
+## CHECK-DAG: Return [<<Sub2>>]
+
+## CHECK-START: int SmaliTests.SubSubConst1(int) instruction_simplifier (after)
+## CHECK-DAG: <<ArgValue:i\d+>> ParameterValue
+## CHECK-DAG: <<ConstM19:i\d+>> IntConstant -19
+## CHECK-DAG: <<Add:i\d+>> Add [<<ArgValue>>,<<ConstM19>>]
+## CHECK-DAG: Return [<<Add>>]
+
+.method public static SubSubConst1(I)I
+ .registers 3
+
+ .prologue
+ const/16 v1, 9
+
+ sub-int v0, p0, v1
+
+ const/16 v1, 10
+
+ sub-int v0, v0, v1
+
+ return v0
+.end method
+
+## CHECK-START: int SmaliTests.SubSubConst2(int) instruction_simplifier (before)
+## CHECK-DAG: <<ArgValue:i\d+>> ParameterValue
+## CHECK-DAG: <<Const11:i\d+>> IntConstant 11
+## CHECK-DAG: <<Const12:i\d+>> IntConstant 12
+## CHECK-DAG: <<Sub1:i\d+>> Sub [<<Const11>>,<<ArgValue>>]
+## CHECK-DAG: <<Sub2:i\d+>> Sub [<<Sub1>>,<<Const12>>]
+## CHECK-DAG: Return [<<Sub2>>]
+
+## CHECK-START: int SmaliTests.SubSubConst2(int) instruction_simplifier (after)
+## CHECK-DAG: <<ArgValue:i\d+>> ParameterValue
+## CHECK-DAG: <<ConstM1:i\d+>> IntConstant -1
+## CHECK-DAG: <<Sub:i\d+>> Sub [<<ConstM1>>,<<ArgValue>>]
+## CHECK-DAG: Return [<<Sub>>]
+
+.method public static SubSubConst2(I)I
+ .registers 3
+
+ .prologue
+ rsub-int/lit8 v0, p0, 11
+
+ const/16 v1, 12
+
+ sub-int v0, v0, v1
+
+ return v0
+.end method
+
+## CHECK-START: int SmaliTests.SubSubConst3(int) instruction_simplifier (before)
+## CHECK-DAG: <<ArgValue:i\d+>> ParameterValue
+## CHECK-DAG: <<Const15:i\d+>> IntConstant 15
+## CHECK-DAG: <<Const16:i\d+>> IntConstant 16
+## CHECK-DAG: <<Sub1:i\d+>> Sub [<<ArgValue>>,<<Const16>>]
+## CHECK-DAG: <<Sub2:i\d+>> Sub [<<Const15>>,<<Sub1>>]
+## CHECK-DAG: Return [<<Sub2>>]
+
+## CHECK-START: int SmaliTests.SubSubConst3(int) instruction_simplifier (after)
+## CHECK-DAG: <<ArgValue:i\d+>> ParameterValue
+## CHECK-DAG: <<Const31:i\d+>> IntConstant 31
+## CHECK-DAG: <<Sub:i\d+>> Sub [<<Const31>>,<<ArgValue>>]
+## CHECK-DAG: Return [<<Sub>>]
+
+.method public static SubSubConst3(I)I
+ .registers 2
+
+ .prologue
+ const/16 v0, 16
+
+ sub-int v0, p0, v0
+
+ rsub-int/lit8 v0, v0, 15
+
+ return v0
+.end method
diff --git a/test/458-checker-instruction-simplification/src/Main.java b/test/458-checker-instruction-simplification/src/Main.java
index ffce49d2e1..c717eaa85e 100644
--- a/test/458-checker-instruction-simplification/src/Main.java
+++ b/test/458-checker-instruction-simplification/src/Main.java
@@ -78,6 +78,29 @@ public class Main {
return 0 + arg;
}
+ /// CHECK-START: int Main.$noinline$AddAddSubAddConst(int) instruction_simplifier (before)
+ /// CHECK-DAG: <<ArgValue:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
+ /// CHECK-DAG: <<Const2:i\d+>> IntConstant 2
+ /// CHECK-DAG: <<ConstM3:i\d+>> IntConstant -3
+ /// CHECK-DAG: <<Const4:i\d+>> IntConstant 4
+ /// CHECK-DAG: <<Add1:i\d+>> Add [<<ArgValue>>,<<Const1>>]
+ /// CHECK-DAG: <<Add2:i\d+>> Add [<<Add1>>,<<Const2>>]
+ /// CHECK-DAG: <<Add3:i\d+>> Add [<<Add2>>,<<ConstM3>>]
+ /// CHECK-DAG: <<Add4:i\d+>> Add [<<Add3>>,<<Const4>>]
+ /// CHECK-DAG: Return [<<Add4>>]
+
+ /// CHECK-START: int Main.$noinline$AddAddSubAddConst(int) instruction_simplifier (after)
+ /// CHECK-DAG: <<ArgValue:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Const4:i\d+>> IntConstant 4
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<ArgValue>>,<<Const4>>]
+ /// CHECK-DAG: Return [<<Add>>]
+
+ public static int $noinline$AddAddSubAddConst(int arg) {
+ if (doThrow) { throw new Error(); }
+ return arg + 1 + 2 - 3 + 4;
+ }
+
/// CHECK-START: int Main.$noinline$AndAllOnes(int) instruction_simplifier (before)
/// CHECK-DAG: <<Arg:i\d+>> ParameterValue
/// CHECK-DAG: <<ConstF:i\d+>> IntConstant -1
@@ -364,6 +387,27 @@ public class Main {
return arg * 128;
}
+ /// CHECK-START: long Main.$noinline$MulMulMulConst(long) instruction_simplifier (before)
+ /// CHECK-DAG: <<ArgValue:j\d+>> ParameterValue
+ /// CHECK-DAG: <<Const10:j\d+>> LongConstant 10
+ /// CHECK-DAG: <<Const11:j\d+>> LongConstant 11
+ /// CHECK-DAG: <<Const12:j\d+>> LongConstant 12
+ /// CHECK-DAG: <<Mul1:j\d+>> Mul [<<Const10>>,<<ArgValue>>]
+ /// CHECK-DAG: <<Mul2:j\d+>> Mul [<<Mul1>>,<<Const11>>]
+ /// CHECK-DAG: <<Mul3:j\d+>> Mul [<<Mul2>>,<<Const12>>]
+ /// CHECK-DAG: Return [<<Mul3>>]
+
+ /// CHECK-START: long Main.$noinline$MulMulMulConst(long) instruction_simplifier (after)
+ /// CHECK-DAG: <<ArgValue:j\d+>> ParameterValue
+ /// CHECK-DAG: <<Const1320:j\d+>> LongConstant 1320
+ /// CHECK-DAG: <<Mul:j\d+>> Mul [<<ArgValue>>,<<Const1320>>]
+ /// CHECK-DAG: Return [<<Mul>>]
+
+ public static long $noinline$MulMulMulConst(long arg) {
+ if (doThrow) { throw new Error(); }
+ return 10 * arg * 11 * 12;
+ }
+
/// CHECK-START: int Main.$noinline$Or0(int) instruction_simplifier (before)
/// CHECK-DAG: <<Arg:i\d+>> ParameterValue
/// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
@@ -490,6 +534,63 @@ public class Main {
return 0 - arg;
}
+ /// CHECK-START: int Main.$noinline$SubAddConst1(int) instruction_simplifier (before)
+ /// CHECK-DAG: <<ArgValue:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Const5:i\d+>> IntConstant 5
+ /// CHECK-DAG: <<Const6:i\d+>> IntConstant 6
+ /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Const5>>,<<ArgValue>>]
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<Sub>>,<<Const6>>]
+ /// CHECK-DAG: Return [<<Add>>]
+
+ /// CHECK-START: int Main.$noinline$SubAddConst1(int) instruction_simplifier (after)
+ /// CHECK-DAG: <<ArgValue:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Const11:i\d+>> IntConstant 11
+ /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Const11>>,<<ArgValue>>]
+ /// CHECK-DAG: Return [<<Sub>>]
+
+ public static int $noinline$SubAddConst1(int arg) {
+ if (doThrow) { throw new Error(); }
+ return 5 - arg + 6;
+ }
+
+ /// CHECK-START: int Main.$noinline$SubAddConst2(int) instruction_simplifier (before)
+ /// CHECK-DAG: <<ArgValue:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Const14:i\d+>> IntConstant 14
+ /// CHECK-DAG: <<Const13:i\d+>> IntConstant 13
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<ArgValue>>,<<Const13>>]
+ /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Const14>>,<<Add>>]
+ /// CHECK-DAG: Return [<<Sub>>]
+
+ /// CHECK-START: int Main.$noinline$SubAddConst2(int) instruction_simplifier (after)
+ /// CHECK-DAG: <<ArgValue:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
+ /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Const1>>,<<ArgValue>>]
+ /// CHECK-DAG: Return [<<Sub>>]
+
+ public static int $noinline$SubAddConst2(int arg) {
+ if (doThrow) { throw new Error(); }
+ return 14 - (arg + 13);
+ }
+
+ /// CHECK-START: long Main.$noinline$SubSubConst(long) instruction_simplifier (before)
+ /// CHECK-DAG: <<ArgValue:j\d+>> ParameterValue
+ /// CHECK-DAG: <<Const17:j\d+>> LongConstant 17
+ /// CHECK-DAG: <<Const18:j\d+>> LongConstant 18
+ /// CHECK-DAG: <<Sub1:j\d+>> Sub [<<Const18>>,<<ArgValue>>]
+ /// CHECK-DAG: <<Sub2:j\d+>> Sub [<<Const17>>,<<Sub1>>]
+ /// CHECK-DAG: Return [<<Sub2>>]
+
+ /// CHECK-START: long Main.$noinline$SubSubConst(long) instruction_simplifier (after)
+ /// CHECK-DAG: <<ArgValue:j\d+>> ParameterValue
+ /// CHECK-DAG: <<ConstM1:j\d+>> LongConstant -1
+ /// CHECK-DAG: <<Add:j\d+>> Add [<<ArgValue>>,<<ConstM1>>]
+ /// CHECK-DAG: Return [<<Add>>]
+
+ public static long $noinline$SubSubConst(long arg) {
+ if (doThrow) { throw new Error(); }
+ return 17 - (18 - arg);
+ }
+
/// CHECK-START: long Main.$noinline$UShr0(long) instruction_simplifier (before)
/// CHECK-DAG: <<Arg:j\d+>> ParameterValue
/// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
@@ -1757,6 +1858,17 @@ public class Main {
}
}
+ public static int $noinline$runSmaliTestConst(String name, int arg) {
+ if (doThrow) { throw new Error(); }
+ try {
+ Class<?> c = Class.forName("SmaliTests");
+ Method m = c.getMethod(name, int.class);
+ return (Integer) m.invoke(null, arg);
+ } catch (Exception ex) {
+ throw new Error(ex);
+ }
+ }
+
/// CHECK-START: int Main.$noinline$intUnnecessaryShiftMasking(int, int) instruction_simplifier (before)
/// CHECK: <<Value:i\d+>> ParameterValue
/// CHECK: <<Shift:i\d+>> ParameterValue
@@ -1863,12 +1975,14 @@ public static void main(String[] args) {
int arg = 123456;
assertLongEquals(arg, $noinline$Add0(arg));
+ assertIntEquals(5, $noinline$AddAddSubAddConst(1));
assertIntEquals(arg, $noinline$AndAllOnes(arg));
assertLongEquals(arg, $noinline$Div1(arg));
assertIntEquals(-arg, $noinline$DivN1(arg));
assertLongEquals(arg, $noinline$Mul1(arg));
assertIntEquals(-arg, $noinline$MulN1(arg));
assertLongEquals((128 * arg), $noinline$MulPowerOfTwo128(arg));
+ assertLongEquals(2640, $noinline$MulMulMulConst(2));
assertIntEquals(arg, $noinline$Or0(arg));
assertLongEquals(arg, $noinline$OrSame(arg));
assertIntEquals(arg, $noinline$Shl0(arg));
@@ -1876,6 +1990,9 @@ public static void main(String[] args) {
assertLongEquals(arg, $noinline$Shr64(arg));
assertLongEquals(arg, $noinline$Sub0(arg));
assertIntEquals(-arg, $noinline$SubAliasNeg(arg));
+ assertIntEquals(9, $noinline$SubAddConst1(2));
+ assertIntEquals(-2, $noinline$SubAddConst2(3));
+ assertLongEquals(3, $noinline$SubSubConst(4));
assertLongEquals(arg, $noinline$UShr0(arg));
assertIntEquals(arg, $noinline$Xor0(arg));
assertIntEquals(~arg, $noinline$XorAllOnes(arg));
@@ -2011,6 +2128,11 @@ public static void main(String[] args) {
}
}
+ assertIntEquals(0, $noinline$runSmaliTestConst("AddSubConst", 1));
+ assertIntEquals(3, $noinline$runSmaliTestConst("SubAddConst", 2));
+ assertIntEquals(-16, $noinline$runSmaliTestConst("SubSubConst1", 3));
+ assertIntEquals(-5, $noinline$runSmaliTestConst("SubSubConst2", 4));
+ assertIntEquals(26, $noinline$runSmaliTestConst("SubSubConst3", 5));
assertIntEquals(0x5e6f7808, $noinline$intUnnecessaryShiftMasking(0xabcdef01, 3));
assertIntEquals(0x5e6f7808, $noinline$intUnnecessaryShiftMasking(0xabcdef01, 3 + 32));
assertLongEquals(0xffffffffffffeaf3L, $noinline$longUnnecessaryShiftMasking(0xabcdef0123456789L, 50));
diff --git a/test/478-checker-clinit-check-pruning/src/Main.java b/test/478-checker-clinit-check-pruning/src/Main.java
index 6fc12f138c..c2982b48db 100644
--- a/test/478-checker-clinit-check-pruning/src/Main.java
+++ b/test/478-checker-clinit-check-pruning/src/Main.java
@@ -103,10 +103,8 @@ public class Main {
static boolean doThrow = false;
static void $noinline$staticMethod() {
- if (doThrow) {
- // Try defeating inlining.
- throw new Error();
- }
+ // Try defeating inlining.
+ if (doThrow) { throw new Error(); }
}
}
@@ -181,10 +179,8 @@ public class Main {
static boolean doThrow = false;
static void $noinline$staticMethod() {
- if (doThrow) {
// Try defeating inlining.
- throw new Error();
- }
+ if (doThrow) { throw new Error(); }
}
}
@@ -245,10 +241,8 @@ public class Main {
static boolean doThrow = false;
static void $noinline$staticMethod() {
- if (doThrow) {
// Try defeating inlining.
- throw new Error();
- }
+ if (doThrow) { throw new Error(); }
}
static {
@@ -314,7 +308,7 @@ public class Main {
static void constClassAndInvokeStatic(Iterable<?> it) {
$opt$inline$ignoreClass(ClassWithClinit7.class);
- ClassWithClinit7.someStaticMethod(it);
+ ClassWithClinit7.$noinline$someStaticMethod(it);
}
static void $opt$inline$ignoreClass(Class<?> c) {
@@ -325,10 +319,10 @@ public class Main {
System.out.println("Main$ClassWithClinit7's static initializer");
}
- // Note: not inlined from constClassAndInvokeStatic() but fully inlined from main().
- static void someStaticMethod(Iterable<?> it) {
- // We're not inlining invoke-interface at the moment.
+ static void $noinline$someStaticMethod(Iterable<?> it) {
it.iterator();
+ // We're not inlining throw at the moment.
+ if (doThrow) { throw new Error(""); }
}
}
@@ -345,7 +339,7 @@ public class Main {
static void sgetAndInvokeStatic(Iterable<?> it) {
$opt$inline$ignoreInt(ClassWithClinit8.value);
- ClassWithClinit8.someStaticMethod(it);
+ ClassWithClinit8.$noinline$someStaticMethod(it);
}
static void $opt$inline$ignoreInt(int i) {
@@ -357,10 +351,10 @@ public class Main {
System.out.println("Main$ClassWithClinit8's static initializer");
}
- // Note: not inlined from sgetAndInvokeStatic() but fully inlined from main().
- static void someStaticMethod(Iterable<?> it) {
- // We're not inlining invoke-interface at the moment.
+ static void $noinline$someStaticMethod(Iterable<?> it) {
it.iterator();
+ // We're not inlining throw at the moment.
+ if (doThrow) { throw new Error(""); }
}
}
@@ -377,7 +371,7 @@ public class Main {
static void constClassSgetAndInvokeStatic(Iterable<?> it) {
$opt$inline$ignoreClass(ClassWithClinit9.class);
$opt$inline$ignoreInt(ClassWithClinit9.value);
- ClassWithClinit9.someStaticMethod(it);
+ ClassWithClinit9.$noinline$someStaticMethod(it);
}
static class ClassWithClinit9 {
@@ -386,10 +380,10 @@ public class Main {
System.out.println("Main$ClassWithClinit9's static initializer");
}
- // Note: not inlined from constClassSgetAndInvokeStatic() but fully inlined from main().
- static void someStaticMethod(Iterable<?> it) {
- // We're not inlining invoke-interface at the moment.
+ static void $noinline$someStaticMethod(Iterable<?> it) {
it.iterator();
+ // We're not inlining throw at the moment.
+ if (doThrow) { throw new Error(""); }
}
}
@@ -422,8 +416,9 @@ public class Main {
static void inlinedForNull(Iterable<?> it) {
if (it != null) {
- // We're not inlining invoke-interface at the moment.
it.iterator();
+ // We're not inlining throw at the moment.
+ if (doThrow) { throw new Error(""); }
}
}
}
@@ -460,8 +455,11 @@ public class Main {
}
static void inlinedForNull(Iterable<?> it) {
- // We're not inlining invoke-interface at the moment.
it.iterator();
+ if (it != null) {
+ // We're not inlining throw at the moment.
+ if (doThrow) { throw new Error(""); }
+ }
}
}
@@ -494,8 +492,8 @@ public class Main {
static void inlinedForNull(Iterable<?> it) {
if (it != null) {
- // We're not inlining invoke-interface at the moment.
- it.iterator();
+ // We're not inlining throw at the moment.
+ if (doThrow) { throw new Error(""); }
}
}
}
@@ -510,8 +508,9 @@ public class Main {
}
public static void $noinline$getIterator(Iterable<?> it) {
- // We're not inlining invoke-interface at the moment.
it.iterator();
+ // We're not inlining throw at the moment.
+ if (doThrow) { throw new Error(""); }
}
}
diff --git a/test/530-checker-loops1/src/Main.java b/test/530-checker-loops1/src/Main.java
index 948a7b7dcc..dde4d62475 100644
--- a/test/530-checker-loops1/src/Main.java
+++ b/test/530-checker-loops1/src/Main.java
@@ -562,7 +562,7 @@ public class Main {
//
/// CHECK-START: void Main.linearTriangularOnTwoArrayLengths(int) BCE (after)
/// CHECK-NOT: BoundsCheck
- // TODO: also CHECK-NOT: Deoptimize, see b/27151190
+ /// CHECK-NOT: Deoptimize
private static void linearTriangularOnTwoArrayLengths(int n) {
int[] a = new int[n];
for (int i = 0; i < a.length; i++) {
@@ -604,7 +604,7 @@ public class Main {
//
/// CHECK-START: void Main.linearTriangularOnParameter(int) BCE (after)
/// CHECK-NOT: BoundsCheck
- // TODO: also CHECK-NOT: Deoptimize, see b/27151190
+ /// CHECK-NOT: Deoptimize
private static void linearTriangularOnParameter(int n) {
int[] a = new int[n];
for (int i = 0; i < n; i++) {
@@ -619,56 +619,56 @@ public class Main {
}
}
- /// CHECK-START: void Main.linearTriangularVariationsInnerStrict(int) BCE (before)
+ /// CHECK-START: void Main.linearTriangularStrictLower(int) BCE (before)
/// CHECK-DAG: BoundsCheck
/// CHECK-DAG: BoundsCheck
/// CHECK-DAG: BoundsCheck
/// CHECK-DAG: BoundsCheck
//
- /// CHECK-START: void Main.linearTriangularVariationsInnerStrict(int) BCE (after)
+ /// CHECK-START: void Main.linearTriangularStrictLower(int) BCE (after)
/// CHECK-NOT: BoundsCheck
- // TODO: also CHECK-NOT: Deoptimize, see b/27151190
- private static void linearTriangularVariationsInnerStrict(int n) {
+ /// CHECK-NOT: Deoptimize
+ private static void linearTriangularStrictLower(int n) {
int[] a = new int[n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < i; j++) {
a[j] += 1;
}
- for (int j = i - 1; j > -1; j--) {
+ for (int j = i - 1; j >= 0; j--) {
a[j] += 1;
}
for (int j = i; j < n; j++) {
a[j] += 1;
}
- for (int j = n - 1; j > i - 1; j--) {
+ for (int j = n - 1; j >= i; j--) {
a[j] += 1;
}
}
verifyTriangular(a);
}
- /// CHECK-START: void Main.linearTriangularVariationsInnerNonStrict(int) BCE (before)
+ /// CHECK-START: void Main.linearTriangularStrictUpper(int) BCE (before)
/// CHECK-DAG: BoundsCheck
/// CHECK-DAG: BoundsCheck
/// CHECK-DAG: BoundsCheck
/// CHECK-DAG: BoundsCheck
//
- /// CHECK-START: void Main.linearTriangularVariationsInnerNonStrict(int) BCE (after)
+ /// CHECK-START: void Main.linearTriangularStrictUpper(int) BCE (after)
/// CHECK-NOT: BoundsCheck
- // TODO: also CHECK-NOT: Deoptimize, see b/27151190
- private static void linearTriangularVariationsInnerNonStrict(int n) {
+ /// CHECK-NOT: Deoptimize
+ private static void linearTriangularStrictUpper(int n) {
int[] a = new int[n];
for (int i = 0; i < n; i++) {
- for (int j = 0; j <= i - 1; j++) {
+ for (int j = 0; j <= i; j++) {
a[j] += 1;
}
- for (int j = i - 1; j >= 0; j--) {
+ for (int j = i; j >= 0; j--) {
a[j] += 1;
}
- for (int j = i; j <= n - 1; j++) {
+ for (int j = i + 1; j < n; j++) {
a[j] += 1;
}
- for (int j = n - 1; j >= i; j--) {
+ for (int j = n - 1; j >= i + 1; j--) {
a[j] += 1;
}
}
@@ -802,8 +802,8 @@ public class Main {
linearTriangularOnTwoArrayLengths(10);
linearTriangularOnOneArrayLength(10);
linearTriangularOnParameter(10);
- linearTriangularVariationsInnerStrict(10);
- linearTriangularVariationsInnerNonStrict(10);
+ linearTriangularStrictLower(10);
+ linearTriangularStrictUpper(10);
{
int[] t = linearTriangularOOB();
for (int i = 0; i < 200; i++) {
diff --git a/test/530-checker-loops2/src/Main.java b/test/530-checker-loops2/src/Main.java
index b12fbd6091..7acf0080f8 100644
--- a/test/530-checker-loops2/src/Main.java
+++ b/test/530-checker-loops2/src/Main.java
@@ -31,7 +31,7 @@ public class Main {
//
/// CHECK-START: void Main.bubble(int[]) BCE (after)
/// CHECK-NOT: BoundsCheck
- // TODO: also CHECK-NOT: Deoptimize, see b/27151190
+ /// CHECK-NOT: Deoptimize
private static void bubble(int[] a) {
for (int i = a.length; --i >= 0;) {
for (int j = 0; j < i; j++) {
@@ -301,6 +301,53 @@ public class Main {
} while (-1 <= i);
}
+ /// CHECK-START: void Main.justRightTriangular1() BCE (before)
+ /// CHECK-DAG: BoundsCheck
+ //
+ /// CHECK-START: void Main.justRightTriangular1() BCE (after)
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK-NOT: Deoptimize
+ private static void justRightTriangular1() {
+ int[] a = { 1 } ;
+ for (int i = Integer.MIN_VALUE + 5; i <= Integer.MIN_VALUE + 10; i++) {
+ for (int j = Integer.MIN_VALUE + 4; j < i - 5; j++) {
+ sResult += a[j - (Integer.MIN_VALUE + 4)];
+ }
+ }
+ }
+
+ /// CHECK-START: void Main.justRightTriangular2() BCE (before)
+ /// CHECK-DAG: BoundsCheck
+ //
+ /// CHECK-START: void Main.justRightTriangular2() BCE (after)
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK-NOT: Deoptimize
+ private static void justRightTriangular2() {
+ int[] a = { 1 } ;
+ for (int i = Integer.MIN_VALUE + 5; i <= 10; i++) {
+ for (int j = 4; j < i - 5; j++) {
+ sResult += a[j - 4];
+ }
+ }
+ }
+
+ /// CHECK-START: void Main.justOOBTriangular() BCE (before)
+ /// CHECK-DAG: BoundsCheck
+ //
+ /// CHECK-START: void Main.justOOBTriangular() BCE (after)
+ /// CHECK-DAG: Deoptimize
+ //
+ /// CHECK-START: void Main.justOOBTriangular() BCE (after)
+ /// CHECK-NOT: BoundsCheck
+ private static void justOOBTriangular() {
+ int[] a = { 1 } ;
+ for (int i = Integer.MIN_VALUE + 4; i <= 10; i++) {
+ for (int j = 4; j < i - 5; j++) {
+ sResult += a[j - 4];
+ }
+ }
+ }
+
/// CHECK-START: void Main.hiddenOOB1(int) BCE (before)
/// CHECK-DAG: BoundsCheck
//
@@ -315,7 +362,6 @@ public class Main {
// Dangerous loop where careless static range analysis would yield strict upper bound
// on index j of 5. When, for instance, lo and thus i = -2147483648, the upper bound
// becomes really positive due to arithmetic wrap-around, causing OOB.
- // Dynamic BCE is feasible though, since it checks the range.
for (int j = 4; j < i - 5; j++) {
sResult += a[j - 4];
}
@@ -336,13 +382,32 @@ public class Main {
// Dangerous loop where careless static range analysis would yield strict lower bound
// on index j of 5. When, for instance, hi and thus i = 2147483647, the upper bound
// becomes really negative due to arithmetic wrap-around, causing OOB.
- // Dynamic BCE is feasible though, since it checks the range.
for (int j = 6; j > i + 5; j--) {
sResult += a[j - 6];
}
}
}
+ /// CHECK-START: void Main.hiddenOOB3(int) BCE (before)
+ /// CHECK-DAG: BoundsCheck
+ //
+ /// CHECK-START: void Main.hiddenOOB3(int) BCE (after)
+ /// CHECK-DAG: Deoptimize
+ //
+ /// CHECK-START: void Main.hiddenOOB3(int) BCE (after)
+ /// CHECK-NOT: BoundsCheck
+ private static void hiddenOOB3(int hi) {
+ int[] a = { 11 } ;
+ for (int i = -1; i <= hi; i++) {
+ // Dangerous loop where careless static range analysis would yield strict lower bound
+ // on index j of 0. For large i, the initial value of j becomes really negative due
+ // to arithmetic wrap-around, causing OOB.
+ for (int j = i + 1; j < 1; j++) {
+ sResult += a[j];
+ }
+ }
+ }
+
/// CHECK-START: void Main.hiddenInfiniteOOB() BCE (before)
/// CHECK-DAG: BoundsCheck
//
@@ -376,7 +441,6 @@ public class Main {
for (int i = -1; i <= 0; i++) {
// Dangerous loop similar as above where the loop is now finite, but the
// loop still goes out of bounds for i = -1 due to the large upper bound.
- // Dynamic BCE is feasible though, since it checks the range.
for (int j = -4; j < 2147483646 * i - 3; j++) {
sResult += a[j + 4];
}
@@ -432,6 +496,25 @@ public class Main {
}
}
+ /// CHECK-START: int Main.doNotHoist(int[]) BCE (before)
+ /// CHECK-DAG: BoundsCheck
+ //
+ /// CHECK-START: int Main.doNotHoist(int[]) BCE (after)
+ /// CHECK-NOT: BoundsCheck
+ public static int doNotHoist(int[] a) {
+ int n = a.length;
+ int x = 0;
+ // BCE applies, but hoisting would crash the loop.
+ for (int i = -10000; i < 10000; i++) {
+ for (int j = 0; j <= 1; j++) {
+ if (0 <= i && i < n)
+ x += a[i];
+ }
+ }
+ return x;
+ }
+
+
/// CHECK-START: int[] Main.add() BCE (before)
/// CHECK-DAG: BoundsCheck
//
@@ -687,7 +770,7 @@ public class Main {
/// CHECK-START: int Main.dynamicBCEAndConstantIndices(int[], int[][], int, int) BCE (after)
// Order matters:
/// CHECK: Deoptimize loop:<<Loop:B\d+>>
- // CHECK-NOT: Goto loop:<<Loop>>
+ /// CHECK-NOT: Goto loop:<<Loop>>
/// CHECK-DAG: {{l\d+}} ArrayGet loop:<<Loop>>
/// CHECK-DAG: {{l\d+}} ArrayGet loop:<<Loop>>
/// CHECK-DAG: {{l\d+}} ArrayGet loop:<<Loop>>
@@ -839,6 +922,8 @@ public class Main {
expectEquals(55, justRightDown1());
expectEquals(55, justRightDown2());
expectEquals(55, justRightDown3());
+
+ // Large bounds OOB.
sResult = 0;
try {
justOOBUp();
@@ -890,6 +975,23 @@ public class Main {
}
expectEquals(1055, sResult);
+ // Triangular.
+ sResult = 0;
+ justRightTriangular1();
+ expectEquals(1, sResult);
+ if (HEAVY) {
+ sResult = 0;
+ justRightTriangular2();
+ expectEquals(1, sResult);
+ }
+ sResult = 0;
+ try {
+ justOOBTriangular();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ sResult += 1000;
+ }
+ expectEquals(1001, sResult);
+
// Hidden OOB.
sResult = 0;
try {
@@ -912,6 +1014,15 @@ public class Main {
sResult += 1000;
}
expectEquals(1, sResult);
+ sResult = 0;
+ try {
+ hiddenOOB3(-1); // no OOB
+ } catch (ArrayIndexOutOfBoundsException e) {
+ sResult += 1000;
+ }
+ expectEquals(11, sResult);
+
+ // Expensive hidden OOB test.
if (HEAVY) {
sResult = 0;
try {
@@ -920,7 +1031,16 @@ public class Main {
sResult += 1000;
}
expectEquals(1002, sResult);
+ sResult = 0;
+ try {
+ hiddenOOB3(2147483647); // OOB
+ } catch (ArrayIndexOutOfBoundsException e) {
+ sResult += 1000;
+ }
+ expectEquals(1011, sResult);
}
+
+ // More hidden OOB.
sResult = 0;
try {
hiddenInfiniteOOB();
@@ -966,6 +1086,9 @@ public class Main {
expectEquals(i < 128 ? i : 0, a200[i]);
}
+ // No hoisting after BCE.
+ expectEquals(110, doNotHoist(x));
+
// Addition.
{
int[] e1 ={ 1, 2, 3, 4, 4, 4, 4, 3, 2, 1 };
diff --git a/test/548-checker-inlining-and-dce/src/Main.java b/test/548-checker-inlining-and-dce/src/Main.java
index 38fdcc0b94..bf64c3bb36 100644
--- a/test/548-checker-inlining-and-dce/src/Main.java
+++ b/test/548-checker-inlining-and-dce/src/Main.java
@@ -16,17 +16,19 @@
public class Main {
+ static boolean doThrow = false;
+
private void inlinedForNull(Iterable it) {
if (it != null) {
- // We're not inlining invoke-interface at the moment.
- it.iterator();
+ // We're not inlining throw at the moment.
+ if (doThrow) { throw new Error(""); }
}
}
private void inlinedForFalse(boolean value, Iterable it) {
if (value) {
- // We're not inlining invoke-interface at the moment.
- it.iterator();
+ // We're not inlining throw at the moment.
+ if (doThrow) { throw new Error(""); }
}
}
diff --git a/test/609-checker-inline-interface/expected.txt b/test/609-checker-inline-interface/expected.txt
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/609-checker-inline-interface/expected.txt
diff --git a/test/609-checker-inline-interface/info.txt b/test/609-checker-inline-interface/info.txt
new file mode 100644
index 0000000000..35eee08985
--- /dev/null
+++ b/test/609-checker-inline-interface/info.txt
@@ -0,0 +1,2 @@
+Checker test that we inline interface calls and if we can't inline
+them, we can turn them into a virtual invoke.
diff --git a/test/609-checker-inline-interface/src/Main.java b/test/609-checker-inline-interface/src/Main.java
new file mode 100644
index 0000000000..413f2dd51d
--- /dev/null
+++ b/test/609-checker-inline-interface/src/Main.java
@@ -0,0 +1,70 @@
+/*
+ * 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 final class Main implements Interface {
+
+ static void methodWithInvokeInterface(Interface interf) {
+ interf.doCall();
+ }
+
+ public void doCall() {
+ if (doThrow) throw new Error("");
+ }
+
+ public static void main(String[] args) {
+ testInlineInterfaceCall();
+ testInterfaceToVirtualCall();
+ }
+
+ /// CHECK-START: void Main.testInlineInterfaceCall() inliner (before)
+ /// CHECK: InvokeStaticOrDirect method_name:Main.methodWithInvokeInterface
+
+ /// CHECK-START: void Main.testInlineInterfaceCall() inliner (before)
+ /// CHECK-NOT: InvokeInterface
+
+ /// CHECK-START: void Main.testInlineInterfaceCall() inliner (after)
+ /// CHECK: InvokeInterface method_name:Interface.doCall
+
+ /// CHECK-START: void Main.testInlineInterfaceCall() inliner (after)
+ /// CHECK-NOT: InvokeStaticOrDirect
+ public static void testInlineInterfaceCall() {
+ methodWithInvokeInterface(itf);
+ }
+
+ /// CHECK-START: void Main.testInterfaceToVirtualCall() inliner (before)
+ /// CHECK: InvokeStaticOrDirect method_name:Main.methodWithInvokeInterface
+
+ /// CHECK-START: void Main.testInterfaceToVirtualCall() inliner (before)
+ /// CHECK-NOT: InvokeInterface
+
+ /// CHECK-START: void Main.testInterfaceToVirtualCall() inliner (after)
+ /// CHECK: InvokeVirtual method_name:Main.doCall
+
+ /// CHECK-START: void Main.testInterfaceToVirtualCall() inliner (after)
+ /// CHECK-NOT: InvokeStaticOrDirect
+ /// CHECK-NOT: InvokeInterface
+ public static void testInterfaceToVirtualCall() {
+ methodWithInvokeInterface(m);
+ }
+
+ static Interface itf = new Main();
+ static Main m = new Main();
+ static boolean doThrow = false;
+}
+
+interface Interface {
+ public void doCall();
+}
diff --git a/test/610-arraycopy/expected.txt b/test/610-arraycopy/expected.txt
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/610-arraycopy/expected.txt
diff --git a/test/610-arraycopy/info.txt b/test/610-arraycopy/info.txt
new file mode 100644
index 0000000000..a77190d8fa
--- /dev/null
+++ b/test/610-arraycopy/info.txt
@@ -0,0 +1,2 @@
+Regression test for the System.arraycopy intrinsic, which had a bug
+when doing the copy on the same array.
diff --git a/test/610-arraycopy/src/Main.java b/test/610-arraycopy/src/Main.java
new file mode 100644
index 0000000000..ee11c8ee2a
--- /dev/null
+++ b/test/610-arraycopy/src/Main.java
@@ -0,0 +1,44 @@
+/*
+ * 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) {
+ Object[] a = new Object[5];
+ for (int i = 0; i < 5; i++) {
+ a[i] = new Integer(i);
+ }
+ $noinline$callArrayCopy(a, a);
+
+ expectEquals(0, ((Integer)a[0]).intValue());
+ expectEquals(0, ((Integer)a[1]).intValue());
+ expectEquals(1, ((Integer)a[2]).intValue());
+ expectEquals(2, ((Integer)a[3]).intValue());
+ expectEquals(4, ((Integer)a[4]).intValue());
+ }
+
+ public static void expectEquals(int expected, int actual) {
+ if (expected != actual) {
+ throw new Error("Expected " + expected + ", got " + actual);
+ }
+ }
+
+ public static void $noinline$callArrayCopy(Object[] a, Object[] b) {
+ System.arraycopy(a, 0, b, 1, 3);
+ if (doThrow) { throw new Error(); }
+ }
+
+ static boolean doThrow = false;
+}