From 61b922847403ac0e74b6477114c81a28ac2e01a0 Mon Sep 17 00:00:00 2001 From: Vladimir Marko Date: Wed, 11 Oct 2017 13:23:17 +0100 Subject: ART: Introduce Uint8 loads in compiled code. Some vectorization patterns are not recognized anymore. This shall be fixed later. Test: m test-art-host-gtest Test: testrunner.py --host --optimizing Test: testrunner.py --target --optimizing on Nexus 5X Test: Nexus 5X boots. Bug: 23964345 Bug: 67935418 Change-Id: I587a328d4799529949c86fa8045c6df21e3a8617 --- .../src/Main.java | 360 ++++++++++++++++++++- 1 file changed, 359 insertions(+), 1 deletion(-) (limited to 'test/458-checker-instruct-simplification/src/Main.java') diff --git a/test/458-checker-instruct-simplification/src/Main.java b/test/458-checker-instruct-simplification/src/Main.java index 20858f560f..262d2c1983 100644 --- a/test/458-checker-instruct-simplification/src/Main.java +++ b/test/458-checker-instruct-simplification/src/Main.java @@ -218,6 +218,28 @@ public class Main { return (arg >> 24) & 255; } + /// CHECK-START: int Main.$noinline$Shr25And127(int) instruction_simplifier (before) + /// CHECK-DAG: <> ParameterValue + /// CHECK-DAG: <> IntConstant 25 + /// CHECK-DAG: <> IntConstant 127 + /// CHECK-DAG: <> Shr [<>,<>] + /// CHECK-DAG: <> And [<>,<>] + /// CHECK-DAG: Return [<>] + + /// CHECK-START: int Main.$noinline$Shr25And127(int) instruction_simplifier (after) + /// CHECK-DAG: <> ParameterValue + /// CHECK-DAG: <> IntConstant 25 + /// CHECK-DAG: <> UShr [<>,<>] + /// CHECK-DAG: Return [<>] + + /// CHECK-START: int Main.$noinline$Shr25And127(int) instruction_simplifier (after) + /// CHECK-NOT: Shr + /// CHECK-NOT: And + + public static int $noinline$Shr25And127(int arg) { + return (arg >> 25) & 127; + } + /// CHECK-START: long Main.$noinline$Shr56And255(long) instruction_simplifier (before) /// CHECK-DAG: <> ParameterValue /// CHECK-DAG: <> IntConstant 56 @@ -240,6 +262,28 @@ public class Main { return (arg >> 56) & 255; } + /// CHECK-START: long Main.$noinline$Shr57And127(long) instruction_simplifier (before) + /// CHECK-DAG: <> ParameterValue + /// CHECK-DAG: <> IntConstant 57 + /// CHECK-DAG: <> LongConstant 127 + /// CHECK-DAG: <> Shr [<>,<>] + /// CHECK-DAG: <> And [<>,<>] + /// CHECK-DAG: Return [<>] + + /// CHECK-START: long Main.$noinline$Shr57And127(long) instruction_simplifier (after) + /// CHECK-DAG: <> ParameterValue + /// CHECK-DAG: <> IntConstant 57 + /// CHECK-DAG: <> UShr [<>,<>] + /// CHECK-DAG: Return [<>] + + /// CHECK-START: long Main.$noinline$Shr57And127(long) instruction_simplifier (after) + /// CHECK-NOT: Shr + /// CHECK-NOT: And + + public static long $noinline$Shr57And127(long arg) { + return (arg >> 57) & 127; + } + /// CHECK-START: int Main.$noinline$Shr24And127(int) instruction_simplifier (before) /// CHECK-DAG: <> ParameterValue /// CHECK-DAG: <> IntConstant 24 @@ -2222,7 +2266,279 @@ public class Main { return y + sub; } - public static void main(String[] args) { + /// CHECK-START: int Main.$noinline$getUint8FromInstanceByteField(Main) instruction_simplifier (before) + /// CHECK-DAG: <> IntConstant 255 + /// CHECK-DAG: <> InstanceFieldGet + /// CHECK-DAG: <> And [<>,<>] + /// CHECK-DAG: Return [<>] + + /// CHECK-START: int Main.$noinline$getUint8FromInstanceByteField(Main) instruction_simplifier (after) + /// CHECK-DAG: <> InstanceFieldGet + /// CHECK-DAG: Return [<>] + + /// CHECK-START: int Main.$noinline$getUint8FromInstanceByteField(Main) instruction_simplifier (after) + /// CHECK-NOT: And + /// CHECK-NOT: TypeConversion + public static int $noinline$getUint8FromInstanceByteField(Main m) { + return m.instanceByteField & 0xff; + } + + /// CHECK-START: int Main.$noinline$getUint8FromStaticByteField() instruction_simplifier (before) + /// CHECK-DAG: <> IntConstant 255 + /// CHECK-DAG: <> StaticFieldGet + /// CHECK-DAG: <> And [<>,<>] + /// CHECK-DAG: Return [<>] + + /// CHECK-START: int Main.$noinline$getUint8FromStaticByteField() instruction_simplifier (after) + /// CHECK-DAG: <> StaticFieldGet + /// CHECK-DAG: Return [<>] + + /// CHECK-START: int Main.$noinline$getUint8FromStaticByteField() instruction_simplifier (after) + /// CHECK-NOT: And + /// CHECK-NOT: TypeConversion + public static int $noinline$getUint8FromStaticByteField() { + return staticByteField & 0xff; + } + + /// CHECK-START: int Main.$noinline$getUint8FromByteArray(byte[]) instruction_simplifier (before) + /// CHECK-DAG: <> IntConstant 255 + /// CHECK-DAG: <> ArrayGet + /// CHECK-DAG: <> And [<>,<>] + /// CHECK-DAG: Return [<>] + + /// CHECK-START: int Main.$noinline$getUint8FromByteArray(byte[]) instruction_simplifier (after) + /// CHECK-DAG: <> ArrayGet + /// CHECK-DAG: Return [<>] + + /// CHECK-START: int Main.$noinline$getUint8FromByteArray(byte[]) instruction_simplifier (after) + /// CHECK-NOT: And + /// CHECK-NOT: TypeConversion + public static int $noinline$getUint8FromByteArray(byte[] a) { + return a[0] & 0xff; + } + + /// CHECK-START: int Main.$noinline$getUint16FromInstanceShortField(Main) instruction_simplifier (before) + /// CHECK-DAG: <> IntConstant 65535 + /// CHECK-DAG: <> InstanceFieldGet + /// CHECK-DAG: <> And [<>,<>] + /// CHECK-DAG: Return [<>] + + /// CHECK-START: int Main.$noinline$getUint16FromInstanceShortField(Main) instruction_simplifier (after) + /// CHECK-DAG: <> InstanceFieldGet + /// CHECK-DAG: Return [<>] + + /// CHECK-START: int Main.$noinline$getUint16FromInstanceShortField(Main) instruction_simplifier (after) + /// CHECK-NOT: And + /// CHECK-NOT: TypeConversion + public static int $noinline$getUint16FromInstanceShortField(Main m) { + return m.instanceShortField & 0xffff; + } + + /// CHECK-START: int Main.$noinline$getUint16FromStaticShortField() instruction_simplifier (before) + /// CHECK-DAG: <> IntConstant 65535 + /// CHECK-DAG: <> StaticFieldGet + /// CHECK-DAG: <> And [<>,<>] + /// CHECK-DAG: Return [<>] + + /// CHECK-START: int Main.$noinline$getUint16FromStaticShortField() instruction_simplifier (after) + /// CHECK-DAG: <> StaticFieldGet + /// CHECK-DAG: Return [<>] + + /// CHECK-START: int Main.$noinline$getUint16FromStaticShortField() instruction_simplifier (after) + /// CHECK-NOT: And + /// CHECK-NOT: TypeConversion + public static int $noinline$getUint16FromStaticShortField() { + return staticShortField & 0xffff; + } + + /// CHECK-START: int Main.$noinline$getUint16FromShortArray(short[]) instruction_simplifier (before) + /// CHECK-DAG: <> IntConstant 65535 + /// CHECK-DAG: <> ArrayGet + /// CHECK-DAG: <> And [<>,<>] + /// CHECK-DAG: Return [<>] + + /// CHECK-START: int Main.$noinline$getUint16FromShortArray(short[]) instruction_simplifier (after) + /// CHECK-DAG: <> ArrayGet + /// CHECK-DAG: Return [<>] + + /// CHECK-START: int Main.$noinline$getUint16FromShortArray(short[]) instruction_simplifier (after) + /// CHECK-NOT: And + /// CHECK-NOT: TypeConversion + public static int $noinline$getUint16FromShortArray(short[] a) { + return a[0] & 0xffff; + } + + /// CHECK-START: int Main.$noinline$getInt16FromInstanceCharField(Main) instruction_simplifier (before) + /// CHECK-DAG: <> InstanceFieldGet + /// CHECK-DAG: <> TypeConversion [<>] + /// CHECK-DAG: Return [<>] + + /// CHECK-START: int Main.$noinline$getInt16FromInstanceCharField(Main) instruction_simplifier (after) + /// CHECK-DAG: <> InstanceFieldGet + /// CHECK-DAG: Return [<>] + + /// CHECK-START: int Main.$noinline$getInt16FromInstanceCharField(Main) instruction_simplifier (after) + /// CHECK-NOT: And + /// CHECK-NOT: TypeConversion + public static int $noinline$getInt16FromInstanceCharField(Main m) { + return (short) m.instanceCharField; + } + + /// CHECK-START: int Main.$noinline$getInt16FromStaticCharField() instruction_simplifier (before) + /// CHECK-DAG: <> StaticFieldGet + /// CHECK-DAG: <> TypeConversion [<>] + /// CHECK-DAG: Return [<>] + + /// CHECK-START: int Main.$noinline$getInt16FromStaticCharField() instruction_simplifier (after) + /// CHECK-DAG: <> StaticFieldGet + /// CHECK-DAG: Return [<>] + + /// CHECK-START: int Main.$noinline$getInt16FromStaticCharField() instruction_simplifier (after) + /// CHECK-NOT: And + /// CHECK-NOT: TypeConversion + public static int $noinline$getInt16FromStaticCharField() { + return (short) staticCharField; + } + + /// CHECK-START: int Main.$noinline$getInt16FromCharArray(char[]) instruction_simplifier (before) + /// CHECK-DAG: <> ArrayGet + /// CHECK-DAG: <> TypeConversion [<>] + /// CHECK-DAG: Return [<>] + + /// CHECK-START: int Main.$noinline$getInt16FromCharArray(char[]) instruction_simplifier (after) + /// CHECK-DAG: <> ArrayGet + /// CHECK-DAG: Return [<>] + + /// CHECK-START: int Main.$noinline$getInt16FromCharArray(char[]) instruction_simplifier (after) + /// CHECK-NOT: And + /// CHECK-NOT: TypeConversion + public static int $noinline$getInt16FromCharArray(char[] a) { + return (short) a[0]; + } + + /// CHECK-START: int Main.$noinline$byteToUint8AndBack() instruction_simplifier (before) + /// CHECK-DAG: <> IntConstant 255 + /// CHECK-DAG: <> StaticFieldGet + /// CHECK-DAG: <> And [<>,<>] + /// CHECK-DAG: <> InvokeStaticOrDirect [<>{{(,[ij]\d+)?}}] + /// CHECK-DAG: Return [<>] + + /// CHECK-START: int Main.$noinline$byteToUint8AndBack() instruction_simplifier (after) + /// CHECK-DAG: <> StaticFieldGet + /// CHECK-DAG: <> InvokeStaticOrDirect [<>{{(,[ij]\d+)?}}] + /// CHECK-DAG: Return [<>] + + /// CHECK-START: int Main.$noinline$byteToUint8AndBack() instruction_simplifier$after_inlining (before) + /// CHECK-DAG: <> StaticFieldGet + /// CHECK-DAG: <> TypeConversion [<>] + /// CHECK-DAG: Return [<>] + + /// CHECK-START: int Main.$noinline$byteToUint8AndBack() instruction_simplifier$after_inlining (after) + /// CHECK-DAG: <> StaticFieldGet + /// CHECK-DAG: Return [<>] + public static int $noinline$byteToUint8AndBack() { + return $inline$toByte(staticByteField & 0xff); + } + + public static int $inline$toByte(int value) { + return (byte) value; + } + + /// CHECK-START: int Main.$noinline$getStaticCharFieldAnd0xff() instruction_simplifier (before) + /// CHECK-DAG: <> IntConstant 255 + /// CHECK-DAG: <> StaticFieldGet + /// CHECK-DAG: <> And [<>,<>] + /// CHECK-DAG: Return [<>] + + /// CHECK-START: int Main.$noinline$getStaticCharFieldAnd0xff() instruction_simplifier (after) + /// CHECK-DAG: <> IntConstant 255 + /// CHECK-DAG: <> StaticFieldGet + /// CHECK-DAG: <> TypeConversion [<>] + /// CHECK-DAG: Return [<>] + + /// CHECK-START: int Main.$noinline$getStaticCharFieldAnd0xff() instruction_simplifier (after) + /// CHECK-NOT: {{a\d+}} StaticFieldGet + public static int $noinline$getStaticCharFieldAnd0xff() { + return staticCharField & 0xff; + } + + /// CHECK-START: int Main.$noinline$getUint8FromInstanceByteFieldWithAnotherUse(Main) instruction_simplifier (before) + /// CHECK-DAG: <> IntConstant 8 + /// CHECK-DAG: <> IntConstant 255 + /// CHECK-DAG: <> InstanceFieldGet + /// CHECK-DAG: <> And [<>,<>] + /// CHECK-DAG: <> Shl [<>,<>] + /// CHECK-DAG: <> Add [<>,<>] + /// CHECK-DAG: Return [<>] + + /// CHECK-START: int Main.$noinline$getUint8FromInstanceByteFieldWithAnotherUse(Main) instruction_simplifier (after) + /// CHECK-DAG: <> IntConstant 8 + /// CHECK-DAG: <> IntConstant 255 + /// CHECK-DAG: <> InstanceFieldGet + /// CHECK-DAG: <> TypeConversion [<>] + /// CHECK-DAG: <> Shl [<>,<>] + /// CHECK-DAG: <> Add [<>,<>] + /// CHECK-DAG: Return [<>] + + /// CHECK-START: int Main.$noinline$getUint8FromInstanceByteFieldWithAnotherUse(Main) instruction_simplifier (after) + /// CHECK-NOT: {{a\d+}} InstanceFieldGet + public static int $noinline$getUint8FromInstanceByteFieldWithAnotherUse(Main m) { + byte b = m.instanceByteField; + int v1 = b & 0xff; + int v2 = (b << 8); + return v1 + v2; + } + + /// CHECK-START: int Main.$noinline$intAnd0xffToChar(int) instruction_simplifier (before) + /// CHECK-DAG: <> ParameterValue + /// CHECK-DAG: <> IntConstant 255 + /// CHECK-DAG: <> And [<>,<>] + /// CHECK-DAG: <> TypeConversion [<>] + /// CHECK-DAG: Return [<>] + + /// CHECK-START: int Main.$noinline$intAnd0xffToChar(int) instruction_simplifier (after) + /// CHECK-DAG: <> ParameterValue + /// CHECK-DAG: <> TypeConversion [<>] + /// CHECK-DAG: Return [<>] + public static int $noinline$intAnd0xffToChar(int value) { + return (char) (value & 0xff); + } + + /// CHECK-START: int Main.$noinline$intAnd0x1ffToChar(int) instruction_simplifier (before) + /// CHECK-DAG: <> ParameterValue + /// CHECK-DAG: <> IntConstant 511 + /// CHECK-DAG: <> And [<>,<>] + /// CHECK-DAG: <> TypeConversion [<>] + /// CHECK-DAG: Return [<>] + + // TODO: Simplify this. Unlike the $noinline$intAnd0xffToChar(), the TypeConversion + // to `char` is not eliminated despite the result of the And being within the `char` range. + + // CHECK-START: int Main.$noinline$intAnd0x1ffToChar(int) instruction_simplifier (after) + // CHECK-DAG: <> ParameterValue + // CHECK-DAG: <> IntConstant 511 + // CHECK-DAG: <> And [<>,<>] + // CHECK-DAG: Return [<>] + public static int $noinline$intAnd0x1ffToChar(int value) { + return (char) (value & 0x1ff); + } + + /// CHECK-START: int Main.$noinline$getInstanceCharFieldAnd0x1ffff(Main) instruction_simplifier (before) + /// CHECK-DAG: <> IntConstant 131071 + /// CHECK-DAG: <> InstanceFieldGet + /// CHECK-DAG: <> And [<>,<>] + /// CHECK-DAG: Return [<>] + + // TODO: Simplify this. The And is useless. + + // CHECK-START: int Main.$noinline$getInstanceCharFieldAnd0x1ffff(Main) instruction_simplifier (after) + // CHECK-DAG: <> InstanceFieldGet + // CHECK-DAG: Return [<>] + public static int $noinline$getInstanceCharFieldAnd0x1ffff(Main m) { + return m.instanceCharField & 0x1ffff; + } + + public static void main(String[] args) { int arg = 123456; float floatArg = 123456.125f; @@ -2282,7 +2598,9 @@ public class Main { assertIntEquals(0x4, $noinline$UShr28And7(0xc1234567)); assertLongEquals(0x4L, $noinline$UShr60And7(0xc123456787654321L)); assertIntEquals(0xc1, $noinline$Shr24And255(0xc1234567)); + assertIntEquals(0x60, $noinline$Shr25And127(0xc1234567)); assertLongEquals(0xc1L, $noinline$Shr56And255(0xc123456787654321L)); + assertLongEquals(0x60L, $noinline$Shr57And127(0xc123456787654321L)); assertIntEquals(0x41, $noinline$Shr24And127(0xc1234567)); assertLongEquals(0x41L, $noinline$Shr56And127(0xc123456787654321L)); assertIntEquals(0, $noinline$mulPow2Plus1(0)); @@ -2422,10 +2740,50 @@ public class Main { assertFloatEquals(floatArg, $noinline$floatAddSubSimplifyArg2(floatArg, 654321.125f)); assertFloatEquals(floatArg, $noinline$floatSubAddSimplifyLeft(floatArg, 654321.125f)); assertFloatEquals(floatArg, $noinline$floatSubAddSimplifyRight(floatArg, 654321.125f)); + + Main m = new Main(); + m.instanceByteField = -1; + assertIntEquals(0xff, $noinline$getUint8FromInstanceByteField(m)); + staticByteField = -2; + assertIntEquals(0xfe, $noinline$getUint8FromStaticByteField()); + assertIntEquals(0xfd, $noinline$getUint8FromByteArray(new byte[] { -3 })); + m.instanceShortField = -4; + assertIntEquals(0xfffc, $noinline$getUint16FromInstanceShortField(m)); + staticShortField = -5; + assertIntEquals(0xfffb, $noinline$getUint16FromStaticShortField()); + assertIntEquals(0xfffa, $noinline$getUint16FromShortArray(new short[] { -6 })); + m.instanceCharField = 0xfff9; + assertIntEquals(-7, $noinline$getInt16FromInstanceCharField(m)); + staticCharField = 0xfff8; + assertIntEquals(-8, $noinline$getInt16FromStaticCharField()); + assertIntEquals(-9, $noinline$getInt16FromCharArray(new char[] { 0xfff7 })); + + staticCharField = 0xfff6; + assertIntEquals(0xf6, $noinline$getStaticCharFieldAnd0xff()); + + staticByteField = -11; + assertIntEquals(-11, $noinline$byteToUint8AndBack()); + + m.instanceByteField = -12; + assertIntEquals(0xfffff4f4, $noinline$getUint8FromInstanceByteFieldWithAnotherUse(m)); + + assertIntEquals(0x21, $noinline$intAnd0xffToChar(0x87654321)); + assertIntEquals(0x121, $noinline$intAnd0x1ffToChar(0x87654321)); + + m.instanceCharField = 'x'; + assertIntEquals('x', $noinline$getInstanceCharFieldAnd0x1ffff(m)); } private static boolean $inline$true() { return true; } private static boolean $inline$false() { return false; } public static boolean booleanField; + + public static byte staticByteField; + public static char staticCharField; + public static short staticShortField; + + public byte instanceByteField; + public char instanceCharField; + public short instanceShortField; } -- cgit v1.2.3-59-g8ed1b