Merge "[CF] Use existing opcode name table from ASM."
diff --git a/src/main/java/com/android/tools/r8/ir/code/ConstString.java b/src/main/java/com/android/tools/r8/ir/code/ConstString.java
index febbda3..412a7a1 100644
--- a/src/main/java/com/android/tools/r8/ir/code/ConstString.java
+++ b/src/main/java/com/android/tools/r8/ir/code/ConstString.java
@@ -12,6 +12,7 @@
 import com.android.tools.r8.ir.conversion.CfBuilder;
 import com.android.tools.r8.ir.conversion.DexBuilder;
 import com.android.tools.r8.utils.InternalOptions;
+import java.io.UTFDataFormatException;
 
 public class ConstString extends ConstInstruction {
 
@@ -86,8 +87,21 @@
 
   @Override
   public boolean canBeDeadCode(IRCode code, InternalOptions options) {
-    // The const-string instruction is a throwing instruction in DEX, but not so in CF.
-    return options.outputClassFiles;
+    // The const-string instruction can be a throwing instruction in DEX, if decode() fails,
+    // but not so in CF.
+    if (options.outputClassFiles) {
+      return true;
+    }
+    try {
+      value.toString();
+    } catch (RuntimeException e) {
+      if (e.getCause() instanceof UTFDataFormatException) {
+        return false;
+      } else {
+        throw e;
+      }
+    }
+    return true;
   }
 
   @Override
diff --git a/src/test/java/com/android/tools/r8/compatproguard/ForNameTest.java b/src/test/java/com/android/tools/r8/compatproguard/ForNameTest.java
index 2c7927e..8480791 100644
--- a/src/test/java/com/android/tools/r8/compatproguard/ForNameTest.java
+++ b/src/test/java/com/android/tools/r8/compatproguard/ForNameTest.java
@@ -53,15 +53,11 @@
     assertTrue(method.isPresent());
 
     DexCode code = method.getMethod().getCode().asDexCode();
-    // TODO(b/36799092): DeadCodeRemover should be able to remove this instruction.
     assertTrue(code.instructions[0] instanceof ConstString);
     ConstString constString = (ConstString) code.instructions[0];
-    assertEquals(BOO, constString.getString().toString());
-    assertTrue(code.instructions[1] instanceof ConstString);
-    constString = (ConstString) code.instructions[1];
     assertNotEquals(BOO, constString.getString().toString());
-    assertTrue(code.instructions[2] instanceof InvokeStatic);
-    assertTrue(code.instructions[3] instanceof ReturnVoid);
+    assertTrue(code.instructions[1] instanceof InvokeStatic);
+    assertTrue(code.instructions[2] instanceof ReturnVoid);
   }
 
   @Test
diff --git a/src/test/java/com/android/tools/r8/naming/IdentifierNameStringMarkerTest.java b/src/test/java/com/android/tools/r8/naming/IdentifierNameStringMarkerTest.java
index fa7a608..62c1bec 100644
--- a/src/test/java/com/android/tools/r8/naming/IdentifierNameStringMarkerTest.java
+++ b/src/test/java/com/android/tools/r8/naming/IdentifierNameStringMarkerTest.java
@@ -62,14 +62,10 @@
     DexCode code = method.getCode().asDexCode();
     assertTrue(code.instructions[0] instanceof InvokeDirect);
     assertTrue(code.instructions[1] instanceof ConstString);
-    // TODO(b/36799092): DeadCodeRemover should be able to remove this instruction.
     ConstString constString = (ConstString) code.instructions[1];
     assertEquals(BOO, constString.getString().toString());
-    assertTrue(code.instructions[2] instanceof ConstString);
-    constString = (ConstString) code.instructions[2];
-    assertEquals(BOO, constString.getString().toString());
-    assertTrue(code.instructions[3] instanceof IputObject);
-    assertTrue(code.instructions[4] instanceof ReturnVoid);
+    assertTrue(code.instructions[2] instanceof IputObject);
+    assertTrue(code.instructions[3] instanceof ReturnVoid);
   }
 
   @Test
@@ -169,15 +165,11 @@
     assertNotNull(method);
 
     DexCode code = method.getCode().asDexCode();
-    // TODO(b/36799092): DeadCodeRemover should be able to remove this instruction.
     assertTrue(code.instructions[0] instanceof ConstString);
     ConstString constString = (ConstString) code.instructions[0];
     assertEquals(BOO, constString.getString().toString());
-    assertTrue(code.instructions[1] instanceof ConstString);
-    constString = (ConstString) code.instructions[1];
-    assertEquals(BOO, constString.getString().toString());
-    assertTrue(code.instructions[2] instanceof SputObject);
-    assertTrue(code.instructions[3] instanceof ReturnVoid);
+    assertTrue(code.instructions[1] instanceof SputObject);
+    assertTrue(code.instructions[2] instanceof ReturnVoid);
   }
 
   @Test
@@ -375,18 +367,14 @@
 
     DexCode code = method.getCode().asDexCode();
     assertTrue(code.instructions[0] instanceof InvokeDirect);
-    // TODO(b/36799092): DeadCodeRemover should be able to remove this instruction.
     assertTrue(code.instructions[1] instanceof ConstString);
     ConstString constString = (ConstString) code.instructions[1];
-    assertEquals(BOO, constString.getString().toString());
+    assertEquals("Mixed/form.Boo", constString.getString().toString());
     assertTrue(code.instructions[2] instanceof ConstString);
     constString = (ConstString) code.instructions[2];
-    assertEquals("Mixed/form.Boo", constString.getString().toString());
-    assertTrue(code.instructions[3] instanceof ConstString);
-    constString = (ConstString) code.instructions[3];
     assertEquals(BOO, constString.getString().toString());
-    assertTrue(code.instructions[4] instanceof InvokeStatic);
-    assertTrue(code.instructions[5] instanceof ReturnVoid);
+    assertTrue(code.instructions[3] instanceof InvokeStatic);
+    assertTrue(code.instructions[4] instanceof ReturnVoid);
   }
 
   @Test
@@ -516,15 +504,11 @@
     DexCode code = method.getCode().asDexCode();
     assertTrue(code.instructions[0] instanceof InvokeDirect);
     assertTrue(code.instructions[1] instanceof ConstClass);
-    // TODO(b/36799092): DeadCodeRemover should be able to remove this instruction.
     assertTrue(code.instructions[2] instanceof ConstString);
     ConstString constString = (ConstString) code.instructions[2];
     assertEquals("foo", constString.getString().toString());
-    assertTrue(code.instructions[3] instanceof ConstString);
-    constString = (ConstString) code.instructions[3];
-    assertEquals("foo", constString.getString().toString());
-    assertTrue(code.instructions[4] instanceof InvokeStatic);
-    assertTrue(code.instructions[5] instanceof ReturnVoid);
+    assertTrue(code.instructions[3] instanceof InvokeStatic);
+    assertTrue(code.instructions[4] instanceof ReturnVoid);
   }
 
   @Test
@@ -568,15 +552,11 @@
     DexCode code = method.getCode().asDexCode();
     assertTrue(code.instructions[0] instanceof InvokeDirect);
     assertTrue(code.instructions[1] instanceof ConstClass);
-    // TODO(b/36799092): DeadCodeRemover should be able to remove this instruction.
     assertTrue(code.instructions[2] instanceof ConstString);
     ConstString constString = (ConstString) code.instructions[2];
-    assertEquals("foo", constString.getString().toString());
-    assertTrue(code.instructions[3] instanceof ConstString);
-    constString = (ConstString) code.instructions[3];
     assertNotEquals("foo", constString.getString().toString());
-    assertTrue(code.instructions[4] instanceof InvokeStatic);
-    assertTrue(code.instructions[5] instanceof ReturnVoid);
+    assertTrue(code.instructions[3] instanceof InvokeStatic);
+    assertTrue(code.instructions[4] instanceof ReturnVoid);
   }
 
   @Test
@@ -631,15 +611,11 @@
     assertTrue(code.instructions[3] instanceof NewArray);
     assertTrue(code.instructions[4] instanceof Const4);
     assertTrue(code.instructions[5] instanceof AputObject);
-    // TODO(b/36799092): DeadCodeRemover should be able to remove this instruction.
     assertTrue(code.instructions[6] instanceof ConstString);
     ConstString constString = (ConstString) code.instructions[6];
     assertEquals("foo", constString.getString().toString());
-    assertTrue(code.instructions[7] instanceof ConstString);
-    constString = (ConstString) code.instructions[7];
-    assertEquals("foo", constString.getString().toString());
-    assertTrue(code.instructions[8] instanceof InvokeStatic);
-    assertTrue(code.instructions[9] instanceof ReturnVoid);
+    assertTrue(code.instructions[7] instanceof InvokeStatic);
+    assertTrue(code.instructions[8] instanceof ReturnVoid);
   }
 
   @Test
@@ -694,15 +670,11 @@
     assertTrue(code.instructions[3] instanceof NewArray);
     assertTrue(code.instructions[4] instanceof Const4);
     assertTrue(code.instructions[5] instanceof AputObject);
-    // TODO(b/36799092): DeadCodeRemover should be able to remove this instruction.
     assertTrue(code.instructions[6] instanceof ConstString);
     ConstString constString = (ConstString) code.instructions[6];
-    assertEquals("foo", constString.getString().toString());
-    assertTrue(code.instructions[7] instanceof ConstString);
-    constString = (ConstString) code.instructions[7];
     assertNotEquals("foo", constString.getString().toString());
-    assertTrue(code.instructions[8] instanceof InvokeStatic);
-    assertTrue(code.instructions[9] instanceof ReturnVoid);
+    assertTrue(code.instructions[7] instanceof InvokeStatic);
+    assertTrue(code.instructions[8] instanceof ReturnVoid);
   }
 
   private DexInspector getInspectorAfterRunR8(