Clean up after verifier changes wrt. conflict/undefined reg.

Remove unused path in RegType::Merge() and compare undefined
type as pointers. Reduce the number of edges to merge in
b_22331663.smali to just those that we really want to test.

Bug: 22331663
Change-Id: I16b83c4c97fd40be9dd246ef13ccda6e924eef60
diff --git a/runtime/verifier/reg_type.cc b/runtime/verifier/reg_type.cc
index 1435607..9c52819 100644
--- a/runtime/verifier/reg_type.cc
+++ b/runtime/verifier/reg_type.cc
@@ -583,24 +583,20 @@
 
 const RegType& RegType::Merge(const RegType& incoming_type, RegTypeCache* reg_types) const {
   DCHECK(!Equals(incoming_type));  // Trivial equality handled by caller
-  // Perform pointer equality tests for conflict to avoid virtual method dispatch.
+  // Perform pointer equality tests for undefined and conflict to avoid virtual method dispatch.
+  const UndefinedType& undefined = reg_types->Undefined();
   const ConflictType& conflict = reg_types->Conflict();
-  if (IsUndefined() || incoming_type.IsUndefined()) {
+  DCHECK_EQ(this == &undefined, IsUndefined());
+  DCHECK_EQ(&incoming_type == &undefined, incoming_type.IsUndefined());
+  DCHECK_EQ(this == &conflict, IsConflict());
+  DCHECK_EQ(&incoming_type == &conflict, incoming_type.IsConflict());
+  if (this == &undefined || &incoming_type == &undefined) {
     // There is a difference between undefined and conflict. Conflicts may be copied around, but
     // not used. Undefined registers must not be copied. So any merge with undefined should return
     // undefined.
-    if (IsUndefined()) {
-      return *this;
-    }
-    return incoming_type;
-  } else if (this == &conflict) {
-    DCHECK(IsConflict());
-    return *this;  // Conflict MERGE * => Conflict
-  } else if (&incoming_type == &conflict) {
-    DCHECK(incoming_type.IsConflict());
-    return incoming_type;  // * MERGE Conflict => Conflict
-  } else if (IsUndefined() || incoming_type.IsUndefined()) {
-    return conflict;  // Unknown MERGE * => Conflict
+    return undefined;
+  } else if (this == &conflict || &incoming_type == &conflict) {
+    return conflict;  // (Conflict MERGE *) or (* MERGE Conflict) => Conflict
   } else if (IsConstant() && incoming_type.IsConstant()) {
     const ConstantType& type1 = *down_cast<const ConstantType*>(this);
     const ConstantType& type2 = *down_cast<const ConstantType*>(&incoming_type);
diff --git a/test/800-smali/smali/b_22331663.smali b/test/800-smali/smali/b_22331663.smali
index 057fc7f..bae75c2 100644
--- a/test/800-smali/smali/b_22331663.smali
+++ b/test/800-smali/smali/b_22331663.smali
@@ -4,29 +4,29 @@
 
 .method public static run(Z)V
 .registers 6
-       # Make v4 defined, just use null.
-       const v4, 0
+       if-eqz v5, :if_eqz_target
 
-       if-eqz v5, :Label2
-
-:Label1
        # Construct a java.lang.Object completely, and throw a new exception.
        new-instance v4, Ljava/lang/Object;
        invoke-direct {v4}, Ljava/lang/Object;-><init>()V
 
        new-instance v3, Ljava/lang/RuntimeException;
        invoke-direct {v3}, Ljava/lang/RuntimeException;-><init>()V
+:throw1_begin
        throw v3
+:throw1_end
 
-:Label2
+:if_eqz_target
        # Allocate a java.lang.Object (do not initialize), and throw a new exception.
        new-instance v4, Ljava/lang/Object;
 
        new-instance v3, Ljava/lang/RuntimeException;
        invoke-direct {v3}, Ljava/lang/RuntimeException;-><init>()V
+:throw2_begin
        throw v3
+:throw2_end
 
-:Label3
+:catch_entry
        # Catch handler. Here we had to merge the uninitialized with the initialized reference,
        # which creates a conflict. Copy the conflict, and then return. This should not make the
        # verifier fail the method.
@@ -34,5 +34,6 @@
 
        return-void
 
-.catchall {:Label1 .. :Label3} :Label3
+.catchall {:throw1_begin .. :throw1_end} :catch_entry
+.catchall {:throw2_begin .. :throw2_end} :catch_entry
 .end method