Mark operands of POP2 as don't touch in unused expression elimination

Fixes KT-20879.
This commit is contained in:
Dmitry Petrov
2017-10-24 11:46:43 +03:00
parent 537600b3b3
commit f23dfdc0ac
6 changed files with 53 additions and 2 deletions

View File

@@ -79,18 +79,22 @@ class PopBackwardPropagationTransformer : MethodTransformer() {
private fun analyzeMethodBody(): Array<out Frame<SourceValue>?> {
val frames = Analyzer<SourceValue>(HazardsTrackingInterpreter()).analyze("fake", methodNode)
postprocessDupNxM(frames)
postprocessStackHazards(frames)
return frames
}
private fun postprocessDupNxM(frames: Array<out Frame<SourceValue>?>) {
private fun postprocessStackHazards(frames: Array<out Frame<SourceValue>?>) {
val insns = methodNode.instructions.toArray()
for (i in frames.indices) {
val frame = frames[i] ?: continue
val insn = insns[i]
when (insn.opcode) {
Opcodes.POP2 -> {
val top2 = frame.peekWords(2) ?: throwIncorrectBytecode(insn, frame)
top2.forEach { it.insns.markAsDontTouch() }
}
Opcodes.DUP_X1 -> {
val top2 = frame.peekWords(1, 1) ?: throwIncorrectBytecode(insn, frame)
top2.forEach { it.insns.markAsDontTouch() }

View File

@@ -0,0 +1,23 @@
fun abs(x: Int) = if (x < 0) -x else x
fun abs(x: Long) = if (x < 0) -x else x
fun test1() =
5 in abs(-1) .. 10
fun test2() =
5 in 1 .. abs(-10)
fun test3() =
5L in abs(-1L) .. 10L
fun test4() =
5L in 1L .. abs(-10L)
fun box(): String {
if (!test1()) return "Fail 1"
if (!test2()) return "Fail 2"
if (!test3()) return "Fail 3"
if (!test4()) return "Fail 4"
return "OK"
}

View File

@@ -14116,6 +14116,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/ranges/contains"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
}
@TestMetadata("comparisonWithRangeBoundEliminated.kt")
public void testComparisonWithRangeBoundEliminated() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/comparisonWithRangeBoundEliminated.kt");
doTest(fileName);
}
@TestMetadata("evaluationOrderForCollection.kt")
public void testEvaluationOrderForCollection() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/evaluationOrderForCollection.kt");

View File

@@ -14116,6 +14116,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/ranges/contains"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
}
@TestMetadata("comparisonWithRangeBoundEliminated.kt")
public void testComparisonWithRangeBoundEliminated() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/comparisonWithRangeBoundEliminated.kt");
doTest(fileName);
}
@TestMetadata("evaluationOrderForCollection.kt")
public void testEvaluationOrderForCollection() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/evaluationOrderForCollection.kt");

View File

@@ -14116,6 +14116,12 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/ranges/contains"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
}
@TestMetadata("comparisonWithRangeBoundEliminated.kt")
public void testComparisonWithRangeBoundEliminated() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/comparisonWithRangeBoundEliminated.kt");
doTest(fileName);
}
@TestMetadata("evaluationOrderForCollection.kt")
public void testEvaluationOrderForCollection() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/evaluationOrderForCollection.kt");

View File

@@ -15454,6 +15454,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/ranges/contains"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true);
}
@TestMetadata("comparisonWithRangeBoundEliminated.kt")
public void testComparisonWithRangeBoundEliminated() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/comparisonWithRangeBoundEliminated.kt");
doTest(fileName);
}
@TestMetadata("evaluationOrderForCollection.kt")
public void testEvaluationOrderForCollection() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/evaluationOrderForCollection.kt");