Mark operands of POP2 as don't touch in unused expression elimination
Fixes KT-20879.
This commit is contained in:
+6
-2
@@ -79,18 +79,22 @@ class PopBackwardPropagationTransformer : MethodTransformer() {
|
|||||||
private fun analyzeMethodBody(): Array<out Frame<SourceValue>?> {
|
private fun analyzeMethodBody(): Array<out Frame<SourceValue>?> {
|
||||||
val frames = Analyzer<SourceValue>(HazardsTrackingInterpreter()).analyze("fake", methodNode)
|
val frames = Analyzer<SourceValue>(HazardsTrackingInterpreter()).analyze("fake", methodNode)
|
||||||
|
|
||||||
postprocessDupNxM(frames)
|
postprocessStackHazards(frames)
|
||||||
|
|
||||||
return frames
|
return frames
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun postprocessDupNxM(frames: Array<out Frame<SourceValue>?>) {
|
private fun postprocessStackHazards(frames: Array<out Frame<SourceValue>?>) {
|
||||||
val insns = methodNode.instructions.toArray()
|
val insns = methodNode.instructions.toArray()
|
||||||
for (i in frames.indices) {
|
for (i in frames.indices) {
|
||||||
val frame = frames[i] ?: continue
|
val frame = frames[i] ?: continue
|
||||||
val insn = insns[i]
|
val insn = insns[i]
|
||||||
|
|
||||||
when (insn.opcode) {
|
when (insn.opcode) {
|
||||||
|
Opcodes.POP2 -> {
|
||||||
|
val top2 = frame.peekWords(2) ?: throwIncorrectBytecode(insn, frame)
|
||||||
|
top2.forEach { it.insns.markAsDontTouch() }
|
||||||
|
}
|
||||||
Opcodes.DUP_X1 -> {
|
Opcodes.DUP_X1 -> {
|
||||||
val top2 = frame.peekWords(1, 1) ?: throwIncorrectBytecode(insn, frame)
|
val top2 = frame.peekWords(1, 1) ?: throwIncorrectBytecode(insn, frame)
|
||||||
top2.forEach { it.insns.markAsDontTouch() }
|
top2.forEach { it.insns.markAsDontTouch() }
|
||||||
|
|||||||
+23
@@ -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"
|
||||||
|
}
|
||||||
+6
@@ -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);
|
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")
|
@TestMetadata("evaluationOrderForCollection.kt")
|
||||||
public void testEvaluationOrderForCollection() throws Exception {
|
public void testEvaluationOrderForCollection() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/evaluationOrderForCollection.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/evaluationOrderForCollection.kt");
|
||||||
|
|||||||
@@ -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);
|
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")
|
@TestMetadata("evaluationOrderForCollection.kt")
|
||||||
public void testEvaluationOrderForCollection() throws Exception {
|
public void testEvaluationOrderForCollection() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/evaluationOrderForCollection.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/evaluationOrderForCollection.kt");
|
||||||
|
|||||||
@@ -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);
|
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")
|
@TestMetadata("evaluationOrderForCollection.kt")
|
||||||
public void testEvaluationOrderForCollection() throws Exception {
|
public void testEvaluationOrderForCollection() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/evaluationOrderForCollection.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/evaluationOrderForCollection.kt");
|
||||||
|
|||||||
@@ -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);
|
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")
|
@TestMetadata("evaluationOrderForCollection.kt")
|
||||||
public void testEvaluationOrderForCollection() throws Exception {
|
public void testEvaluationOrderForCollection() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/evaluationOrderForCollection.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/evaluationOrderForCollection.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user