[js] Fix constant folding for unsigned aithmetic in IR

this resolves KT-44138
This commit is contained in:
Shagen Ogandzhanian
2021-03-30 16:53:12 +02:00
parent 36bc71121a
commit e0e2715864
13 changed files with 677 additions and 213 deletions
@@ -7142,6 +7142,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/constants/float.kt");
}
@Test
@TestMetadata("foldingBinaryOpsUnsigned.kt")
public void testFoldingBinaryOpsUnsigned() throws Exception {
runTest("compiler/testData/codegen/box/constants/foldingBinaryOpsUnsigned.kt");
}
@Test
@TestMetadata("kt9532.kt")
public void testKt9532() throws Exception {
@@ -40360,12 +40366,6 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/unsignedTypes/kt25784.kt");
}
@Test
@TestMetadata("kt30402.kt")
public void testKt30402() throws Exception {
runTest("compiler/testData/codegen/box/unsignedTypes/kt30402.kt");
}
@Test
@TestMetadata("kt43286.kt")
public void testKt43286() throws Exception {
@@ -166,13 +166,13 @@ class FoldConstantLowering(
evaluateBinary(
call.symbol.owner.name.toString(),
lhs.kind.toString(),
lhs.value!!,
normalizeUnsignedValue(lhs)!!,
// 1. Although some operators have nullable parameters, evaluators deals with non-nullable types only.
// The passed parameters are guaranteed to be non-null, since they are from IrConst.
// 2. The operators are registered with prototype as if virtual member functions. They are identified by
// actual_receiver_type.operator_name(parameter_type_in_prototype).
call.symbol.owner.valueParameters[0].type.typeConstructorName(),
rhs.value!!
normalizeUnsignedValue(rhs)!!
) ?: return call
} catch (e: Exception) {
// Don't cast a runtime exception into compile time. E.g., division by zero.
@@ -201,7 +201,24 @@ class FoldConstantLowering(
return buildIrConstant(call.startOffset, call.endOffset, call.type, evaluated)
}
// Unsigned constants are represented through signed constants with a different IrType.
private fun normalizeUnsignedValue(const: IrConst<*>): Any? {
// Unsigned constants are represented through signed constants with a different IrType
if (const.type.isUnsigned()) {
@OptIn(ExperimentalUnsignedTypes::class)
when (val kind = const.kind) {
is IrConstKind.Byte ->
return kind.valueOf(const).toUByte()
is IrConstKind.Short ->
return kind.valueOf(const).toUShort()
is IrConstKind.Int ->
return kind.valueOf(const).toUInt()
is IrConstKind.Long ->
return kind.valueOf(const).toULong()
}
}
return const.value
}
private fun constToString(const: IrConst<*>): String {
if (floatSpecial) {
when (val kind = const.kind) {
@@ -224,20 +241,7 @@ class FoldConstantLowering(
}
}
if (const.type.isUnsigned()) {
@OptIn(ExperimentalUnsignedTypes::class)
when (val kind = const.kind) {
is IrConstKind.Byte ->
return kind.valueOf(const).toUByte().toString()
is IrConstKind.Short ->
return kind.valueOf(const).toUShort().toString()
is IrConstKind.Int ->
return kind.valueOf(const).toUInt().toString()
is IrConstKind.Long ->
return kind.valueOf(const).toULong().toString()
}
}
return const.value.toString()
return normalizeUnsignedValue(const).toString()
}
@ExperimentalUnsignedTypes
@@ -0,0 +1,42 @@
// WITH_RUNTIME
// IGNORE_BACKEND: JVM
// IGNORE_BACKEND: WASM
val a = "INT " + 0x8fffffffU
val b = "BYTE " + 0x8ffU
val c = "LONG " + 0xffff_ffff_ffffU
val uint = 0x8fffffffU
val ubyte = 0x8ffU
val ulong = 0xffff_ffff_ffffU
val aa = "INT " + uint
val bb = "BYTE " + ubyte
val cc = "LONG " + ulong
fun box(): String {
if (a != "INT 2415919103") {
return "FAIL 0: $a"
}
if (aa != "INT 2415919103") {
return "FAIL 1: $aa"
}
if (b != "BYTE 2303") {
return "FAIL 2: $b"
}
if (bb != "BYTE 2303") {
return "FAIL 3: $bb"
}
if (c != "LONG 281474976710655") {
return "FAIL 4: $c"
}
if (cc != "LONG 281474976710655") {
return "FAIL 5: $cc"
}
return "OK"
}
-14
View File
@@ -1,14 +0,0 @@
// WITH_RUNTIME
// IGNORE_BACKEND: JVM
// IGNORE_BACKEND: JS_IR
// IGNORE_LIGHT_ANALYSIS
val unsigned = 0x8fffffffU
val good = "123 " + unsigned
val bad = "123 " + 0x8fffffffU
fun box(): String {
if (good != "123 2415919103") return "good: '$good'"
if (bad != "123 2415919103") return "bad: '$bad'"
return "OK"
}
@@ -7142,6 +7142,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/constants/float.kt");
}
@Test
@TestMetadata("foldingBinaryOpsUnsigned.kt")
public void testFoldingBinaryOpsUnsigned() throws Exception {
runTest("compiler/testData/codegen/box/constants/foldingBinaryOpsUnsigned.kt");
}
@Test
@TestMetadata("kt9532.kt")
public void testKt9532() throws Exception {
@@ -40342,12 +40348,6 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/unsignedTypes/kt25784.kt");
}
@Test
@TestMetadata("kt30402.kt")
public void testKt30402() throws Exception {
runTest("compiler/testData/codegen/box/unsignedTypes/kt30402.kt");
}
@Test
@TestMetadata("kt43286.kt")
public void testKt43286() throws Exception {
@@ -7142,6 +7142,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/constants/float.kt");
}
@Test
@TestMetadata("foldingBinaryOpsUnsigned.kt")
public void testFoldingBinaryOpsUnsigned() throws Exception {
runTest("compiler/testData/codegen/box/constants/foldingBinaryOpsUnsigned.kt");
}
@Test
@TestMetadata("kt9532.kt")
public void testKt9532() throws Exception {
@@ -40360,12 +40366,6 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/unsignedTypes/kt25784.kt");
}
@Test
@TestMetadata("kt30402.kt")
public void testKt30402() throws Exception {
runTest("compiler/testData/codegen/box/unsignedTypes/kt30402.kt");
}
@Test
@TestMetadata("kt43286.kt")
public void testKt43286() throws Exception {
@@ -5377,6 +5377,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Constants extends AbstractLightAnalysisModeTest {
@TestMetadata("foldingBinaryOpsUnsigned.kt")
public void ignoreFoldingBinaryOpsUnsigned() throws Exception {
runTest("compiler/testData/codegen/box/constants/foldingBinaryOpsUnsigned.kt");
}
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
}
@@ -32278,11 +32283,6 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class UnsignedTypes extends AbstractLightAnalysisModeTest {
@TestMetadata("kt30402.kt")
public void ignoreKt30402() throws Exception {
runTest("compiler/testData/codegen/box/unsignedTypes/kt30402.kt");
}
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
}
File diff suppressed because it is too large Load Diff
@@ -4,7 +4,7 @@
* 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
@@ -4819,6 +4819,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
runTest("compiler/testData/codegen/box/constants/float.kt");
}
@TestMetadata("foldingBinaryOpsUnsigned.kt")
public void testFoldingBinaryOpsUnsigned() throws Exception {
runTest("compiler/testData/codegen/box/constants/foldingBinaryOpsUnsigned.kt");
}
@TestMetadata("kt9532.kt")
public void testKt9532() throws Exception {
runTest("compiler/testData/codegen/box/constants/kt9532.kt");
@@ -27316,11 +27321,6 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
runTest("compiler/testData/codegen/box/unsignedTypes/kt25784.kt");
}
@TestMetadata("kt30402.kt")
public void testKt30402() throws Exception {
runTest("compiler/testData/codegen/box/unsignedTypes/kt30402.kt");
}
@TestMetadata("kt43286.kt")
public void testKt43286() throws Exception {
runTest("compiler/testData/codegen/box/unsignedTypes/kt43286.kt");
@@ -4240,6 +4240,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/constants/float.kt");
}
@TestMetadata("foldingBinaryOpsUnsigned.kt")
public void testFoldingBinaryOpsUnsigned() throws Exception {
runTest("compiler/testData/codegen/box/constants/foldingBinaryOpsUnsigned.kt");
}
@TestMetadata("kt9532.kt")
public void testKt9532() throws Exception {
runTest("compiler/testData/codegen/box/constants/kt9532.kt");
@@ -26737,11 +26742,6 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/unsignedTypes/kt25784.kt");
}
@TestMetadata("kt30402.kt")
public void testKt30402() throws Exception {
runTest("compiler/testData/codegen/box/unsignedTypes/kt30402.kt");
}
@TestMetadata("kt43286.kt")
public void testKt43286() throws Exception {
runTest("compiler/testData/codegen/box/unsignedTypes/kt43286.kt");
@@ -4240,6 +4240,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/constants/float.kt");
}
@TestMetadata("foldingBinaryOpsUnsigned.kt")
public void testFoldingBinaryOpsUnsigned() throws Exception {
runTest("compiler/testData/codegen/box/constants/foldingBinaryOpsUnsigned.kt");
}
@TestMetadata("kt9532.kt")
public void testKt9532() throws Exception {
runTest("compiler/testData/codegen/box/constants/kt9532.kt");
@@ -26697,11 +26702,6 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/unsignedTypes/kt25784.kt");
}
@TestMetadata("kt30402.kt")
public void testKt30402() throws Exception {
runTest("compiler/testData/codegen/box/unsignedTypes/kt30402.kt");
}
@TestMetadata("kt43286.kt")
public void testKt43286() throws Exception {
runTest("compiler/testData/codegen/box/unsignedTypes/kt43286.kt");
@@ -3046,6 +3046,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
runTest("compiler/testData/codegen/box/constants/constantsInWhen.kt");
}
@TestMetadata("foldingBinaryOpsUnsigned.kt")
public void testFoldingBinaryOpsUnsigned() throws Exception {
runTest("compiler/testData/codegen/box/constants/foldingBinaryOpsUnsigned.kt");
}
@TestMetadata("long.kt")
public void testLong() throws Exception {
runTest("compiler/testData/codegen/box/constants/long.kt");
@@ -14996,11 +15001,6 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
runTest("compiler/testData/codegen/box/unsignedTypes/iterateOverListOfBoxedUnsignedValues.kt");
}
@TestMetadata("kt30402.kt")
public void testKt30402() throws Exception {
runTest("compiler/testData/codegen/box/unsignedTypes/kt30402.kt");
}
@TestMetadata("kt43286.kt")
public void testKt43286() throws Exception {
runTest("compiler/testData/codegen/box/unsignedTypes/kt43286.kt");