diff --git a/src/main/java/com/android/tools/r8/Version.java b/src/main/java/com/android/tools/r8/Version.java
index a6a6702..35b3491 100644
--- a/src/main/java/com/android/tools/r8/Version.java
+++ b/src/main/java/com/android/tools/r8/Version.java
@@ -11,7 +11,7 @@
 
   // This field is accessed from release scripts using simple pattern matching.
   // Therefore, changing this field could break our release scripts.
-  public static final String LABEL = "1.2.30";
+  public static final String LABEL = "1.2.31";
 
   private Version() {
   }
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
index 50fc1c9..65c59ae 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
@@ -759,6 +759,10 @@
     // Analysis must be done after method is rewritten by logArgumentTypes()
     codeRewriter.identifyClassInlinerEligibility(method, code, feedback);
 
+    if (options.canHaveNumberConversionRegisterAllocationBug()) {
+      codeRewriter.workaroundNumberConversionRegisterAllocationBug(code);
+    }
+
     printMethod(code, "Optimized IR (SSA)");
     finalizeIR(method, code, feedback);
   }
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 ae57f48..bc083c9 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
@@ -55,6 +55,7 @@
 import com.android.tools.r8.ir.code.InvokeDirect;
 import com.android.tools.r8.ir.code.InvokeMethod;
 import com.android.tools.r8.ir.code.InvokeNewArray;
+import com.android.tools.r8.ir.code.InvokeStatic;
 import com.android.tools.r8.ir.code.InvokeVirtual;
 import com.android.tools.r8.ir.code.MemberType;
 import com.android.tools.r8.ir.code.NewArrayEmpty;
@@ -2782,4 +2783,59 @@
       }
     }
   }
+
+  // See comment for InternalOptions.canHaveNumberConversionRegisterAllocationBug().
+  public void workaroundNumberConversionRegisterAllocationBug(IRCode code) {
+    final Supplier<DexMethod> javaLangDoubleisNaN = Suppliers.memoize(() ->
+     dexItemFactory.createMethod(
+        dexItemFactory.createString("Ljava/lang/Double;"),
+        dexItemFactory.createString("isNaN"),
+        dexItemFactory.booleanDescriptor,
+        new DexString[]{dexItemFactory.doubleDescriptor}));
+
+    ListIterator<BasicBlock> blocks = code.listIterator();
+    while (blocks.hasNext()) {
+      BasicBlock block = blocks.next();
+      InstructionListIterator it = block.listIterator();
+      while (it.hasNext()) {
+        Instruction instruction = it.next();
+        if (instruction.isArithmeticBinop() || instruction.isNeg()) {
+          for (Value value : instruction.inValues()) {
+            // Insert a call to Double.isNaN on each value which come from a number conversion
+            // to double and flows into an arithmetic instruction. This seems to break the traces
+            // in the Dalvik JIT and avoid the bug where the generated ARM code can clobber float
+            // values in a single-precision registers with double values written to
+            // double-precision registers. See b/77496850 for examples.
+            if (!value.isPhi()
+                && value.definition.isNumberConversion()
+                && value.definition.asNumberConversion().to == NumericType.DOUBLE) {
+              InvokeStatic invokeIsNaN =
+                  new InvokeStatic(javaLangDoubleisNaN.get(), null, ImmutableList.of(value));
+              invokeIsNaN.setPosition(instruction.getPosition());
+
+              // Insert the invoke before the current instruction.
+              it.previous();
+              BasicBlock blockWithInvokeNaN =
+                  block.hasCatchHandlers() ? it.split(code, blocks) : block;
+              if (blockWithInvokeNaN != block) {
+                // If we split, add the invoke at the end of the original block.
+                it = block.listIterator(block.getInstructions().size());
+                it.previous();
+                it.add(invokeIsNaN);
+                // Continue iteration in the split block.
+                block = blockWithInvokeNaN;
+                it = block.listIterator();
+              } else {
+                // Otherwise, add it to the current block.
+                it.add(invokeIsNaN);
+              }
+              // Skip over the instruction causing the invoke to be inserted.
+              Instruction temp = it.next();
+              assert temp == instruction;
+            }
+          }
+        }
+      }
+    }
+  }
 }
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index 5f0ec45..e2c8ff9 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -629,4 +629,12 @@
   public boolean canHaveArtStringNewInitBug() {
     return minApiLevel <= AndroidApiLevel.P.getLevel();
   }
+
+  // Dalvik tracing JIT may perform invalid optimizations when int/float values are converted to
+  // double and used in arithmetic operations.
+  //
+  // See b/77496850.
+  public boolean canHaveNumberConversionRegisterAllocationBug() {
+    return minApiLevel <= AndroidApiLevel.K.getLevel();
+  }
 }
diff --git a/src/test/java/com/android/tools/r8/regress/b77496850/B77496850.java b/src/test/java/com/android/tools/r8/regress/b77496850/B77496850.java
new file mode 100644
index 0000000..03614b9
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/regress/b77496850/B77496850.java
@@ -0,0 +1,507 @@
+// Copyright (c) 2018, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.regress.b77496850;
+
+import static org.junit.Assert.assertEquals;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.code.InvokeStatic;
+import com.android.tools.r8.dex.Marker.Tool;
+import com.android.tools.r8.graph.DexCode;
+import com.android.tools.r8.graph.DexItemFactory;
+import com.android.tools.r8.graph.DexMethod;
+import com.android.tools.r8.graph.DexString;
+import com.android.tools.r8.utils.AndroidApiLevel;
+import com.android.tools.r8.utils.AndroidApp;
+import com.android.tools.r8.utils.DexInspector;
+import com.android.tools.r8.utils.DexInspector.ClassSubject;
+import com.android.tools.r8.utils.DexInspector.MethodSubject;
+import com.google.common.collect.ImmutableList;
+import org.junit.Test;
+
+public class B77496850 extends TestBase {
+
+  static final String LOGTAG = "";
+
+  // Mock class for the code in PathParser below.
+  public static class Path {
+    void rLineTo(int x, int y) {
+    }
+    void cubicTo(float a, float b, float c, float d, float e, float f) {
+    }
+  }
+
+  // Mock class for the code in PathParser below.
+  public static class Log {
+    static void w(String x, String y) {
+    }
+  }
+
+  // Code copied from Android support library:
+  // https://android.googlesource.com/platform/frameworks/support/+/9791ac540f94c318f6602123d7000bfc55909b81/compat/src/main/java/android/support/v4/graphics/PathParser.java
+  public static class PathParser {
+
+    private static void drawArc(Path p,
+        float x0,
+        float y0,
+        float x1,
+        float y1,
+        float a,
+        float b,
+        float theta,
+        boolean isMoreThanHalf,
+        boolean isPositiveArc) {
+      /* Convert rotation angle from degrees to radians */
+      double thetaD = Math.toRadians(theta);
+      /* Pre-compute rotation matrix entries */
+      double cosTheta = Math.cos(thetaD);
+      double sinTheta = Math.sin(thetaD);
+      /* Transform (x0, y0) and (x1, y1) into unit space */
+      /* using (inverse) rotation, followed by (inverse) scale */
+      double x0p = (x0 * cosTheta + y0 * sinTheta) / a;
+      double y0p = (-x0 * sinTheta + y0 * cosTheta) / b;
+      double x1p = (x1 * cosTheta + y1 * sinTheta) / a;
+      double y1p = (-x1 * sinTheta + y1 * cosTheta) / b;
+      /* Compute differences and averages */
+      double dx = x0p - x1p;
+      double dy = y0p - y1p;
+      double xm = (x0p + x1p) / 2;
+      double ym = (y0p + y1p) / 2;
+      /* Solve for intersecting unit circles */
+      double dsq = dx * dx + dy * dy;
+      if (dsq == 0.0) {
+        Log.w(LOGTAG, " Points are coincident");
+        return; /* Points are coincident */
+      }
+      double disc = 1.0 / dsq - 1.0 / 4.0;
+      if (disc < 0.0) {
+        Log.w(LOGTAG, "Points are too far apart " + dsq);
+        float adjust = (float) (Math.sqrt(dsq) / 1.99999);
+        drawArc(p, x0, y0, x1, y1, a * adjust,
+            b * adjust, theta, isMoreThanHalf, isPositiveArc);
+        return; /* Points are too far apart */
+      }
+      double s = Math.sqrt(disc);
+      double sdx = s * dx;
+      double sdy = s * dy;
+      double cx;
+      double cy;
+      if (isMoreThanHalf == isPositiveArc) {
+        cx = xm - sdy;
+        cy = ym + sdx;
+      } else {
+        cx = xm + sdy;
+        cy = ym - sdx;
+      }
+      double eta0 = Math.atan2((y0p - cy), (x0p - cx));
+      double eta1 = Math.atan2((y1p - cy), (x1p - cx));
+      double sweep = (eta1 - eta0);
+      if (isPositiveArc != (sweep >= 0)) {
+        if (sweep > 0) {
+          sweep -= 2 * Math.PI;
+        } else {
+          sweep += 2 * Math.PI;
+        }
+      }
+      cx *= a;
+      cy *= b;
+      double tcx = cx;
+      cx = cx * cosTheta - cy * sinTheta;
+      cy = tcx * sinTheta + cy * cosTheta;
+      arcToBezier(p, cx, cy, a, b, x0, y0, thetaD, eta0, sweep);
+    }
+
+    /**
+     * Converts an arc to cubic Bezier segments and records them in p.
+     *
+     * @param p     The target for the cubic Bezier segments
+     * @param cx    The x coordinate center of the ellipse
+     * @param cy    The y coordinate center of the ellipse
+     * @param a     The radius of the ellipse in the horizontal direction
+     * @param b     The radius of the ellipse in the vertical direction
+     * @param e1x   E(eta1) x coordinate of the starting point of the arc
+     * @param e1y   E(eta2) y coordinate of the starting point of the arc
+     * @param theta The angle that the ellipse bounding rectangle makes with horizontal plane
+     * @param start The start angle of the arc on the ellipse
+     * @param sweep The angle (positive or negative) of the sweep of the arc on the ellipse
+     */
+    private static void arcToBezier(Path p,
+        double cx,
+        double cy,
+        double a,
+        double b,
+        double e1x,
+        double e1y,
+        double theta,
+        double start,
+        double sweep) {
+      // Taken from equations at: http://spaceroots.org/documents/ellipse/node8.html
+      // and http://www.spaceroots.org/documents/ellipse/node22.html
+      // Maximum of 45 degrees per cubic Bezier segment
+      int numSegments = (int) Math.ceil(Math.abs(sweep * 4 / Math.PI));
+      double eta1 = start;
+      double cosTheta = Math.cos(theta);
+      double sinTheta = Math.sin(theta);
+      double cosEta1 = Math.cos(eta1);
+      double sinEta1 = Math.sin(eta1);
+      double ep1x = (-a * cosTheta * sinEta1) - (b * sinTheta * cosEta1);
+      double ep1y = (-a * sinTheta * sinEta1) + (b * cosTheta * cosEta1);
+      double anglePerSegment = sweep / numSegments;
+      for (int i = 0; i < numSegments; i++) {
+        double eta2 = eta1 + anglePerSegment;
+        double sinEta2 = Math.sin(eta2);
+        double cosEta2 = Math.cos(eta2);
+        double e2x = cx + (a * cosTheta * cosEta2) - (b * sinTheta * sinEta2);
+        double e2y = cy + (a * sinTheta * cosEta2) + (b * cosTheta * sinEta2);
+        double ep2x = -a * cosTheta * sinEta2 - b * sinTheta * cosEta2;
+        double ep2y = -a * sinTheta * sinEta2 + b * cosTheta * cosEta2;
+        double tanDiff2 = Math.tan((eta2 - eta1) / 2);
+        double alpha =
+            Math.sin(eta2 - eta1) * (Math.sqrt(4 + (3 * tanDiff2 * tanDiff2)) - 1) / 3;
+        double q1x = e1x + alpha * ep1x;
+        double q1y = e1y + alpha * ep1y;
+        double q2x = e2x - alpha * ep2x;
+        double q2y = e2y - alpha * ep2y;
+        // Adding this no-op call to workaround a proguard related issue.
+        p.rLineTo(0, 0);
+        p.cubicTo((float) q1x,
+            (float) q1y,
+            (float) q2x,
+            (float) q2y,
+            (float) e2x,
+            (float) e2y);
+        eta1 = eta2;
+        e1x = e2x;
+        e1y = e2y;
+        ep1x = ep2x;
+        ep1y = ep2y;
+      }
+    }
+  }
+
+  // Same code as PathParser above, but with exception handlers in the two methods.
+  public static class PathParserWithExceptionHandler {
+
+    private static void drawArc(Path p,
+        float x0,
+        float y0,
+        float x1,
+        float y1,
+        float a,
+        float b,
+        float theta,
+        boolean isMoreThanHalf,
+        boolean isPositiveArc) {
+      try {
+        /* Convert rotation angle from degrees to radians */
+        double thetaD = Math.toRadians(theta);
+        /* Pre-compute rotation matrix entries */
+        double cosTheta = Math.cos(thetaD);
+        double sinTheta = Math.sin(thetaD);
+        /* Transform (x0, y0) and (x1, y1) into unit space */
+        /* using (inverse) rotation, followed by (inverse) scale */
+        double x0p = (x0 * cosTheta + y0 * sinTheta) / a;
+        double y0p = (-x0 * sinTheta + y0 * cosTheta) / b;
+        double x1p = (x1 * cosTheta + y1 * sinTheta) / a;
+        double y1p = (-x1 * sinTheta + y1 * cosTheta) / b;
+        /* Compute differences and averages */
+        double dx = x0p - x1p;
+        double dy = y0p - y1p;
+        double xm = (x0p + x1p) / 2;
+        double ym = (y0p + y1p) / 2;
+        /* Solve for intersecting unit circles */
+        double dsq = dx * dx + dy * dy;
+        if (dsq == 0.0) {
+          Log.w(LOGTAG, " Points are coincident");
+          return; /* Points are coincident */
+        }
+        double disc = 1.0 / dsq - 1.0 / 4.0;
+        if (disc < 0.0) {
+          Log.w(LOGTAG, "Points are too far apart " + dsq);
+          float adjust = (float) (Math.sqrt(dsq) / 1.99999);
+          drawArc(p, x0, y0, x1, y1, a * adjust,
+              b * adjust, theta, isMoreThanHalf, isPositiveArc);
+          return; /* Points are too far apart */
+        }
+        double s = Math.sqrt(disc);
+        double sdx = s * dx;
+        double sdy = s * dy;
+        double cx;
+        double cy;
+        if (isMoreThanHalf == isPositiveArc) {
+          cx = xm - sdy;
+          cy = ym + sdx;
+        } else {
+          cx = xm + sdy;
+          cy = ym - sdx;
+        }
+        double eta0 = Math.atan2((y0p - cy), (x0p - cx));
+        double eta1 = Math.atan2((y1p - cy), (x1p - cx));
+        double sweep = (eta1 - eta0);
+        if (isPositiveArc != (sweep >= 0)) {
+          if (sweep > 0) {
+            sweep -= 2 * Math.PI;
+          } else {
+            sweep += 2 * Math.PI;
+          }
+        }
+        cx *= a;
+        cy *= b;
+        double tcx = cx;
+        cx = cx * cosTheta - cy * sinTheta;
+        cy = tcx * sinTheta + cy * cosTheta;
+        arcToBezier(p, cx, cy, a, b, x0, y0, thetaD, eta0, sweep);
+      } catch (Throwable t) {
+        // Ignore.
+      }
+    }
+
+    /**
+     * Converts an arc to cubic Bezier segments and records them in p.
+     *
+     * @param p     The target for the cubic Bezier segments
+     * @param cx    The x coordinate center of the ellipse
+     * @param cy    The y coordinate center of the ellipse
+     * @param a     The radius of the ellipse in the horizontal direction
+     * @param b     The radius of the ellipse in the vertical direction
+     * @param e1x   E(eta1) x coordinate of the starting point of the arc
+     * @param e1y   E(eta2) y coordinate of the starting point of the arc
+     * @param theta The angle that the ellipse bounding rectangle makes with horizontal plane
+     * @param start The start angle of the arc on the ellipse
+     * @param sweep The angle (positive or negative) of the sweep of the arc on the ellipse
+     */
+    private static void arcToBezier(Path p,
+        double cx,
+        double cy,
+        double a,
+        double b,
+        double e1x,
+        double e1y,
+        double theta,
+        double start,
+        double sweep) {
+      try {
+        // Taken from equations at: http://spaceroots.org/documents/ellipse/node8.html
+        // and http://www.spaceroots.org/documents/ellipse/node22.html
+        // Maximum of 45 degrees per cubic Bezier segment
+        int numSegments = (int) Math.ceil(Math.abs(sweep * 4 / Math.PI));
+        double eta1 = start;
+        double cosTheta = Math.cos(theta);
+        double sinTheta = Math.sin(theta);
+        double cosEta1 = Math.cos(eta1);
+        double sinEta1 = Math.sin(eta1);
+        double ep1x = (-a * cosTheta * sinEta1) - (b * sinTheta * cosEta1);
+        double ep1y = (-a * sinTheta * sinEta1) + (b * cosTheta * cosEta1);
+        double anglePerSegment = sweep / numSegments;
+        for (int i = 0; i < numSegments; i++) {
+          double eta2 = eta1 + anglePerSegment;
+          double sinEta2 = Math.sin(eta2);
+          double cosEta2 = Math.cos(eta2);
+          double e2x = cx + (a * cosTheta * cosEta2) - (b * sinTheta * sinEta2);
+          double e2y = cy + (a * sinTheta * cosEta2) + (b * cosTheta * sinEta2);
+          double ep2x = -a * cosTheta * sinEta2 - b * sinTheta * cosEta2;
+          double ep2y = -a * sinTheta * sinEta2 + b * cosTheta * cosEta2;
+          double tanDiff2 = Math.tan((eta2 - eta1) / 2);
+          double alpha =
+              Math.sin(eta2 - eta1) * (Math.sqrt(4 + (3 * tanDiff2 * tanDiff2)) - 1) / 3;
+          double q1x = e1x + alpha * ep1x;
+          double q1y = e1y + alpha * ep1y;
+          double q2x = e2x - alpha * ep2x;
+          double q2y = e2y - alpha * ep2y;
+          // Adding this no-op call to workaround a proguard related issue.
+          p.rLineTo(0, 0);
+          p.cubicTo((float) q1x,
+              (float) q1y,
+              (float) q2x,
+              (float) q2y,
+              (float) e2x,
+              (float) e2y);
+          eta1 = eta2;
+          e1x = e2x;
+          e1y = e2y;
+          ep1x = ep2x;
+          ep1y = ep2y;
+        }
+      } catch (Throwable t) {
+        // Ignore.
+      }
+    }
+
+  }
+
+  // Reproduction from b/77496850.
+  public static class Reproduction {
+    public int test() {
+      int count = 0;
+      for (int i = 0; i < 1000; i++){
+        count += arcToBezier(1.0, 1.0, 2.0);
+      }
+      return count;
+    }
+
+    private static int arcToBezier(double a, double b, double sweep) {
+      int count = 0;
+
+      int numSegments = (int) sweep;
+
+      double cosTheta = 0.5;
+      double sinTheta = 0.5;
+      double cosEta1 = 0.5;
+      double sinEta1 = 0.5;
+      double ep1x = (-a * cosTheta * sinEta1) - (b * sinTheta * cosEta1);
+      double anglePerSegment = sweep / numSegments;
+
+      for (int i = 0; i < numSegments; i++) {
+        count++;
+      }
+      if (numSegments != count) {
+        return 1;
+      }
+      return 0;
+    }
+
+    public static void main(String[] args) {
+      for (int i = 0; i < 100; i++) {
+        System.out.println(new Reproduction().test());
+      }
+    }
+  }
+
+  // Reproduction from b/77496850 with exception handler.
+  public static class ReproductionWithExceptionHandler {
+    public int test() {
+      int count = 0;
+      for (int i = 0; i < 1000; i++){
+        count += arcToBezier(1.0, 1.0, 2.0);
+      }
+      return count;
+    }
+
+    private static int arcToBezier(double a, double b, double sweep) {
+      try {
+        int count = 0;
+
+        int numSegments = (int) sweep;
+
+        double cosTheta = 0.5;
+        double sinTheta = 0.5;
+        double cosEta1 = 0.5;
+        double sinEta1 = 0.5;
+        double ep1x = (-a * cosTheta * sinEta1) - (b * sinTheta * cosEta1);
+        double anglePerSegment = sweep / numSegments;
+
+        for (int i = 0; i < numSegments; i++) {
+          count++;
+        }
+        if (numSegments != count) {
+          return 1;
+        }
+        return 0;
+      } catch (Throwable t) {
+        return 1;
+      }
+    }
+
+    public static void main(String[] args) {
+      for (int i = 0; i < 100; i++) {
+        System.out.println(new Reproduction().test());
+      }
+    }
+  }
+
+  private int countInvokeDoubleIsNan(DexItemFactory factory, DexCode code) {
+    int count = 0;
+    DexMethod doubleIsNaN = factory.createMethod(
+        factory.createString("Ljava/lang/Double;"),
+        factory.createString("isNaN"),
+        factory.booleanDescriptor,
+        new DexString[]{factory.doubleDescriptor});
+    for (int i = 0; i < code.instructions.length; i++) {
+      if (code.instructions[i] instanceof InvokeStatic) {
+        InvokeStatic invoke = (InvokeStatic) code.instructions[i];
+        if (invoke.getMethod() == doubleIsNaN) {
+          count++;
+        }
+      }
+    }
+    return count;
+  }
+
+  private void checkPathParserMethods(AndroidApp app, Class testClass, int a, int b)
+      throws Exception {
+    DexInspector inspector = new DexInspector(app);
+    DexItemFactory factory = inspector.getFactory();
+    ClassSubject clazz = inspector.clazz(testClass);
+    MethodSubject drawArc = clazz.method(
+        "void",
+        "drawArc",
+        ImmutableList.of(
+            getClass().getCanonicalName() + "$Path",
+            "float", "float", "float", "float", "float", "float", "float", "boolean", "boolean"));
+    MethodSubject arcToBezier = clazz.method(
+        "void",
+        "arcToBezier",
+        ImmutableList.of(
+            getClass().getCanonicalName() + "$Path",
+            "double", "double", "double", "double", "double", "double",
+            "double", "double", "double"));
+    assertEquals(a, countInvokeDoubleIsNan(factory, drawArc.getMethod().getCode().asDexCode()));
+    assertEquals(b, countInvokeDoubleIsNan(factory, arcToBezier.getMethod().getCode().asDexCode()));
+  }
+
+  private void runTestPathParser(
+      Tool compiler, Class testClass, AndroidApiLevel apiLevel, int a, int b)
+      throws Exception {
+    AndroidApp app = readClasses(Path.class, Log.class, testClass);
+    if (compiler == Tool.D8) {
+      app = compileWithD8(app, o -> o.minApiLevel = apiLevel.getLevel());
+    } else {
+      assert compiler == Tool.R8;
+      app = compileWithR8(app, "-keep class * { *; }", o -> o.minApiLevel = apiLevel.getLevel());
+    }
+    checkPathParserMethods(app, testClass, a, b);
+  }
+
+  @Test
+  public void testSupportLibraryPathParser() throws Exception{
+    for (Tool tool : Tool.values()) {
+      runTestPathParser(tool, PathParser.class, AndroidApiLevel.K, 14, 1);
+      runTestPathParser(tool, PathParser.class, AndroidApiLevel.L, 0, 0);
+      runTestPathParser(tool, PathParserWithExceptionHandler.class, AndroidApiLevel.K, 14, 1);
+      runTestPathParser(tool, PathParserWithExceptionHandler.class, AndroidApiLevel.L, 0, 0);
+    }
+  }
+
+  private void runTestReproduction(
+      Tool compiler, Class testClass, AndroidApiLevel apiLevel, int expectedInvokeDoubleIsNanCount)
+      throws Exception {
+    AndroidApp app = readClasses(testClass);
+    if (compiler == Tool.D8) {
+      app = compileWithD8(app, o -> o.minApiLevel = apiLevel.getLevel());
+    } else {
+      assert compiler == Tool.R8;
+      app = compileWithR8(app, "-keep class * { *; }", o -> o.minApiLevel = apiLevel.getLevel());
+    }
+    DexInspector inspector = new DexInspector(app);
+    DexItemFactory factory = inspector.getFactory();
+    ClassSubject clazz = inspector.clazz(testClass);
+    MethodSubject arcToBezier = clazz.method(
+        "int", "arcToBezier", ImmutableList.of("double", "double", "double"));
+    assertEquals(
+      expectedInvokeDoubleIsNanCount,
+      countInvokeDoubleIsNan(factory, arcToBezier.getMethod().getCode().asDexCode()));
+  }
+
+  @Test
+  public void testReproduction() throws Exception{
+    for (Tool tool : Tool.values()) {
+      runTestReproduction(tool, Reproduction.class, AndroidApiLevel.K, tool == Tool.D8 ? 1 : 0);
+      runTestReproduction(tool, Reproduction.class, AndroidApiLevel.L, 0);
+      runTestReproduction(
+          tool, ReproductionWithExceptionHandler.class, AndroidApiLevel.K, tool == Tool.D8 ? 1 : 0);
+      runTestReproduction(tool, ReproductionWithExceptionHandler.class, AndroidApiLevel.L, 0);
+    }
+  }
+}
