diff options
author | 2017-10-11 13:23:17 +0100 | |
---|---|---|
committer | 2017-10-18 15:52:51 +0100 | |
commit | 61b922847403ac0e74b6477114c81a28ac2e01a0 (patch) | |
tree | 02674602fb2592f758f51389b3c7b276ab4df3ee /test/458-checker-instruct-simplification/src/Main.java | |
parent | 6783118d2ad9d759f0617b1219a9e29a10a569f7 (diff) |
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
Diffstat (limited to 'test/458-checker-instruct-simplification/src/Main.java')
-rw-r--r-- | test/458-checker-instruct-simplification/src/Main.java | 360 |
1 files changed, 359 insertions, 1 deletions
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: <<Arg:i\d+>> ParameterValue + /// CHECK-DAG: <<Const25:i\d+>> IntConstant 25 + /// CHECK-DAG: <<Const127:i\d+>> IntConstant 127 + /// CHECK-DAG: <<Shr:i\d+>> Shr [<<Arg>>,<<Const25>>] + /// CHECK-DAG: <<And:i\d+>> And [<<Shr>>,<<Const127>>] + /// CHECK-DAG: Return [<<And>>] + + /// CHECK-START: int Main.$noinline$Shr25And127(int) instruction_simplifier (after) + /// CHECK-DAG: <<Arg:i\d+>> ParameterValue + /// CHECK-DAG: <<Const25:i\d+>> IntConstant 25 + /// CHECK-DAG: <<UShr:i\d+>> UShr [<<Arg>>,<<Const25>>] + /// CHECK-DAG: Return [<<UShr>>] + + /// 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: <<Arg:j\d+>> ParameterValue /// CHECK-DAG: <<Const56:i\d+>> 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: <<Arg:j\d+>> ParameterValue + /// CHECK-DAG: <<Const57:i\d+>> IntConstant 57 + /// CHECK-DAG: <<Const127:j\d+>> LongConstant 127 + /// CHECK-DAG: <<Shr:j\d+>> Shr [<<Arg>>,<<Const57>>] + /// CHECK-DAG: <<And:j\d+>> And [<<Shr>>,<<Const127>>] + /// CHECK-DAG: Return [<<And>>] + + /// CHECK-START: long Main.$noinline$Shr57And127(long) instruction_simplifier (after) + /// CHECK-DAG: <<Arg:j\d+>> ParameterValue + /// CHECK-DAG: <<Const57:i\d+>> IntConstant 57 + /// CHECK-DAG: <<UShr:j\d+>> UShr [<<Arg>>,<<Const57>>] + /// CHECK-DAG: Return [<<UShr>>] + + /// 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: <<Arg:i\d+>> ParameterValue /// CHECK-DAG: <<Const24:i\d+>> 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: <<Const255:i\d+>> IntConstant 255 + /// CHECK-DAG: <<Get:b\d+>> InstanceFieldGet + /// CHECK-DAG: <<And:i\d+>> And [<<Get>>,<<Const255>>] + /// CHECK-DAG: Return [<<And>>] + + /// CHECK-START: int Main.$noinline$getUint8FromInstanceByteField(Main) instruction_simplifier (after) + /// CHECK-DAG: <<Get:a\d+>> InstanceFieldGet + /// CHECK-DAG: Return [<<Get>>] + + /// 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: <<Const255:i\d+>> IntConstant 255 + /// CHECK-DAG: <<Get:b\d+>> StaticFieldGet + /// CHECK-DAG: <<And:i\d+>> And [<<Get>>,<<Const255>>] + /// CHECK-DAG: Return [<<And>>] + + /// CHECK-START: int Main.$noinline$getUint8FromStaticByteField() instruction_simplifier (after) + /// CHECK-DAG: <<Get:a\d+>> StaticFieldGet + /// CHECK-DAG: Return [<<Get>>] + + /// 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: <<Const255:i\d+>> IntConstant 255 + /// CHECK-DAG: <<Get:b\d+>> ArrayGet + /// CHECK-DAG: <<And:i\d+>> And [<<Get>>,<<Const255>>] + /// CHECK-DAG: Return [<<And>>] + + /// CHECK-START: int Main.$noinline$getUint8FromByteArray(byte[]) instruction_simplifier (after) + /// CHECK-DAG: <<Get:a\d+>> ArrayGet + /// CHECK-DAG: Return [<<Get>>] + + /// 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: <<Cst65535:i\d+>> IntConstant 65535 + /// CHECK-DAG: <<Get:s\d+>> InstanceFieldGet + /// CHECK-DAG: <<And:i\d+>> And [<<Get>>,<<Cst65535>>] + /// CHECK-DAG: Return [<<And>>] + + /// CHECK-START: int Main.$noinline$getUint16FromInstanceShortField(Main) instruction_simplifier (after) + /// CHECK-DAG: <<Get:c\d+>> InstanceFieldGet + /// CHECK-DAG: Return [<<Get>>] + + /// 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: <<Cst65535:i\d+>> IntConstant 65535 + /// CHECK-DAG: <<Get:s\d+>> StaticFieldGet + /// CHECK-DAG: <<And:i\d+>> And [<<Get>>,<<Cst65535>>] + /// CHECK-DAG: Return [<<And>>] + + /// CHECK-START: int Main.$noinline$getUint16FromStaticShortField() instruction_simplifier (after) + /// CHECK-DAG: <<Get:c\d+>> StaticFieldGet + /// CHECK-DAG: Return [<<Get>>] + + /// 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: <<Cst65535:i\d+>> IntConstant 65535 + /// CHECK-DAG: <<Get:s\d+>> ArrayGet + /// CHECK-DAG: <<And:i\d+>> And [<<Get>>,<<Cst65535>>] + /// CHECK-DAG: Return [<<And>>] + + /// CHECK-START: int Main.$noinline$getUint16FromShortArray(short[]) instruction_simplifier (after) + /// CHECK-DAG: <<Get:c\d+>> ArrayGet + /// CHECK-DAG: Return [<<Get>>] + + /// 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: <<Get:c\d+>> InstanceFieldGet + /// CHECK-DAG: <<Conv:s\d+>> TypeConversion [<<Get>>] + /// CHECK-DAG: Return [<<Conv>>] + + /// CHECK-START: int Main.$noinline$getInt16FromInstanceCharField(Main) instruction_simplifier (after) + /// CHECK-DAG: <<Get:s\d+>> InstanceFieldGet + /// CHECK-DAG: Return [<<Get>>] + + /// 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: <<Get:c\d+>> StaticFieldGet + /// CHECK-DAG: <<Conv:s\d+>> TypeConversion [<<Get>>] + /// CHECK-DAG: Return [<<Conv>>] + + /// CHECK-START: int Main.$noinline$getInt16FromStaticCharField() instruction_simplifier (after) + /// CHECK-DAG: <<Get:s\d+>> StaticFieldGet + /// CHECK-DAG: Return [<<Get>>] + + /// 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: <<Get:c\d+>> ArrayGet + /// CHECK-DAG: <<Conv:s\d+>> TypeConversion [<<Get>>] + /// CHECK-DAG: Return [<<Conv>>] + + /// CHECK-START: int Main.$noinline$getInt16FromCharArray(char[]) instruction_simplifier (after) + /// CHECK-DAG: <<Get:s\d+>> ArrayGet + /// CHECK-DAG: Return [<<Get>>] + + /// 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: <<Const255:i\d+>> IntConstant 255 + /// CHECK-DAG: <<Get:b\d+>> StaticFieldGet + /// CHECK-DAG: <<And:i\d+>> And [<<Get>>,<<Const255>>] + /// CHECK-DAG: <<Invoke:i\d+>> InvokeStaticOrDirect [<<And>>{{(,[ij]\d+)?}}] + /// CHECK-DAG: Return [<<Invoke>>] + + /// CHECK-START: int Main.$noinline$byteToUint8AndBack() instruction_simplifier (after) + /// CHECK-DAG: <<Get:a\d+>> StaticFieldGet + /// CHECK-DAG: <<Invoke:i\d+>> InvokeStaticOrDirect [<<Get>>{{(,[ij]\d+)?}}] + /// CHECK-DAG: Return [<<Invoke>>] + + /// CHECK-START: int Main.$noinline$byteToUint8AndBack() instruction_simplifier$after_inlining (before) + /// CHECK-DAG: <<Get:a\d+>> StaticFieldGet + /// CHECK-DAG: <<Conv:b\d+>> TypeConversion [<<Get>>] + /// CHECK-DAG: Return [<<Conv>>] + + /// CHECK-START: int Main.$noinline$byteToUint8AndBack() instruction_simplifier$after_inlining (after) + /// CHECK-DAG: <<Get:b\d+>> StaticFieldGet + /// CHECK-DAG: Return [<<Get>>] + 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: <<Const255:i\d+>> IntConstant 255 + /// CHECK-DAG: <<Get:c\d+>> StaticFieldGet + /// CHECK-DAG: <<And:i\d+>> And [<<Get>>,<<Const255>>] + /// CHECK-DAG: Return [<<And>>] + + /// CHECK-START: int Main.$noinline$getStaticCharFieldAnd0xff() instruction_simplifier (after) + /// CHECK-DAG: <<Const255:i\d+>> IntConstant 255 + /// CHECK-DAG: <<Get:c\d+>> StaticFieldGet + /// CHECK-DAG: <<Cnv:a\d+>> TypeConversion [<<Get>>] + /// CHECK-DAG: Return [<<Cnv>>] + + /// 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: <<Const8:i\d+>> IntConstant 8 + /// CHECK-DAG: <<Const255:i\d+>> IntConstant 255 + /// CHECK-DAG: <<Get:b\d+>> InstanceFieldGet + /// CHECK-DAG: <<And:i\d+>> And [<<Get>>,<<Const255>>] + /// CHECK-DAG: <<Shl:i\d+>> Shl [<<Get>>,<<Const8>>] + /// CHECK-DAG: <<Add:i\d+>> Add [<<And>>,<<Shl>>] + /// CHECK-DAG: Return [<<Add>>] + + /// CHECK-START: int Main.$noinline$getUint8FromInstanceByteFieldWithAnotherUse(Main) instruction_simplifier (after) + /// CHECK-DAG: <<Const8:i\d+>> IntConstant 8 + /// CHECK-DAG: <<Const255:i\d+>> IntConstant 255 + /// CHECK-DAG: <<Get:b\d+>> InstanceFieldGet + /// CHECK-DAG: <<Cnv:a\d+>> TypeConversion [<<Get>>] + /// CHECK-DAG: <<Shl:i\d+>> Shl [<<Get>>,<<Const8>>] + /// CHECK-DAG: <<Add:i\d+>> Add [<<Cnv>>,<<Shl>>] + /// CHECK-DAG: Return [<<Add>>] + + /// 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: <<Arg:i\d+>> ParameterValue + /// CHECK-DAG: <<Const255:i\d+>> IntConstant 255 + /// CHECK-DAG: <<And:i\d+>> And [<<Arg>>,<<Const255>>] + /// CHECK-DAG: <<Conv:c\d+>> TypeConversion [<<And>>] + /// CHECK-DAG: Return [<<Conv>>] + + /// CHECK-START: int Main.$noinline$intAnd0xffToChar(int) instruction_simplifier (after) + /// CHECK-DAG: <<Arg:i\d+>> ParameterValue + /// CHECK-DAG: <<Conv:a\d+>> TypeConversion [<<Arg>>] + /// CHECK-DAG: Return [<<Conv>>] + public static int $noinline$intAnd0xffToChar(int value) { + return (char) (value & 0xff); + } + + /// CHECK-START: int Main.$noinline$intAnd0x1ffToChar(int) instruction_simplifier (before) + /// CHECK-DAG: <<Arg:i\d+>> ParameterValue + /// CHECK-DAG: <<Const511:i\d+>> IntConstant 511 + /// CHECK-DAG: <<And:i\d+>> And [<<Arg>>,<<Const511>>] + /// CHECK-DAG: <<Conv:c\d+>> TypeConversion [<<And>>] + /// CHECK-DAG: Return [<<Conv>>] + + // 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: <<Arg:i\d+>> ParameterValue + // CHECK-DAG: <<Const511:i\d+>> IntConstant 511 + // CHECK-DAG: <<And:i\d+>> And [<<Arg>>,<<Const511>>] + // CHECK-DAG: Return [<<And>>] + public static int $noinline$intAnd0x1ffToChar(int value) { + return (char) (value & 0x1ff); + } + + /// CHECK-START: int Main.$noinline$getInstanceCharFieldAnd0x1ffff(Main) instruction_simplifier (before) + /// CHECK-DAG: <<Cst1ffff:i\d+>> IntConstant 131071 + /// CHECK-DAG: <<Get:c\d+>> InstanceFieldGet + /// CHECK-DAG: <<And:i\d+>> And [<<Get>>,<<Cst1ffff>>] + /// CHECK-DAG: Return [<<And>>] + + // TODO: Simplify this. The And is useless. + + // CHECK-START: int Main.$noinline$getInstanceCharFieldAnd0x1ffff(Main) instruction_simplifier (after) + // CHECK-DAG: <<Get:c\d+>> InstanceFieldGet + // CHECK-DAG: Return [<<Get>>] + 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; } |