From f25f0db10e634b38735ca21626b6e72523bc8a28 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Wed, 16 Dec 2015 10:55:55 +0300 Subject: [PATCH] Fixed long / double / float value merge in OptimizationBasicInterpreter #KT-7401 Fixed --- .../common/OptimizationBasicInterpreter.java | 41 ++++++++++--------- .../codegen/box/regressions/doubleMerge.kt | 10 +++++ .../codegen/box/regressions/floatMerge.kt | 10 +++++ .../codegen/box/regressions/kt7401.kt | 10 +++++ .../BlackBoxCodegenTestGenerated.java | 18 ++++++++ 5 files changed, 69 insertions(+), 20 deletions(-) create mode 100644 compiler/testData/codegen/box/regressions/doubleMerge.kt create mode 100644 compiler/testData/codegen/box/regressions/floatMerge.kt create mode 100644 compiler/testData/codegen/box/regressions/kt7401.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/OptimizationBasicInterpreter.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/OptimizationBasicInterpreter.java index d91b2679835..a74c20ecf5d 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/OptimizationBasicInterpreter.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/OptimizationBasicInterpreter.java @@ -91,27 +91,28 @@ public class OptimizationBasicInterpreter extends BasicInterpreter { public BasicValue merge( @NotNull BasicValue v, @NotNull BasicValue w ) { - if (!v.equals(w)) { - if (v == BasicValue.UNINITIALIZED_VALUE || w == BasicValue.UNINITIALIZED_VALUE) { - return BasicValue.UNINITIALIZED_VALUE; - } - - // if merge of two references then `lub` is java/lang/Object - // arrays also are BasicValues with reference type's - if (v.getType().getSort() == Type.OBJECT && w.getType().getSort() == Type.OBJECT) { - return BasicValue.REFERENCE_VALUE; - } - - assert v.getType().getSort() != Type.ARRAY && w.getType().getSort() != Type.ARRAY : "There should not be arrays"; - - // if merge of something can be stored in int var (int, char, boolean, byte, character) - if (v.getType().getOpcode(Opcodes.ISTORE) == Opcodes.ISTORE && - w.getType().getOpcode(Opcodes.ISTORE) == Opcodes.ISTORE) { - return BasicValue.INT_VALUE; - } - + if (v == BasicValue.UNINITIALIZED_VALUE || w == BasicValue.UNINITIALIZED_VALUE) { return BasicValue.UNINITIALIZED_VALUE; } - return v; + // Objects must be equal, others can just have the same sort + if (v.getType().getSort() == w.getType().getSort() && (v.getType().getSort() != Type.OBJECT || v.equals(w))) { + return v; + } + + // if merge of two references then `lub` is java/lang/Object + // arrays also are BasicValues with reference type's + if (v.getType().getSort() == Type.OBJECT && w.getType().getSort() == Type.OBJECT) { + return BasicValue.REFERENCE_VALUE; + } + + assert v.getType().getSort() != Type.ARRAY && w.getType().getSort() != Type.ARRAY : "There should not be arrays"; + + // if merge of something can be stored in int var (int, char, boolean, byte, character) + if (v.getType().getOpcode(Opcodes.ISTORE) == Opcodes.ISTORE && + w.getType().getOpcode(Opcodes.ISTORE) == Opcodes.ISTORE) { + return BasicValue.INT_VALUE; + } + + return BasicValue.UNINITIALIZED_VALUE; } } diff --git a/compiler/testData/codegen/box/regressions/doubleMerge.kt b/compiler/testData/codegen/box/regressions/doubleMerge.kt new file mode 100644 index 00000000000..92e282fab33 --- /dev/null +++ b/compiler/testData/codegen/box/regressions/doubleMerge.kt @@ -0,0 +1,10 @@ +fun foo(): Double { + var d = 2.0 + if (d > 0.0) { + d++ + } + d++ + return d +} + +fun box() = if (foo() > 3.5) "OK" else "Fail" diff --git a/compiler/testData/codegen/box/regressions/floatMerge.kt b/compiler/testData/codegen/box/regressions/floatMerge.kt new file mode 100644 index 00000000000..22033fa3950 --- /dev/null +++ b/compiler/testData/codegen/box/regressions/floatMerge.kt @@ -0,0 +1,10 @@ +fun foo(): Float { + var f = 2.0f + if (f > 0.0f) { + f++ + } + f++ + return f +} + +fun box() = if (foo() > 3.5f) "OK" else "Fail" \ No newline at end of file diff --git a/compiler/testData/codegen/box/regressions/kt7401.kt b/compiler/testData/codegen/box/regressions/kt7401.kt new file mode 100644 index 00000000000..16294c5031b --- /dev/null +++ b/compiler/testData/codegen/box/regressions/kt7401.kt @@ -0,0 +1,10 @@ +fun foo(): Long { + var n = 2L + if (n > 0L) { + n++ + } + n++ + return n +} + +fun box() = if (foo() == 4L) "OK" else "Fail" diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxCodegenTestGenerated.java index 02711497bb8..bba2121594e 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxCodegenTestGenerated.java @@ -6895,6 +6895,18 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/regressions"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("doubleMerge.kt") + public void testDoubleMerge() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/regressions/doubleMerge.kt"); + doTest(fileName); + } + + @TestMetadata("floatMerge.kt") + public void testFloatMerge() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/regressions/floatMerge.kt"); + doTest(fileName); + } + @TestMetadata("kt3107.kt") public void testKt3107() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/regressions/kt3107.kt"); @@ -6937,6 +6949,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("kt7401.kt") + public void testKt7401() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/regressions/kt7401.kt"); + doTest(fileName); + } + @TestMetadata("unjustifiedReferenceTarget.kt") public void testUnjustifiedReferenceTarget() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/regressions/unjustifiedReferenceTarget.kt");