Support inlining methods that may have soft verifier failures.

Test: 536-checker-needs-access-check
Test: 675-checker-unverified-method
Bug: 28313047
Change-Id: Ie532014a658935a20dbd0b6acebfda07c28c4af4
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc
index 1d9520d..664126a 100644
--- a/compiler/optimizing/inliner.cc
+++ b/compiler/optimizing/inliner.cc
@@ -46,6 +46,7 @@
 #include "ssa_builder.h"
 #include "ssa_phi_elimination.h"
 #include "thread.h"
+#include "verifier/verifier_compiler_binding.h"
 
 namespace art {
 
@@ -389,11 +390,21 @@
       return true;
     }
     uint16_t class_def_idx = method->GetDeclaringClass()->GetDexClassDefIndex();
+
+    const VerifiedMethod* verified_method =
+        compiler_options.GetVerifiedMethod(method->GetDexFile(), method->GetDexMethodIndex());
+    if (verified_method != nullptr && verified_method->HasRuntimeThrow()) {
+      // Compiler doesn't handle dead code as nicely as verifier.
+      return true;
+    }
     if (!compiler_options.IsMethodVerifiedWithoutFailures(method->GetDexMethodIndex(),
                                                           class_def_idx,
                                                           *method->GetDexFile())) {
-      // Method has soft or hard failures, don't analyze.
-      return true;
+      if (verified_method == nullptr ||
+          !verifier::CanCompilerHandleVerificationFailure(
+              verified_method->GetEncounteredVerificationFailures())) {
+       return true;
+      }
     }
   }
   return false;
diff --git a/test/536-checker-needs-access-check/src/other2/GetInaccessibleClass.java b/test/536-checker-needs-access-check/src/other2/GetInaccessibleClass.java
index 172dbe5..a9b305b 100644
--- a/test/536-checker-needs-access-check/src/other2/GetInaccessibleClass.java
+++ b/test/536-checker-needs-access-check/src/other2/GetInaccessibleClass.java
@@ -19,9 +19,7 @@
 import other.InaccessibleClass;
 
 public class GetInaccessibleClass {
-  // TODO: Make this method `$inline$` once we do not flag access check
-  // failures as soft-fail in the verifier. b/28313047
-  public static Class<?> get() {
+  public static Class<?> $inline$get() {
     return InaccessibleClass.class;
   }
 }
diff --git a/test/536-checker-needs-access-check/src2/other/InaccessibleClass.java b/test/536-checker-needs-access-check/src2/other/InaccessibleClass.java
index 743d1ff..646cc7e 100644
--- a/test/536-checker-needs-access-check/src2/other/InaccessibleClass.java
+++ b/test/536-checker-needs-access-check/src2/other/InaccessibleClass.java
@@ -25,15 +25,12 @@
     return InaccessibleClass.class;
   }
 
-  /// CHECK-START: java.lang.Class other.InaccessibleClass.$noinline$getReferrersClassViaAnotherClass() builder (after)
-  // CHECK: LoadClass class_name:other.InaccessibleClass needs_access_check:true
+  /// CHECK-START: java.lang.Class other.InaccessibleClass.$noinline$getReferrersClassViaAnotherClass() inliner (after)
+  /// CHECK: LoadClass class_name:other.InaccessibleClass needs_access_check:true
   public static Class<?> $noinline$getReferrersClassViaAnotherClass() {
-    // TODO: Make the called method `$inline$` and enable the CHECK above
-    // once we do not flag access check failures as soft-fail in the verifier.
-    // b/28313047
     Class<?> klass = null;
     try {
-      klass = GetInaccessibleClass.get();
+      klass = GetInaccessibleClass.$inline$get();
       throw new Error("Unreachable");
     } catch (IllegalAccessError expected) {}
     return klass;
diff --git a/test/675-checker-unverified-method/smali/TestCase.smali b/test/675-checker-unverified-method/smali/TestCase.smali
index 673b3f2..a1b89cb 100644
--- a/test/675-checker-unverified-method/smali/TestCase.smali
+++ b/test/675-checker-unverified-method/smali/TestCase.smali
@@ -17,11 +17,9 @@
 .super Ljava/lang/Object;
 
 #
-# Ensure foo() does not analyze unverified bad() always-throws property.
-#
 ## CHECK-START: void TestCase.foo(java.lang.Object) inliner (after)
 ## CHECK-DAG: InvokeStaticOrDirect method_name:TestCase.bar always_throws:true
-## CHECK-DAG: InvokeStaticOrDirect method_name:TestCase.bad always_throws:false
+## CHECK-NOT: InvokeStaticOrDirect method_name:TestCase.bad
 .method public static foo(Ljava/lang/Object;)V
   .registers 1
   if-nez v0, :Skip1
@@ -50,6 +48,6 @@
   .registers 1
   invoke-static {}, LTestCase;->bar()Lwont/be/Resolvable;
   move-result-object v0
-  throw v0
+  return-object v0
 .end method