Quick: Remove broken Mir2Lir::LocToRegClass().

Its use in intrinsics has been bogus. In all other instances
it's been used under the assumption that the inferred type
matches the return type of associated calls. However, if the
type inference identifies a type mismatch, the assumption
doesn't hold and there isn't necessarily a valid value that
the function could reasonably return.

Bug: 19918641
Change-Id: I050934e6f9eb00427d0b888ee29ae9eeb509bb3f
diff --git a/compiler/dex/quick/arm/fp_arm.cc b/compiler/dex/quick/arm/fp_arm.cc
index eb1383f..94fc474 100644
--- a/compiler/dex/quick/arm/fp_arm.cc
+++ b/compiler/dex/quick/arm/fp_arm.cc
@@ -187,7 +187,8 @@
       return;
     }
     case Instruction::FLOAT_TO_LONG:
-      GenConversionCall(kQuickF2l, rl_dest, rl_src);
+      CheckEntrypointTypes<kQuickF2l, int64_t, float>();  // int64_t -> kCoreReg
+      GenConversionCall(kQuickF2l, rl_dest, rl_src, kCoreReg);
       return;
     case Instruction::LONG_TO_FLOAT: {
       rl_src = LoadValueWide(rl_src, kFPReg);
@@ -217,7 +218,8 @@
       return;
     }
     case Instruction::DOUBLE_TO_LONG:
-      GenConversionCall(kQuickD2l, rl_dest, rl_src);
+      CheckEntrypointTypes<kQuickD2l, int64_t, double>();  // int64_t -> kCoreReg
+      GenConversionCall(kQuickD2l, rl_dest, rl_src, kCoreReg);
       return;
     default:
       LOG(FATAL) << "Unexpected opcode: " << opcode;
diff --git a/compiler/dex/quick/arm/int_arm.cc b/compiler/dex/quick/arm/int_arm.cc
index 47669db..62903af 100644
--- a/compiler/dex/quick/arm/int_arm.cc
+++ b/compiler/dex/quick/arm/int_arm.cc
@@ -882,7 +882,7 @@
   RegLocation rl_object = LoadValue(rl_src_obj, kRefReg);
   RegLocation rl_new_value;
   if (!is_long) {
-    rl_new_value = LoadValue(rl_src_new_value, LocToRegClass(rl_src_new_value));
+    rl_new_value = LoadValue(rl_src_new_value, is_object ? kRefReg : kCoreReg);
   } else if (load_early) {
     rl_new_value = LoadValueWide(rl_src_new_value, kCoreReg);
   }
@@ -905,7 +905,7 @@
 
   RegLocation rl_expected;
   if (!is_long) {
-    rl_expected = LoadValue(rl_src_expected, LocToRegClass(rl_src_new_value));
+    rl_expected = LoadValue(rl_src_expected, is_object ? kRefReg : kCoreReg);
   } else if (load_early) {
     rl_expected = LoadValueWide(rl_src_expected, kCoreReg);
   } else {
diff --git a/compiler/dex/quick/dex_file_method_inliner.cc b/compiler/dex/quick/dex_file_method_inliner.cc
index 4ac6c0c..818112d 100644
--- a/compiler/dex/quick/dex_file_method_inliner.cc
+++ b/compiler/dex/quick/dex_file_method_inliner.cc
@@ -368,9 +368,9 @@
 
 #define UNSAFE_GET_PUT(type, code, type_flags) \
     INTRINSIC(SunMiscUnsafe, Get ## type, ObjectJ_ ## code, kIntrinsicUnsafeGet, \
-              type_flags & ~kIntrinsicFlagIsObject), \
+              type_flags), \
     INTRINSIC(SunMiscUnsafe, Get ## type ## Volatile, ObjectJ_ ## code, kIntrinsicUnsafeGet, \
-              (type_flags | kIntrinsicFlagIsVolatile) & ~kIntrinsicFlagIsObject), \
+              type_flags | kIntrinsicFlagIsVolatile), \
     INTRINSIC(SunMiscUnsafe, Put ## type, ObjectJ ## code ## _V, kIntrinsicUnsafePut, \
               type_flags), \
     INTRINSIC(SunMiscUnsafe, Put ## type ## Volatile, ObjectJ ## code ## _V, kIntrinsicUnsafePut, \
@@ -507,6 +507,7 @@
                                     intrinsic.d.data & kIntrinsicFlagIsObject);
     case kIntrinsicUnsafeGet:
       return backend->GenInlinedUnsafeGet(info, intrinsic.d.data & kIntrinsicFlagIsLong,
+                                          intrinsic.d.data & kIntrinsicFlagIsObject,
                                           intrinsic.d.data & kIntrinsicFlagIsVolatile);
     case kIntrinsicUnsafePut:
       return backend->GenInlinedUnsafePut(info, intrinsic.d.data & kIntrinsicFlagIsLong,
diff --git a/compiler/dex/quick/gen_common.cc b/compiler/dex/quick/gen_common.cc
index b132c4c..1a72cd7 100644
--- a/compiler/dex/quick/gen_common.cc
+++ b/compiler/dex/quick/gen_common.cc
@@ -2088,7 +2088,7 @@
 }
 
 void Mir2Lir::GenConversionCall(QuickEntrypointEnum trampoline, RegLocation rl_dest,
-                                RegLocation rl_src) {
+                                RegLocation rl_src, RegisterClass return_reg_class) {
   /*
    * Don't optimize the register usage since it calls out to support
    * functions
@@ -2097,12 +2097,10 @@
   FlushAllRegs();   /* Send everything to home location */
   CallRuntimeHelperRegLocation(trampoline, rl_src, false);
   if (rl_dest.wide) {
-    RegLocation rl_result;
-    rl_result = GetReturnWide(LocToRegClass(rl_dest));
+    RegLocation rl_result = GetReturnWide(return_reg_class);
     StoreValueWide(rl_dest, rl_result);
   } else {
-    RegLocation rl_result;
-    rl_result = GetReturn(LocToRegClass(rl_dest));
+    RegLocation rl_result = GetReturn(return_reg_class);
     StoreValue(rl_dest, rl_result);
   }
 }
diff --git a/compiler/dex/quick/gen_invoke.cc b/compiler/dex/quick/gen_invoke.cc
index db7095d..1eb3a5f 100755
--- a/compiler/dex/quick/gen_invoke.cc
+++ b/compiler/dex/quick/gen_invoke.cc
@@ -882,8 +882,6 @@
         ShortyToRegClass(mir_graph_->GetShortyFromMethodReference(info->method_ref)[0]));
   } else {
     res = info->result;
-    DCHECK_EQ(LocToRegClass(res),
-              ShortyToRegClass(mir_graph_->GetShortyFromMethodReference(info->method_ref)[0]));
   }
   return res;
 }
@@ -896,8 +894,6 @@
         mir_graph_->GetShortyFromMethodReference(info->method_ref)[0]));
   } else {
     res = info->result;
-    DCHECK_EQ(LocToRegClass(res),
-              ShortyToRegClass(mir_graph_->GetShortyFromMethodReference(info->method_ref)[0]));
   }
   return res;
 }
@@ -1338,7 +1334,7 @@
 }
 
 bool Mir2Lir::GenInlinedUnsafeGet(CallInfo* info,
-                                  bool is_long, bool is_volatile) {
+                                  bool is_long, bool is_object, bool is_volatile) {
   if (cu_->instruction_set == kMips || cu_->instruction_set == kMips64) {
     // TODO: add Mips and Mips64 implementations.
     return false;
@@ -1351,7 +1347,7 @@
 
   RegLocation rl_object = LoadValue(rl_src_obj, kRefReg);
   RegLocation rl_offset = LoadValue(rl_src_offset, kCoreReg);
-  RegLocation rl_result = EvalLoc(rl_dest, LocToRegClass(rl_dest), true);
+  RegLocation rl_result = EvalLoc(rl_dest, is_object ? kRefReg : kCoreReg, true);
   if (is_long) {
     if (cu_->instruction_set == kX86 || cu_->instruction_set == kX86_64
         || cu_->instruction_set == kArm64) {
@@ -1411,7 +1407,7 @@
       FreeTemp(rl_temp_offset);
     }
   } else {
-    rl_value = LoadValue(rl_src_value, LocToRegClass(rl_src_value));
+    rl_value = LoadValue(rl_src_value, is_object ? kRefReg : kCoreReg);
     if (rl_value.ref) {
       StoreRefIndexed(rl_object.reg, rl_offset.reg, rl_value.reg, 0);
     } else {
@@ -1499,11 +1495,13 @@
   FreeCallTemps();
   if (info->result.location != kLocInvalid) {
     // We have a following MOVE_RESULT - do it now.
+    RegisterClass reg_class =
+        ShortyToRegClass(mir_graph_->GetShortyFromMethodReference(info->method_ref)[0]);
     if (info->result.wide) {
-      RegLocation ret_loc = GetReturnWide(LocToRegClass(info->result));
+      RegLocation ret_loc = GetReturnWide(reg_class);
       StoreValueWide(info->result, ret_loc);
     } else {
-      RegLocation ret_loc = GetReturn(LocToRegClass(info->result));
+      RegLocation ret_loc = GetReturn(reg_class);
       StoreValue(info->result, ret_loc);
     }
   }
diff --git a/compiler/dex/quick/mir_to_lir.cc b/compiler/dex/quick/mir_to_lir.cc
index 961cd4f..2deb727 100644
--- a/compiler/dex/quick/mir_to_lir.cc
+++ b/compiler/dex/quick/mir_to_lir.cc
@@ -104,19 +104,6 @@
   return res;
 }
 
-RegisterClass Mir2Lir::LocToRegClass(RegLocation loc) {
-  RegisterClass res;
-  if (loc.fp) {
-    DCHECK(!loc.ref) << "At most, one of ref/fp may be set";
-    res = kFPReg;
-  } else if (loc.ref) {
-    res = kRefReg;
-  } else {
-    res = kCoreReg;
-  }
-  return res;
-}
-
 void Mir2Lir::LockArg(size_t in_position) {
   RegStorage reg_arg = in_to_reg_storage_mapping_.GetReg(in_position);
 
@@ -560,25 +547,20 @@
       if (!kLeafOptimization || !mir_graph_->MethodIsLeaf()) {
         GenSuspendTest(opt_flags);
       }
-      DCHECK_EQ(LocToRegClass(rl_src[0]), ShortyToRegClass(cu_->shorty[0]));
-      StoreValue(GetReturn(LocToRegClass(rl_src[0])), rl_src[0]);
+      StoreValue(GetReturn(ShortyToRegClass(cu_->shorty[0])), rl_src[0]);
       break;
 
     case Instruction::RETURN_WIDE:
       if (!kLeafOptimization || !mir_graph_->MethodIsLeaf()) {
         GenSuspendTest(opt_flags);
       }
-      DCHECK_EQ(LocToRegClass(rl_src[0]), ShortyToRegClass(cu_->shorty[0]));
-      StoreValueWide(GetReturnWide(LocToRegClass(rl_src[0])), rl_src[0]);
-      break;
-
-    case Instruction::MOVE_RESULT_WIDE:
-      StoreValueWide(rl_dest, GetReturnWide(LocToRegClass(rl_dest)));
+      StoreValueWide(GetReturnWide(ShortyToRegClass(cu_->shorty[0])), rl_src[0]);
       break;
 
     case Instruction::MOVE_RESULT:
+    case Instruction::MOVE_RESULT_WIDE:
     case Instruction::MOVE_RESULT_OBJECT:
-      StoreValue(rl_dest, GetReturn(LocToRegClass(rl_dest)));
+      // Already processed with invoke or filled-new-array.
       break;
 
     case Instruction::MOVE:
diff --git a/compiler/dex/quick/mir_to_lir.h b/compiler/dex/quick/mir_to_lir.h
index db59714..f9efe37 100644
--- a/compiler/dex/quick/mir_to_lir.h
+++ b/compiler/dex/quick/mir_to_lir.h
@@ -634,7 +634,6 @@
     }
 
     RegisterClass ShortyToRegClass(char shorty_type);
-    RegisterClass LocToRegClass(RegLocation loc);
     int ComputeFrameSize();
     void Materialize();
     virtual CompiledMethod* GetCompiledMethod();
@@ -846,7 +845,8 @@
                           RegLocation rl_src, int lit);
     virtual void GenArithOpLong(Instruction::Code opcode, RegLocation rl_dest,
                                 RegLocation rl_src1, RegLocation rl_src2, int flags);
-    void GenConversionCall(QuickEntrypointEnum trampoline, RegLocation rl_dest, RegLocation rl_src);
+    void GenConversionCall(QuickEntrypointEnum trampoline, RegLocation rl_dest, RegLocation rl_src,
+                           RegisterClass return_reg_class);
     void GenSuspendTest(int opt_flags);
     void GenSuspendTestAndBranch(int opt_flags, LIR* target);
 
@@ -954,7 +954,7 @@
     virtual bool GenInlinedIndexOf(CallInfo* info, bool zero_based);
     bool GenInlinedStringCompareTo(CallInfo* info);
     virtual bool GenInlinedCurrentThread(CallInfo* info);
-    bool GenInlinedUnsafeGet(CallInfo* info, bool is_long, bool is_volatile);
+    bool GenInlinedUnsafeGet(CallInfo* info, bool is_long, bool is_object, bool is_volatile);
     bool GenInlinedUnsafePut(CallInfo* info, bool is_long, bool is_object,
                              bool is_volatile, bool is_ordered);
 
diff --git a/compiler/dex/quick/x86/fp_x86.cc b/compiler/dex/quick/x86/fp_x86.cc
index cfe0480..10af31a 100755
--- a/compiler/dex/quick/x86/fp_x86.cc
+++ b/compiler/dex/quick/x86/fp_x86.cc
@@ -309,7 +309,8 @@
         branch_normal->target = NewLIR0(kPseudoTargetLabel);
         StoreValueWide(rl_dest, rl_result);
       } else {
-        GenConversionCall(kQuickF2l, rl_dest, rl_src);
+        CheckEntrypointTypes<kQuickF2l, int64_t, float>();  // int64_t -> kCoreReg
+        GenConversionCall(kQuickF2l, rl_dest, rl_src, kCoreReg);
       }
       return;
     case Instruction::DOUBLE_TO_LONG:
@@ -334,7 +335,8 @@
         branch_normal->target = NewLIR0(kPseudoTargetLabel);
         StoreValueWide(rl_dest, rl_result);
       } else {
-        GenConversionCall(kQuickD2l, rl_dest, rl_src);
+        CheckEntrypointTypes<kQuickD2l, int64_t, double>();  // int64_t -> kCoreReg
+        GenConversionCall(kQuickD2l, rl_dest, rl_src, kCoreReg);
       }
       return;
     default:
diff --git a/compiler/dex/quick/x86/int_x86.cc b/compiler/dex/quick/x86/int_x86.cc
index 1043815..2c13b61 100755
--- a/compiler/dex/quick/x86/int_x86.cc
+++ b/compiler/dex/quick/x86/int_x86.cc
@@ -1229,7 +1229,7 @@
     LockTemp(rs_r0);
 
     RegLocation rl_object = LoadValue(rl_src_obj, kRefReg);
-    RegLocation rl_new_value = LoadValue(rl_src_new_value, LocToRegClass(rl_src_new_value));
+    RegLocation rl_new_value = LoadValue(rl_src_new_value, is_object ? kRefReg : kCoreReg);
 
     if (is_object && !mir_graph_->IsConstantNullRef(rl_new_value)) {
       // Mark card for object assuming new value is stored.