diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/NumberOperatorCallsTransformer.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/NumberOperatorCallsTransformer.kt index ac8a38a2777..25cdb209df8 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/NumberOperatorCallsTransformer.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/NumberOperatorCallsTransformer.kt @@ -164,7 +164,7 @@ class NumberOperatorCallsTransformer(context: JsIrBackendContext) : CallsTransfo irBinaryOp(call, intrinsics.jsDiv, toInt32 = BinaryOp(call).result.isInt()) private fun transformRem(call: IrFunctionAccessExpression) = - irBinaryOp(call, intrinsics.jsMod) + irBinaryOp(call, intrinsics.jsMod, toInt32 = BinaryOp(call).result.isInt()) private fun transformIncrement(call: IrFunctionAccessExpression) = transformCrement(call, intrinsics.jsPlus) diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrBoxJsTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrBoxJsTestGenerated.java index e3fe279fab0..8ea340324f8 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrBoxJsTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrBoxJsTestGenerated.java @@ -8136,6 +8136,12 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest { runTest("js/js.translator/testData/box/number/intIncDecOverflow.kt"); } + @Test + @TestMetadata("intMod.kt") + public void testIntMod() throws Exception { + runTest("js/js.translator/testData/box/number/intMod.kt"); + } + @Test @TestMetadata("intOverflow.kt") public void testIntOverflow() throws Exception { diff --git a/js/js.translator/testData/box/number/intMod.kt b/js/js.translator/testData/box/number/intMod.kt new file mode 100644 index 00000000000..90cf163eb3b --- /dev/null +++ b/js/js.translator/testData/box/number/intMod.kt @@ -0,0 +1,66 @@ +// DONT_TARGET_EXACT_BACKEND: JS + +fun testModNegativeInt() { + // wrapper prevents the constants folding + infix fun Int.myModInt(y: Int): Any = this % y + + assertEquals(-1 myModInt -1, 0) + assertEquals(-2 myModInt -1, 0) + assertEquals(-2 myModInt -2, 0) + assertEquals(-2 myModInt -3, -2) + assertEquals(Int.MIN_VALUE myModInt -1, 0) + assertEquals(Int.MIN_VALUE myModInt -2, 0) + assertEquals(Int.MIN_VALUE myModInt -3, -2) + assertEquals(Int.MIN_VALUE myModInt Int.MIN_VALUE, 0) +} + +fun testModNegativeByte() { + // wrapper prevents the constants folding + infix fun Byte.myModByte(y: Byte): Any = this % y + + assertEquals((-1).toByte() myModByte (-1).toByte(), (0).toByte()) + assertEquals((-2).toByte() myModByte (-1).toByte(), (0).toByte()) + assertEquals((-2).toByte() myModByte (-2).toByte(), (0).toByte()) + assertEquals((-2).toByte() myModByte (-3).toByte(), (-2).toByte()) + assertEquals(Byte.MIN_VALUE myModByte (-1).toByte(), (0).toByte()) + assertEquals(Byte.MIN_VALUE myModByte (-2).toByte(), (0).toByte()) + assertEquals(Byte.MIN_VALUE myModByte (-3).toByte(), (-2).toByte()) + assertEquals(Byte.MIN_VALUE myModByte Byte.MIN_VALUE, (0).toByte()) +} + +fun testModNegativeShort() { + // wrapper prevents the constants folding + infix fun Short.myModShort(y: Short): Any = this % y + + assertEquals((-1).toShort() myModShort (-1).toShort(), (0).toShort()) + assertEquals((-2).toShort() myModShort (-1).toShort(), (0).toShort()) + assertEquals((-2).toShort() myModShort (-2).toShort(), (0).toShort()) + assertEquals((-2).toShort() myModShort (-3).toShort(), (-2).toShort()) + assertEquals(Short.MIN_VALUE myModShort (-1).toShort(), (0).toShort()) + assertEquals(Short.MIN_VALUE myModShort (-2).toShort(), (0).toShort()) + assertEquals(Short.MIN_VALUE myModShort (-3).toShort(), (-2).toShort()) + assertEquals(Short.MIN_VALUE myModShort Short.MIN_VALUE, (0).toShort()) +} + +fun testModNegativeLong() { + // wrapper prevents the constants folding + infix fun Long.myModLong(y: Long): Any = this % y + + assertEquals(-1L myModLong -1L, 0L) + assertEquals(-2L myModLong -1L, 0L) + assertEquals(-2L myModLong -2L, 0L) + assertEquals(-2L myModLong -3L, -2L) + assertEquals(Long.MIN_VALUE myModLong -1L, 0L) + assertEquals(Long.MIN_VALUE myModLong -2L, 0L) + assertEquals(Long.MIN_VALUE myModLong -3L, -2L) + assertEquals(Long.MIN_VALUE myModLong Long.MIN_VALUE, 0L) +} + +fun box(): String { + testModNegativeInt() + testModNegativeByte() + testModNegativeShort() + testModNegativeLong() + + return "OK" +}