Don't compile OSR methods that have phi equivalents at loop entry.

We currently don't handle this in the stack map, where we only encode
one stack slot for a dex register.

Bug: 136698025
Test: 721-osr
Change-Id: Ib395ed1165387ad5446a463c307cc0a45e365885
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 25f9e3c..09ae6fa 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -131,6 +131,7 @@
   kAnalysisFailThrowCatchLoop,
   kAnalysisFailAmbiguousArrayOp,
   kAnalysisFailIrreducibleLoopAndStringInit,
+  kAnalysisFailPhiEquivalentInOsr,
   kAnalysisSuccess,
 };
 
diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc
index 6f3b9fe..b1a3abe 100644
--- a/compiler/optimizing/optimizing_compiler.cc
+++ b/compiler/optimizing/optimizing_compiler.cc
@@ -914,6 +914,11 @@
                           MethodCompilationStat::kNotCompiledIrreducibleLoopAndStringInit);
           break;
         }
+        case kAnalysisFailPhiEquivalentInOsr: {
+          MaybeRecordStat(compilation_stats_.get(),
+                          MethodCompilationStat::kNotCompiledPhiEquivalentInOsr);
+          break;
+        }
         case kAnalysisSuccess:
           UNREACHABLE();
       }
diff --git a/compiler/optimizing/optimizing_compiler_stats.h b/compiler/optimizing/optimizing_compiler_stats.h
index ddd57f5..83dbef7 100644
--- a/compiler/optimizing/optimizing_compiler_stats.h
+++ b/compiler/optimizing/optimizing_compiler_stats.h
@@ -61,6 +61,7 @@
   kNotCompiledVerificationError,
   kNotCompiledVerifyAtRuntime,
   kNotCompiledIrreducibleLoopAndStringInit,
+  kNotCompiledPhiEquivalentInOsr,
   kInlinedMonomorphicCall,
   kInlinedPolymorphicCall,
   kMonomorphicCall,
diff --git a/compiler/optimizing/ssa_builder.cc b/compiler/optimizing/ssa_builder.cc
index 0d0e1ec..a5e8ff6 100644
--- a/compiler/optimizing/ssa_builder.cc
+++ b/compiler/optimizing/ssa_builder.cc
@@ -496,6 +496,22 @@
   }
 }
 
+static bool HasPhiEquivalentAtLoopEntry(HGraph* graph) {
+  // Phi equivalents for a dex register do not work with OSR, as the phis will
+  // receive two different stack slots but only one is recorded in the stack
+  // map.
+  for (HBasicBlock* block : graph->GetReversePostOrder()) {
+    if (block->IsLoopHeader()) {
+      for (HInstructionIterator it(block->GetPhis()); !it.Done(); it.Advance()) {
+        if (it.Current()->AsPhi()->HasEquivalentPhi()) {
+          return true;
+        }
+      }
+    }
+  }
+  return false;
+}
+
 GraphAnalysisResult SsaBuilder::BuildSsa() {
   DCHECK(!graph_->IsInSsaForm());
 
@@ -574,6 +590,10 @@
   // other optimizations.
   RemoveRedundantUninitializedStrings();
 
+  if (graph_->IsCompilingOsr() && HasPhiEquivalentAtLoopEntry(graph_)) {
+    return kAnalysisFailPhiEquivalentInOsr;
+  }
+
   graph_->SetInSsaForm();
   return kAnalysisSuccess;
 }