Do HuntForOriginalReference for the value in WBE am: 96aab3fef9

Original change: https://android-review.googlesource.com/c/platform/art/+/2967244

Change-Id: Id86985390cd067f96e2773085d9469b0c143adda
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc
index 8974429..50b8648 100644
--- a/compiler/optimizing/code_generator_arm64.cc
+++ b/compiler/optimizing/code_generator_arm64.cc
@@ -2356,14 +2356,12 @@
       codegen_->StoreNeedsWriteBarrier(field_type, instruction->InputAt(1), write_barrier_kind);
 
   if (needs_write_barrier) {
-    // TODO(solanes): If we do a `HuntForOriginalReference` call to the value in WBE, we will be
-    // able to DCHECK that the write_barrier_kind is kBeingReliedOn when Register(value).IsZero(),
-    // and we could remove the `!Register(value).IsZero()` from below.
-    codegen_->MaybeMarkGCCard(obj,
-                              Register(value),
-                              value_can_be_null &&
-                                  write_barrier_kind == WriteBarrierKind::kEmitNotBeingReliedOn &&
-                                  !Register(value).IsZero());
+    DCHECK_IMPLIES(Register(value).IsZero(),
+                   write_barrier_kind == WriteBarrierKind::kEmitBeingReliedOn);
+    codegen_->MaybeMarkGCCard(
+        obj,
+        Register(value),
+        value_can_be_null && write_barrier_kind == WriteBarrierKind::kEmitNotBeingReliedOn);
   } else if (codegen_->ShouldCheckGCCard(field_type, instruction->InputAt(1), write_barrier_kind)) {
     codegen_->CheckGCCardIsValid(obj);
   }
@@ -3052,9 +3050,8 @@
     // write barrier when its value is null (without an extra cbz since we already checked if the
     // value is null for the type check). This will be done as a follow-up since it is a runtime
     // optimization that needs extra care.
-    // TODO(solanes): We can also skip it for known zero values which are not relied on i.e. when
-    // we have the Zero register as the value. If we do `HuntForOriginalReference` on the value
-    // we'll resolve this.
+    DCHECK_IMPLIES(Register(value).IsZero(),
+                   write_barrier_kind == WriteBarrierKind::kEmitBeingReliedOn);
     codegen_->MarkGCCard(array);
 
     UseScratchRegisterScope temps(masm);
diff --git a/compiler/optimizing/code_generator_riscv64.cc b/compiler/optimizing/code_generator_riscv64.cc
index 93bd35b..abbd74a 100644
--- a/compiler/optimizing/code_generator_riscv64.cc
+++ b/compiler/optimizing/code_generator_riscv64.cc
@@ -2518,8 +2518,7 @@
       codegen_->StoreNeedsWriteBarrier(type, instruction->InputAt(1), write_barrier_kind);
   if (needs_write_barrier) {
     if (value.IsConstant()) {
-      // TODO(solanes): If we do a `HuntForOriginalReference` call to the value in WBE, we will be
-      // able to DCHECK that the write_barrier_kind is kBeingReliedOn.
+      DCHECK_EQ(write_barrier_kind, WriteBarrierKind::kEmitBeingReliedOn);
       codegen_->MarkGCCard(obj);
     } else {
       codegen_->MaybeMarkGCCard(
@@ -2947,9 +2946,8 @@
 
   if (needs_write_barrier) {
     DCHECK_EQ(value_type, DataType::Type::kReference);
+    DCHECK_IMPLIES(value.IsConstant(), value.GetConstant()->IsArithmeticZero());
     const bool storing_constant_zero = value.IsConstant();
-    // TODO(solanes): If we do a `HuntForOriginalReference` call to the value in WBE, we will be
-    // able to DCHECK that the write_barrier_kind is kBeingReliedOn when we have a constant.
     if (!storing_constant_zero) {
       Riscv64Label do_store;
 
@@ -3010,11 +3008,13 @@
       }
     }
 
-    DCHECK_NE(instruction->GetWriteBarrierKind(), WriteBarrierKind::kDontEmit);
+    DCHECK_NE(write_barrier_kind, WriteBarrierKind::kDontEmit);
     // TODO(solanes): The WriteBarrierKind::kEmitNotBeingReliedOn case should be able to skip
     // this write barrier when its value is null (without an extra Beqz since we already checked
     // if the value is null for the type check). This will be done as a follow-up since it is a
     // runtime optimization that needs extra care.
+    DCHECK_IMPLIES(storing_constant_zero,
+                   write_barrier_kind == WriteBarrierKind::kEmitBeingReliedOn);
     codegen_->MarkGCCard(array);
   } else if (codegen_->ShouldCheckGCCard(value_type, instruction->GetValue(), write_barrier_kind)) {
     codegen_->CheckGCCardIsValid(array);
diff --git a/compiler/optimizing/graph_checker.cc b/compiler/optimizing/graph_checker.cc
index d60ec06..c880d45 100644
--- a/compiler/optimizing/graph_checker.cc
+++ b/compiler/optimizing/graph_checker.cc
@@ -1291,7 +1291,7 @@
                            HInstruction* value) {
   return write_barrier_kind == WriteBarrierKind::kDontEmit &&
          type == DataType::Type::kReference &&
-         !value->IsNullConstant();
+         !HuntForOriginalReference(value)->IsNullConstant();
 }
 
 void GraphChecker::VisitArraySet(HArraySet* instruction) {
diff --git a/compiler/optimizing/write_barrier_elimination.cc b/compiler/optimizing/write_barrier_elimination.cc
index 220eb78..537bc09 100644
--- a/compiler/optimizing/write_barrier_elimination.cc
+++ b/compiler/optimizing/write_barrier_elimination.cc
@@ -45,7 +45,7 @@
     DCHECK(!instruction->GetSideEffects().Includes(SideEffects::CanTriggerGC()));
 
     if (instruction->GetFieldType() != DataType::Type::kReference ||
-        instruction->GetValue()->IsNullConstant()) {
+        HuntForOriginalReference(instruction->GetValue())->IsNullConstant()) {
       instruction->SetWriteBarrierKind(WriteBarrierKind::kDontEmit);
       return;
     }
@@ -72,7 +72,7 @@
     DCHECK(!instruction->GetSideEffects().Includes(SideEffects::CanTriggerGC()));
 
     if (instruction->GetFieldType() != DataType::Type::kReference ||
-        instruction->GetValue()->IsNullConstant()) {
+        HuntForOriginalReference(instruction->GetValue())->IsNullConstant()) {
       instruction->SetWriteBarrierKind(WriteBarrierKind::kDontEmit);
       return;
     }
@@ -100,7 +100,7 @@
     }
 
     if (instruction->GetComponentType() != DataType::Type::kReference ||
-        instruction->GetValue()->IsNullConstant()) {
+        HuntForOriginalReference(instruction->GetValue())->IsNullConstant()) {
       instruction->SetWriteBarrierKind(WriteBarrierKind::kDontEmit);
       return;
     }
diff --git a/test/2272-checker-codegen-honor-write-barrier-kind/src/Main.java b/test/2272-checker-codegen-honor-write-barrier-kind/src/Main.java
index f07286b..7d67249 100644
--- a/test/2272-checker-codegen-honor-write-barrier-kind/src/Main.java
+++ b/test/2272-checker-codegen-honor-write-barrier-kind/src/Main.java
@@ -42,21 +42,20 @@
     /// CHECK-START: java.lang.String[] Main.$noinline$testArraySetsHonorWriteBarrier(java.lang.String[], java.lang.String) prepare_for_register_allocation (before)
     /// CHECK: <<Null:l\d+>>   NullConstant
     /// CHECK: <<BT:l\d+>>     BoundType [<<Null>>]
-    /// CHECK: ArraySet [<<arr:l\d+>>,<<index:i\d+>>,<<BT>>] value_can_be_null:true needs_type_check:false can_trigger_gc:false write_barrier_kind:EmitBeingReliedOn
-    /// CHECK: ArraySet value_can_be_null:true needs_type_check:false can_trigger_gc:false write_barrier_kind:DontEmit
+    /// CHECK: ArraySet [<<arr:l\d+>>,<<index:i\d+>>,<<BT>>] value_can_be_null:true needs_type_check:false can_trigger_gc:false write_barrier_kind:DontEmit
+    /// CHECK: ArraySet value_can_be_null:true needs_type_check:false can_trigger_gc:false write_barrier_kind:EmitNotBeingReliedOn
 
     /// CHECK-START: java.lang.String[] Main.$noinline$testArraySetsHonorWriteBarrier(java.lang.String[], java.lang.String) prepare_for_register_allocation (after)
     /// CHECK: <<Null:l\d+>>   NullConstant
-    /// CHECK: ArraySet [<<arr:l\d+>>,<<index:i\d+>>,<<Null>>] value_can_be_null:true needs_type_check:false can_trigger_gc:false write_barrier_kind:EmitBeingReliedOn
-    /// CHECK: ArraySet value_can_be_null:true needs_type_check:false can_trigger_gc:false write_barrier_kind:DontEmit
+    /// CHECK: ArraySet [<<arr:l\d+>>,<<index:i\d+>>,<<Null>>] value_can_be_null:true needs_type_check:false can_trigger_gc:false write_barrier_kind:DontEmit
+    /// CHECK: ArraySet value_can_be_null:true needs_type_check:false can_trigger_gc:false write_barrier_kind:EmitNotBeingReliedOn
 
     /// CHECK-START: java.lang.String[] Main.$noinline$testArraySetsHonorWriteBarrier(java.lang.String[], java.lang.String) prepare_for_register_allocation (after)
     /// CHECK-NOT: BoundType
 
     /// CHECK-START: java.lang.String[] Main.$noinline$testArraySetsHonorWriteBarrier(java.lang.String[], java.lang.String) disassembly (after)
-    /// CHECK: ArraySet value_can_be_null:true needs_type_check:false can_trigger_gc:false write_barrier_kind:EmitBeingReliedOn
-    // / CHECK: ; card_table
     /// CHECK: ArraySet value_can_be_null:true needs_type_check:false can_trigger_gc:false write_barrier_kind:DontEmit
+    /// CHECK: ArraySet value_can_be_null:true needs_type_check:false can_trigger_gc:false write_barrier_kind:EmitNotBeingReliedOn
     private static java.lang.String[] $noinline$testArraySetsHonorWriteBarrier(
             String[] arr, String o2) {
         Object o = null;