Extend binop rewriter
- support associative followed by identity absorbing.
Change-Id: Ib3d8e37da0e7d01ce3dfe34345ea106216053df7
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 b95f09d..a0edfc5 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
@@ -301,14 +301,12 @@
// a * x * b => x * (a * b) where (a * b) is a constant.
assert binop.isCommutative();
Value newConst = addNewConstNumber(code, iterator, constB, constA, binopDescriptor);
- iterator.replaceCurrentInstruction(
- instantiateBinop(code, input, newConst, binopDescriptor));
+ replaceBinop(iterator, code, input, newConst, binopDescriptor);
} else if (binopDescriptor.isShift()) {
// x shift: a shift: b => x shift: (a + b) where a + b is a constant.
if (constBRight != null && constARight != null) {
Value newConst = addNewConstNumber(code, iterator, constB, constA, BinopDescriptor.ADD);
- iterator.replaceCurrentInstruction(
- instantiateBinop(code, input, newConst, binopDescriptor));
+ replaceBinop(iterator, code, input, newConst, binopDescriptor);
}
} else if (binop.isSub() && constBRight != null) {
// a - x - b => (a - b) - x where (a - b) is a constant.
@@ -316,12 +314,10 @@
// We ignore b - (x - a) and b - (a - x) with constBRight != null.
if (constARight == null) {
Value newConst = addNewConstNumber(code, iterator, constA, constB, BinopDescriptor.SUB);
- iterator.replaceCurrentInstruction(
- instantiateBinop(code, newConst, input, BinopDescriptor.SUB));
+ replaceBinop(iterator, code, newConst, input, BinopDescriptor.SUB);
} else {
Value newConst = addNewConstNumber(code, iterator, constB, constA, BinopDescriptor.ADD);
- iterator.replaceCurrentInstruction(
- instantiateBinop(code, input, newConst, BinopDescriptor.SUB));
+ replaceBinop(iterator, code, input, newConst, BinopDescriptor.SUB);
}
}
} else {
@@ -330,26 +326,37 @@
// a + x - b => x + (a - b) where (a - b) is a constant.
// We ignore b - (x + a) and b - (a + x) with constBRight != null.
Value newConst = addNewConstNumber(code, iterator, constA, constB, BinopDescriptor.SUB);
- iterator.replaceCurrentInstruction(
- instantiateBinop(code, newConst, input, BinopDescriptor.ADD));
+ replaceBinop(iterator, code, newConst, input, BinopDescriptor.ADD);
} else if (binop.isAdd() && prevBinop.isSub()) {
// x - a + b => x - (a - b) where (a - b) is a constant.
// a - x + b => (a + b) - x where (a + b) is a constant.
if (constALeft == null) {
Value newConst = addNewConstNumber(code, iterator, constA, constB, BinopDescriptor.SUB);
- iterator.replaceCurrentInstruction(
- instantiateBinop(code, input, newConst, BinopDescriptor.SUB));
+ replaceBinop(iterator, code, input, newConst, BinopDescriptor.SUB);
} else {
Value newConst = addNewConstNumber(code, iterator, constB, constA, BinopDescriptor.ADD);
- iterator.replaceCurrentInstruction(
- instantiateBinop(code, newConst, input, BinopDescriptor.SUB));
+ replaceBinop(iterator, code, newConst, input, BinopDescriptor.SUB);
}
}
}
}
- private Instruction instantiateBinop(
- IRCode code, Value left, Value right, BinopDescriptor descriptor) {
+ private void replaceBinop(
+ InstructionListIterator iterator,
+ IRCode code,
+ Value left,
+ Value right,
+ BinopDescriptor binopDescriptor) {
+ Binop newBinop = instantiateBinop(code, left, right, binopDescriptor);
+ iterator.replaceCurrentInstruction(newBinop);
+ // We need to reset the iterator state after replaceCurrentInstruction so that Iterator#remove()
+ // can work in identityAbsorbingSimplification by calling previous then next.
+ iterator.previous();
+ iterator.next();
+ identityAbsorbingSimplification(iterator, newBinop, binopDescriptor);
+ }
+
+ private Binop instantiateBinop(IRCode code, Value left, Value right, BinopDescriptor descriptor) {
TypeElement representative = left.getType().isInt() ? right.getType() : left.getType();
Value newValue = code.createValue(representative);
NumericType numericType = representative.isInt() ? NumericType.INT : NumericType.LONG;
diff --git a/src/test/java/com/android/tools/r8/ir/IdentityAbsorbingIntTest.java b/src/test/java/com/android/tools/r8/ir/IdentityAbsorbingIntTest.java
new file mode 100644
index 0000000..9d7b58d
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/ir/IdentityAbsorbingIntTest.java
@@ -0,0 +1,603 @@
+// Copyright (c) 2023, 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.Assert.assertTrue;
+
+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.android.tools.r8.utils.StringUtils;
+import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class IdentityAbsorbingIntTest extends TestBase {
+
+ private static final String EXPECTED_RESULT =
+ StringUtils.lines(
+ "2147483647",
+ "2147483647",
+ "2147483647",
+ "2147483647",
+ "2147483647",
+ "2147483647",
+ "2147483647",
+ "2147483647",
+ "2147483647",
+ "2147483647",
+ "2147483647",
+ "2147483647",
+ "2147483647",
+ "2147483647",
+ "2147483647",
+ "0",
+ "0",
+ "0",
+ "0",
+ "-1",
+ "-1",
+ "0",
+ "0",
+ "0",
+ "2147483647",
+ "2147483647",
+ "2147483647",
+ "2147483647",
+ "2147483647",
+ "2147483647",
+ "2147483647",
+ "2147483647",
+ "2147483647",
+ "2147483647",
+ "2147483647",
+ "2147483647",
+ "2147483647",
+ "2147483647",
+ "2147483647",
+ "2147483647",
+ "2147483647",
+ "2147483647",
+ "2147483647",
+ "2147483647",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "-1",
+ "-1",
+ "-1",
+ "0",
+ "0",
+ "0",
+ "0",
+ "2147483647",
+ "2147483647",
+ "2147483647",
+ "2147483646",
+ "2147483646",
+ "2147483646",
+ "2147483646",
+ "2147483646",
+ "2147483646",
+ "2147483646",
+ "2147483646",
+ "2147483646",
+ "2147483646",
+ "2147483646",
+ "2147483646",
+ "2147483646",
+ "2147483646",
+ "2147483646",
+ "0",
+ "0",
+ "0",
+ "0",
+ "-1",
+ "-1",
+ "0",
+ "0",
+ "0",
+ "2147483646",
+ "2147483646",
+ "2147483646",
+ "2147483646",
+ "2147483646",
+ "2147483646",
+ "2147483646",
+ "2147483646",
+ "2147483646",
+ "2147483646",
+ "2147483646",
+ "2147483646",
+ "2147483646",
+ "2147483646",
+ "2147483646",
+ "2147483646",
+ "2147483646",
+ "2147483646",
+ "2147483646",
+ "2147483646",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "-1",
+ "-1",
+ "-1",
+ "0",
+ "0",
+ "0",
+ "0",
+ "2147483646",
+ "2147483646",
+ "2147483646",
+ "-2147483648",
+ "-2147483648",
+ "-2147483648",
+ "-2147483648",
+ "-2147483648",
+ "-2147483648",
+ "-2147483648",
+ "-2147483648",
+ "-2147483648",
+ "-2147483648",
+ "-2147483648",
+ "-2147483648",
+ "-2147483648",
+ "-2147483648",
+ "-2147483648",
+ "0",
+ "0",
+ "0",
+ "0",
+ "-1",
+ "-1",
+ "0",
+ "0",
+ "0",
+ "-2147483648",
+ "-2147483648",
+ "-2147483648",
+ "-2147483648",
+ "-2147483648",
+ "-2147483648",
+ "-2147483648",
+ "-2147483648",
+ "-2147483648",
+ "-2147483648",
+ "-2147483648",
+ "-2147483648",
+ "-2147483648",
+ "-2147483648",
+ "-2147483648",
+ "-2147483648",
+ "-2147483648",
+ "-2147483648",
+ "-2147483648",
+ "-2147483648",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "-1",
+ "-1",
+ "-1",
+ "0",
+ "0",
+ "0",
+ "0",
+ "-2147483648",
+ "-2147483648",
+ "-2147483648",
+ "-2147483647",
+ "-2147483647",
+ "-2147483647",
+ "-2147483647",
+ "-2147483647",
+ "-2147483647",
+ "-2147483647",
+ "-2147483647",
+ "-2147483647",
+ "-2147483647",
+ "-2147483647",
+ "-2147483647",
+ "-2147483647",
+ "-2147483647",
+ "-2147483647",
+ "0",
+ "0",
+ "0",
+ "0",
+ "-1",
+ "-1",
+ "0",
+ "0",
+ "0",
+ "-2147483647",
+ "-2147483647",
+ "-2147483647",
+ "-2147483647",
+ "-2147483647",
+ "-2147483647",
+ "-2147483647",
+ "-2147483647",
+ "-2147483647",
+ "-2147483647",
+ "-2147483647",
+ "-2147483647",
+ "-2147483647",
+ "-2147483647",
+ "-2147483647",
+ "-2147483647",
+ "-2147483647",
+ "-2147483647",
+ "-2147483647",
+ "-2147483647",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "-1",
+ "-1",
+ "-1",
+ "0",
+ "0",
+ "0",
+ "0",
+ "-2147483647",
+ "-2147483647",
+ "-2147483647",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "-1",
+ "-1",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "-1",
+ "-1",
+ "-1",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "0",
+ "0",
+ "0",
+ "0",
+ "-1",
+ "-1",
+ "0",
+ "0",
+ "0",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "-1",
+ "-1",
+ "-1",
+ "0",
+ "0",
+ "0",
+ "0",
+ "1",
+ "1",
+ "1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "0",
+ "0",
+ "0",
+ "0",
+ "-1",
+ "-1",
+ "0",
+ "0",
+ "0",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "-1",
+ "-1",
+ "-1",
+ "0",
+ "0",
+ "0",
+ "0",
+ "-1",
+ "-1",
+ "-1");
+
+ private final TestParameters parameters;
+
+ @Parameterized.Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters().withCfRuntimes().withDexRuntimes().withAllApiLevels().build();
+ }
+
+ public IdentityAbsorbingIntTest(TestParameters parameters) {
+ this.parameters = parameters;
+ }
+
+ @Test
+ public void testD8() throws Exception {
+ testForRuntime(parameters)
+ .addProgramClasses(Main.class)
+ .run(parameters.getRuntime(), Main.class)
+ .assertSuccessWithOutput(EXPECTED_RESULT);
+ }
+
+ @Test
+ public void testR8() throws Exception {
+ testForR8(parameters.getBackend())
+ .addProgramClasses(Main.class)
+ .addKeepMainRule(Main.class)
+ .enableInliningAnnotations()
+ .setMinApi(parameters)
+ .compile()
+ .inspect(this::inspect)
+ .run(parameters.getRuntime(), Main.class)
+ .assertSuccessWithOutput(EXPECTED_RESULT);
+ }
+
+ private void inspect(CodeInspector inspector) {
+ inspector
+ .clazz(Main.class)
+ .forAllMethods(
+ m ->
+ assertTrue(
+ m.streamInstructions()
+ .noneMatch(i -> i.isIntLogicalBinop() || i.isIntArithmeticBinop())));
+ }
+
+ static class Main {
+
+ public static void main(String[] args) {
+ intTests(Integer.MAX_VALUE);
+ intTests(Integer.MAX_VALUE - 1);
+ intTests(Integer.MIN_VALUE);
+ intTests(Integer.MIN_VALUE + 1);
+ intTests(System.currentTimeMillis() > 0 ? 0 : 1);
+ intTests(System.currentTimeMillis() > 0 ? 1 : 9);
+ intTests(System.currentTimeMillis() > 0 ? -1 : 1);
+ }
+
+ private static void intTests(int val) {
+ identityIntTest(val);
+ absorbingIntTest(val);
+ identityDoubleIntTest(val);
+ absorbingDoubleIntTest(val);
+ chainIntTest(val);
+ associativeIdentityIntTest(val);
+ }
+
+ @NeverInline
+ private static void identityDoubleIntTest(int val) {
+ System.out.println(val + 0 + 0);
+ System.out.println(0 + val + 0);
+ System.out.println(0 + 0 + val);
+ System.out.println(val - 0 - 0);
+ System.out.println(val * 1 * 1);
+ System.out.println(1 * val * 1);
+ System.out.println(1 * 1 * val);
+ System.out.println(val / 1 / 1);
+
+ System.out.println(val & -1 & -1);
+ System.out.println(-1 & val & -1);
+ System.out.println(-1 & -1 & val);
+ System.out.println(val | 0 | 0);
+ System.out.println(0 | val | 0);
+ System.out.println(0 | 0 | val);
+ System.out.println(val ^ 0 ^ 0);
+ System.out.println(0 ^ val ^ 0);
+ System.out.println(0 ^ 0 ^ val);
+ System.out.println(val << 0 << 0);
+ System.out.println(val >> 0 >> 0);
+ System.out.println(val >>> 0 >>> 0);
+ }
+
+ @NeverInline
+ private static void identityIntTest(int val) {
+ System.out.println(val + 0);
+ System.out.println(0 + val);
+ System.out.println(val - 0);
+ System.out.println(val * 1);
+ System.out.println(1 * val);
+ System.out.println(val / 1);
+
+ System.out.println(val & -1);
+ System.out.println(-1 & val);
+ System.out.println(val | 0);
+ System.out.println(0 | val);
+ System.out.println(val ^ 0);
+ System.out.println(0 ^ val);
+ System.out.println(val << 0);
+ System.out.println(val >> 0);
+ System.out.println(val >>> 0);
+ }
+
+ @NeverInline
+ private static void associativeIdentityIntTest(int val) {
+ int minusOne = -1;
+ System.out.println(val + 1 + minusOne);
+ System.out.println(val + 1 - 1);
+ System.out.println(val - 1 - minusOne);
+ }
+
+ @NeverInline
+ private static void absorbingDoubleIntTest(int val) {
+ System.out.println(val * 0 * 0);
+ System.out.println(0 * val * 0);
+ System.out.println(0 * 0 * val);
+ // val would need to be proven non zero.
+ // System.out.println(0 / val);
+ // System.out.println(0 % val);
+
+ System.out.println(0 & 0 & val);
+ System.out.println(0 & val & 0);
+ System.out.println(val & 0 & 0);
+ System.out.println(-1 | -1 | val);
+ System.out.println(-1 | val | -1);
+ System.out.println(val | -1 | -1);
+ System.out.println(0 << 0 << val);
+ System.out.println(0 >> 0 >> val);
+ System.out.println(0 >>> 0 >>> val);
+ }
+
+ @NeverInline
+ private static void absorbingIntTest(int val) {
+ System.out.println(val * 0);
+ System.out.println(0 * val);
+ // val would need to be proven non zero.
+ // System.out.println(0 / val);
+ // System.out.println(0 % val);
+
+ System.out.println(0 & val);
+ System.out.println(val & 0);
+ System.out.println(-1 | val);
+ System.out.println(val | -1);
+ System.out.println(0 << val);
+ System.out.println(0 >> val);
+ System.out.println(0 >>> val);
+ }
+
+ private static void chainIntTest(int val) {
+ int abs = System.currentTimeMillis() > 0 ? val * 0 : 0 * val;
+ System.out.println(abs * val);
+ }
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/ir/IdentityAbsorbingLongTest.java b/src/test/java/com/android/tools/r8/ir/IdentityAbsorbingLongTest.java
new file mode 100644
index 0000000..a1f0c1c
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/ir/IdentityAbsorbingLongTest.java
@@ -0,0 +1,590 @@
+// Copyright (c) 2023, 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.Assert.assertTrue;
+
+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.android.tools.r8.utils.StringUtils;
+import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class IdentityAbsorbingLongTest extends TestBase {
+
+ private static final String EXPECTED_RESULT =
+ StringUtils.lines(
+ "9223372036854775807",
+ "9223372036854775807",
+ "9223372036854775807",
+ "9223372036854775807",
+ "9223372036854775807",
+ "9223372036854775807",
+ "9223372036854775807",
+ "9223372036854775807",
+ "9223372036854775807",
+ "9223372036854775807",
+ "9223372036854775807",
+ "9223372036854775807",
+ "9223372036854775807",
+ "9223372036854775807",
+ "9223372036854775807",
+ "0",
+ "0",
+ "0",
+ "0",
+ "-1",
+ "-1",
+ "0",
+ "0",
+ "0",
+ "9223372036854775807",
+ "9223372036854775807",
+ "9223372036854775807",
+ "9223372036854775807",
+ "9223372036854775807",
+ "9223372036854775807",
+ "9223372036854775807",
+ "9223372036854775807",
+ "9223372036854775807",
+ "9223372036854775807",
+ "9223372036854775807",
+ "9223372036854775807",
+ "9223372036854775807",
+ "9223372036854775807",
+ "9223372036854775807",
+ "9223372036854775807",
+ "9223372036854775807",
+ "9223372036854775807",
+ "9223372036854775807",
+ "9223372036854775807",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "-1",
+ "-1",
+ "-1",
+ "0",
+ "0",
+ "0",
+ "9223372036854775807",
+ "9223372036854775807",
+ "9223372036854775807",
+ "9223372036854775806",
+ "9223372036854775806",
+ "9223372036854775806",
+ "9223372036854775806",
+ "9223372036854775806",
+ "9223372036854775806",
+ "9223372036854775806",
+ "9223372036854775806",
+ "9223372036854775806",
+ "9223372036854775806",
+ "9223372036854775806",
+ "9223372036854775806",
+ "9223372036854775806",
+ "9223372036854775806",
+ "9223372036854775806",
+ "0",
+ "0",
+ "0",
+ "0",
+ "-1",
+ "-1",
+ "0",
+ "0",
+ "0",
+ "9223372036854775806",
+ "9223372036854775806",
+ "9223372036854775806",
+ "9223372036854775806",
+ "9223372036854775806",
+ "9223372036854775806",
+ "9223372036854775806",
+ "9223372036854775806",
+ "9223372036854775806",
+ "9223372036854775806",
+ "9223372036854775806",
+ "9223372036854775806",
+ "9223372036854775806",
+ "9223372036854775806",
+ "9223372036854775806",
+ "9223372036854775806",
+ "9223372036854775806",
+ "9223372036854775806",
+ "9223372036854775806",
+ "9223372036854775806",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "-1",
+ "-1",
+ "-1",
+ "0",
+ "0",
+ "0",
+ "9223372036854775806",
+ "9223372036854775806",
+ "9223372036854775806",
+ "-9223372036854775808",
+ "-9223372036854775808",
+ "-9223372036854775808",
+ "-9223372036854775808",
+ "-9223372036854775808",
+ "-9223372036854775808",
+ "-9223372036854775808",
+ "-9223372036854775808",
+ "-9223372036854775808",
+ "-9223372036854775808",
+ "-9223372036854775808",
+ "-9223372036854775808",
+ "-9223372036854775808",
+ "-9223372036854775808",
+ "-9223372036854775808",
+ "0",
+ "0",
+ "0",
+ "0",
+ "-1",
+ "-1",
+ "0",
+ "0",
+ "0",
+ "-9223372036854775808",
+ "-9223372036854775808",
+ "-9223372036854775808",
+ "-9223372036854775808",
+ "-9223372036854775808",
+ "-9223372036854775808",
+ "-9223372036854775808",
+ "-9223372036854775808",
+ "-9223372036854775808",
+ "-9223372036854775808",
+ "-9223372036854775808",
+ "-9223372036854775808",
+ "-9223372036854775808",
+ "-9223372036854775808",
+ "-9223372036854775808",
+ "-9223372036854775808",
+ "-9223372036854775808",
+ "-9223372036854775808",
+ "-9223372036854775808",
+ "-9223372036854775808",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "-1",
+ "-1",
+ "-1",
+ "0",
+ "0",
+ "0",
+ "-9223372036854775808",
+ "-9223372036854775808",
+ "-9223372036854775808",
+ "-9223372036854775807",
+ "-9223372036854775807",
+ "-9223372036854775807",
+ "-9223372036854775807",
+ "-9223372036854775807",
+ "-9223372036854775807",
+ "-9223372036854775807",
+ "-9223372036854775807",
+ "-9223372036854775807",
+ "-9223372036854775807",
+ "-9223372036854775807",
+ "-9223372036854775807",
+ "-9223372036854775807",
+ "-9223372036854775807",
+ "-9223372036854775807",
+ "0",
+ "0",
+ "0",
+ "0",
+ "-1",
+ "-1",
+ "0",
+ "0",
+ "0",
+ "-9223372036854775807",
+ "-9223372036854775807",
+ "-9223372036854775807",
+ "-9223372036854775807",
+ "-9223372036854775807",
+ "-9223372036854775807",
+ "-9223372036854775807",
+ "-9223372036854775807",
+ "-9223372036854775807",
+ "-9223372036854775807",
+ "-9223372036854775807",
+ "-9223372036854775807",
+ "-9223372036854775807",
+ "-9223372036854775807",
+ "-9223372036854775807",
+ "-9223372036854775807",
+ "-9223372036854775807",
+ "-9223372036854775807",
+ "-9223372036854775807",
+ "-9223372036854775807",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "-1",
+ "-1",
+ "-1",
+ "0",
+ "0",
+ "0",
+ "-9223372036854775807",
+ "-9223372036854775807",
+ "-9223372036854775807",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "-1",
+ "-1",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "-1",
+ "-1",
+ "-1",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "0",
+ "0",
+ "0",
+ "0",
+ "-1",
+ "-1",
+ "0",
+ "0",
+ "0",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "-1",
+ "-1",
+ "-1",
+ "0",
+ "0",
+ "0",
+ "1",
+ "1",
+ "1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "0",
+ "0",
+ "0",
+ "0",
+ "-1",
+ "-1",
+ "0",
+ "0",
+ "0",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "-1",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "0",
+ "-1",
+ "-1",
+ "-1",
+ "0",
+ "0",
+ "0",
+ "-1",
+ "-1",
+ "-1");
+
+ private final TestParameters parameters;
+
+ @Parameterized.Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters().withCfRuntimes().withDexRuntimes().withAllApiLevels().build();
+ }
+
+ public IdentityAbsorbingLongTest(TestParameters parameters) {
+ this.parameters = parameters;
+ }
+
+ @Test
+ public void testD8() throws Exception {
+ testForRuntime(parameters)
+ .addProgramClasses(Main.class)
+ .run(parameters.getRuntime(), Main.class)
+ .assertSuccessWithOutput(EXPECTED_RESULT);
+ }
+
+ @Test
+ public void testR8() throws Exception {
+ testForR8(parameters.getBackend())
+ .addProgramClasses(Main.class)
+ .addKeepMainRule(Main.class)
+ .enableInliningAnnotations()
+ .setMinApi(parameters)
+ .compile()
+ .inspect(this::inspect)
+ .run(parameters.getRuntime(), Main.class)
+ .assertSuccessWithOutput(EXPECTED_RESULT);
+ }
+
+ private void inspect(CodeInspector inspector) {
+ inspector
+ .clazz(Main.class)
+ .forAllMethods(
+ m ->
+ assertTrue(
+ m.streamInstructions()
+ .noneMatch(i -> i.isLongArithmeticBinop() || i.isLongLogicalBinop())));
+ }
+
+ static class Main {
+
+ public static void main(String[] args) {
+ longTests(Long.MAX_VALUE);
+ longTests(Long.MAX_VALUE - 1);
+ longTests(Long.MIN_VALUE);
+ longTests(Long.MIN_VALUE + 1);
+ longTests(System.currentTimeMillis() > 0 ? 0L : 1L);
+ longTests(System.currentTimeMillis() > 0 ? 1L : 9L);
+ longTests(System.currentTimeMillis() > 0 ? -1L : 1L);
+ }
+
+ private static void longTests(long val) {
+ identityLongTest(val);
+ absorbingLongTest(val);
+ identityDoubleLongTest(val);
+ absorbingDoubleLongTest(val);
+ associativeIdentityLongTest(val);
+ }
+
+ @NeverInline
+ private static void identityDoubleLongTest(long val) {
+ System.out.println(val + 0L + 0L);
+ System.out.println(0L + val + 0L);
+ System.out.println(0L + 0L + val);
+ System.out.println(val - 0L - 0L);
+ System.out.println(val * 1L * 1L);
+ System.out.println(1L * val * 1L);
+ System.out.println(1L * 1L * val);
+ System.out.println(val / 1L / 1L);
+
+ System.out.println(val & -1L & -1L);
+ System.out.println(-1L & val & -1L);
+ System.out.println(-1L & -1L & val);
+ System.out.println(val | 0L | 0L);
+ System.out.println(0L | val | 0L);
+ System.out.println(0L | 0L | val);
+ System.out.println(val ^ 0L ^ 0L);
+ System.out.println(0L ^ val ^ 0L);
+ System.out.println(0L ^ 0L ^ val);
+ System.out.println(val << 0L << 0L);
+ System.out.println(val >> 0L >> 0L);
+ System.out.println(val >>> 0L >>> 0L);
+ }
+
+ @NeverInline
+ private static void identityLongTest(long val) {
+ System.out.println(val + 0L);
+ System.out.println(0L + val);
+ System.out.println(val - 0L);
+ System.out.println(val * 1L);
+ System.out.println(1L * val);
+ System.out.println(val / 1L);
+
+ System.out.println(val & -1L);
+ System.out.println(-1L & val);
+ System.out.println(val | 0L);
+ System.out.println(0L | val);
+ System.out.println(val ^ 0L);
+ System.out.println(0L ^ val);
+ System.out.println(val << 0L);
+ System.out.println(val >> 0L);
+ System.out.println(val >>> 0L);
+ }
+
+ @NeverInline
+ private static void associativeIdentityLongTest(long val) {
+ long minusOne = -1L;
+ System.out.println(val + 1L + minusOne);
+ System.out.println(val + 1L - 1L);
+ System.out.println(val - 1L - minusOne);
+ }
+
+ @NeverInline
+ private static void absorbingDoubleLongTest(long val) {
+ System.out.println(val * 0L * 0L);
+ System.out.println(0L * val * 0L);
+ System.out.println(0L * 0L * val);
+ // val would need to be proven non zero.
+ // System.out.println(0L / val);
+ // System.out.println(0L % val);
+
+ System.out.println(0L & 0L & val);
+ System.out.println(0L & val & 0L);
+ System.out.println(val & 0L & 0L);
+ System.out.println(-1L | -1L | val);
+ System.out.println(-1L | val | -1L);
+ System.out.println(val | -1L | -1L);
+ System.out.println(0L << 0L << val);
+ System.out.println(0L >> 0L >> val);
+ System.out.println(0L >>> 0L >>> val);
+ }
+
+ @NeverInline
+ private static void absorbingLongTest(long val) {
+ System.out.println(val * 0L);
+ System.out.println(0L * val);
+ // val would need to be proven non zero.
+ // System.out.println(0L / val);
+ // System.out.println(0L % val);
+
+ System.out.println(0L & val);
+ System.out.println(val & 0L);
+ System.out.println(-1L | val);
+ System.out.println(val | -1L);
+ System.out.println(0L << val);
+ System.out.println(0L >> val);
+ System.out.println(0L >>> val);
+ }
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/ir/IdentityAbsorbingTest.java b/src/test/java/com/android/tools/r8/ir/IdentityAbsorbingTest.java
deleted file mode 100644
index 3f9a8b2..0000000
--- a/src/test/java/com/android/tools/r8/ir/IdentityAbsorbingTest.java
+++ /dev/null
@@ -1,1067 +0,0 @@
-// Copyright (c) 2023, 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.Assert.assertTrue;
-
-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.android.tools.r8.utils.StringUtils;
-import com.android.tools.r8.utils.codeinspector.CodeInspector;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-@RunWith(Parameterized.class)
-public class IdentityAbsorbingTest extends TestBase {
-
- private static final String EXPECTED_RESULT =
- StringUtils.lines(
- "2147483647",
- "2147483647",
- "2147483647",
- "2147483647",
- "2147483647",
- "2147483647",
- "2147483647",
- "2147483647",
- "2147483647",
- "2147483647",
- "2147483647",
- "2147483647",
- "2147483647",
- "2147483647",
- "2147483647",
- "0",
- "0",
- "0",
- "0",
- "-1",
- "-1",
- "0",
- "0",
- "0",
- "2147483647",
- "2147483647",
- "2147483647",
- "2147483647",
- "2147483647",
- "2147483647",
- "2147483647",
- "2147483647",
- "2147483647",
- "2147483647",
- "2147483647",
- "2147483647",
- "2147483647",
- "2147483647",
- "2147483647",
- "2147483647",
- "2147483647",
- "2147483647",
- "2147483647",
- "2147483647",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "-1",
- "-1",
- "-1",
- "0",
- "0",
- "0",
- "0",
- "2147483646",
- "2147483646",
- "2147483646",
- "2147483646",
- "2147483646",
- "2147483646",
- "2147483646",
- "2147483646",
- "2147483646",
- "2147483646",
- "2147483646",
- "2147483646",
- "2147483646",
- "2147483646",
- "2147483646",
- "0",
- "0",
- "0",
- "0",
- "-1",
- "-1",
- "0",
- "0",
- "0",
- "2147483646",
- "2147483646",
- "2147483646",
- "2147483646",
- "2147483646",
- "2147483646",
- "2147483646",
- "2147483646",
- "2147483646",
- "2147483646",
- "2147483646",
- "2147483646",
- "2147483646",
- "2147483646",
- "2147483646",
- "2147483646",
- "2147483646",
- "2147483646",
- "2147483646",
- "2147483646",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "-1",
- "-1",
- "-1",
- "0",
- "0",
- "0",
- "0",
- "-2147483648",
- "-2147483648",
- "-2147483648",
- "-2147483648",
- "-2147483648",
- "-2147483648",
- "-2147483648",
- "-2147483648",
- "-2147483648",
- "-2147483648",
- "-2147483648",
- "-2147483648",
- "-2147483648",
- "-2147483648",
- "-2147483648",
- "0",
- "0",
- "0",
- "0",
- "-1",
- "-1",
- "0",
- "0",
- "0",
- "-2147483648",
- "-2147483648",
- "-2147483648",
- "-2147483648",
- "-2147483648",
- "-2147483648",
- "-2147483648",
- "-2147483648",
- "-2147483648",
- "-2147483648",
- "-2147483648",
- "-2147483648",
- "-2147483648",
- "-2147483648",
- "-2147483648",
- "-2147483648",
- "-2147483648",
- "-2147483648",
- "-2147483648",
- "-2147483648",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "-1",
- "-1",
- "-1",
- "0",
- "0",
- "0",
- "0",
- "-2147483647",
- "-2147483647",
- "-2147483647",
- "-2147483647",
- "-2147483647",
- "-2147483647",
- "-2147483647",
- "-2147483647",
- "-2147483647",
- "-2147483647",
- "-2147483647",
- "-2147483647",
- "-2147483647",
- "-2147483647",
- "-2147483647",
- "0",
- "0",
- "0",
- "0",
- "-1",
- "-1",
- "0",
- "0",
- "0",
- "-2147483647",
- "-2147483647",
- "-2147483647",
- "-2147483647",
- "-2147483647",
- "-2147483647",
- "-2147483647",
- "-2147483647",
- "-2147483647",
- "-2147483647",
- "-2147483647",
- "-2147483647",
- "-2147483647",
- "-2147483647",
- "-2147483647",
- "-2147483647",
- "-2147483647",
- "-2147483647",
- "-2147483647",
- "-2147483647",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "-1",
- "-1",
- "-1",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "-1",
- "-1",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "-1",
- "-1",
- "-1",
- "0",
- "0",
- "0",
- "0",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "0",
- "0",
- "0",
- "0",
- "-1",
- "-1",
- "0",
- "0",
- "0",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "-1",
- "-1",
- "-1",
- "0",
- "0",
- "0",
- "0",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "0",
- "0",
- "0",
- "0",
- "-1",
- "-1",
- "0",
- "0",
- "0",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "-1",
- "-1",
- "-1",
- "0",
- "0",
- "0",
- "0",
- "9223372036854775807",
- "9223372036854775807",
- "9223372036854775807",
- "9223372036854775807",
- "9223372036854775807",
- "9223372036854775807",
- "9223372036854775807",
- "9223372036854775807",
- "9223372036854775807",
- "9223372036854775807",
- "9223372036854775807",
- "9223372036854775807",
- "9223372036854775807",
- "9223372036854775807",
- "9223372036854775807",
- "0",
- "0",
- "0",
- "0",
- "-1",
- "-1",
- "0",
- "0",
- "0",
- "9223372036854775807",
- "9223372036854775807",
- "9223372036854775807",
- "9223372036854775807",
- "9223372036854775807",
- "9223372036854775807",
- "9223372036854775807",
- "9223372036854775807",
- "9223372036854775807",
- "9223372036854775807",
- "9223372036854775807",
- "9223372036854775807",
- "9223372036854775807",
- "9223372036854775807",
- "9223372036854775807",
- "9223372036854775807",
- "9223372036854775807",
- "9223372036854775807",
- "9223372036854775807",
- "9223372036854775807",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "-1",
- "-1",
- "-1",
- "0",
- "0",
- "0",
- "9223372036854775806",
- "9223372036854775806",
- "9223372036854775806",
- "9223372036854775806",
- "9223372036854775806",
- "9223372036854775806",
- "9223372036854775806",
- "9223372036854775806",
- "9223372036854775806",
- "9223372036854775806",
- "9223372036854775806",
- "9223372036854775806",
- "9223372036854775806",
- "9223372036854775806",
- "9223372036854775806",
- "0",
- "0",
- "0",
- "0",
- "-1",
- "-1",
- "0",
- "0",
- "0",
- "9223372036854775806",
- "9223372036854775806",
- "9223372036854775806",
- "9223372036854775806",
- "9223372036854775806",
- "9223372036854775806",
- "9223372036854775806",
- "9223372036854775806",
- "9223372036854775806",
- "9223372036854775806",
- "9223372036854775806",
- "9223372036854775806",
- "9223372036854775806",
- "9223372036854775806",
- "9223372036854775806",
- "9223372036854775806",
- "9223372036854775806",
- "9223372036854775806",
- "9223372036854775806",
- "9223372036854775806",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "-1",
- "-1",
- "-1",
- "0",
- "0",
- "0",
- "-9223372036854775808",
- "-9223372036854775808",
- "-9223372036854775808",
- "-9223372036854775808",
- "-9223372036854775808",
- "-9223372036854775808",
- "-9223372036854775808",
- "-9223372036854775808",
- "-9223372036854775808",
- "-9223372036854775808",
- "-9223372036854775808",
- "-9223372036854775808",
- "-9223372036854775808",
- "-9223372036854775808",
- "-9223372036854775808",
- "0",
- "0",
- "0",
- "0",
- "-1",
- "-1",
- "0",
- "0",
- "0",
- "-9223372036854775808",
- "-9223372036854775808",
- "-9223372036854775808",
- "-9223372036854775808",
- "-9223372036854775808",
- "-9223372036854775808",
- "-9223372036854775808",
- "-9223372036854775808",
- "-9223372036854775808",
- "-9223372036854775808",
- "-9223372036854775808",
- "-9223372036854775808",
- "-9223372036854775808",
- "-9223372036854775808",
- "-9223372036854775808",
- "-9223372036854775808",
- "-9223372036854775808",
- "-9223372036854775808",
- "-9223372036854775808",
- "-9223372036854775808",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "-1",
- "-1",
- "-1",
- "0",
- "0",
- "0",
- "-9223372036854775807",
- "-9223372036854775807",
- "-9223372036854775807",
- "-9223372036854775807",
- "-9223372036854775807",
- "-9223372036854775807",
- "-9223372036854775807",
- "-9223372036854775807",
- "-9223372036854775807",
- "-9223372036854775807",
- "-9223372036854775807",
- "-9223372036854775807",
- "-9223372036854775807",
- "-9223372036854775807",
- "-9223372036854775807",
- "0",
- "0",
- "0",
- "0",
- "-1",
- "-1",
- "0",
- "0",
- "0",
- "-9223372036854775807",
- "-9223372036854775807",
- "-9223372036854775807",
- "-9223372036854775807",
- "-9223372036854775807",
- "-9223372036854775807",
- "-9223372036854775807",
- "-9223372036854775807",
- "-9223372036854775807",
- "-9223372036854775807",
- "-9223372036854775807",
- "-9223372036854775807",
- "-9223372036854775807",
- "-9223372036854775807",
- "-9223372036854775807",
- "-9223372036854775807",
- "-9223372036854775807",
- "-9223372036854775807",
- "-9223372036854775807",
- "-9223372036854775807",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "-1",
- "-1",
- "-1",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "-1",
- "-1",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "-1",
- "-1",
- "-1",
- "0",
- "0",
- "0",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "0",
- "0",
- "0",
- "0",
- "-1",
- "-1",
- "0",
- "0",
- "0",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "1",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "-1",
- "-1",
- "-1",
- "0",
- "0",
- "0",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "0",
- "0",
- "0",
- "0",
- "-1",
- "-1",
- "0",
- "0",
- "0",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "-1",
- "0",
- "0",
- "0",
- "0",
- "0",
- "0",
- "-1",
- "-1",
- "-1",
- "0",
- "0",
- "0");
-
- private final TestParameters parameters;
-
- @Parameterized.Parameters(name = "{0}")
- public static TestParametersCollection data() {
- return getTestParameters().withCfRuntimes().withDexRuntimes().withAllApiLevels().build();
- }
-
- public IdentityAbsorbingTest(TestParameters parameters) {
- this.parameters = parameters;
- }
-
- @Test
- public void testD8() throws Exception {
- testForRuntime(parameters)
- .addProgramClasses(Main.class)
- .run(parameters.getRuntime(), Main.class)
- .assertSuccessWithOutput(EXPECTED_RESULT);
- }
-
- @Test
- public void testR8() throws Exception {
- testForR8(parameters.getBackend())
- .addProgramClasses(Main.class)
- .addKeepMainRule(Main.class)
- .enableInliningAnnotations()
- .setMinApi(parameters)
- .compile()
- .inspect(this::inspect)
- .run(parameters.getRuntime(), Main.class)
- .assertSuccessWithOutput(EXPECTED_RESULT);
- }
-
- private void inspect(CodeInspector inspector) {
- inspector
- .clazz(Main.class)
- .forAllMethods(
- m ->
- assertTrue(
- m.streamInstructions()
- .noneMatch(
- i ->
- i.isIntLogicalBinop()
- || i.isLongLogicalBinop()
- || i.isIntArithmeticBinop()
- || i.isLongArithmeticBinop())));
- }
-
- static class Main {
-
- public static void main(String[] args) {
- intTests(Integer.MAX_VALUE);
- intTests(Integer.MAX_VALUE - 1);
- intTests(Integer.MIN_VALUE);
- intTests(Integer.MIN_VALUE + 1);
- intTests(System.currentTimeMillis() > 0 ? 0 : 1);
- intTests(System.currentTimeMillis() > 0 ? 1 : 9);
- intTests(System.currentTimeMillis() > 0 ? -1 : 1);
-
- longTests(Long.MAX_VALUE);
- longTests(Long.MAX_VALUE - 1);
- longTests(Long.MIN_VALUE);
- longTests(Long.MIN_VALUE + 1);
- longTests(System.currentTimeMillis() > 0 ? 0L : 1L);
- longTests(System.currentTimeMillis() > 0 ? 1L : 9L);
- longTests(System.currentTimeMillis() > 0 ? -1L : 1L);
- }
-
- private static void longTests(long val) {
- identityLongTest(val);
- absorbingLongTest(val);
- identityDoubleLongTest(val);
- absorbingDoubleLongTest(val);
- }
-
- private static void intTests(int val) {
- identityIntTest(val);
- absorbingIntTest(val);
- identityDoubleIntTest(val);
- absorbingDoubleIntTest(val);
- chainIntTest(val);
- }
-
- @NeverInline
- private static void identityDoubleIntTest(int val) {
- System.out.println(val + 0 + 0);
- System.out.println(0 + val + 0);
- System.out.println(0 + 0 + val);
- System.out.println(val - 0 - 0);
- System.out.println(val * 1 * 1);
- System.out.println(1 * val * 1);
- System.out.println(1 * 1 * val);
- System.out.println(val / 1 / 1);
-
- System.out.println(val & -1 & -1);
- System.out.println(-1 & val & -1);
- System.out.println(-1 & -1 & val);
- System.out.println(val | 0 | 0);
- System.out.println(0 | val | 0);
- System.out.println(0 | 0 | val);
- System.out.println(val ^ 0 ^ 0);
- System.out.println(0 ^ val ^ 0);
- System.out.println(0 ^ 0 ^ val);
- System.out.println(val << 0 << 0);
- System.out.println(val >> 0 >> 0);
- System.out.println(val >>> 0 >>> 0);
- }
-
- @NeverInline
- private static void identityDoubleLongTest(long val) {
- System.out.println(val + 0L + 0L);
- System.out.println(0L + val + 0L);
- System.out.println(0L + 0L + val);
- System.out.println(val - 0L - 0L);
- System.out.println(val * 1L * 1L);
- System.out.println(1L * val * 1L);
- System.out.println(1L * 1L * val);
- System.out.println(val / 1L / 1L);
-
- System.out.println(val & -1L & -1L);
- System.out.println(-1L & val & -1L);
- System.out.println(-1L & -1L & val);
- System.out.println(val | 0L | 0L);
- System.out.println(0L | val | 0L);
- System.out.println(0L | 0L | val);
- System.out.println(val ^ 0L ^ 0L);
- System.out.println(0L ^ val ^ 0L);
- System.out.println(0L ^ 0L ^ val);
- System.out.println(val << 0L << 0L);
- System.out.println(val >> 0L >> 0L);
- System.out.println(val >>> 0L >>> 0L);
- }
-
- @NeverInline
- private static void identityIntTest(int val) {
- System.out.println(val + 0);
- System.out.println(0 + val);
- System.out.println(val - 0);
- System.out.println(val * 1);
- System.out.println(1 * val);
- System.out.println(val / 1);
-
- System.out.println(val & -1);
- System.out.println(-1 & val);
- System.out.println(val | 0);
- System.out.println(0 | val);
- System.out.println(val ^ 0);
- System.out.println(0 ^ val);
- System.out.println(val << 0);
- System.out.println(val >> 0);
- System.out.println(val >>> 0);
- }
-
- @NeverInline
- private static void identityLongTest(long val) {
- System.out.println(val + 0L);
- System.out.println(0L + val);
- System.out.println(val - 0L);
- System.out.println(val * 1L);
- System.out.println(1L * val);
- System.out.println(val / 1L);
-
- System.out.println(val & -1L);
- System.out.println(-1L & val);
- System.out.println(val | 0L);
- System.out.println(0L | val);
- System.out.println(val ^ 0L);
- System.out.println(0L ^ val);
- System.out.println(val << 0L);
- System.out.println(val >> 0L);
- System.out.println(val >>> 0L);
- }
-
- @NeverInline
- private static void absorbingDoubleIntTest(int val) {
- System.out.println(val * 0 * 0);
- System.out.println(0 * val * 0);
- System.out.println(0 * 0 * val);
- // val would need to be proven non zero.
- // System.out.println(0 / val);
- // System.out.println(0 % val);
-
- System.out.println(0 & 0 & val);
- System.out.println(0 & val & 0);
- System.out.println(val & 0 & 0);
- System.out.println(-1 | -1 | val);
- System.out.println(-1 | val | -1);
- System.out.println(val | -1 | -1);
- System.out.println(0 << 0 << val);
- System.out.println(0 >> 0 >> val);
- System.out.println(0 >>> 0 >>> val);
- }
-
- @NeverInline
- private static void absorbingDoubleLongTest(long val) {
- System.out.println(val * 0L * 0L);
- System.out.println(0L * val * 0L);
- System.out.println(0L * 0L * val);
- // val would need to be proven non zero.
- // System.out.println(0L / val);
- // System.out.println(0L % val);
-
- System.out.println(0L & 0L & val);
- System.out.println(0L & val & 0L);
- System.out.println(val & 0L & 0L);
- System.out.println(-1L | -1L | val);
- System.out.println(-1L | val | -1L);
- System.out.println(val | -1L | -1L);
- System.out.println(0L << 0L << val);
- System.out.println(0L >> 0L >> val);
- System.out.println(0L >>> 0L >>> val);
- }
-
- @NeverInline
- private static void absorbingIntTest(int val) {
- System.out.println(val * 0);
- System.out.println(0 * val);
- // val would need to be proven non zero.
- // System.out.println(0 / val);
- // System.out.println(0 % val);
-
- System.out.println(0 & val);
- System.out.println(val & 0);
- System.out.println(-1 | val);
- System.out.println(val | -1);
- System.out.println(0 << val);
- System.out.println(0 >> val);
- System.out.println(0 >>> val);
- }
-
- @NeverInline
- private static void absorbingLongTest(long val) {
- System.out.println(val * 0L);
- System.out.println(0L * val);
- // val would need to be proven non zero.
- // System.out.println(0L / val);
- // System.out.println(0L % val);
-
- System.out.println(0L & val);
- System.out.println(val & 0L);
- System.out.println(-1L | val);
- System.out.println(val | -1L);
- System.out.println(0L << val);
- System.out.println(0L >> val);
- System.out.println(0L >>> val);
- }
-
- private static void chainIntTest(int val) {
- int abs = System.currentTimeMillis() > 0 ? val * 0 : 0 * val;
- System.out.println(abs * val);
- }
- }
-}