diff options
Diffstat (limited to 'test')
| -rw-r--r-- | test/541-checker-instruction-simplifier-rotate/expected.txt | 0 | ||||
| -rw-r--r-- | test/541-checker-instruction-simplifier-rotate/info.txt | 1 | ||||
| -rw-r--r-- | test/541-checker-instruction-simplifier-rotate/src/Main.java | 659 | ||||
| -rw-r--r-- | test/542-bitfield-rotates/expected.txt | 0 | ||||
| -rw-r--r-- | test/542-bitfield-rotates/info.txt | 1 | ||||
| -rw-r--r-- | test/542-bitfield-rotates/src/Main.java | 423 | ||||
| -rw-r--r-- | test/Android.run-test.mk | 16 |
7 files changed, 1100 insertions, 0 deletions
diff --git a/test/541-checker-instruction-simplifier-rotate/expected.txt b/test/541-checker-instruction-simplifier-rotate/expected.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/541-checker-instruction-simplifier-rotate/expected.txt diff --git a/test/541-checker-instruction-simplifier-rotate/info.txt b/test/541-checker-instruction-simplifier-rotate/info.txt new file mode 100644 index 0000000000..f9a86f8009 --- /dev/null +++ b/test/541-checker-instruction-simplifier-rotate/info.txt @@ -0,0 +1 @@ +Tests simplification of bitfield rotate patterns in optimizing compiler. diff --git a/test/541-checker-instruction-simplifier-rotate/src/Main.java b/test/541-checker-instruction-simplifier-rotate/src/Main.java new file mode 100644 index 0000000000..027f262db1 --- /dev/null +++ b/test/541-checker-instruction-simplifier-rotate/src/Main.java @@ -0,0 +1,659 @@ +/* + * 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 Main { + + public static void assertIntEquals(int expected, int actual) { + if (expected != actual) { + throw new Error("Expected: " + expected + ", found: " + actual); + } + } + + public static void assertLongEquals(long expected, long actual) { + if (expected != actual) { + throw new Error("Expected: " + expected + ", found: " + actual); + } + } + + /// CHECK-START: int Main.rotateIntegerRight(int, int) instruction_simplifier (before) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK: <<Invoke:i\d+>> InvokeStaticOrDirect intrinsic:IntegerRotateRight + + /// CHECK-START: int Main.rotateIntegerRight(int, int) instruction_simplifier (after) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<ArgDistance>>] + /// CHECK: Return [<<Ror>>] + + /// CHECK-START: int Main.rotateIntegerRight(int, int) instruction_simplifier (after) + /// CHECK-NOT: LoadClass + /// CHECK-NOT: ClinitCheck + /// CHECK-NOT: InvokeStaticOrDirect + public static int rotateIntegerRight(int value, int distance) { + return java.lang.Integer.rotateRight(value, distance); + } + + /// CHECK-START: int Main.rotateIntegerLeft(int, int) instruction_simplifier (before) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK: <<Invoke:i\d+>> InvokeStaticOrDirect intrinsic:IntegerRotateLeft + + /// CHECK-START: int Main.rotateIntegerLeft(int, int) instruction_simplifier (after) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK: <<Neg:i\d+>> Neg [<<ArgDistance>>] + /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<Neg>>] + /// CHECK: Return [<<Ror>>] + + /// CHECK-START: int Main.rotateIntegerLeft(int, int) instruction_simplifier (after) + /// CHECK-NOT: LoadClass + /// CHECK-NOT: ClinitCheck + /// CHECK-NOT: InvokeStaticOrDirect + public static int rotateIntegerLeft(int value, int distance) { + return java.lang.Integer.rotateLeft(value, distance); + } + + /// CHECK-START: long Main.rotateLongRight(long, int) instruction_simplifier (before) + /// CHECK: <<ArgValue:j\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK: <<Invoke:j\d+>> InvokeStaticOrDirect intrinsic:LongRotateRight + + /// CHECK-START: long Main.rotateLongRight(long, int) instruction_simplifier (after) + /// CHECK: <<ArgValue:j\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK: <<Ror:j\d+>> Ror [<<ArgValue>>,<<ArgDistance>>] + /// CHECK: Return [<<Ror>>] + + /// CHECK-START: long Main.rotateLongRight(long, int) instruction_simplifier (after) + /// CHECK-NOT: LoadClass + /// CHECK-NOT: ClinitCheck + /// CHECK-NOT: InvokeStaticOrDirect + public static long rotateLongRight(long value, int distance) { + return java.lang.Long.rotateRight(value, distance); + } + + /// CHECK-START: long Main.rotateLongLeft(long, int) instruction_simplifier (before) + /// CHECK: <<ArgValue:j\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK: <<Invoke:j\d+>> InvokeStaticOrDirect intrinsic:LongRotateLeft + + /// CHECK-START: long Main.rotateLongLeft(long, int) instruction_simplifier (after) + /// CHECK: <<ArgValue:j\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK: <<Neg:i\d+>> Neg [<<ArgDistance>>] + /// CHECK: <<Ror:j\d+>> Ror [<<ArgValue>>,<<Neg>>] + /// CHECK: Return [<<Ror>>] + + /// CHECK-START: long Main.rotateLongLeft(long, int) instruction_simplifier (after) + /// CHECK-NOT: LoadClass + /// CHECK-NOT: ClinitCheck + /// CHECK-NOT: InvokeStaticOrDirect + public static long rotateLongLeft(long value, int distance) { + return java.lang.Long.rotateLeft(value, distance); + } + + // (i >>> #distance) | (i << #(reg_bits - distance)) + + /// CHECK-START: int Main.ror_int_constant_c_c(int) instruction_simplifier (before) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<Const2:i\d+>> IntConstant 2 + /// CHECK: <<Const30:i\d+>> IntConstant 30 + /// CHECK-DAG: <<UShr:i\d+>> UShr [<<ArgValue>>,<<Const2>>] + /// CHECK-DAG: <<Shl:i\d+>> Shl [<<ArgValue>>,<<Const30>>] + /// CHECK: <<Or:i\d+>> Or [<<UShr>>,<<Shl>>] + /// CHECK: Return [<<Or>>] + + /// CHECK-START: int Main.ror_int_constant_c_c(int) instruction_simplifier (after) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<Const2:i\d+>> IntConstant 2 + /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<Const2>>] + /// CHECK: Return [<<Ror>>] + + /// CHECK-START: int Main.ror_int_constant_c_c(int) instruction_simplifier (after) + /// CHECK-NOT: UShr + /// CHECK-NOT: Shl + public static int ror_int_constant_c_c(int value) { + return (value >>> 2) | (value << 30); + } + + /// CHECK-START: int Main.ror_int_constant_c_c_0(int) instruction_simplifier (after) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<Const2:i\d+>> IntConstant 2 + /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<Const2>>] + /// CHECK: Return [<<Ror>>] + + /// CHECK-START: int Main.ror_int_constant_c_c_0(int) instruction_simplifier (after) + /// CHECK-NOT: UShr + /// CHECK-NOT: Shl + public static int ror_int_constant_c_c_0(int value) { + return (value >>> 2) | (value << 62); + } + + // (j >>> #distance) | (j << #(reg_bits - distance)) + + /// CHECK-START: long Main.ror_long_constant_c_c(long) instruction_simplifier (before) + /// CHECK: <<ArgValue:j\d+>> ParameterValue + /// CHECK: <<Const2:i\d+>> IntConstant 2 + /// CHECK: <<Const62:i\d+>> IntConstant 62 + /// CHECK-DAG: <<UShr:j\d+>> UShr [<<ArgValue>>,<<Const2>>] + /// CHECK-DAG: <<Shl:j\d+>> Shl [<<ArgValue>>,<<Const62>>] + /// CHECK: <<Or:j\d+>> Or [<<UShr>>,<<Shl>>] + /// CHECK: Return [<<Or>>] + + /// CHECK-START: long Main.ror_long_constant_c_c(long) instruction_simplifier (after) + /// CHECK: <<ArgValue:j\d+>> ParameterValue + /// CHECK: <<Const2:i\d+>> IntConstant 2 + /// CHECK: <<Ror:j\d+>> Ror [<<ArgValue>>,<<Const2>>] + /// CHECK: Return [<<Ror>>] + + /// CHECK-START: long Main.ror_long_constant_c_c(long) instruction_simplifier (after) + /// CHECK-NOT: UShr + /// CHECK-NOT: Shl + public static long ror_long_constant_c_c(long value) { + return (value >>> 2) | (value << 62); + } + + /// CHECK-START: long Main.ror_long_constant_c_c_0(long) instruction_simplifier (after) + /// CHECK-NOT: Ror + public static long ror_long_constant_c_c_0(long value) { + return (value >>> 2) | (value << 30); + } + + // (i >>> #distance) | (i << #-distance) + + /// CHECK-START: int Main.ror_int_constant_c_negc(int) instruction_simplifier (before) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<Const2:i\d+>> IntConstant 2 + /// CHECK: <<ConstNeg2:i\d+>> IntConstant -2 + /// CHECK-DAG: <<UShr:i\d+>> UShr [<<ArgValue>>,<<Const2>>] + /// CHECK-DAG: <<Shl:i\d+>> Shl [<<ArgValue>>,<<ConstNeg2>>] + /// CHECK: <<Or:i\d+>> Or [<<UShr>>,<<Shl>>] + /// CHECK: Return [<<Or>>] + + /// CHECK-START: int Main.ror_int_constant_c_negc(int) instruction_simplifier (after) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<Const2:i\d+>> IntConstant 2 + /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<Const2>>] + /// CHECK: Return [<<Ror>>] + + /// CHECK-START: int Main.ror_int_constant_c_negc(int) instruction_simplifier (after) + /// CHECK-NOT: UShr + /// CHECK-NOT: Shl + public static int ror_int_constant_c_negc(int value) { + return (value >>> 2) | (value << -2); + } + + // (j >>> #distance) | (j << #-distance) + + /// CHECK-START: long Main.ror_long_constant_c_negc(long) instruction_simplifier (before) + /// CHECK: <<ArgValue:j\d+>> ParameterValue + /// CHECK: <<Const2:i\d+>> IntConstant 2 + /// CHECK: <<ConstNeg2:i\d+>> IntConstant -2 + /// CHECK-DAG: <<UShr:j\d+>> UShr [<<ArgValue>>,<<Const2>>] + /// CHECK-DAG: <<Shl:j\d+>> Shl [<<ArgValue>>,<<ConstNeg2>>] + /// CHECK: <<Or:j\d+>> Or [<<UShr>>,<<Shl>>] + /// CHECK: Return [<<Or>>] + + /// CHECK-START: long Main.ror_long_constant_c_negc(long) instruction_simplifier (after) + /// CHECK: <<ArgValue:j\d+>> ParameterValue + /// CHECK: <<Const2:i\d+>> IntConstant 2 + /// CHECK: <<Ror:j\d+>> Ror [<<ArgValue>>,<<Const2>>] + /// CHECK: Return [<<Ror>>] + + /// CHECK-START: long Main.ror_long_constant_c_negc(long) instruction_simplifier (after) + /// CHECK-NOT: UShr + /// CHECK-NOT: Shl + public static long ror_long_constant_c_negc(long value) { + return (value >>> 2) | (value << -2); + } + + // (i >>> distance) | (i << (#reg_bits - distance) + + /// CHECK-START: int Main.ror_int_reg_v_csubv(int, int) instruction_simplifier (before) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK: <<Const32:i\d+>> IntConstant 32 + /// CHECK-DAG: <<UShr:i\d+>> UShr [<<ArgValue>>,<<ArgDistance>>] + /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Const32>>,<<ArgDistance>>] + /// CHECK-DAG: <<Shl:i\d+>> Shl [<<ArgValue>>,<<Sub>>] + /// CHECK: <<Or:i\d+>> Or [<<UShr>>,<<Shl>>] + /// CHECK: Return [<<Or>>] + + /// CHECK-START: int Main.ror_int_reg_v_csubv(int, int) instruction_simplifier (after) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<ArgDistance>>] + /// CHECK: Return [<<Ror>>] + + /// CHECK-START: int Main.ror_int_reg_v_csubv(int, int) instruction_simplifier (after) + /// CHECK-NOT: UShr + /// CHECK-NOT: Shl + /// CHECK-NOT: Sub + public static int ror_int_reg_v_csubv(int value, int distance) { + return (value >>> distance) | (value << (32 - distance)); + } + + // (distance = x - y) + // (i >>> distance) | (i << (#reg_bits - distance) + + /// CHECK-START: int Main.ror_int_subv_csubv(int, int, int) instruction_simplifier (before) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<ArgX:i\d+>> ParameterValue + /// CHECK: <<ArgY:i\d+>> ParameterValue + /// CHECK: <<Const32:i\d+>> IntConstant 32 + /// CHECK-DAG: <<SubDistance:i\d+>> Sub [<<ArgX>>,<<ArgY>>] + /// CHECK-DAG: <<Sub32:i\d+>> Sub [<<Const32>>,<<SubDistance>>] + /// CHECK-DAG: <<Shl:i\d+>> Shl [<<ArgValue>>,<<Sub32>>] + /// CHECK-DAG: <<UShr:i\d+>> UShr [<<ArgValue>>,<<SubDistance>>] + /// CHECK: <<Or:i\d+>> Or [<<UShr>>,<<Shl>>] + /// CHECK: Return [<<Or>>] + + /// CHECK-START: int Main.ror_int_subv_csubv(int, int, int) instruction_simplifier (after) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<ArgX:i\d+>> ParameterValue + /// CHECK: <<ArgY:i\d+>> ParameterValue + /// CHECK: <<SubDistance:i\d+>> Sub [<<ArgX>>,<<ArgY>>] + /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<SubDistance>>] + /// CHECK: Return [<<Ror>>] + + /// CHECK-START: int Main.ror_int_subv_csubv(int, int, int) instruction_simplifier (after) + /// CHECK: Sub + /// CHECK-NOT: Sub + + /// CHECK-START: int Main.ror_int_subv_csubv(int, int, int) instruction_simplifier (after) + /// CHECK-NOT: UShr + /// CHECK-NOT: Shl + public static int ror_int_subv_csubv(int value, int x, int y) { + int distance = x - y; + return (value >>> distance) | (value << (32 - distance)); + } + + /// CHECK-START: int Main.ror_int_subv_csubv_env(int, int, int) instruction_simplifier (before) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<ArgX:i\d+>> ParameterValue + /// CHECK: <<ArgY:i\d+>> ParameterValue + /// CHECK: <<Const32:i\d+>> IntConstant 32 + /// CHECK-DAG: <<SubDistance:i\d+>> Sub [<<ArgX>>,<<ArgY>>] + /// CHECK-DAG: <<Sub32:i\d+>> Sub [<<Const32>>,<<SubDistance>>] + /// CHECK-DAG: <<UShr:i\d+>> UShr [<<ArgValue>>,<<SubDistance>>] + /// CHECK-DAG: <<Shl:i\d+>> Shl [<<ArgValue>>,<<Sub32>>] + /// CHECK: <<Or:i\d+>> Or [<<UShr>>,<<Shl>>] + /// CHECK: <<Add:i\d+>> Add [<<Or>>,<<Sub32>>] + /// CHECK: Return [<<Add>>] + + /// CHECK-START: int Main.ror_int_subv_csubv_env(int, int, int) instruction_simplifier (after) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<ArgX:i\d+>> ParameterValue + /// CHECK: <<ArgY:i\d+>> ParameterValue + /// CHECK: <<Const32:i\d+>> IntConstant 32 + /// CHECK-DAG: <<SubDistance:i\d+>> Sub [<<ArgX>>,<<ArgY>>] + /// CHECK-DAG: <<Sub32:i\d+>> Sub [<<Const32>>,<<SubDistance>>] + /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<SubDistance>>] + /// CHECK: <<Add:i\d+>> Add [<<Ror>>,<<Sub32>>] + /// CHECK: Return [<<Add>>] + + /// CHECK-START: int Main.ror_int_subv_csubv_env(int, int, int) instruction_simplifier (after) + /// CHECK-NOT: UShr + /// CHECK-NOT: Shl + public static int ror_int_subv_csubv_env(int value, int x, int y) { + int distance = x - y; + int bits_minus_dist = 32 - distance; + return ((value >>> distance) | (value << bits_minus_dist)) + bits_minus_dist; + } + + // (j >>> distance) | (j << (#reg_bits - distance) + + /// CHECK-START: long Main.ror_long_reg_v_csubv(long, int) instruction_simplifier (before) + /// CHECK: <<ArgValue:j\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK: <<Const64:i\d+>> IntConstant 64 + /// CHECK-DAG: <<UShr:j\d+>> UShr [<<ArgValue>>,<<ArgDistance>>] + /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Const64>>,<<ArgDistance>>] + /// CHECK-DAG: <<Shl:j\d+>> Shl [<<ArgValue>>,<<Sub>>] + /// CHECK: <<Or:j\d+>> Or [<<UShr>>,<<Shl>>] + /// CHECK: Return [<<Or>>] + + /// CHECK-START: long Main.ror_long_reg_v_csubv(long, int) instruction_simplifier (after) + /// CHECK: <<ArgValue:j\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK: <<Ror:j\d+>> Ror [<<ArgValue>>,<<ArgDistance>>] + /// CHECK: Return [<<Ror>>] + + /// CHECK-START: long Main.ror_long_reg_v_csubv(long, int) instruction_simplifier (after) + /// CHECK-NOT: UShr + /// CHECK-NOT: Shl + /// CHECK-NOT: Sub + public static long ror_long_reg_v_csubv(long value, int distance) { + return (value >>> distance) | (value << (64 - distance)); + } + + /// CHECK-START: long Main.ror_long_reg_v_csubv_0(long, int) instruction_simplifier (after) + /// CHECK-NOT: Ror + public static long ror_long_reg_v_csubv_0(long value, int distance) { + return (value >>> distance) | (value << (32 - distance)); + } + + /// CHECK-START: long Main.ror_long_subv_csubv_0(long, int, int) instruction_simplifier (after) + /// CHECK-NOT: Ror + public static long ror_long_subv_csubv_0(long value, int x, int y) { + int distance = x - y; + return (value >>> distance) | (value << (32 - distance)); + } + + // (i >>> (#reg_bits - distance)) | (i << distance) + + /// CHECK-START: int Main.rol_int_reg_csubv_v(int, int) instruction_simplifier (before) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK: <<Const32:i\d+>> IntConstant 32 + /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Const32>>,<<ArgDistance>>] + /// CHECK-DAG: <<UShr:i\d+>> UShr [<<ArgValue>>,<<Sub>>] + /// CHECK-DAG: <<Shl:i\d+>> Shl [<<ArgValue>>,<<ArgDistance>>] + /// CHECK: <<Or:i\d+>> Or [<<UShr>>,<<Shl>>] + /// CHECK: Return [<<Or>>] + + /// CHECK-START: int Main.rol_int_reg_csubv_v(int, int) instruction_simplifier (after) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK: <<Const32:i\d+>> IntConstant 32 + /// CHECK: <<Sub:i\d+>> Sub [<<Const32>>,<<ArgDistance>>] + /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<Sub>>] + /// CHECK: Return [<<Ror>>] + + /// CHECK-START: int Main.rol_int_reg_csubv_v(int, int) instruction_simplifier (after) + /// CHECK-NOT: UShr + /// CHECK-NOT: Shl + public static int rol_int_reg_csubv_v(int value, int distance) { + return (value >>> (32 - distance)) | (value << distance); + } + + // (distance = x - y) + // (i >>> (#reg_bits - distance)) | (i << distance) + + /// CHECK-START: int Main.rol_int_csubv_subv(int, int, int) instruction_simplifier (before) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<ArgX:i\d+>> ParameterValue + /// CHECK: <<ArgY:i\d+>> ParameterValue + /// CHECK: <<Const32:i\d+>> IntConstant 32 + /// CHECK-DAG: <<SubDistance:i\d+>> Sub [<<ArgX>>,<<ArgY>>] + /// CHECK-DAG: <<Sub32:i\d+>> Sub [<<Const32>>,<<SubDistance>>] + /// CHECK-DAG: <<Shl:i\d+>> Shl [<<ArgValue>>,<<SubDistance>>] + /// CHECK-DAG: <<UShr:i\d+>> UShr [<<ArgValue>>,<<Sub32>>] + /// CHECK: <<Or:i\d+>> Or [<<UShr>>,<<Shl>>] + /// CHECK: Return [<<Or>>] + + /// CHECK-START: int Main.rol_int_csubv_subv(int, int, int) instruction_simplifier (after) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<ArgX:i\d+>> ParameterValue + /// CHECK: <<ArgY:i\d+>> ParameterValue + /// CHECK: <<Const32:i\d+>> IntConstant 32 + /// CHECK: <<SubDistance:i\d+>> Sub [<<ArgX>>,<<ArgY>>] + /// CHECK: <<Sub:i\d+>> Sub [<<Const32>>,<<SubDistance>>] + /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<Sub>>] + /// CHECK: Return [<<Ror>>] + + /// CHECK-START: int Main.rol_int_csubv_subv(int, int, int) instruction_simplifier (after) + /// CHECK: Sub + /// CHECK: Sub + + /// CHECK-START: int Main.rol_int_csubv_subv(int, int, int) instruction_simplifier (after) + /// CHECK-NOT: UShr + /// CHECK-NOT: Shl + public static int rol_int_csubv_subv(int value, int x, int y) { + int distance = x - y; + return (value >>> (32 - distance)) | (value << distance); + } + + // (j >>> (#reg_bits - distance)) | (j << distance) + + /// CHECK-START: long Main.rol_long_reg_csubv_v(long, int) instruction_simplifier (before) + /// CHECK: <<ArgValue:j\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK: <<Const64:i\d+>> IntConstant 64 + /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Const64>>,<<ArgDistance>>] + /// CHECK-DAG: <<UShr:j\d+>> UShr [<<ArgValue>>,<<Sub>>] + /// CHECK-DAG: <<Shl:j\d+>> Shl [<<ArgValue>>,<<ArgDistance>>] + /// CHECK: <<Or:j\d+>> Or [<<UShr>>,<<Shl>>] + /// CHECK: Return [<<Or>>] + + /// CHECK-START: long Main.rol_long_reg_csubv_v(long, int) instruction_simplifier (after) + /// CHECK: <<ArgValue:j\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK: <<Const64:i\d+>> IntConstant 64 + /// CHECK: <<Sub:i\d+>> Sub [<<Const64>>,<<ArgDistance>>] + /// CHECK: <<Ror:j\d+>> Ror [<<ArgValue>>,<<Sub>>] + /// CHECK: Return [<<Ror>>] + + /// CHECK-START: long Main.rol_long_reg_csubv_v(long, int) instruction_simplifier (after) + /// CHECK-NOT: UShr + /// CHECK-NOT: Shl + public static long rol_long_reg_csubv_v(long value, int distance) { + return (value >>> (64 - distance)) | (value << distance); + } + + /// CHECK-START: long Main.rol_long_reg_csubv_v_0(long, int) instruction_simplifier (after) + /// CHECK-NOT: Ror + public static long rol_long_reg_csubv_v_0(long value, int distance) { + return (value >>> (32 - distance)) | (value << distance); + } + + // (i >>> distance) | (i << -distance) (i.e. libcore's Integer.rotateRight) + + /// CHECK-START: int Main.ror_int_reg_v_negv(int, int) instruction_simplifier (before) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK-DAG: <<UShr:i\d+>> UShr [<<ArgValue>>,<<ArgDistance>>] + /// CHECK-DAG: <<Neg:i\d+>> Neg [<<ArgDistance>>] + /// CHECK-DAG: <<Shl:i\d+>> Shl [<<ArgValue>>,<<Neg>>] + /// CHECK: <<Or:i\d+>> Or [<<UShr>>,<<Shl>>] + /// CHECK: Return [<<Or>>] + + /// CHECK-START: int Main.ror_int_reg_v_negv(int, int) instruction_simplifier (after) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<ArgDistance>>] + /// CHECK: Return [<<Ror>>] + + /// CHECK-START: int Main.ror_int_reg_v_negv(int, int) instruction_simplifier (after) + /// CHECK-NOT: UShr + /// CHECK-NOT: Shl + /// CHECK-NOT: Neg + public static int ror_int_reg_v_negv(int value, int distance) { + return (value >>> distance) | (value << -distance); + } + + /// CHECK-START: int Main.ror_int_reg_v_negv_env(int, int) instruction_simplifier (before) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK-DAG: <<Neg:i\d+>> Neg [<<ArgDistance>>] + /// CHECK-DAG: <<UShr:i\d+>> UShr [<<ArgValue>>,<<ArgDistance>>] + /// CHECK-DAG: <<Shl:i\d+>> Shl [<<ArgValue>>,<<Neg>>] + /// CHECK: <<Or:i\d+>> Or [<<UShr>>,<<Shl>>] + /// CHECK: <<Add:i\d+>> Add [<<Or>>,<<Neg>>] + /// CHECK: Return [<<Add>>] + + /// CHECK-START: int Main.ror_int_reg_v_negv_env(int, int) instruction_simplifier (after) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<ArgDistance>>] + /// CHECK: <<Sub:i\d+>> Sub [<<Ror>>,<<ArgDistance>>] + /// CHECK: Return [<<Sub>>] + + /// CHECK-START: int Main.ror_int_reg_v_negv_env(int, int) instruction_simplifier (after) + /// CHECK-NOT: UShr + /// CHECK-NOT: Shl + public static int ror_int_reg_v_negv_env(int value, int distance) { + int neg_distance = -distance; + return ((value >>> distance) | (value << neg_distance)) + neg_distance; + } + + // (j >>> distance) | (j << -distance) (i.e. libcore's Long.rotateRight) + + /// CHECK-START: long Main.ror_long_reg_v_negv(long, int) instruction_simplifier (before) + /// CHECK: <<ArgValue:j\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK-DAG: <<UShr:j\d+>> UShr [<<ArgValue>>,<<ArgDistance>>] + /// CHECK-DAG: <<Neg:i\d+>> Neg [<<ArgDistance>>] + /// CHECK-DAG: <<Shl:j\d+>> Shl [<<ArgValue>>,<<Neg>>] + /// CHECK: <<Or:j\d+>> Or [<<UShr>>,<<Shl>>] + /// CHECK: Return [<<Or>>] + + /// CHECK-START: long Main.ror_long_reg_v_negv(long, int) instruction_simplifier (after) + /// CHECK: <<ArgValue:j\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK: <<Ror:j\d+>> Ror [<<ArgValue>>,<<ArgDistance>>] + /// CHECK: Return [<<Ror>>] + + /// CHECK-START: long Main.ror_long_reg_v_negv(long, int) instruction_simplifier (after) + /// CHECK-NOT: UShr + /// CHECK-NOT: Shl + /// CHECK-NOT: Neg + public static long ror_long_reg_v_negv(long value, int distance) { + return (value >>> distance) | (value << -distance); + } + + // (i << distance) | (i >>> -distance) (i.e. libcore's Integer.rotateLeft) + + /// CHECK-START: int Main.rol_int_reg_negv_v(int, int) instruction_simplifier (before) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK-DAG: <<Neg:i\d+>> Neg [<<ArgDistance>>] + /// CHECK-DAG: <<UShr:i\d+>> UShr [<<ArgValue>>,<<Neg>>] + /// CHECK-DAG: <<Shl:i\d+>> Shl [<<ArgValue>>,<<ArgDistance>>] + /// CHECK: <<Or:i\d+>> Or [<<Shl>>,<<UShr>>] + /// CHECK: Return [<<Or>>] + + /// CHECK-START: int Main.rol_int_reg_negv_v(int, int) instruction_simplifier (after) + /// CHECK: <<ArgValue:i\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK: <<Neg:i\d+>> Neg [<<ArgDistance>>] + /// CHECK: <<Ror:i\d+>> Ror [<<ArgValue>>,<<Neg>>] + /// CHECK: Return [<<Ror>>] + + /// CHECK-START: int Main.rol_int_reg_negv_v(int, int) instruction_simplifier (after) + /// CHECK-NOT: UShr + /// CHECK-NOT: Shl + public static int rol_int_reg_negv_v(int value, int distance) { + return (value << distance) | (value >>> -distance); + } + + // (j << distance) | (j >>> -distance) (i.e. libcore's Long.rotateLeft) + + /// CHECK-START: long Main.rol_long_reg_negv_v(long, int) instruction_simplifier (before) + /// CHECK: <<ArgValue:j\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK-DAG: <<Neg:i\d+>> Neg [<<ArgDistance>>] + /// CHECK-DAG: <<UShr:j\d+>> UShr [<<ArgValue>>,<<Neg>>] + /// CHECK-DAG: <<Shl:j\d+>> Shl [<<ArgValue>>,<<ArgDistance>>] + /// CHECK: <<Or:j\d+>> Or [<<Shl>>,<<UShr>>] + /// CHECK: Return [<<Or>>] + + /// CHECK-START: long Main.rol_long_reg_negv_v(long, int) instruction_simplifier (after) + /// CHECK: <<ArgValue:j\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK: <<Neg:i\d+>> Neg [<<ArgDistance>>] + /// CHECK: <<Ror:j\d+>> Ror [<<ArgValue>>,<<Neg>>] + /// CHECK: Return [<<Ror>>] + + /// CHECK-START: long Main.rol_long_reg_negv_v(long, int) instruction_simplifier (after) + /// CHECK-NOT: UShr + /// CHECK-NOT: Shl + public static long rol_long_reg_negv_v(long value, int distance) { + return (value << distance) | (value >>> -distance); + } + + // (j << distance) + (j >>> -distance) + + /// CHECK-START: long Main.rol_long_reg_v_negv_add(long, int) instruction_simplifier (before) + /// CHECK: <<ArgValue:j\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK-DAG: <<Neg:i\d+>> Neg [<<ArgDistance>>] + /// CHECK-DAG: <<UShr:j\d+>> UShr [<<ArgValue>>,<<Neg>>] + /// CHECK-DAG: <<Shl:j\d+>> Shl [<<ArgValue>>,<<ArgDistance>>] + /// CHECK: <<Add:j\d+>> Add [<<Shl>>,<<UShr>>] + /// CHECK: Return [<<Add>>] + + /// CHECK-START: long Main.rol_long_reg_v_negv_add(long, int) instruction_simplifier (after) + /// CHECK: <<ArgValue:j\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK: <<Neg:i\d+>> Neg [<<ArgDistance>>] + /// CHECK: <<Ror:j\d+>> Ror [<<ArgValue>>,<<Neg>>] + /// CHECK: Return [<<Ror>>] + + /// CHECK-START: long Main.rol_long_reg_v_negv_add(long, int) instruction_simplifier (after) + /// CHECK-NOT: Add + /// CHECK-NOT: Shl + /// CHECK-NOT: UShr + public static long rol_long_reg_v_negv_add(long value, int distance) { + return (value << distance) + (value >>> -distance); + } + + // (j << distance) ^ (j >>> -distance) + + /// CHECK-START: long Main.rol_long_reg_v_negv_xor(long, int) instruction_simplifier (before) + /// CHECK: <<ArgValue:j\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK-DAG: <<Neg:i\d+>> Neg [<<ArgDistance>>] + /// CHECK-DAG: <<UShr:j\d+>> UShr [<<ArgValue>>,<<Neg>>] + /// CHECK-DAG: <<Shl:j\d+>> Shl [<<ArgValue>>,<<ArgDistance>>] + /// CHECK: <<Xor:j\d+>> Xor [<<Shl>>,<<UShr>>] + /// CHECK: Return [<<Xor>>] + + /// CHECK-START: long Main.rol_long_reg_v_negv_xor(long, int) instruction_simplifier (after) + /// CHECK: <<ArgValue:j\d+>> ParameterValue + /// CHECK: <<ArgDistance:i\d+>> ParameterValue + /// CHECK: <<Neg:i\d+>> Neg [<<ArgDistance>>] + /// CHECK: <<Ror:j\d+>> Ror [<<ArgValue>>,<<Neg>>] + /// CHECK: Return [<<Ror>>] + + /// CHECK-START: long Main.rol_long_reg_v_negv_xor(long, int) instruction_simplifier (after) + /// CHECK-NOT: Xor + /// CHECK-NOT: Shl + /// CHECK-NOT: UShr + public static long rol_long_reg_v_negv_xor(long value, int distance) { + return (value << distance) ^ (value >>> -distance); + } + + public static void main(String[] args) { + assertIntEquals(2, ror_int_constant_c_c(8)); + assertIntEquals(2, ror_int_constant_c_c_0(8)); + assertLongEquals(2L, ror_long_constant_c_c(8L)); + + assertIntEquals(2, ror_int_constant_c_negc(8)); + assertLongEquals(2L, ror_long_constant_c_negc(8L)); + + assertIntEquals(2, ror_int_reg_v_csubv(8, 2)); + assertLongEquals(2L, ror_long_reg_v_csubv(8L, 2)); + + assertIntEquals(2, ror_int_subv_csubv(8, 2, 0)); + assertIntEquals(32, ror_int_subv_csubv_env(8, 2, 0)); + assertIntEquals(32, rol_int_csubv_subv(8, 2, 0)); + + assertIntEquals(32, rol_int_reg_csubv_v(8, 2)); + assertLongEquals(32L, rol_long_reg_csubv_v(8L, 2)); + + assertIntEquals(2, ror_int_reg_v_negv(8, 2)); + assertIntEquals(0, ror_int_reg_v_negv_env(8, 2)); + assertLongEquals(2L, ror_long_reg_v_negv(8L, 2)); + + assertIntEquals(32, rol_int_reg_negv_v(8, 2)); + assertLongEquals(32L, rol_long_reg_negv_v(8L, 2)); + + assertLongEquals(32L, rol_long_reg_v_negv_add(8L, 2)); + assertLongEquals(32L, rol_long_reg_v_negv_xor(8L, 2)); + } +} diff --git a/test/542-bitfield-rotates/expected.txt b/test/542-bitfield-rotates/expected.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/542-bitfield-rotates/expected.txt diff --git a/test/542-bitfield-rotates/info.txt b/test/542-bitfield-rotates/info.txt new file mode 100644 index 0000000000..961be3bdae --- /dev/null +++ b/test/542-bitfield-rotates/info.txt @@ -0,0 +1 @@ +Tests bitfield rotate simplification in optimizing compiler. diff --git a/test/542-bitfield-rotates/src/Main.java b/test/542-bitfield-rotates/src/Main.java new file mode 100644 index 0000000000..9ef5f93ea2 --- /dev/null +++ b/test/542-bitfield-rotates/src/Main.java @@ -0,0 +1,423 @@ +/* + * Copyright (C) 2007 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 assertIntEquals(int expected, int actual) { + if (expected != actual) { + throw new Error("Expected: " + expected + ", found: " + actual); + } + } + + public static void assertLongEquals(long expected, long actual) { + if (expected != actual) { + throw new Error("Expected: " + expected + ", found: " + actual); + } + } + + public static void main(String args[]) throws Exception { + test_Integer_right_v_csubv(); + test_Long_right_v_csubv(); + + test_Integer_right_constant_v(); + test_Long_right_constant_v(); + + test_Integer_left_csubv_v(); + test_Long_left_csubv_v(); + + test_Integer_right_v_negv(); + test_Long_right_v_negv(); + + test_Integer_left_negv_v(); + test_Long_left_negv_v(); + + test_Integer_left_constant_v(); + test_Long_left_constant_v(); + } + + public static boolean doThrow = false; + + public static int $noinline$rotate_int_right_reg_v_csubv(int value, int distance) { + if (doThrow) { + throw new Error(); + } + return (value >>> distance) | (value << (32 - distance)); + } + + public static void test_Integer_right_v_csubv() throws Exception { + assertIntEquals($noinline$rotate_int_right_reg_v_csubv(0x11, 0), 0x11); + + assertIntEquals($noinline$rotate_int_right_reg_v_csubv(0x11, 1), 0x80000008); + assertIntEquals($noinline$rotate_int_right_reg_v_csubv(0x11, Integer.SIZE - 1), 0x22); + assertIntEquals($noinline$rotate_int_right_reg_v_csubv(0x11, Integer.SIZE), 0x11); + assertIntEquals($noinline$rotate_int_right_reg_v_csubv(0x11, Integer.SIZE + 1), 0x80000008); + + assertIntEquals($noinline$rotate_int_right_reg_v_csubv(0x11, -1), 0x22); + assertIntEquals($noinline$rotate_int_right_reg_v_csubv(0x11, -(Integer.SIZE - 1)), 0x80000008); + assertIntEquals($noinline$rotate_int_right_reg_v_csubv(0x11, -Integer.SIZE), 0x11); + assertIntEquals($noinline$rotate_int_right_reg_v_csubv(0x11, -(Integer.SIZE + 1)), 0x22); + + assertIntEquals($noinline$rotate_int_right_reg_v_csubv(0x80000000, 1), 0x40000000); + } + + public static long $noinline$rotate_long_right_reg_v_csubv(long value, int distance) { + if (doThrow) { + throw new Error(); + } + return (value >>> distance) | (value << (64 - distance)); + } + + public static void test_Long_right_v_csubv() throws Exception { + assertLongEquals($noinline$rotate_long_right_reg_v_csubv(0x11, 0), 0x11); + + assertLongEquals($noinline$rotate_long_right_reg_v_csubv(0x11, 1), 0x8000000000000008L); + assertLongEquals($noinline$rotate_long_right_reg_v_csubv(0x11, Long.SIZE - 1), 0x22); + assertLongEquals($noinline$rotate_long_right_reg_v_csubv(0x11, Long.SIZE), 0x11); + assertLongEquals($noinline$rotate_long_right_reg_v_csubv(0x11, Long.SIZE + 1), 0x8000000000000008L); + + assertLongEquals($noinline$rotate_long_right_reg_v_csubv(0x11, -1), 0x22); + assertLongEquals($noinline$rotate_long_right_reg_v_csubv(0x11, -(Long.SIZE - 1)), 0x8000000000000008L); + assertLongEquals($noinline$rotate_long_right_reg_v_csubv(0x11, -Long.SIZE), 0x11); + assertLongEquals($noinline$rotate_long_right_reg_v_csubv(0x11, -(Long.SIZE + 1)), 0x22); + + assertLongEquals($noinline$rotate_long_right_reg_v_csubv(0x8000000000000000L, 1), 0x4000000000000000L); + } + + public static int $noinline$rotate_int_left_reg_csubv_v(int value, int distance) { + if (doThrow) { + throw new Error(); + } + return (value >>> (32 - distance)) | (value << distance); + } + + public static void test_Integer_left_csubv_v() throws Exception { + assertIntEquals($noinline$rotate_int_left_reg_csubv_v(0x11, 0), 0x11); + + assertIntEquals($noinline$rotate_int_left_reg_csubv_v(0x11, 1), 0x22); + assertIntEquals($noinline$rotate_int_left_reg_csubv_v(0x11, Integer.SIZE - 1), 0x80000008); + assertIntEquals($noinline$rotate_int_left_reg_csubv_v(0x11, Integer.SIZE), 0x11); + assertIntEquals($noinline$rotate_int_left_reg_csubv_v(0x11, Integer.SIZE + 1), 0x22); + + assertIntEquals($noinline$rotate_int_left_reg_csubv_v(0x11, -1), 0x80000008); + assertIntEquals($noinline$rotate_int_left_reg_csubv_v(0x11, -(Integer.SIZE - 1)), 0x22); + assertIntEquals($noinline$rotate_int_left_reg_csubv_v(0x11, -Integer.SIZE), 0x11); + assertIntEquals($noinline$rotate_int_left_reg_csubv_v(0x11, -(Integer.SIZE + 1)), 0x80000008); + + assertIntEquals($noinline$rotate_int_left_reg_csubv_v(0xC0000000, 1), 0x80000001); + } + + public static long $noinline$rotate_long_left_reg_csubv_v(long value, int distance) { + if (doThrow) { + throw new Error(); + } + return (value >>> (64 - distance)) | (value << distance); + } + + public static void test_Long_left_csubv_v() throws Exception { + assertLongEquals($noinline$rotate_long_left_reg_csubv_v(0x11, 0), 0x11); + + assertLongEquals($noinline$rotate_long_left_reg_csubv_v(0x11, 1), 0x22); + assertLongEquals($noinline$rotate_long_left_reg_csubv_v(0x11, Long.SIZE - 1), 0x8000000000000008L); + assertLongEquals($noinline$rotate_long_left_reg_csubv_v(0x11, Long.SIZE), 0x11); + assertLongEquals($noinline$rotate_long_left_reg_csubv_v(0x11, Long.SIZE + 1), 0x22); + + assertLongEquals($noinline$rotate_long_left_reg_csubv_v(0x11, -1), 0x8000000000000008L); + assertLongEquals($noinline$rotate_long_left_reg_csubv_v(0x11, -(Long.SIZE - 1)), 0x22); + assertLongEquals($noinline$rotate_long_left_reg_csubv_v(0x11, -Long.SIZE), 0x11); + assertLongEquals($noinline$rotate_long_left_reg_csubv_v(0x11, -(Long.SIZE + 1)), 0x8000000000000008L); + + assertLongEquals($noinline$rotate_long_left_reg_csubv_v(0xC000000000000000L, 1), 0x8000000000000001L); + } + + public static int $noinline$rotate_int_right_reg_v_negv(int value, int distance) { + if (doThrow) { + throw new Error(); + } + return (value >>> distance) | (value << -distance); + } + + public static void test_Integer_right_v_negv() throws Exception { + assertIntEquals($noinline$rotate_int_right_reg_v_negv(0x11, 0), 0x11); + + assertIntEquals($noinline$rotate_int_right_reg_v_negv(0x11, 1), 0x80000008); + assertIntEquals($noinline$rotate_int_right_reg_v_negv(0x11, Integer.SIZE - 1), 0x22); + assertIntEquals($noinline$rotate_int_right_reg_v_negv(0x11, Integer.SIZE), 0x11); + assertIntEquals($noinline$rotate_int_right_reg_v_negv(0x11, Integer.SIZE + 1), 0x80000008); + + assertIntEquals($noinline$rotate_int_right_reg_v_negv(0x11, -1), 0x22); + assertIntEquals($noinline$rotate_int_right_reg_v_negv(0x11, -(Integer.SIZE - 1)), 0x80000008); + assertIntEquals($noinline$rotate_int_right_reg_v_negv(0x11, -Integer.SIZE), 0x11); + assertIntEquals($noinline$rotate_int_right_reg_v_negv(0x11, -(Integer.SIZE + 1)), 0x22); + + assertIntEquals($noinline$rotate_int_right_reg_v_negv(0x80000000, 1), 0x40000000); + } + + public static long $noinline$rotate_long_right_reg_v_negv(long value, int distance) { + if (doThrow) { + throw new Error(); + } + return (value >>> distance) | (value << -distance); + } + + public static void test_Long_right_v_negv() throws Exception { + assertLongEquals($noinline$rotate_long_right_reg_v_negv(0x11, 0), 0x11); + + assertLongEquals($noinline$rotate_long_right_reg_v_negv(0x11, 1), 0x8000000000000008L); + assertLongEquals($noinline$rotate_long_right_reg_v_negv(0x11, Long.SIZE - 1), 0x22); + assertLongEquals($noinline$rotate_long_right_reg_v_negv(0x11, Long.SIZE), 0x11); + assertLongEquals($noinline$rotate_long_right_reg_v_negv(0x11, Long.SIZE + 1), 0x8000000000000008L); + + assertLongEquals($noinline$rotate_long_right_reg_v_negv(0x11, -1), 0x22); + assertLongEquals($noinline$rotate_long_right_reg_v_negv(0x11, -(Long.SIZE - 1)), 0x8000000000000008L); + assertLongEquals($noinline$rotate_long_right_reg_v_negv(0x11, -Long.SIZE), 0x11); + assertLongEquals($noinline$rotate_long_right_reg_v_negv(0x11, -(Long.SIZE + 1)), 0x22); + + assertLongEquals($noinline$rotate_long_right_reg_v_negv(0x8000000000000000L, 1), 0x4000000000000000L); + } + + public static int $noinline$rotate_int_left_reg_negv_v(int value, int distance) { + if (doThrow) { + throw new Error(); + } + return (value >>> -distance) | (value << distance); + } + + public static void test_Integer_left_negv_v() throws Exception { + assertIntEquals($noinline$rotate_int_left_reg_negv_v(0x11, 0), 0x11); + + assertIntEquals($noinline$rotate_int_left_reg_negv_v(0x11, 1), 0x22); + assertIntEquals($noinline$rotate_int_left_reg_negv_v(0x11, Integer.SIZE - 1), 0x80000008); + assertIntEquals($noinline$rotate_int_left_reg_negv_v(0x11, Integer.SIZE), 0x11); + assertIntEquals($noinline$rotate_int_left_reg_negv_v(0x11, Integer.SIZE + 1), 0x22); + + assertIntEquals($noinline$rotate_int_left_reg_negv_v(0x11, -1), 0x80000008); + assertIntEquals($noinline$rotate_int_left_reg_negv_v(0x11, -(Integer.SIZE - 1)), 0x22); + assertIntEquals($noinline$rotate_int_left_reg_negv_v(0x11, -Integer.SIZE), 0x11); + assertIntEquals($noinline$rotate_int_left_reg_negv_v(0x11, -(Integer.SIZE + 1)), 0x80000008); + + assertIntEquals($noinline$rotate_int_left_reg_negv_v(0xC0000000, 1), 0x80000001); + } + + public static long $noinline$rotate_long_left_reg_negv_v(long value, int distance) { + if (doThrow) { + throw new Error(); + } + return (value >>> -distance) | (value << distance); + } + + public static void test_Long_left_negv_v() throws Exception { + assertLongEquals($noinline$rotate_long_left_reg_negv_v(0x11, 0), 0x11); + + assertLongEquals($noinline$rotate_long_left_reg_negv_v(0x11, 1), 0x22); + assertLongEquals($noinline$rotate_long_left_reg_negv_v(0x11, Long.SIZE - 1), 0x8000000000000008L); + assertLongEquals($noinline$rotate_long_left_reg_negv_v(0x11, Long.SIZE), 0x11); + assertLongEquals($noinline$rotate_long_left_reg_negv_v(0x11, Long.SIZE + 1), 0x22); + + assertLongEquals($noinline$rotate_long_left_reg_negv_v(0x11, -1), 0x8000000000000008L); + assertLongEquals($noinline$rotate_long_left_reg_negv_v(0x11, -(Long.SIZE - 1)), 0x22); + assertLongEquals($noinline$rotate_long_left_reg_negv_v(0x11, -Long.SIZE), 0x11); + assertLongEquals($noinline$rotate_long_left_reg_negv_v(0x11, -(Long.SIZE + 1)), 0x8000000000000008L); + + assertLongEquals($noinline$rotate_long_left_reg_negv_v(0xC000000000000000L, 1), 0x8000000000000001L); + } + + public static int $noinline$rotate_int_right_constant_0(int value) { + if (doThrow) { + throw new Error(); + } + return (value >>> 0) | (value << 0); + } + + public static int $noinline$rotate_int_right_constant_1(int value) { + if (doThrow) { + throw new Error(); + } + return (value >>> 1) | (value << -1); + } + + public static int $noinline$rotate_int_right_constant_m1(int value) { + if (doThrow) { + throw new Error(); + } + return (value >>> -1) | (value << 1); + } + + public static int $noinline$rotate_int_right_constant_16(int value) { + if (doThrow) { + throw new Error(); + } + return (value >>> 16) | (value << -16); + } + + public static void test_Integer_right_constant_v() throws Exception { + assertIntEquals($noinline$rotate_int_right_constant_0(0x11), 0x11); + assertIntEquals($noinline$rotate_int_right_constant_1(0x11), 0x80000008); + assertIntEquals($noinline$rotate_int_right_constant_m1(0x11), 0x22); + assertIntEquals($noinline$rotate_int_right_constant_16(0x11), 0x110000); + } + + public static long $noinline$rotate_long_right_constant_0(long value) { + if (doThrow) { + throw new Error(); + } + return (value >>> 0) | (value << 0); + } + + public static long $noinline$rotate_long_right_constant_1(long value) { + if (doThrow) { + throw new Error(); + } + return (value >>> 1) | (value << -1); + } + + public static long $noinline$rotate_long_right_constant_m1(long value) { + if (doThrow) { + throw new Error(); + } + return (value >>> -1) | (value << 1); + } + + public static long $noinline$rotate_long_right_constant_16(long value) { + if (doThrow) { + throw new Error(); + } + return (value >>> 16) | (value << -16); + } + + public static long $noinline$rotate_long_right_constant_32(long value) { + if (doThrow) { + throw new Error(); + } + return (value >>> 32) | (value << -32); + } + + public static long $noinline$rotate_long_right_constant_48(long value) { + if (doThrow) { + throw new Error(); + } + return (value >>> 48) | (value << -48); + } + + public static long $noinline$rotate_long_right_constant_64(long value) { + if (doThrow) { + throw new Error(); + } + return (value >>> 64) | (value << -64); + } + + public static void test_Long_right_constant_v() throws Exception { + assertLongEquals($noinline$rotate_long_right_constant_0(0x11), 0x11); + assertLongEquals($noinline$rotate_long_right_constant_1(0x11), 0x8000000000000008L); + assertLongEquals($noinline$rotate_long_right_constant_m1(0x11), 0x22); + assertLongEquals($noinline$rotate_long_right_constant_16(0x11), 0x11000000000000L); + assertLongEquals($noinline$rotate_long_right_constant_32(0x11), 0x1100000000L); + assertLongEquals($noinline$rotate_long_right_constant_48(0x11), 0x110000L); + } + + public static int $noinline$rotate_int_left_constant_0(int value) { + if (doThrow) { + throw new Error(); + } + return (value << 0) | (value >>> 0); + } + + public static int $noinline$rotate_int_left_constant_1(int value) { + if (doThrow) { + throw new Error(); + } + return (value << 1) | (value >>> -1); + } + + public static int $noinline$rotate_int_left_constant_m1(int value) { + if (doThrow) { + throw new Error(); + } + return (value << -1) | (value >>> 1); + } + + public static int $noinline$rotate_int_left_constant_16(int value) { + if (doThrow) { + throw new Error(); + } + return (value << 16) | (value >>> -16); + } + + public static void test_Integer_left_constant_v() throws Exception { + assertIntEquals($noinline$rotate_int_left_constant_0(0x11), 0x11); + assertIntEquals($noinline$rotate_int_left_constant_1(0x11), 0x22); + assertIntEquals($noinline$rotate_int_left_constant_m1(0x11), 0x80000008); + assertIntEquals($noinline$rotate_int_left_constant_16(0x11), 0x110000); + } + + public static long $noinline$rotate_long_left_constant_0(long value) { + if (doThrow) { + throw new Error(); + } + return (value << 0) | (value >>> 0); + } + + public static long $noinline$rotate_long_left_constant_1(long value) { + if (doThrow) { + throw new Error(); + } + return (value << 1) | (value >>> -1); + } + + public static long $noinline$rotate_long_left_constant_m1(long value) { + if (doThrow) { + throw new Error(); + } + return (value << -1) | (value >>> 1); + } + + public static long $noinline$rotate_long_left_constant_16(long value) { + if (doThrow) { + throw new Error(); + } + return (value << 16) | (value >>> -16); + } + + public static long $noinline$rotate_long_left_constant_32(long value) { + if (doThrow) { + throw new Error(); + } + return (value << 32) | (value >>> -32); + } + + public static long $noinline$rotate_long_left_constant_48(long value) { + if (doThrow) { + throw new Error(); + } + return (value << 48) | (value >>> -48); + } + + public static long $noinline$rotate_long_left_constant_64(long value) { + if (doThrow) { + throw new Error(); + } + return (value << 64) | (value >>> -64); + } + + public static void test_Long_left_constant_v() throws Exception { + assertLongEquals($noinline$rotate_long_left_constant_0(0x11), 0x11); + assertLongEquals($noinline$rotate_long_left_constant_1(0x11), 0x22); + assertLongEquals($noinline$rotate_long_left_constant_m1(0x11), 0x8000000000000008L); + assertLongEquals($noinline$rotate_long_left_constant_16(0x11), 0x110000L); + assertLongEquals($noinline$rotate_long_left_constant_32(0x11), 0x1100000000L); + assertLongEquals($noinline$rotate_long_left_constant_48(0x11), 0x11000000000000L); + } + +} diff --git a/test/Android.run-test.mk b/test/Android.run-test.mk index 0925d36058..beaafd0875 100644 --- a/test/Android.run-test.mk +++ b/test/Android.run-test.mk @@ -454,6 +454,7 @@ TEST_ART_BROKEN_OPTIMIZING_MIPS_RUN_TESTS := \ 441-checker-inliner \ 510-checker-try-catch \ 536-checker-intrinsic-optimization \ + 541-checker-instruction-simplifier-rotate \ ifeq (mips,$(TARGET_ARCH)) ifneq (,$(filter optimizing,$(COMPILER_TYPES))) @@ -466,6 +467,21 @@ endif TEST_ART_BROKEN_OPTIMIZING_MIPS_RUN_TESTS := +# Known broken tests for the mips64 optimizing compiler backend. +TEST_ART_BROKEN_OPTIMIZING_MIPS64_RUN_TESTS := \ + 541-checker-instruction-simplifier-rotate \ + +ifeq (mips64,$(TARGET_ARCH)) + ifneq (,$(filter optimizing,$(COMPILER_TYPES))) + ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,target,$(RUN_TYPES),$(PREBUILD_TYPES), \ + optimizing,$(RELOCATE_TYPES),$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES), \ + $(IMAGE_TYPES),$(PICTEST_TYPES),$(DEBUGGABLE_TYPES), \ + $(TEST_ART_BROKEN_OPTIMIZING_MIPS64_RUN_TESTS),$(ALL_ADDRESS_SIZES)) + endif +endif + +TEST_ART_BROKEN_OPTIMIZING_MIPS64_RUN_TESTS := + # Tests that should fail when the optimizing compiler compiles them non-debuggable. TEST_ART_BROKEN_OPTIMIZING_NONDEBUGGABLE_RUN_TESTS := \ 454-get-vreg \ |