Set more RTI only if they are valid

Follow-up to aosp/2442280. We haven't seen crashes with these ones,
but we can't guarantee that the RTI will be valid in these code paths.

Test: art/test/testrunner/testrunner.py --host --64 --optimizing -b
Change-Id: I80da85a6549ba0275a80027016363e0cf9fb8045
diff --git a/compiler/optimizing/bounds_check_elimination.cc b/compiler/optimizing/bounds_check_elimination.cc
index 52f1e9a..210f978 100644
--- a/compiler/optimizing/bounds_check_elimination.cc
+++ b/compiler/optimizing/bounds_check_elimination.cc
@@ -2011,7 +2011,7 @@
     phi->SetRawInputAt(0, instruction);
     phi->SetRawInputAt(1, zero);
     if (type == DataType::Type::kReference) {
-      phi->SetReferenceTypeInfo(instruction->GetReferenceTypeInfo());
+      phi->SetReferenceTypeInfoIfValid(instruction->GetReferenceTypeInfo());
     }
     new_preheader->AddPhi(phi);
     return phi;
diff --git a/compiler/optimizing/dead_code_elimination.cc b/compiler/optimizing/dead_code_elimination.cc
index 5437d9b..cf49e39 100644
--- a/compiler/optimizing/dead_code_elimination.cc
+++ b/compiler/optimizing/dead_code_elimination.cc
@@ -181,6 +181,13 @@
   } else if (!cond->InputAt(0)->IsNullConstant()) {
     return false;
   }
+
+  // We can't create a BoundType for an object with an invalid RTI.
+  const ReferenceTypeInfo ti = obj->GetReferenceTypeInfo();
+  if (!ti.IsValid()) {
+    return false;
+  }
+
   // Scan all uses of obj and find null check under control dependence.
   HBoundType* bound = nullptr;
   const HUseList<HInstruction*>& uses = obj->GetUses();
@@ -193,7 +200,6 @@
           user_block != throws &&
           block->Dominates(user_block)) {
         if (bound == nullptr) {
-          ReferenceTypeInfo ti = obj->GetReferenceTypeInfo();
           bound = new (obj->GetBlock()->GetGraph()->GetAllocator()) HBoundType(obj);
           bound->SetUpperBound(ti, /*can_be_null*/ false);
           bound->SetReferenceTypeInfo(ti);
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc
index 0e4d587..c24ac84 100644
--- a/compiler/optimizing/inliner.cc
+++ b/compiler/optimizing/inliner.cc
@@ -1327,7 +1327,7 @@
   invoke_instruction->GetBlock()->InsertInstructionBefore(new_invoke, invoke_instruction);
   new_invoke->CopyEnvironmentFrom(invoke_instruction->GetEnvironment());
   if (invoke_instruction->GetType() == DataType::Type::kReference) {
-    new_invoke->SetReferenceTypeInfo(invoke_instruction->GetReferenceTypeInfo());
+    new_invoke->SetReferenceTypeInfoIfValid(invoke_instruction->GetReferenceTypeInfo());
   }
   *replacement = new_invoke;
 
@@ -1529,7 +1529,7 @@
     invoke_instruction->GetBlock()->InsertInstructionBefore(new_invoke, invoke_instruction);
     new_invoke->CopyEnvironmentFrom(invoke_instruction->GetEnvironment());
     if (invoke_instruction->GetType() == DataType::Type::kReference) {
-      new_invoke->SetReferenceTypeInfo(invoke_instruction->GetReferenceTypeInfo());
+      new_invoke->SetReferenceTypeInfoIfValid(invoke_instruction->GetReferenceTypeInfo());
     }
     *return_replacement = new_invoke;
     return true;
@@ -1854,8 +1854,8 @@
         if (!resolved_method->IsStatic() && parameter_index == 0 && receiver_type.IsValid()) {
           run_rtp = true;
           current->SetReferenceTypeInfo(receiver_type);
-        } else if (argument->GetReferenceTypeInfo().IsValid()) {
-          current->SetReferenceTypeInfo(argument->GetReferenceTypeInfo());
+        } else {
+          current->SetReferenceTypeInfoIfValid(argument->GetReferenceTypeInfo());
         }
         current->AsParameterValue()->SetCanBeNull(argument->CanBeNull());
       }
diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc
index 86b9dba..12ca30f 100644
--- a/compiler/optimizing/instruction_simplifier.cc
+++ b/compiler/optimizing/instruction_simplifier.cc
@@ -970,7 +970,7 @@
                           pred_get->GetFieldInfo().GetDexFile(),
                           pred_get->GetDexPc());
     if (pred_get->GetType() == DataType::Type::kReference) {
-      replace_with->SetReferenceTypeInfo(pred_get->GetReferenceTypeInfo());
+      replace_with->SetReferenceTypeInfoIfValid(pred_get->GetReferenceTypeInfo());
     }
     pred_get->GetBlock()->InsertInstructionBefore(replace_with, pred_get);
     pred_get->ReplaceWith(replace_with);
@@ -2782,7 +2782,7 @@
   ArenaAllocator* allocator = block->GetGraph()->GetAllocator();
   HStringBuilderAppend* append = new (allocator) HStringBuilderAppend(
       fmt, num_args, has_fp_args, allocator, invoke->GetDexPc());
-  append->SetReferenceTypeInfo(invoke->GetReferenceTypeInfo());
+  append->SetReferenceTypeInfoIfValid(invoke->GetReferenceTypeInfo());
   for (size_t i = 0; i != num_args; ++i) {
     append->SetArgumentAt(i, args[num_args - 1u - i]);
   }
diff --git a/compiler/optimizing/load_store_elimination.cc b/compiler/optimizing/load_store_elimination.cc
index cd44082..9cabb12 100644
--- a/compiler/optimizing/load_store_elimination.cc
+++ b/compiler/optimizing/load_store_elimination.cc
@@ -3386,7 +3386,7 @@
           ins->GetBlock()->InsertInstructionBefore(new_fget, ins);
           if (ins->GetType() == DataType::Type::kReference) {
             // Reference info is the same
-            new_fget->SetReferenceTypeInfo(ins->GetReferenceTypeInfo());
+            new_fget->SetReferenceTypeInfoIfValid(ins->GetReferenceTypeInfo());
           }
           // In this phase, substitute instructions are used only for the predicated get
           // default values which are used only if the partial singleton did not escape,
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc
index 0876ce0..c99cfab 100644
--- a/compiler/optimizing/nodes.cc
+++ b/compiler/optimizing/nodes.cc
@@ -688,7 +688,7 @@
                                                     0,
                                                     header_phi->GetType());
     if (header_phi->GetType() == DataType::Type::kReference) {
-      preheader_phi->SetReferenceTypeInfo(header_phi->GetReferenceTypeInfo());
+      preheader_phi->SetReferenceTypeInfoIfValid(header_phi->GetReferenceTypeInfo());
     }
     preheader->AddPhi(preheader_phi);
 
@@ -3215,6 +3215,12 @@
   SetPackedFlag<kFlagReferenceTypeIsExact>(rti.IsExact());
 }
 
+void HInstruction::SetReferenceTypeInfoIfValid(ReferenceTypeInfo rti) {
+  if (rti.IsValid()) {
+    SetReferenceTypeInfo(rti);
+  }
+}
+
 bool HBoundType::InstructionDataEquals(const HInstruction* other) const {
   const HBoundType* other_bt = other->AsBoundType();
   ScopedObjectAccess soa(Thread::Current());
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 58ce9ce..5854fa2 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -2377,7 +2377,10 @@
     return GetType() == DataType::Type::kReference;
   }
 
+  // Sets the ReferenceTypeInfo. The RTI must be valid.
   void SetReferenceTypeInfo(ReferenceTypeInfo rti);
+  // Same as above, but we only set it if it's valid. Otherwise, we don't change the current RTI.
+  void SetReferenceTypeInfoIfValid(ReferenceTypeInfo rti);
 
   ReferenceTypeInfo GetReferenceTypeInfo() const {
     DCHECK_EQ(GetType(), DataType::Type::kReference);
diff --git a/compiler/optimizing/select_generator.cc b/compiler/optimizing/select_generator.cc
index 761e7b5..6a10440 100644
--- a/compiler/optimizing/select_generator.cc
+++ b/compiler/optimizing/select_generator.cc
@@ -160,7 +160,7 @@
       ReferenceTypePropagation::FixUpInstructionType(select, graph_->GetHandleCache());
     }
   } else if (phi->GetType() == DataType::Type::kReference) {
-    select->SetReferenceTypeInfo(phi->GetReferenceTypeInfo());
+    select->SetReferenceTypeInfoIfValid(phi->GetReferenceTypeInfo());
   }
   block->InsertInstructionBefore(select, if_instruction);
 
diff --git a/compiler/optimizing/superblock_cloner.cc b/compiler/optimizing/superblock_cloner.cc
index ba56eb8..7c0097c 100644
--- a/compiler/optimizing/superblock_cloner.cc
+++ b/compiler/optimizing/superblock_cloner.cc
@@ -633,7 +633,7 @@
     HPhi* phi = new (arena_) HPhi(arena_, kNoRegNumber, 0, value->GetType());
 
     if (value->GetType() == DataType::Type::kReference) {
-      phi->SetReferenceTypeInfo(value->GetReferenceTypeInfo());
+      phi->SetReferenceTypeInfoIfValid(value->GetReferenceTypeInfo());
     }
 
     exit_block->AddPhi(phi);