Merge "CSE must not remove instructions related to debug info"
diff --git a/src/main/java/com/android/tools/r8/ir/code/Instruction.java b/src/main/java/com/android/tools/r8/ir/code/Instruction.java
index c110f2f..801c684 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Instruction.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Instruction.java
@@ -57,6 +57,15 @@
}
}
+ public boolean hasInValueWithLocalInfo() {
+ for (Value inValue : inValues()) {
+ if (inValue.getLocalInfo() != null) {
+ return true;
+ }
+ }
+ return false;
+ }
+
public Value outValue() {
return outValue;
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
index 454d6cd..e87b29b 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
@@ -1646,7 +1646,7 @@
}
}
}
- if (!eliminated) {
+ if (!eliminated && !instruction.hasInValueWithLocalInfo()) {
instructionToValue.put(equivalence.wrap(instruction), instruction.outValue());
}
}
diff --git a/src/test/debugTestResources/Locals.java b/src/test/debugTestResources/Locals.java
index 1221234..205ae64 100644
--- a/src/test/debugTestResources/Locals.java
+++ b/src/test/debugTestResources/Locals.java
@@ -338,6 +338,14 @@
return result;
}
+ public static int localTriggeringCSE() {
+ int a = 1;
+ int b = 3;
+ int c = a + b;
+ int d = a + b;
+ return c + d;
+ }
+
public static void main(String[] args) {
noLocals();
unusedLocals();
@@ -360,5 +368,6 @@
regression65066975(false);
System.out.println(localConstant(true));
System.out.println(localConstantBis(true));
+ System.out.println(localTriggeringCSE());
}
}
diff --git a/src/test/java/com/android/tools/r8/debug/LocalsTest.java b/src/test/java/com/android/tools/r8/debug/LocalsTest.java
index 9b0a888..177efbe 100644
--- a/src/test/java/com/android/tools/r8/debug/LocalsTest.java
+++ b/src/test/java/com/android/tools/r8/debug/LocalsTest.java
@@ -608,4 +608,44 @@
checkNoLocal("result2"),
run());
}
+
+ @Test
+ public void testLocalTriggeringCSE() throws Throwable {
+ final String className = "Locals";
+ final String methodName = "localTriggeringCSE";
+ runDebugTest(className,
+ breakpoint(className, methodName),
+ run(),
+ checkLine(SOURCE_FILE, 342),
+ checkNoLocal("a"),
+ checkNoLocal("b"),
+ checkNoLocal("c"),
+ checkNoLocal("d"),
+ stepOver(),
+ checkLine(SOURCE_FILE, 343),
+ checkLocal("a", Value.createInt(1)),
+ checkNoLocal("b"),
+ checkNoLocal("c"),
+ checkNoLocal("d"),
+ stepOver(),
+ checkLine(SOURCE_FILE, 344),
+ checkLocal("a", Value.createInt(1)),
+ checkLocal("b", Value.createInt(3)),
+ checkNoLocal("c"),
+ checkNoLocal("d"),
+ stepOver(),
+ checkLine(SOURCE_FILE, 345),
+ checkLocal("a", Value.createInt(1)),
+ checkLocal("b", Value.createInt(3)),
+ checkLocal("c", Value.createInt(4)),
+ checkNoLocal("d"),
+ setLocal("a", Value.createInt(2)),
+ stepOver(),
+ checkLine(SOURCE_FILE, 346),
+ checkLocal("a", Value.createInt(2)),
+ checkLocal("b", Value.createInt(3)),
+ checkLocal("c", Value.createInt(4)),
+ checkLocal("d", Value.createInt(5)),
+ run());
+ }
}