Fix shift rewriting for arithemetic right shift
Arithemitic right shift with more more than the bits in the value
does not always yield 0 but 0 or -1 depending on the upper bit
in the value.
Also add a more exhaustive test of successive shift operations.
Bug: b/342067836
Change-Id: I368a0c5de057503aa4e6b65e984a9c73e13ae62b
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/passes/BinopRewriter.java b/src/main/java/com/android/tools/r8/ir/conversion/passes/BinopRewriter.java
index ec2d309..9929d22 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/passes/BinopRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/passes/BinopRewriter.java
@@ -365,12 +365,15 @@
ConstNumber constARight,
Value input,
IRCode code) {
+ assert binop.isShl() || binop.isShr() || binop.isUshr();
int mask = input.outType().isWide() ? 63 : 31;
int intA = constARight.getIntValue() & mask;
int intB = constBRight.getIntValue() & mask;
if (intA + intB > mask) {
- ConstNumber zero = code.createNumberConstant(0, binop.outValue().getType());
- iterator.replaceCurrentInstruction(zero);
+ if (!binop.isShr()) {
+ ConstNumber zero = code.createNumberConstant(0, binop.outValue().getType());
+ iterator.replaceCurrentInstruction(zero);
+ }
} else {
iterator.previous();
Value newConstantValue =
diff --git a/src/test/java/com/android/tools/r8/ir/ShiftExhaustiveTest.java b/src/test/java/com/android/tools/r8/ir/ShiftExhaustiveTest.java
new file mode 100644
index 0000000..13ef103
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/ir/ShiftExhaustiveTest.java
@@ -0,0 +1,610 @@
+// Copyright (c) 2024, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.ir;
+
+import static org.junit.Assume.assumeTrue;
+
+import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.google.common.collect.ImmutableList;
+import java.util.ArrayList;
+import java.util.List;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class ShiftExhaustiveTest extends TestBase {
+
+ private static final List<String> shiptOperations = ImmutableList.of(">>", ">>>", "<<");
+ private static final List<Integer> negativeShiftValuesForInt =
+ ImmutableList.of(0, -1, -2, -10, -20, -30, -31, -32);
+ private static final List<Integer> positiveShiftValuesForInt =
+ ImmutableList.of(0, 1, 2, 10, 20, 30, 31, 32);
+ private static final List<Integer> negativeShiftValuesForLong =
+ ImmutableList.of(0, -1, -2, -20, -40, -62, -63, -64);
+ private static final List<Integer> positiveShiftValuesForLong =
+ ImmutableList.of(0, 1, 2, 20, 40, 62, 63, 64);
+ private static final List<Integer> testValuesInt =
+ ImmutableList.of(
+ Integer.MIN_VALUE,
+ Integer.MIN_VALUE + 1,
+ -2,
+ -1,
+ 0,
+ 1,
+ 2,
+ Integer.MAX_VALUE - 1,
+ Integer.MAX_VALUE);
+ private static final List<Long> testValuesLong =
+ ImmutableList.of(
+ Long.MIN_VALUE,
+ Long.MIN_VALUE + 1L,
+ -2L,
+ -1L,
+ 0L,
+ 1L,
+ 2L,
+ Long.MAX_VALUE - 1,
+ Long.MAX_VALUE);
+
+ private static List<String> EXPECTED_RESULT;
+
+ @BeforeClass
+ public static void generateExpectedResult() {
+ List<String> result = new ArrayList<>();
+ for (int i : testValuesInt) {
+ generateTestResultsInt(i, result);
+ }
+ for (long l : testValuesLong) {
+ generateTestResultsLong(l, result);
+ }
+ EXPECTED_RESULT = result;
+ }
+
+ public static void generateTestResultsInt(int x, List<String> result) {
+ for (String op : shiptOperations) {
+ for (int f : negativeShiftValuesForInt) {
+ for (int s : positiveShiftValuesForInt) {
+ if (op.equals(">>")) {
+ result.add("" + (x >> f >> s));
+ }
+ if (op.equals(">>>")) {
+ result.add("" + (x >>> f >>> s));
+ }
+ if (op.equals("<<")) {
+ result.add("" + (x << f << s));
+ }
+ }
+ }
+ }
+ }
+
+ public static void generateTestResultsLong(long x, List<String> result) {
+ for (String op : shiptOperations) {
+ for (int f : negativeShiftValuesForLong) {
+ for (int s : positiveShiftValuesForLong) {
+ switch (op) {
+ case ">>":
+ result.add("" + (x >> f >> s));
+ break;
+ case ">>>":
+ result.add("" + (x >>> f >>> s));
+ break;
+ case "<<":
+ result.add("" + (x << f << s));
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ @Parameterized.Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters().withCfRuntimes().withDexRuntimes().withAllApiLevels().build();
+ }
+
+ private final TestParameters parameters;
+
+ public ShiftExhaustiveTest(TestParameters parameters) {
+ this.parameters = parameters;
+ }
+
+ @Test
+ public void testJvm() throws Exception {
+ assumeTrue(parameters.isCfRuntime());
+ testForJvm(parameters)
+ .addProgramClasses(Main.class)
+ .run(parameters.getRuntime(), Main.class)
+ .assertSuccessWithOutputLines(EXPECTED_RESULT);
+ }
+
+ @Test
+ public void testD8() throws Exception {
+ testForRuntime(parameters)
+ .addProgramClasses(Main.class)
+ .run(parameters.getRuntime(), Main.class)
+ .assertSuccessWithOutputLines(EXPECTED_RESULT);
+ }
+
+ @Test
+ public void testR8() throws Exception {
+ testForR8(parameters.getBackend())
+ .addProgramClasses(Main.class)
+ .addKeepMainRule(Main.class)
+ .enableInliningAnnotations()
+ .setMinApi(parameters)
+ .run(parameters.getRuntime(), Main.class)
+ .assertSuccessWithOutputLines(EXPECTED_RESULT);
+ }
+
+ // Methods of Main class generated by outer class main method below.
+ public static class Main {
+
+ public static void main(String[] args) {
+ testInt(-2147483648);
+ testInt(-2147483647);
+ testInt(-2);
+ testInt(-1);
+ testInt(0);
+ testInt(1);
+ testInt(2);
+ testInt(2147483646);
+ testInt(2147483647);
+ testLong(-9223372036854775808L);
+ testLong(-9223372036854775807L);
+ testLong(-2L);
+ testLong(-1L);
+ testLong(0L);
+ testLong(1L);
+ testLong(2L);
+ testLong(9223372036854775806L);
+ testLong(9223372036854775807L);
+ }
+
+ @NeverInline
+ private static void testInt(int x) {
+ System.out.println(x >> 0 >> 0);
+ System.out.println(x >> 0 >> 1);
+ System.out.println(x >> 0 >> 2);
+ System.out.println(x >> 0 >> 10);
+ System.out.println(x >> 0 >> 20);
+ System.out.println(x >> 0 >> 30);
+ System.out.println(x >> 0 >> 31);
+ System.out.println(x >> 0 >> 32);
+ System.out.println(x >> -1 >> 0);
+ System.out.println(x >> -1 >> 1);
+ System.out.println(x >> -1 >> 2);
+ System.out.println(x >> -1 >> 10);
+ System.out.println(x >> -1 >> 20);
+ System.out.println(x >> -1 >> 30);
+ System.out.println(x >> -1 >> 31);
+ System.out.println(x >> -1 >> 32);
+ System.out.println(x >> -2 >> 0);
+ System.out.println(x >> -2 >> 1);
+ System.out.println(x >> -2 >> 2);
+ System.out.println(x >> -2 >> 10);
+ System.out.println(x >> -2 >> 20);
+ System.out.println(x >> -2 >> 30);
+ System.out.println(x >> -2 >> 31);
+ System.out.println(x >> -2 >> 32);
+ System.out.println(x >> -10 >> 0);
+ System.out.println(x >> -10 >> 1);
+ System.out.println(x >> -10 >> 2);
+ System.out.println(x >> -10 >> 10);
+ System.out.println(x >> -10 >> 20);
+ System.out.println(x >> -10 >> 30);
+ System.out.println(x >> -10 >> 31);
+ System.out.println(x >> -10 >> 32);
+ System.out.println(x >> -20 >> 0);
+ System.out.println(x >> -20 >> 1);
+ System.out.println(x >> -20 >> 2);
+ System.out.println(x >> -20 >> 10);
+ System.out.println(x >> -20 >> 20);
+ System.out.println(x >> -20 >> 30);
+ System.out.println(x >> -20 >> 31);
+ System.out.println(x >> -20 >> 32);
+ System.out.println(x >> -30 >> 0);
+ System.out.println(x >> -30 >> 1);
+ System.out.println(x >> -30 >> 2);
+ System.out.println(x >> -30 >> 10);
+ System.out.println(x >> -30 >> 20);
+ System.out.println(x >> -30 >> 30);
+ System.out.println(x >> -30 >> 31);
+ System.out.println(x >> -30 >> 32);
+ System.out.println(x >> -31 >> 0);
+ System.out.println(x >> -31 >> 1);
+ System.out.println(x >> -31 >> 2);
+ System.out.println(x >> -31 >> 10);
+ System.out.println(x >> -31 >> 20);
+ System.out.println(x >> -31 >> 30);
+ System.out.println(x >> -31 >> 31);
+ System.out.println(x >> -31 >> 32);
+ System.out.println(x >> -32 >> 0);
+ System.out.println(x >> -32 >> 1);
+ System.out.println(x >> -32 >> 2);
+ System.out.println(x >> -32 >> 10);
+ System.out.println(x >> -32 >> 20);
+ System.out.println(x >> -32 >> 30);
+ System.out.println(x >> -32 >> 31);
+ System.out.println(x >> -32 >> 32);
+ System.out.println(x >>> 0 >>> 0);
+ System.out.println(x >>> 0 >>> 1);
+ System.out.println(x >>> 0 >>> 2);
+ System.out.println(x >>> 0 >>> 10);
+ System.out.println(x >>> 0 >>> 20);
+ System.out.println(x >>> 0 >>> 30);
+ System.out.println(x >>> 0 >>> 31);
+ System.out.println(x >>> 0 >>> 32);
+ System.out.println(x >>> -1 >>> 0);
+ System.out.println(x >>> -1 >>> 1);
+ System.out.println(x >>> -1 >>> 2);
+ System.out.println(x >>> -1 >>> 10);
+ System.out.println(x >>> -1 >>> 20);
+ System.out.println(x >>> -1 >>> 30);
+ System.out.println(x >>> -1 >>> 31);
+ System.out.println(x >>> -1 >>> 32);
+ System.out.println(x >>> -2 >>> 0);
+ System.out.println(x >>> -2 >>> 1);
+ System.out.println(x >>> -2 >>> 2);
+ System.out.println(x >>> -2 >>> 10);
+ System.out.println(x >>> -2 >>> 20);
+ System.out.println(x >>> -2 >>> 30);
+ System.out.println(x >>> -2 >>> 31);
+ System.out.println(x >>> -2 >>> 32);
+ System.out.println(x >>> -10 >>> 0);
+ System.out.println(x >>> -10 >>> 1);
+ System.out.println(x >>> -10 >>> 2);
+ System.out.println(x >>> -10 >>> 10);
+ System.out.println(x >>> -10 >>> 20);
+ System.out.println(x >>> -10 >>> 30);
+ System.out.println(x >>> -10 >>> 31);
+ System.out.println(x >>> -10 >>> 32);
+ System.out.println(x >>> -20 >>> 0);
+ System.out.println(x >>> -20 >>> 1);
+ System.out.println(x >>> -20 >>> 2);
+ System.out.println(x >>> -20 >>> 10);
+ System.out.println(x >>> -20 >>> 20);
+ System.out.println(x >>> -20 >>> 30);
+ System.out.println(x >>> -20 >>> 31);
+ System.out.println(x >>> -20 >>> 32);
+ System.out.println(x >>> -30 >>> 0);
+ System.out.println(x >>> -30 >>> 1);
+ System.out.println(x >>> -30 >>> 2);
+ System.out.println(x >>> -30 >>> 10);
+ System.out.println(x >>> -30 >>> 20);
+ System.out.println(x >>> -30 >>> 30);
+ System.out.println(x >>> -30 >>> 31);
+ System.out.println(x >>> -30 >>> 32);
+ System.out.println(x >>> -31 >>> 0);
+ System.out.println(x >>> -31 >>> 1);
+ System.out.println(x >>> -31 >>> 2);
+ System.out.println(x >>> -31 >>> 10);
+ System.out.println(x >>> -31 >>> 20);
+ System.out.println(x >>> -31 >>> 30);
+ System.out.println(x >>> -31 >>> 31);
+ System.out.println(x >>> -31 >>> 32);
+ System.out.println(x >>> -32 >>> 0);
+ System.out.println(x >>> -32 >>> 1);
+ System.out.println(x >>> -32 >>> 2);
+ System.out.println(x >>> -32 >>> 10);
+ System.out.println(x >>> -32 >>> 20);
+ System.out.println(x >>> -32 >>> 30);
+ System.out.println(x >>> -32 >>> 31);
+ System.out.println(x >>> -32 >>> 32);
+ System.out.println(x << 0 << 0);
+ System.out.println(x << 0 << 1);
+ System.out.println(x << 0 << 2);
+ System.out.println(x << 0 << 10);
+ System.out.println(x << 0 << 20);
+ System.out.println(x << 0 << 30);
+ System.out.println(x << 0 << 31);
+ System.out.println(x << 0 << 32);
+ System.out.println(x << -1 << 0);
+ System.out.println(x << -1 << 1);
+ System.out.println(x << -1 << 2);
+ System.out.println(x << -1 << 10);
+ System.out.println(x << -1 << 20);
+ System.out.println(x << -1 << 30);
+ System.out.println(x << -1 << 31);
+ System.out.println(x << -1 << 32);
+ System.out.println(x << -2 << 0);
+ System.out.println(x << -2 << 1);
+ System.out.println(x << -2 << 2);
+ System.out.println(x << -2 << 10);
+ System.out.println(x << -2 << 20);
+ System.out.println(x << -2 << 30);
+ System.out.println(x << -2 << 31);
+ System.out.println(x << -2 << 32);
+ System.out.println(x << -10 << 0);
+ System.out.println(x << -10 << 1);
+ System.out.println(x << -10 << 2);
+ System.out.println(x << -10 << 10);
+ System.out.println(x << -10 << 20);
+ System.out.println(x << -10 << 30);
+ System.out.println(x << -10 << 31);
+ System.out.println(x << -10 << 32);
+ System.out.println(x << -20 << 0);
+ System.out.println(x << -20 << 1);
+ System.out.println(x << -20 << 2);
+ System.out.println(x << -20 << 10);
+ System.out.println(x << -20 << 20);
+ System.out.println(x << -20 << 30);
+ System.out.println(x << -20 << 31);
+ System.out.println(x << -20 << 32);
+ System.out.println(x << -30 << 0);
+ System.out.println(x << -30 << 1);
+ System.out.println(x << -30 << 2);
+ System.out.println(x << -30 << 10);
+ System.out.println(x << -30 << 20);
+ System.out.println(x << -30 << 30);
+ System.out.println(x << -30 << 31);
+ System.out.println(x << -30 << 32);
+ System.out.println(x << -31 << 0);
+ System.out.println(x << -31 << 1);
+ System.out.println(x << -31 << 2);
+ System.out.println(x << -31 << 10);
+ System.out.println(x << -31 << 20);
+ System.out.println(x << -31 << 30);
+ System.out.println(x << -31 << 31);
+ System.out.println(x << -31 << 32);
+ System.out.println(x << -32 << 0);
+ System.out.println(x << -32 << 1);
+ System.out.println(x << -32 << 2);
+ System.out.println(x << -32 << 10);
+ System.out.println(x << -32 << 20);
+ System.out.println(x << -32 << 30);
+ System.out.println(x << -32 << 31);
+ System.out.println(x << -32 << 32);
+ }
+
+ @NeverInline
+ private static void testLong(long x) {
+ System.out.println(x >> 0 >> 0);
+ System.out.println(x >> 0 >> 1);
+ System.out.println(x >> 0 >> 2);
+ System.out.println(x >> 0 >> 20);
+ System.out.println(x >> 0 >> 40);
+ System.out.println(x >> 0 >> 62);
+ System.out.println(x >> 0 >> 63);
+ System.out.println(x >> 0 >> 64);
+ System.out.println(x >> -1 >> 0);
+ System.out.println(x >> -1 >> 1);
+ System.out.println(x >> -1 >> 2);
+ System.out.println(x >> -1 >> 20);
+ System.out.println(x >> -1 >> 40);
+ System.out.println(x >> -1 >> 62);
+ System.out.println(x >> -1 >> 63);
+ System.out.println(x >> -1 >> 64);
+ System.out.println(x >> -2 >> 0);
+ System.out.println(x >> -2 >> 1);
+ System.out.println(x >> -2 >> 2);
+ System.out.println(x >> -2 >> 20);
+ System.out.println(x >> -2 >> 40);
+ System.out.println(x >> -2 >> 62);
+ System.out.println(x >> -2 >> 63);
+ System.out.println(x >> -2 >> 64);
+ System.out.println(x >> -20 >> 0);
+ System.out.println(x >> -20 >> 1);
+ System.out.println(x >> -20 >> 2);
+ System.out.println(x >> -20 >> 20);
+ System.out.println(x >> -20 >> 40);
+ System.out.println(x >> -20 >> 62);
+ System.out.println(x >> -20 >> 63);
+ System.out.println(x >> -20 >> 64);
+ System.out.println(x >> -40 >> 0);
+ System.out.println(x >> -40 >> 1);
+ System.out.println(x >> -40 >> 2);
+ System.out.println(x >> -40 >> 20);
+ System.out.println(x >> -40 >> 40);
+ System.out.println(x >> -40 >> 62);
+ System.out.println(x >> -40 >> 63);
+ System.out.println(x >> -40 >> 64);
+ System.out.println(x >> -62 >> 0);
+ System.out.println(x >> -62 >> 1);
+ System.out.println(x >> -62 >> 2);
+ System.out.println(x >> -62 >> 20);
+ System.out.println(x >> -62 >> 40);
+ System.out.println(x >> -62 >> 62);
+ System.out.println(x >> -62 >> 63);
+ System.out.println(x >> -62 >> 64);
+ System.out.println(x >> -63 >> 0);
+ System.out.println(x >> -63 >> 1);
+ System.out.println(x >> -63 >> 2);
+ System.out.println(x >> -63 >> 20);
+ System.out.println(x >> -63 >> 40);
+ System.out.println(x >> -63 >> 62);
+ System.out.println(x >> -63 >> 63);
+ System.out.println(x >> -63 >> 64);
+ System.out.println(x >> -64 >> 0);
+ System.out.println(x >> -64 >> 1);
+ System.out.println(x >> -64 >> 2);
+ System.out.println(x >> -64 >> 20);
+ System.out.println(x >> -64 >> 40);
+ System.out.println(x >> -64 >> 62);
+ System.out.println(x >> -64 >> 63);
+ System.out.println(x >> -64 >> 64);
+ System.out.println(x >>> 0 >>> 0);
+ System.out.println(x >>> 0 >>> 1);
+ System.out.println(x >>> 0 >>> 2);
+ System.out.println(x >>> 0 >>> 20);
+ System.out.println(x >>> 0 >>> 40);
+ System.out.println(x >>> 0 >>> 62);
+ System.out.println(x >>> 0 >>> 63);
+ System.out.println(x >>> 0 >>> 64);
+ System.out.println(x >>> -1 >>> 0);
+ System.out.println(x >>> -1 >>> 1);
+ System.out.println(x >>> -1 >>> 2);
+ System.out.println(x >>> -1 >>> 20);
+ System.out.println(x >>> -1 >>> 40);
+ System.out.println(x >>> -1 >>> 62);
+ System.out.println(x >>> -1 >>> 63);
+ System.out.println(x >>> -1 >>> 64);
+ System.out.println(x >>> -2 >>> 0);
+ System.out.println(x >>> -2 >>> 1);
+ System.out.println(x >>> -2 >>> 2);
+ System.out.println(x >>> -2 >>> 20);
+ System.out.println(x >>> -2 >>> 40);
+ System.out.println(x >>> -2 >>> 62);
+ System.out.println(x >>> -2 >>> 63);
+ System.out.println(x >>> -2 >>> 64);
+ System.out.println(x >>> -20 >>> 0);
+ System.out.println(x >>> -20 >>> 1);
+ System.out.println(x >>> -20 >>> 2);
+ System.out.println(x >>> -20 >>> 20);
+ System.out.println(x >>> -20 >>> 40);
+ System.out.println(x >>> -20 >>> 62);
+ System.out.println(x >>> -20 >>> 63);
+ System.out.println(x >>> -20 >>> 64);
+ System.out.println(x >>> -40 >>> 0);
+ System.out.println(x >>> -40 >>> 1);
+ System.out.println(x >>> -40 >>> 2);
+ System.out.println(x >>> -40 >>> 20);
+ System.out.println(x >>> -40 >>> 40);
+ System.out.println(x >>> -40 >>> 62);
+ System.out.println(x >>> -40 >>> 63);
+ System.out.println(x >>> -40 >>> 64);
+ System.out.println(x >>> -62 >>> 0);
+ System.out.println(x >>> -62 >>> 1);
+ System.out.println(x >>> -62 >>> 2);
+ System.out.println(x >>> -62 >>> 20);
+ System.out.println(x >>> -62 >>> 40);
+ System.out.println(x >>> -62 >>> 62);
+ System.out.println(x >>> -62 >>> 63);
+ System.out.println(x >>> -62 >>> 64);
+ System.out.println(x >>> -63 >>> 0);
+ System.out.println(x >>> -63 >>> 1);
+ System.out.println(x >>> -63 >>> 2);
+ System.out.println(x >>> -63 >>> 20);
+ System.out.println(x >>> -63 >>> 40);
+ System.out.println(x >>> -63 >>> 62);
+ System.out.println(x >>> -63 >>> 63);
+ System.out.println(x >>> -63 >>> 64);
+ System.out.println(x >>> -64 >>> 0);
+ System.out.println(x >>> -64 >>> 1);
+ System.out.println(x >>> -64 >>> 2);
+ System.out.println(x >>> -64 >>> 20);
+ System.out.println(x >>> -64 >>> 40);
+ System.out.println(x >>> -64 >>> 62);
+ System.out.println(x >>> -64 >>> 63);
+ System.out.println(x >>> -64 >>> 64);
+ System.out.println(x << 0 << 0);
+ System.out.println(x << 0 << 1);
+ System.out.println(x << 0 << 2);
+ System.out.println(x << 0 << 20);
+ System.out.println(x << 0 << 40);
+ System.out.println(x << 0 << 62);
+ System.out.println(x << 0 << 63);
+ System.out.println(x << 0 << 64);
+ System.out.println(x << -1 << 0);
+ System.out.println(x << -1 << 1);
+ System.out.println(x << -1 << 2);
+ System.out.println(x << -1 << 20);
+ System.out.println(x << -1 << 40);
+ System.out.println(x << -1 << 62);
+ System.out.println(x << -1 << 63);
+ System.out.println(x << -1 << 64);
+ System.out.println(x << -2 << 0);
+ System.out.println(x << -2 << 1);
+ System.out.println(x << -2 << 2);
+ System.out.println(x << -2 << 20);
+ System.out.println(x << -2 << 40);
+ System.out.println(x << -2 << 62);
+ System.out.println(x << -2 << 63);
+ System.out.println(x << -2 << 64);
+ System.out.println(x << -20 << 0);
+ System.out.println(x << -20 << 1);
+ System.out.println(x << -20 << 2);
+ System.out.println(x << -20 << 20);
+ System.out.println(x << -20 << 40);
+ System.out.println(x << -20 << 62);
+ System.out.println(x << -20 << 63);
+ System.out.println(x << -20 << 64);
+ System.out.println(x << -40 << 0);
+ System.out.println(x << -40 << 1);
+ System.out.println(x << -40 << 2);
+ System.out.println(x << -40 << 20);
+ System.out.println(x << -40 << 40);
+ System.out.println(x << -40 << 62);
+ System.out.println(x << -40 << 63);
+ System.out.println(x << -40 << 64);
+ System.out.println(x << -62 << 0);
+ System.out.println(x << -62 << 1);
+ System.out.println(x << -62 << 2);
+ System.out.println(x << -62 << 20);
+ System.out.println(x << -62 << 40);
+ System.out.println(x << -62 << 62);
+ System.out.println(x << -62 << 63);
+ System.out.println(x << -62 << 64);
+ System.out.println(x << -63 << 0);
+ System.out.println(x << -63 << 1);
+ System.out.println(x << -63 << 2);
+ System.out.println(x << -63 << 20);
+ System.out.println(x << -63 << 40);
+ System.out.println(x << -63 << 62);
+ System.out.println(x << -63 << 63);
+ System.out.println(x << -63 << 64);
+ System.out.println(x << -64 << 0);
+ System.out.println(x << -64 << 1);
+ System.out.println(x << -64 << 2);
+ System.out.println(x << -64 << 20);
+ System.out.println(x << -64 << 40);
+ System.out.println(x << -64 << 62);
+ System.out.println(x << -64 << 63);
+ System.out.println(x << -64 << 64);
+ }
+ }
+
+ private static void generateTestMain() {
+ System.out.println(" public static void main(String[] args) {");
+ for (int i : testValuesInt) {
+ System.out.println(" testInt(" + i + ");");
+ }
+ for (long l : testValuesLong) {
+ System.out.println(" testLong(" + l + "L);");
+ }
+ System.out.println(" }");
+ }
+
+ private static void generateTestSourceInt() {
+ System.out.println(" @NeverInline");
+ System.out.println(" private static void testInt(int x) {");
+ for (String op : shiptOperations) {
+ for (int f : negativeShiftValuesForInt) {
+ for (int s : positiveShiftValuesForInt) {
+ System.out.println(
+ " System.out.println(x " + op + " " + f + " " + op + " " + s + ");");
+ }
+ }
+ }
+ System.out.println(" }");
+ }
+
+ private static void generateTestSourceLong() {
+ System.out.println(" @NeverInline");
+ System.out.println(" private static void testLong(long x) {");
+ for (String op : shiptOperations) {
+ for (int f : negativeShiftValuesForLong) {
+ for (int s : positiveShiftValuesForLong) {
+ System.out.println(
+ " System.out.println(x " + op + " " + f + " " + op + " " + s + ");");
+ }
+ }
+ }
+ System.out.println(" }");
+ }
+
+ public static void main(String[] args) {
+ generateTestMain();
+ System.out.println();
+ generateTestSourceInt();
+ System.out.println();
+ generateTestSourceLong();
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/ir/ShiftOppositeSignTest.java b/src/test/java/com/android/tools/r8/ir/ShiftOppositeSignTest.java
index 62cd987..e54e7b5 100644
--- a/src/test/java/com/android/tools/r8/ir/ShiftOppositeSignTest.java
+++ b/src/test/java/com/android/tools/r8/ir/ShiftOppositeSignTest.java
@@ -18,6 +18,13 @@
private static final String EXPECTED_RESULT =
StringUtils.lines(
+ "=== 2147483647 ===",
+ "shl: 0 -134217728 0 -512",
+ "shr: 0 15 0 4194303",
+ "ushr: 0 15 0 4194303",
+ "shl: 0 -64 -268435456 0",
+ "shr: 0 33554431 7 0",
+ "ushr: 0 33554431 7 0",
"=== 1 ===",
"shl: 0 134217728 0 512",
"shr: 0 0 0 0",
@@ -31,7 +38,21 @@
"ushr: 0 0 0 241",
"shl: 0 7901184 0 0",
"shr: 0 1929 0 0",
- "ushr: 0 1929 0 0");
+ "ushr: 0 1929 0 0",
+ "=== -1 ===",
+ "shl: 0 -134217728 0 -512",
+ "shr: -1 -1 -1 -1",
+ "ushr: 0 31 0 8388607",
+ "shl: 0 -64 -268435456 0",
+ "shr: -1 -1 -1 -1",
+ "ushr: 0 67108863 15 0",
+ "=== -2147483648 ===",
+ "shl: 0 0 0 0",
+ "shr: -1 -16 -1 -4194304",
+ "ushr: 0 16 0 4194304",
+ "shl: 0 0 0 0",
+ "shr: -1 -33554432 -8 -1",
+ "ushr: 0 33554432 8 0");
@Parameterized.Parameters(name = "{0}")
public static TestParametersCollection data() {
@@ -66,8 +87,11 @@
public static class Main {
public static void main(String[] args) {
+ test(Integer.MAX_VALUE);
test(1);
test(123456);
+ test(-1);
+ test(Integer.MIN_VALUE);
}
@NeverInline