blob: 2f5af4d7c149e707b749246eb6aa69ad7b91a958 [file]
// Copyright (c) 2025, 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.optimize.numberconversion;
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.NeverPropagateValue;
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 org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@RunWith(Parameterized.class)
public class ConversionTest extends TestBase {
private static final String EXPECTED_OUTPUT =
StringUtils.lines(
"INT_TO_BYTE",
"42",
"0",
"-13",
"-1",
"0",
"127",
"-128",
"-128",
"INT_TO_CHAR",
"42",
"0",
"65523",
"65535",
"0",
"65535",
"0",
"0",
"INT_TO_SHORT",
"42",
"0",
"-13",
"-1",
"0",
"32767",
"-32768",
"-32768",
"INT_TO_LONG",
"42",
"0",
"-13",
"2147483647",
"-2147483648",
"INT_TO_FLOAT",
"1109917696",
"0",
"-1051721728",
"1325400064",
"-822083584",
"INT_TO_DOUBLE",
"4631107791820423168",
"0",
"-4599864069405540352",
"4746794007244308480",
"-4476578029606273024",
"LONG_TO_INT",
"42",
"0",
"-13",
"-1",
"0",
"2147483647",
"-2147483648",
"-2147483648",
"LONG_TO_FLOAT",
"1109917696",
"0",
"-1051721728",
"1593835520",
"-553648128",
"1325400064",
"1325400064",
"-822083584",
"LONG_TO_DOUBLE",
"4631107791820423168",
"0",
"-4599864069405540352",
"4890909195324358656",
"-4332462841530417152",
"4746794007244308480",
"4746794007248502784",
"-4476578029606273024",
"FLOAT_TO_INT",
"42",
"42",
"0",
"0",
"-13",
"-13",
"2147483647",
"2147483647",
"0",
"0",
"-2147483648",
"-2147483648",
"0",
"0",
"2147483647",
"2147483647",
"-2147483648",
"FLOAT_TO_LONG",
"42",
"42",
"0",
"0",
"-13",
"-13",
"9223372036854775807",
"9223372036854775807",
"0",
"0",
"-9223372036854775808",
"-9223372036854775808",
"0",
"0",
"9223372036854775807",
"9223372036854775807",
"-9223372036854775808",
"-9223372036854775808",
"FLOAT_TO_DOUBLE",
"4631107791820423168",
"4631171123797557248",
"0",
"-9223372036854775808",
"true",
"-4599864069405540352",
"-4599610742033874944",
"9218868437227405312",
"5183643170566569984",
"3936146074321813504",
"-5287225962532962304",
"-4039728866288205824",
"-4503599627370496",
"9221120237041090560",
"-536870912",
"true",
"DOUBLE_TO_INT",
"42",
"42",
"0",
"0",
"-13",
"-13",
"2147483647",
"2147483647",
"0",
"0",
"-2147483648",
"-2147483648",
"0",
"0",
"2147483647",
"2147483647",
"-2147483648",
"DOUBLE_TO_LONG",
"42",
"42",
"0",
"0",
"-13",
"-13",
"9223372036854775807",
"9223372036854775807",
"0",
"0",
"-9223372036854775808",
"-9223372036854775808",
"0",
"0",
"9223372036854775807",
"9223372036854775807",
"-9223372036854775808",
"-9223372036854775808",
"DOUBLE_TO_FLOAT",
"1109917696",
"1110035661",
"0",
"-2147483648",
"true",
"-1051721728",
"-1051249869",
"2139095040",
"2139095040",
"0",
"-2147483648",
"-8388608",
"-8388608",
"2143289344",
"-1",
"true");
@Parameterized.Parameter(0)
public TestParameters parameters;
@Parameterized.Parameters(name = "{0}")
public static TestParametersCollection data() {
return getTestParameters().withAllRuntimesAndApiLevels().build();
}
@Test
public void testJvm() throws Exception {
parameters.assumeJvmTestParameters();
testForJvm(parameters)
.addProgramClasses(TestClass.class)
.run(parameters.getRuntime(), TestClass.class)
.assertSuccessWithOutput(EXPECTED_OUTPUT);
}
@Test
public void testR8() throws Exception {
testForR8(parameters)
.addProgramClasses(TestClass.class)
.enableMemberValuePropagationAnnotations()
.enableInliningAnnotations()
.addKeepMainRule(TestClass.class)
.compile()
.run(parameters.getRuntime(), TestClass.class)
.assertSuccessWithOutput(EXPECTED_OUTPUT);
}
@Test
public void testD8() throws Exception {
parameters.assumeDexRuntime();
testForD8(parameters)
.addProgramClasses(TestClass.class)
.compile()
.run(parameters.getRuntime(), TestClass.class)
.assertSuccessWithOutput(EXPECTED_OUTPUT);
}
public static class TestClass {
public static void main(String[] args) {
System.out.println("INT_TO_BYTE");
System.out.println((byte) 42);
System.out.println((byte) 0);
System.out.println((byte) -13);
System.out.println((byte) Integer.MAX_VALUE);
System.out.println((byte) Integer.MIN_VALUE);
System.out.println((byte) 127);
System.out.println((byte) (127 + 1));
System.out.println((byte) -128);
System.out.println("INT_TO_CHAR");
System.out.println(charBits((char) 42));
System.out.println(charBits((char) 0));
System.out.println(charBits((char) -13));
System.out.println(charBits((char) Integer.MAX_VALUE));
System.out.println(charBits((char) Integer.MIN_VALUE));
System.out.println(charBits((char) 0xFFFF));
System.out.println(charBits((char) (0xFFFF + 1)));
System.out.println(charBits((char) 0x0000));
System.out.println("INT_TO_SHORT");
System.out.println((short) 42);
System.out.println((short) 0);
System.out.println((short) -13);
System.out.println((short) Integer.MAX_VALUE);
System.out.println((short) Integer.MIN_VALUE);
System.out.println((short) 32767);
System.out.println((short) (32767 + 1));
System.out.println((short) -32768);
System.out.println("INT_TO_LONG");
System.out.println((long) 42);
System.out.println((long) 0);
System.out.println((long) -13);
System.out.println((long) Integer.MAX_VALUE);
System.out.println((long) Integer.MIN_VALUE);
System.out.println("INT_TO_FLOAT");
System.out.println(Float.floatToRawIntBits((float) 42));
System.out.println(Float.floatToRawIntBits((float) 0));
System.out.println(Float.floatToRawIntBits((float) -13));
System.out.println(Float.floatToRawIntBits((float) Integer.MAX_VALUE));
System.out.println(Float.floatToRawIntBits((float) Integer.MIN_VALUE));
System.out.println("INT_TO_DOUBLE");
System.out.println(Double.doubleToRawLongBits((double) 42));
System.out.println(Double.doubleToRawLongBits((double) 0));
System.out.println(Double.doubleToRawLongBits((double) -13));
System.out.println(Double.doubleToRawLongBits((double) Integer.MAX_VALUE));
System.out.println(Double.doubleToRawLongBits((double) Integer.MIN_VALUE));
System.out.println("LONG_TO_INT");
System.out.println((int) 42L);
System.out.println((int) 0L);
System.out.println((int) -13L);
System.out.println((int) Long.MAX_VALUE);
System.out.println((int) Long.MIN_VALUE);
System.out.println((int) 2147483647L);
System.out.println((int) (2147483647L + 1));
System.out.println((int) -2147483648L);
System.out.println("LONG_TO_FLOAT");
System.out.println(Float.floatToRawIntBits((float) 42L));
System.out.println(Float.floatToRawIntBits((float) 0L));
System.out.println(Float.floatToRawIntBits((float) -13L));
System.out.println(Float.floatToRawIntBits((float) Long.MAX_VALUE));
System.out.println(Float.floatToRawIntBits((float) Long.MIN_VALUE));
System.out.println(Float.floatToRawIntBits((float) 2147483647L));
System.out.println(Float.floatToRawIntBits((float) (2147483647L + 1)));
System.out.println(Float.floatToRawIntBits((float) -2147483648L));
System.out.println("LONG_TO_DOUBLE");
System.out.println(Double.doubleToRawLongBits((double) 42L));
System.out.println(Double.doubleToRawLongBits((double) 0L));
System.out.println(Double.doubleToRawLongBits((double) -13L));
System.out.println(Double.doubleToRawLongBits((double) Long.MAX_VALUE));
System.out.println(Double.doubleToRawLongBits((double) Long.MIN_VALUE));
System.out.println(Double.doubleToRawLongBits((double) 2147483647L));
System.out.println(Double.doubleToRawLongBits((double) (2147483647L + 1)));
System.out.println(Double.doubleToRawLongBits((double) -2147483648L));
System.out.println("FLOAT_TO_INT");
System.out.println((int) 42F);
System.out.println((int) 42.45F);
System.out.println((int) +0F);
System.out.println((int) -0F);
System.out.println((int) -13F);
System.out.println((int) -13.45F);
System.out.println((int) Float.POSITIVE_INFINITY);
System.out.println((int) Float.MAX_VALUE);
System.out.println((int) Float.MIN_VALUE);
System.out.println((int) -Float.MIN_VALUE);
System.out.println((int) -Float.MAX_VALUE);
System.out.println((int) Float.NEGATIVE_INFINITY);
System.out.println((int) Float.NaN);
System.out.println((int) Float.intBitsToFloat(0xFFFFFFFF));
System.out.println((int) 2147483647F);
System.out.println((int) (2147483647F + 100));
System.out.println((int) -2147483648F);
System.out.println("FLOAT_TO_LONG");
System.out.println((long) 42F);
System.out.println((long) 42.45F);
System.out.println((long) +0F);
System.out.println((long) -0F);
System.out.println((long) -13F);
System.out.println((long) -13.45F);
System.out.println((long) Float.POSITIVE_INFINITY);
System.out.println((long) Float.MAX_VALUE);
System.out.println((long) Float.MIN_VALUE);
System.out.println((long) -Float.MIN_VALUE);
System.out.println((long) -Float.MAX_VALUE);
System.out.println((long) Float.NEGATIVE_INFINITY);
System.out.println((long) Float.NaN);
System.out.println((long) Float.intBitsToFloat(0xFFFFFFFF));
System.out.println((long) 9223372036854775807F);
System.out.println((long) (9223372036854775807F + 100));
System.out.println((long) -9223372036854775808F);
System.out.println((long) (-9223372036854775808F - 100));
System.out.println("FLOAT_TO_DOUBLE");
System.out.println(Double.doubleToRawLongBits((double) 42F));
System.out.println(Double.doubleToRawLongBits((double) 42.45F));
System.out.println(Double.doubleToRawLongBits((double) +0F));
System.out.println(Double.doubleToRawLongBits((double) -0F));
System.out.println(
Double.doubleToRawLongBits((double) +0F) != Double.doubleToRawLongBits((double) -0F));
System.out.println(Double.doubleToRawLongBits((double) -13F));
System.out.println(Double.doubleToRawLongBits((double) -13.45F));
System.out.println(Double.doubleToRawLongBits((double) Float.POSITIVE_INFINITY));
System.out.println(Double.doubleToRawLongBits((double) Float.MAX_VALUE));
System.out.println(Double.doubleToRawLongBits((double) Float.MIN_VALUE));
System.out.println(Double.doubleToRawLongBits((double) -Float.MIN_VALUE));
System.out.println(Double.doubleToRawLongBits((double) -Float.MAX_VALUE));
System.out.println(Double.doubleToRawLongBits((double) Float.NEGATIVE_INFINITY));
System.out.println(Double.doubleToRawLongBits((double) Float.NaN));
System.out.println(Double.doubleToRawLongBits((double) Float.intBitsToFloat(0xFFFFFFFF)));
System.out.println(
Double.doubleToRawLongBits((double) Float.NaN)
!= Double.doubleToRawLongBits((double) Float.intBitsToFloat(0xFFFFFFFF)));
System.out.println("DOUBLE_TO_INT");
System.out.println((int) 42D);
System.out.println((int) 42.45D);
System.out.println((int) +0D);
System.out.println((int) -0D);
System.out.println((int) -13D);
System.out.println((int) -13.45D);
System.out.println((int) Double.POSITIVE_INFINITY);
System.out.println((int) Double.MAX_VALUE);
System.out.println((int) Double.MIN_VALUE);
System.out.println((int) -Double.MIN_VALUE);
System.out.println((int) -Double.MAX_VALUE);
System.out.println((int) Double.NEGATIVE_INFINITY);
System.out.println((int) Double.NaN);
System.out.println((int) Double.longBitsToDouble(0xFFFFFFFFFFFFFFFFL));
System.out.println((int) 2147483647F);
System.out.println((int) (2147483647F + 100));
System.out.println((int) -2147483648F);
System.out.println("DOUBLE_TO_LONG");
System.out.println((long) 42D);
System.out.println((long) 42.45D);
System.out.println((long) +0D);
System.out.println((long) -0D);
System.out.println((long) -13D);
System.out.println((long) -13.45D);
System.out.println((long) Double.POSITIVE_INFINITY);
System.out.println((long) Double.MAX_VALUE);
System.out.println((long) Double.MIN_VALUE);
System.out.println((long) -Double.MIN_VALUE);
System.out.println((long) -Double.MAX_VALUE);
System.out.println((long) Double.NEGATIVE_INFINITY);
System.out.println((long) Double.NaN);
System.out.println((long) Double.longBitsToDouble(0xFFFFFFFFFFFFFFFFL));
System.out.println((long) 9223372036854775807D);
System.out.println((long) (9223372036854775807D + 100));
System.out.println((long) -9223372036854775808D);
System.out.println((long) (-9223372036854775808D - 100));
System.out.println("DOUBLE_TO_FLOAT");
System.out.println(Float.floatToRawIntBits((float) 42D));
System.out.println(Float.floatToRawIntBits((float) 42.45D));
System.out.println(Float.floatToRawIntBits((float) +0D));
System.out.println(Float.floatToRawIntBits((float) -0D));
System.out.println(Float.floatToIntBits((float) +0D) != Float.floatToIntBits((float) -0D));
System.out.println(Float.floatToRawIntBits((float) -13D));
System.out.println(Float.floatToRawIntBits((float) -13.45D));
System.out.println(Float.floatToRawIntBits((float) Double.POSITIVE_INFINITY));
System.out.println(Float.floatToRawIntBits((float) Double.MAX_VALUE));
System.out.println(Float.floatToRawIntBits((float) Double.MIN_VALUE));
System.out.println(Float.floatToRawIntBits((float) -Double.MIN_VALUE));
System.out.println(Float.floatToRawIntBits((float) -Double.MAX_VALUE));
System.out.println(Float.floatToRawIntBits((float) Double.NEGATIVE_INFINITY));
System.out.println(Float.floatToRawIntBits((float) Double.NaN));
System.out.println(
Float.floatToRawIntBits((float) Double.longBitsToDouble(0xFFFFFFFFFFFFFFFFL)));
System.out.println(
Float.floatToRawIntBits((float) Double.NaN)
!= Float.floatToRawIntBits((float) Double.longBitsToDouble(0xFFFFFFFFFFFFFFFFL)));
}
@NeverInline
@NeverPropagateValue
private static int charBits(char c) {
return (int) c;
}
}
}