Eliminate dead LoadClass when pruning ClinitCheck.

Prebuilt sizes for aosp_taimen-userdebug:
 - before:
   arm/boot*.oat: 19192012
   arm64/boot*.oat: 22603096
 - after:
   arm/boot*.oat: 19150692 (-40KiB, -0.22%)
   arm64/boot*.oat: 22565976 (-36KiB, -0.16%)

Test: Add checker statements to 478-checker-clinit-check-pruning
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Bug: 35772576
Change-Id: I2485e832e77b68357f3bc0268afa8bd6a87083d5
diff --git a/compiler/optimizing/prepare_for_register_allocation.cc b/compiler/optimizing/prepare_for_register_allocation.cc
index fbdbf9d..8c4615d 100644
--- a/compiler/optimizing/prepare_for_register_allocation.cc
+++ b/compiler/optimizing/prepare_for_register_allocation.cc
@@ -160,8 +160,8 @@
   if (implicit_clinit != nullptr) {
     // Remove the check from the graph. It has been merged into the invoke or new-instance.
     check->GetBlock()->RemoveInstruction(check);
-    // Check if we can merge the load class as well.
-    if (can_merge_with_load_class && !load_class->HasUses()) {
+    // Check if we can merge the load class as well, or whether the LoadClass is now dead.
+    if ((can_merge_with_load_class || !load_class->CanThrow()) && !load_class->HasUses()) {
       load_class->GetBlock()->RemoveInstruction(load_class);
     }
   } else if (can_merge_with_load_class &&
diff --git a/test/478-checker-clinit-check-pruning/src/Main.java b/test/478-checker-clinit-check-pruning/src/Main.java
index b1bc51e..5b9ebc8 100644
--- a/test/478-checker-clinit-check-pruning/src/Main.java
+++ b/test/478-checker-clinit-check-pruning/src/Main.java
@@ -225,6 +225,19 @@
   /// CHECK-DAG:                           ClinitCheck
   /// CHECK-DAG:                           InvokeStaticOrDirect
 
+  // The following checks ensure the clinit check and load class
+  // instructions added by the builder are pruned by the
+  // PrepareForRegisterAllocation.  As the control flow graph is not
+  // dumped after (nor before) this step, we check the CFG as it is
+  // before the next pass (liveness analysis) instead.
+
+  /// CHECK-START: void Main$ClassWithClinit4Instance.invokeStaticNotInlined() liveness (before)
+  /// CHECK:                               InvokeStaticOrDirect clinit_check:implicit
+
+  /// CHECK-START: void Main$ClassWithClinit4Instance.invokeStaticNotInlined() liveness (before)
+  /// CHECK-NOT:                           LoadClass
+  /// CHECK-NOT:                           ClinitCheck
+
   static class ClassWithClinit4Instance {
     void invokeStaticNotInlined() {
       // ClinitCheck required.