Make art::HCompare support boolean, byte, short and char inputs.

Also extend tests covering the IntegerSignum, LongSignum,
IntegerCompare and LongCompare intrinsics and their
translation into an art::HCompare instruction.

Bug: 27629913
Change-Id: I0afc75ee6e82602b01ec348bbb36a08e8abb8bb8
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc
index 2b54ff8..34fd9ff 100644
--- a/compiler/optimizing/code_generator_arm.cc
+++ b/compiler/optimizing/code_generator_arm.cc
@@ -3672,6 +3672,10 @@
   LocationSummary* locations =
       new (GetGraph()->GetArena()) LocationSummary(compare, LocationSummary::kNoCall);
   switch (compare->InputAt(0)->GetType()) {
+    case Primitive::kPrimBoolean:
+    case Primitive::kPrimByte:
+    case Primitive::kPrimShort:
+    case Primitive::kPrimChar:
     case Primitive::kPrimInt:
     case Primitive::kPrimLong: {
       locations->SetInAt(0, Location::RequiresRegister());
@@ -3702,6 +3706,10 @@
   Primitive::Type type = compare->InputAt(0)->GetType();
   Condition less_cond;
   switch (type) {
+    case Primitive::kPrimBoolean:
+    case Primitive::kPrimByte:
+    case Primitive::kPrimShort:
+    case Primitive::kPrimChar:
     case Primitive::kPrimInt: {
       __ LoadImmediate(out, 0);
       __ cmp(left.AsRegister<Register>(),
diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc
index 20e0770..a220e59 100644
--- a/compiler/optimizing/code_generator_arm64.cc
+++ b/compiler/optimizing/code_generator_arm64.cc
@@ -2388,6 +2388,10 @@
       new (GetGraph()->GetArena()) LocationSummary(compare, LocationSummary::kNoCall);
   Primitive::Type in_type = compare->InputAt(0)->GetType();
   switch (in_type) {
+    case Primitive::kPrimBoolean:
+    case Primitive::kPrimByte:
+    case Primitive::kPrimShort:
+    case Primitive::kPrimChar:
     case Primitive::kPrimInt:
     case Primitive::kPrimLong: {
       locations->SetInAt(0, Location::RequiresRegister());
@@ -2417,6 +2421,10 @@
   //  1 if: left  > right
   // -1 if: left  < right
   switch (in_type) {
+    case Primitive::kPrimBoolean:
+    case Primitive::kPrimByte:
+    case Primitive::kPrimShort:
+    case Primitive::kPrimChar:
     case Primitive::kPrimInt:
     case Primitive::kPrimLong: {
       Register result = OutputRegister(compare);
diff --git a/compiler/optimizing/code_generator_mips.cc b/compiler/optimizing/code_generator_mips.cc
index 2e2ceaa..3c2c0b0 100644
--- a/compiler/optimizing/code_generator_mips.cc
+++ b/compiler/optimizing/code_generator_mips.cc
@@ -2070,6 +2070,10 @@
       new (GetGraph()->GetArena()) LocationSummary(compare, LocationSummary::kNoCall);
 
   switch (in_type) {
+    case Primitive::kPrimBoolean:
+    case Primitive::kPrimByte:
+    case Primitive::kPrimShort:
+    case Primitive::kPrimChar:
     case Primitive::kPrimInt:
     case Primitive::kPrimLong:
       locations->SetInAt(0, Location::RequiresRegister());
@@ -2100,6 +2104,10 @@
   //  1 if: left  > right
   // -1 if: left  < right
   switch (in_type) {
+    case Primitive::kPrimBoolean:
+    case Primitive::kPrimByte:
+    case Primitive::kPrimShort:
+    case Primitive::kPrimChar:
     case Primitive::kPrimInt: {
       Register lhs = locations->InAt(0).AsRegister<Register>();
       Register rhs = locations->InAt(1).AsRegister<Register>();
diff --git a/compiler/optimizing/code_generator_mips64.cc b/compiler/optimizing/code_generator_mips64.cc
index 5ac8c27..ddc873d 100644
--- a/compiler/optimizing/code_generator_mips64.cc
+++ b/compiler/optimizing/code_generator_mips64.cc
@@ -1691,6 +1691,10 @@
   LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(compare);
 
   switch (in_type) {
+    case Primitive::kPrimBoolean:
+    case Primitive::kPrimByte:
+    case Primitive::kPrimShort:
+    case Primitive::kPrimChar:
     case Primitive::kPrimInt:
     case Primitive::kPrimLong:
       locations->SetInAt(0, Location::RequiresRegister());
@@ -1719,6 +1723,10 @@
   //  1 if: left  > right
   // -1 if: left  < right
   switch (in_type) {
+    case Primitive::kPrimBoolean:
+    case Primitive::kPrimByte:
+    case Primitive::kPrimShort:
+    case Primitive::kPrimChar:
     case Primitive::kPrimInt:
     case Primitive::kPrimLong: {
       GpuRegister lhs = locations->InAt(0).AsRegister<GpuRegister>();
@@ -1726,18 +1734,18 @@
       bool use_imm = rhs_location.IsConstant();
       GpuRegister rhs = ZERO;
       if (use_imm) {
-        if (in_type == Primitive::kPrimInt) {
-          int32_t value = CodeGenerator::GetInt32ValueOf(rhs_location.GetConstant()->AsConstant());
-          if (value != 0) {
-            rhs = AT;
-            __ LoadConst32(rhs, value);
-          }
-        } else {
+        if (in_type == Primitive::kPrimLong) {
           int64_t value = CodeGenerator::GetInt64ValueOf(rhs_location.GetConstant()->AsConstant());
           if (value != 0) {
             rhs = AT;
             __ LoadConst64(rhs, value);
           }
+        } else {
+          int32_t value = CodeGenerator::GetInt32ValueOf(rhs_location.GetConstant()->AsConstant());
+          if (value != 0) {
+            rhs = AT;
+            __ LoadConst32(rhs, value);
+          }
         }
       } else {
         rhs = rhs_location.AsRegister<GpuRegister>();
diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc
index b4b1679..9acaa1d 100644
--- a/compiler/optimizing/code_generator_x86.cc
+++ b/compiler/optimizing/code_generator_x86.cc
@@ -4186,6 +4186,10 @@
   LocationSummary* locations =
       new (GetGraph()->GetArena()) LocationSummary(compare, LocationSummary::kNoCall);
   switch (compare->InputAt(0)->GetType()) {
+    case Primitive::kPrimBoolean:
+    case Primitive::kPrimByte:
+    case Primitive::kPrimShort:
+    case Primitive::kPrimChar:
     case Primitive::kPrimInt:
     case Primitive::kPrimLong: {
       locations->SetInAt(0, Location::RequiresRegister());
@@ -4221,6 +4225,10 @@
   Condition less_cond = kLess;
 
   switch (compare->InputAt(0)->GetType()) {
+    case Primitive::kPrimBoolean:
+    case Primitive::kPrimByte:
+    case Primitive::kPrimShort:
+    case Primitive::kPrimChar:
     case Primitive::kPrimInt: {
       GenerateIntCompare(left, right);
       break;
diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc
index 03e6952..51bc8c2 100644
--- a/compiler/optimizing/code_generator_x86_64.cc
+++ b/compiler/optimizing/code_generator_x86_64.cc
@@ -1860,6 +1860,10 @@
   LocationSummary* locations =
       new (GetGraph()->GetArena()) LocationSummary(compare, LocationSummary::kNoCall);
   switch (compare->InputAt(0)->GetType()) {
+    case Primitive::kPrimBoolean:
+    case Primitive::kPrimByte:
+    case Primitive::kPrimShort:
+    case Primitive::kPrimChar:
     case Primitive::kPrimInt:
     case Primitive::kPrimLong: {
       locations->SetInAt(0, Location::RequiresRegister());
@@ -1890,6 +1894,10 @@
   Condition less_cond = kLess;
 
   switch (type) {
+    case Primitive::kPrimBoolean:
+    case Primitive::kPrimByte:
+    case Primitive::kPrimShort:
+    case Primitive::kPrimChar:
     case Primitive::kPrimInt: {
       CpuRegister left_reg = left.AsRegister<CpuRegister>();
       if (right.IsConstant()) {
diff --git a/compiler/optimizing/graph_checker.cc b/compiler/optimizing/graph_checker.cc
index 4a49c83..1fbb2d5 100644
--- a/compiler/optimizing/graph_checker.cc
+++ b/compiler/optimizing/graph_checker.cc
@@ -661,19 +661,6 @@
   }
 }
 
-static Primitive::Type PrimitiveKind(Primitive::Type type) {
-  switch (type) {
-    case Primitive::kPrimBoolean:
-    case Primitive::kPrimByte:
-    case Primitive::kPrimShort:
-    case Primitive::kPrimChar:
-    case Primitive::kPrimInt:
-      return Primitive::kPrimInt;
-    default:
-      return type;
-  }
-}
-
 static bool IsSameSizeConstant(HInstruction* insn1, HInstruction* insn2) {
   return insn1->IsConstant()
       && insn2->IsConstant()
@@ -716,10 +703,10 @@
   // Ensure that the inputs have the same primitive kind as the phi.
   for (size_t i = 0, e = phi->InputCount(); i < e; ++i) {
     HInstruction* input = phi->InputAt(i);
-    if (PrimitiveKind(input->GetType()) != PrimitiveKind(phi->GetType())) {
+    if (Primitive::PrimitiveKind(input->GetType()) != Primitive::PrimitiveKind(phi->GetType())) {
         AddError(StringPrintf(
             "Input %d at index %zu of phi %d from block %d does not have the "
-            "same type as the phi: %s versus %s",
+            "same kind as the phi: %s versus %s",
             input->GetId(), i, phi->GetId(), phi->GetBlock()->GetBlockId(),
             Primitive::PrettyDescriptor(input->GetType()),
             Primitive::PrettyDescriptor(phi->GetType())));
@@ -910,9 +897,9 @@
   }
   HInstruction* lhs = op->InputAt(0);
   HInstruction* rhs = op->InputAt(1);
-  if (PrimitiveKind(lhs->GetType()) != PrimitiveKind(rhs->GetType())) {
+  if (Primitive::PrimitiveKind(lhs->GetType()) != Primitive::PrimitiveKind(rhs->GetType())) {
     AddError(StringPrintf(
-        "Condition %s %d has inputs of different types: %s, and %s.",
+        "Condition %s %d has inputs of different kinds: %s, and %s.",
         op->DebugName(), op->GetId(),
         Primitive::PrettyDescriptor(lhs->GetType()),
         Primitive::PrettyDescriptor(rhs->GetType())));
@@ -932,42 +919,39 @@
 
 void GraphChecker::VisitBinaryOperation(HBinaryOperation* op) {
   VisitInstruction(op);
+  Primitive::Type lhs_type = op->InputAt(0)->GetType();
+  Primitive::Type rhs_type = op->InputAt(1)->GetType();
+  Primitive::Type result_type = op->GetType();
   if (op->IsUShr() || op->IsShr() || op->IsShl() || op->IsRor()) {
-    if (PrimitiveKind(op->InputAt(1)->GetType()) != Primitive::kPrimInt) {
-      AddError(StringPrintf(
-          "Shift operation %s %d has a non-int kind second input: "
-          "%s of type %s.",
-          op->DebugName(), op->GetId(),
-          op->InputAt(1)->DebugName(),
-          Primitive::PrettyDescriptor(op->InputAt(1)->GetType())));
+    if (Primitive::PrimitiveKind(rhs_type) != Primitive::kPrimInt) {
+      AddError(StringPrintf("Shift operation %s %d has a non-int kind second input: %s of type %s.",
+                            op->DebugName(), op->GetId(),
+                            op->InputAt(1)->DebugName(),
+                            Primitive::PrettyDescriptor(rhs_type)));
     }
   } else {
-    if (PrimitiveKind(op->InputAt(0)->GetType()) != PrimitiveKind(op->InputAt(1)->GetType())) {
-      AddError(StringPrintf(
-          "Binary operation %s %d has inputs of different types: "
-          "%s, and %s.",
-          op->DebugName(), op->GetId(),
-          Primitive::PrettyDescriptor(op->InputAt(0)->GetType()),
-          Primitive::PrettyDescriptor(op->InputAt(1)->GetType())));
+    if (Primitive::PrimitiveKind(lhs_type) != Primitive::PrimitiveKind(rhs_type)) {
+      AddError(StringPrintf("Binary operation %s %d has inputs of different kinds: %s, and %s.",
+                            op->DebugName(), op->GetId(),
+                            Primitive::PrettyDescriptor(lhs_type),
+                            Primitive::PrettyDescriptor(rhs_type)));
     }
   }
 
   if (op->IsCompare()) {
-    if (op->GetType() != Primitive::kPrimInt) {
-      AddError(StringPrintf(
-          "Compare operation %d has a non-int result type: %s.",
-          op->GetId(),
-          Primitive::PrettyDescriptor(op->GetType())));
+    if (result_type != Primitive::kPrimInt) {
+      AddError(StringPrintf("Compare operation %d has a non-int result type: %s.",
+                            op->GetId(),
+                            Primitive::PrettyDescriptor(result_type)));
     }
   } else {
     // Use the first input, so that we can also make this check for shift operations.
-    if (PrimitiveKind(op->GetType()) != PrimitiveKind(op->InputAt(0)->GetType())) {
-      AddError(StringPrintf(
-          "Binary operation %s %d has a result type different "
-          "from its input type: %s vs %s.",
-          op->DebugName(), op->GetId(),
-          Primitive::PrettyDescriptor(op->GetType()),
-          Primitive::PrettyDescriptor(op->InputAt(0)->GetType())));
+    if (Primitive::PrimitiveKind(result_type) != Primitive::PrimitiveKind(lhs_type)) {
+      AddError(StringPrintf("Binary operation %s %d has a result kind different "
+                            "from its input kind: %s vs %s.",
+                            op->DebugName(), op->GetId(),
+                            Primitive::PrettyDescriptor(result_type),
+                            Primitive::PrettyDescriptor(lhs_type)));
     }
   }
 }
diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc
index 9dfb51c..dd2977f 100644
--- a/compiler/optimizing/instruction_simplifier.cc
+++ b/compiler/optimizing/instruction_simplifier.cc
@@ -99,7 +99,7 @@
   void SimplifyRotate(HInvoke* invoke, bool is_left);
   void SimplifySystemArrayCopy(HInvoke* invoke);
   void SimplifyStringEquals(HInvoke* invoke);
-  void SimplifyCompare(HInvoke* invoke, bool has_zero_op);
+  void SimplifyCompare(HInvoke* invoke, bool is_signum, Primitive::Type type);
   void SimplifyIsNaN(HInvoke* invoke);
   void SimplifyFP2Int(HInvoke* invoke);
   void SimplifyMemBarrier(HInvoke* invoke, MemBarrierKind barrier_kind);
@@ -1619,12 +1619,13 @@
   }
 }
 
-void InstructionSimplifierVisitor::SimplifyCompare(HInvoke* invoke, bool is_signum) {
+void InstructionSimplifierVisitor::SimplifyCompare(HInvoke* invoke,
+                                                   bool is_signum,
+                                                   Primitive::Type type) {
   DCHECK(invoke->IsInvokeStaticOrDirect());
   uint32_t dex_pc = invoke->GetDexPc();
   HInstruction* left = invoke->InputAt(0);
   HInstruction* right;
-  Primitive::Type type = left->GetType();
   if (!is_signum) {
     right = invoke->InputAt(1);
   } else if (type == Primitive::kPrimLong) {
@@ -1701,12 +1702,16 @@
       SimplifyRotate(instruction, true);
       break;
     case Intrinsics::kIntegerCompare:
+      SimplifyCompare(instruction, /* is_signum */ false, Primitive::kPrimInt);
+      break;
     case Intrinsics::kLongCompare:
-      SimplifyCompare(instruction, /* is_signum */ false);
+      SimplifyCompare(instruction, /* is_signum */ false, Primitive::kPrimLong);
       break;
     case Intrinsics::kIntegerSignum:
+      SimplifyCompare(instruction, /* is_signum */ true, Primitive::kPrimInt);
+      break;
     case Intrinsics::kLongSignum:
-      SimplifyCompare(instruction, /* is_signum */ true);
+      SimplifyCompare(instruction, /* is_signum */ true, Primitive::kPrimLong);
       break;
     case Intrinsics::kFloatIsNaN:
     case Intrinsics::kDoubleIsNaN:
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 3733850..e2a54f4 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -3428,7 +3428,10 @@
 // Result is 0 if input0 == input1, 1 if input0 > input1, or -1 if input0 < input1.
 class HCompare : public HBinaryOperation {
  public:
-  HCompare(Primitive::Type type,
+  // Note that `comparison_type` is the type of comparison performed
+  // between the comparison's inputs, not the type of the instantiated
+  // HCompare instruction (which is always Primitive::kPrimInt).
+  HCompare(Primitive::Type comparison_type,
            HInstruction* first,
            HInstruction* second,
            ComparisonBias bias,
@@ -3436,11 +3439,13 @@
       : HBinaryOperation(Primitive::kPrimInt,
                          first,
                          second,
-                         SideEffectsForArchRuntimeCalls(type),
+                         SideEffectsForArchRuntimeCalls(comparison_type),
                          dex_pc) {
     SetPackedField<ComparisonBiasField>(bias);
-    DCHECK_EQ(type, first->GetType());
-    DCHECK_EQ(type, second->GetType());
+    if (kIsDebugBuild) {
+      DCHECK_EQ(comparison_type, Primitive::PrimitiveKind(first->GetType()));
+      DCHECK_EQ(comparison_type, Primitive::PrimitiveKind(second->GetType()));
+    }
   }
 
   template <typename T>
diff --git a/runtime/primitive.h b/runtime/primitive.h
index 2454a21..9c19ad5 100644
--- a/runtime/primitive.h
+++ b/runtime/primitive.h
@@ -166,6 +166,20 @@
     return type == kPrimLong || type == kPrimDouble;
   }
 
+  // Return the general kind of `type`, fusing integer-like types as kPrimInt.
+  static Type PrimitiveKind(Type type) {
+    switch (type) {
+      case kPrimBoolean:
+      case kPrimByte:
+      case kPrimShort:
+      case kPrimChar:
+      case kPrimInt:
+        return kPrimInt;
+      default:
+        return type;
+    }
+  }
+
  private:
   DISALLOW_IMPLICIT_CONSTRUCTORS(Primitive);
 };
diff --git a/test/566-checker-signum/src/Main.java b/test/566-checker-signum/src/Main.java
index 0ad0042..5f2cf3d 100644
--- a/test/566-checker-signum/src/Main.java
+++ b/test/566-checker-signum/src/Main.java
@@ -16,65 +16,213 @@
 
 public class Main {
 
-  /// CHECK-START: int Main.sign32(int) intrinsics_recognition (after)
-  /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerSignum
-  /// CHECK-DAG:                 Return [<<Result>>]
-  private static int sign32(int x) {
+  /// CHECK-START: int Main.signBoolean(boolean) intrinsics_recognition (after)
+  /// CHECK-DAG:     <<Method:[ij]\d+>> CurrentMethod
+  /// CHECK-DAG:     <<Zero:i\d+>>   IntConstant 0
+  /// CHECK-DAG:     <<One:i\d+>>    IntConstant 1
+  /// CHECK-DAG:     <<Phi:i\d+>>    Phi [<<One>>,<<Zero>>]
+  /// CHECK-DAG:     <<Result:i\d+>> InvokeStaticOrDirect [<<Phi>>,<<Method>>] intrinsic:IntegerSignum
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.signBoolean(boolean) instruction_simplifier (after)
+  /// CHECK-DAG:     <<Zero:i\d+>>   IntConstant 0
+  /// CHECK-DAG:     <<One:i\d+>>    IntConstant 1
+  /// CHECK-DAG:     <<Phi:i\d+>>    Phi [<<One>>,<<Zero>>]
+  /// CHECK-DAG:     <<Result:i\d+>> Compare [<<Phi>>,<<Zero>>]
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.signBoolean(boolean) instruction_simplifier (after)
+  /// CHECK-NOT:                     InvokeStaticOrDirect
+
+  /// CHECK-START: int Main.signBoolean(boolean) select_generator (after)
+  /// CHECK-DAG:     <<Arg:z\d+>>    ParameterValue
+  /// CHECK-DAG:     <<Zero:i\d+>>   IntConstant 0
+  /// CHECK-DAG:     <<One:i\d+>>    IntConstant 1
+  /// CHECK-DAG:     <<Sel:i\d+>>    Select [<<Zero>>,<<One>>,<<Arg>>]
+  /// CHECK-DAG:     <<Result:i\d+>> Compare [<<Sel>>,<<Zero>>]
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.signBoolean(boolean) select_generator (after)
+  /// CHECK-NOT:                     Phi
+
+  /// CHECK-START: int Main.signBoolean(boolean) instruction_simplifier_after_bce (after)
+  /// CHECK-DAG:     <<Arg:z\d+>>    ParameterValue
+  /// CHECK-DAG:     <<Zero:i\d+>>   IntConstant 0
+  /// CHECK-DAG:     <<Result:i\d+>> Compare [<<Arg>>,<<Zero>>]
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.signBoolean(boolean) instruction_simplifier_after_bce (after)
+  /// CHECK-NOT:                     Select
+
+  private static int signBoolean(boolean x) {
+    return Integer.signum(x ? 1 : 0);
+  }
+
+  /// CHECK-START: int Main.signByte(byte) intrinsics_recognition (after)
+  /// CHECK-DAG:     <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerSignum
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.signByte(byte) instruction_simplifier (after)
+  /// CHECK-DAG:     <<Result:i\d+>> Compare
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.signByte(byte) instruction_simplifier (after)
+  /// CHECK-NOT:                     InvokeStaticOrDirect
+
+  private static int signByte(byte x) {
     return Integer.signum(x);
   }
 
-  /// CHECK-START: int Main.sign64(long) intrinsics_recognition (after)
-  /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:LongSignum
-  /// CHECK-DAG:                 Return [<<Result>>]
-  private static int sign64(long x) {
+  /// CHECK-START: int Main.signShort(short) intrinsics_recognition (after)
+  /// CHECK-DAG:     <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerSignum
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.signShort(short) instruction_simplifier (after)
+  /// CHECK-DAG:     <<Result:i\d+>> Compare
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.signShort(short) instruction_simplifier (after)
+  /// CHECK-NOT:                     InvokeStaticOrDirect
+
+  private static int signShort(short x) {
+    return Integer.signum(x);
+  }
+
+  /// CHECK-START: int Main.signChar(char) intrinsics_recognition (after)
+  /// CHECK-DAG:     <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerSignum
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.signChar(char) instruction_simplifier (after)
+  /// CHECK-DAG:     <<Result:i\d+>> Compare
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.signChar(char) instruction_simplifier (after)
+  /// CHECK-NOT:                     InvokeStaticOrDirect
+
+  private static int signChar(char x) {
+    return Integer.signum(x);
+  }
+
+  /// CHECK-START: int Main.signInt(int) intrinsics_recognition (after)
+  /// CHECK-DAG:     <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerSignum
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.signInt(int) instruction_simplifier (after)
+  /// CHECK-DAG:     <<Result:i\d+>> Compare
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.signInt(int) instruction_simplifier (after)
+  /// CHECK-NOT:                     InvokeStaticOrDirect
+
+  private static int signInt(int x) {
+    return Integer.signum(x);
+  }
+
+  /// CHECK-START: int Main.signLong(long) intrinsics_recognition (after)
+  /// CHECK-DAG:     <<Result:i\d+>> InvokeStaticOrDirect intrinsic:LongSignum
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.signLong(long) instruction_simplifier (after)
+  /// CHECK-DAG:     <<Result:i\d+>> Compare
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.signLong(long) instruction_simplifier (after)
+  /// CHECK-NOT:                     InvokeStaticOrDirect
+
+  private static int signLong(long x) {
     return Long.signum(x);
   }
 
-  public static void main(String args[]) {
-    expectEquals(-1, sign32(Integer.MIN_VALUE));
-    expectEquals(-1, sign32(-12345));
-    expectEquals(-1, sign32(-1));
-    expectEquals(0, sign32(0));
-    expectEquals(1, sign32(1));
-    expectEquals(1, sign32(12345));
-    expectEquals(1, sign32(Integer.MAX_VALUE));
+
+  public static void testSignBoolean() {
+    expectEquals(0, signBoolean(false));
+    expectEquals(1, signBoolean(true));
+  }
+
+  public static void testSignByte() {
+    expectEquals(-1, signByte((byte)Byte.MIN_VALUE));
+    expectEquals(-1, signByte((byte)-64));
+    expectEquals(-1, signByte((byte)-1));
+    expectEquals(0, signByte((byte)0));
+    expectEquals(1, signByte((byte)1));
+    expectEquals(1, signByte((byte)64));
+    expectEquals(1, signByte((byte)Byte.MAX_VALUE));
+  }
+
+  public static void testSignShort() {
+    expectEquals(-1, signShort((short)Short.MIN_VALUE));
+    expectEquals(-1, signShort((short)-12345));
+    expectEquals(-1, signShort((short)-1));
+    expectEquals(0, signShort((short)0));
+    expectEquals(1, signShort((short)1));
+    expectEquals(1, signShort((short)12345));
+    expectEquals(1, signShort((short)Short.MAX_VALUE));
+  }
+
+  public static void testSignChar() {
+    expectEquals(0, signChar((char)0));
+    expectEquals(1, signChar((char)1));
+    expectEquals(1, signChar((char)12345));
+    expectEquals(1, signChar((char)Character.MAX_VALUE));
+  }
+
+  public static void testSignInt() {
+    expectEquals(-1, signInt(Integer.MIN_VALUE));
+    expectEquals(-1, signInt(-12345));
+    expectEquals(-1, signInt(-1));
+    expectEquals(0, signInt(0));
+    expectEquals(1, signInt(1));
+    expectEquals(1, signInt(12345));
+    expectEquals(1, signInt(Integer.MAX_VALUE));
 
     for (int i = -11; i <= 11; i++) {
       int expected = 0;
       if (i < 0) expected = -1;
       else if (i > 0) expected = 1;
-      expectEquals(expected, sign32(i));
+      expectEquals(expected, signInt(i));
     }
+  }
 
-    expectEquals(-1, sign64(Long.MIN_VALUE));
-    expectEquals(-1, sign64(-12345L));
-    expectEquals(-1, sign64(-1L));
-    expectEquals(0, sign64(0L));
-    expectEquals(1, sign64(1L));
-    expectEquals(1, sign64(12345L));
-    expectEquals(1, sign64(Long.MAX_VALUE));
+  public static void testSignLong() {
+    expectEquals(-1, signLong(Long.MIN_VALUE));
+    expectEquals(-1, signLong(-12345L));
+    expectEquals(-1, signLong(-1L));
+    expectEquals(0, signLong(0L));
+    expectEquals(1, signLong(1L));
+    expectEquals(1, signLong(12345L));
+    expectEquals(1, signLong(Long.MAX_VALUE));
 
-    expectEquals(-1, sign64(0x800000007FFFFFFFL));
-    expectEquals(-1, sign64(0x80000000FFFFFFFFL));
-    expectEquals(1, sign64(0x000000007FFFFFFFL));
-    expectEquals(1, sign64(0x00000000FFFFFFFFL));
-    expectEquals(1, sign64(0x7FFFFFFF7FFFFFFFL));
-    expectEquals(1, sign64(0x7FFFFFFFFFFFFFFFL));
+    expectEquals(-1, signLong(0x800000007FFFFFFFL));
+    expectEquals(-1, signLong(0x80000000FFFFFFFFL));
+    expectEquals(1, signLong(0x000000007FFFFFFFL));
+    expectEquals(1, signLong(0x00000000FFFFFFFFL));
+    expectEquals(1, signLong(0x7FFFFFFF7FFFFFFFL));
+    expectEquals(1, signLong(0x7FFFFFFFFFFFFFFFL));
 
     for (long i = -11L; i <= 11L; i++) {
       int expected = 0;
       if (i < 0) expected = -1;
       else if (i > 0) expected = 1;
-      expectEquals(expected, sign64(i));
+      expectEquals(expected, signLong(i));
     }
 
     for (long i = Long.MIN_VALUE; i <= Long.MIN_VALUE + 11L; i++) {
-      expectEquals(-1, sign64(i));
+      expectEquals(-1, signLong(i));
     }
 
     for (long i = Long.MAX_VALUE; i >= Long.MAX_VALUE - 11L; i--) {
-      expectEquals(1, sign64(i));
+      expectEquals(1, signLong(i));
     }
+  }
+
+
+  public static void main(String args[]) {
+    testSignBoolean();
+    testSignByte();
+    testSignShort();
+    testSignChar();
+    testSignInt();
+    testSignLong();
 
     System.out.println("passed");
   }
diff --git a/test/567-checker-compare/src/Main.java b/test/567-checker-compare/src/Main.java
index 951d2c7..f95ff1a 100644
--- a/test/567-checker-compare/src/Main.java
+++ b/test/567-checker-compare/src/Main.java
@@ -16,98 +16,902 @@
 
 public class Main {
 
-  /// CHECK-START: int Main.compare32(int, int) intrinsics_recognition (after)
-  /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerCompare
-  /// CHECK-DAG:                 Return [<<Result>>]
-  private static int compare32(int x, int y) {
+  /// CHECK-START: int Main.compareBooleans(boolean, boolean) intrinsics_recognition (after)
+  /// CHECK-DAG:     <<Method:[ij]\d+>> CurrentMethod
+  /// CHECK-DAG:     <<Zero:i\d+>>   IntConstant 0
+  /// CHECK-DAG:     <<One:i\d+>>    IntConstant 1
+  /// CHECK-DAG:     <<PhiX:i\d+>>   Phi [<<One>>,<<Zero>>]
+  /// CHECK-DAG:     <<PhiY:i\d+>>   Phi [<<One>>,<<Zero>>]
+  /// CHECK-DAG:     <<Result:i\d+>> InvokeStaticOrDirect [<<PhiX>>,<<PhiY>>,<<Method>>] intrinsic:IntegerCompare
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.compareBooleans(boolean, boolean) instruction_simplifier (after)
+  /// CHECK-DAG:     <<Zero:i\d+>>   IntConstant 0
+  /// CHECK-DAG:     <<One:i\d+>>    IntConstant 1
+  /// CHECK-DAG:     <<PhiX:i\d+>>   Phi [<<One>>,<<Zero>>]
+  /// CHECK-DAG:     <<PhiY:i\d+>>   Phi [<<One>>,<<Zero>>]
+  /// CHECK-DAG:     <<Result:i\d+>> Compare [<<PhiX>>,<<PhiY>>]
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.compareBooleans(boolean, boolean) instruction_simplifier (after)
+  /// CHECK-NOT:                     InvokeStaticOrDirect
+
+  /// CHECK-START: int Main.compareBooleans(boolean, boolean) select_generator (after)
+  /// CHECK:         <<ArgX:z\d+>>   ParameterValue
+  /// CHECK:         <<ArgY:z\d+>>   ParameterValue
+  /// CHECK-DAG:     <<Zero:i\d+>>   IntConstant 0
+  /// CHECK-DAG:     <<One:i\d+>>    IntConstant 1
+  /// CHECK-DAG:     <<SelX:i\d+>>   Select [<<Zero>>,<<One>>,<<ArgX>>]
+  /// CHECK-DAG:     <<SelY:i\d+>>   Select [<<Zero>>,<<One>>,<<ArgY>>]
+  /// CHECK-DAG:     <<Result:i\d+>> Compare [<<SelX>>,<<SelY>>]
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.compareBooleans(boolean, boolean) select_generator (after)
+  /// CHECK-NOT:                     Phi
+
+  /// CHECK-START: int Main.compareBooleans(boolean, boolean) instruction_simplifier_after_bce (after)
+  /// CHECK:         <<ArgX:z\d+>>   ParameterValue
+  /// CHECK:         <<ArgY:z\d+>>   ParameterValue
+  /// CHECK-DAG:     <<Result:i\d+>> Compare [<<ArgX>>,<<ArgY>>]
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.compareBooleans(boolean, boolean) instruction_simplifier_after_bce (after)
+  /// CHECK-NOT:                     Select
+
+  private static int compareBooleans(boolean x, boolean y) {
+    return Integer.compare((x ? 1 : 0), (y ? 1 : 0));
+  }
+
+  /// CHECK-START: int Main.compareBytes(byte, byte) intrinsics_recognition (after)
+  /// CHECK-DAG:     <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerCompare
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.compareBytes(byte, byte) instruction_simplifier (after)
+  /// CHECK-DAG:     <<Result:i\d+>> Compare
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.compareBytes(byte, byte) instruction_simplifier (after)
+  /// CHECK-NOT:                     InvokeStaticOrDirect
+
+  private static int compareBytes(byte x, byte y) {
     return Integer.compare(x, y);
   }
 
-  /// CHECK-START: int Main.compare64(long, long) intrinsics_recognition (after)
-  /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:LongCompare
-  /// CHECK-DAG:                 Return [<<Result>>]
-  private static int compare64(long x, long y) {
+  /// CHECK-START: int Main.compareShorts(short, short) intrinsics_recognition (after)
+  /// CHECK-DAG:     <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerCompare
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.compareShorts(short, short) instruction_simplifier (after)
+  /// CHECK-DAG:     <<Result:i\d+>> Compare
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.compareShorts(short, short) instruction_simplifier (after)
+  /// CHECK-NOT:                     InvokeStaticOrDirect
+
+  private static int compareShorts(short x, short y) {
+    return Integer.compare(x, y);
+  }
+
+  /// CHECK-START: int Main.compareChars(char, char) intrinsics_recognition (after)
+  /// CHECK-DAG:     <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerCompare
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.compareChars(char, char) instruction_simplifier (after)
+  /// CHECK-DAG:     <<Result:i\d+>> Compare
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.compareChars(char, char) instruction_simplifier (after)
+  /// CHECK-NOT:                     InvokeStaticOrDirect
+
+  private static int compareChars(char x, char y) {
+    return Integer.compare(x, y);
+  }
+
+  /// CHECK-START: int Main.compareInts(int, int) intrinsics_recognition (after)
+  /// CHECK-DAG:     <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerCompare
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.compareInts(int, int) instruction_simplifier (after)
+  /// CHECK-DAG:     <<Result:i\d+>> Compare
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.compareInts(int, int) instruction_simplifier (after)
+  /// CHECK-NOT:                     InvokeStaticOrDirect
+
+  private static int compareInts(int x, int y) {
+    return Integer.compare(x, y);
+  }
+
+  /// CHECK-START: int Main.compareLongs(long, long) intrinsics_recognition (after)
+  /// CHECK-DAG:     <<Result:i\d+>> InvokeStaticOrDirect intrinsic:LongCompare
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.compareLongs(long, long) instruction_simplifier (after)
+  /// CHECK-DAG:     <<Result:i\d+>> Compare
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.compareLongs(long, long) instruction_simplifier (after)
+  /// CHECK-NOT:                     InvokeStaticOrDirect
+
+  private static int compareLongs(long x, long y) {
     return Long.compare(x, y);
   }
 
-  public static void main(String args[]) {
-    expectEquals(-1, compare32(Integer.MIN_VALUE, Integer.MIN_VALUE + 1));
-    expectEquals(-1, compare32(Integer.MIN_VALUE, -1));
-    expectEquals(-1, compare32(Integer.MIN_VALUE, 0));
-    expectEquals(-1, compare32(Integer.MIN_VALUE, 1));
-    expectEquals(-1, compare32(Integer.MIN_VALUE, Integer.MAX_VALUE));
-    expectEquals(-1, compare32(-1, 0));
-    expectEquals(-1, compare32(-1, 1));
-    expectEquals(-1, compare32(0, 1));
 
-    expectEquals(0, compare32(Integer.MIN_VALUE, Integer.MIN_VALUE));
-    expectEquals(0, compare32(-1, -1));
-    expectEquals(0, compare32(0, 0));
-    expectEquals(0, compare32(1, 1));
-    expectEquals(0, compare32(Integer.MAX_VALUE, Integer.MAX_VALUE));
+  /// CHECK-START: int Main.compareByteShort(byte, short) intrinsics_recognition (after)
+  /// CHECK-DAG:     <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerCompare
+  /// CHECK-DAG:                     Return [<<Result>>]
 
-    expectEquals(1, compare32(0, -1));
-    expectEquals(1, compare32(1, -1));
-    expectEquals(1, compare32(1, 0));
-    expectEquals(1, compare32(Integer.MAX_VALUE, Integer.MIN_VALUE));
-    expectEquals(1, compare32(Integer.MAX_VALUE, -1));
-    expectEquals(1, compare32(Integer.MAX_VALUE, 0));
-    expectEquals(1, compare32(Integer.MAX_VALUE, 1));
-    expectEquals(1, compare32(Integer.MAX_VALUE, Integer.MAX_VALUE - 1));
+  /// CHECK-START: int Main.compareByteShort(byte, short) instruction_simplifier (after)
+  /// CHECK-DAG:     <<Result:i\d+>> Compare
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.compareByteShort(byte, short) instruction_simplifier (after)
+  /// CHECK-NOT:                     InvokeStaticOrDirect
+
+  public static int compareByteShort(byte x, short y) {
+    return Integer.compare(x, y);
+  }
+
+  /// CHECK-START: int Main.compareByteChar(byte, char) intrinsics_recognition (after)
+  /// CHECK-DAG:     <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerCompare
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.compareByteChar(byte, char) instruction_simplifier (after)
+  /// CHECK-DAG:     <<Result:i\d+>> Compare
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.compareByteChar(byte, char) instruction_simplifier (after)
+  /// CHECK-NOT:                     InvokeStaticOrDirect
+
+  public static int compareByteChar(byte x, char y) {
+    return Integer.compare(x, y);
+  }
+
+  /// CHECK-START: int Main.compareByteInt(byte, int) intrinsics_recognition (after)
+  /// CHECK-DAG:     <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerCompare
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.compareByteInt(byte, int) instruction_simplifier (after)
+  /// CHECK-DAG:     <<Result:i\d+>> Compare
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.compareByteInt(byte, int) instruction_simplifier (after)
+  /// CHECK-NOT:                     InvokeStaticOrDirect
+
+  public static int compareByteInt(byte x, int y) {
+    return Integer.compare(x, y);
+  }
+
+
+  /// CHECK-START: int Main.compareShortByte(short, byte) intrinsics_recognition (after)
+  /// CHECK-DAG:     <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerCompare
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.compareShortByte(short, byte) instruction_simplifier (after)
+  /// CHECK-DAG:     <<Result:i\d+>> Compare
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.compareShortByte(short, byte) instruction_simplifier (after)
+  /// CHECK-NOT:                     InvokeStaticOrDirect
+
+  public static int compareShortByte(short x, byte y) {
+    return Integer.compare(x, y);
+  }
+
+  /// CHECK-START: int Main.compareShortChar(short, char) intrinsics_recognition (after)
+  /// CHECK-DAG:     <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerCompare
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.compareShortChar(short, char) instruction_simplifier (after)
+  /// CHECK-DAG:     <<Result:i\d+>> Compare
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.compareShortChar(short, char) instruction_simplifier (after)
+  /// CHECK-NOT:                     InvokeStaticOrDirect
+
+  public static int compareShortChar(short x, char y) {
+    return Integer.compare(x, y);
+  }
+
+  /// CHECK-START: int Main.compareShortInt(short, int) intrinsics_recognition (after)
+  /// CHECK-DAG:     <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerCompare
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.compareShortInt(short, int) instruction_simplifier (after)
+  /// CHECK-DAG:     <<Result:i\d+>> Compare
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.compareShortInt(short, int) instruction_simplifier (after)
+  /// CHECK-NOT:                     InvokeStaticOrDirect
+
+  public static int compareShortInt(short x, int y) {
+    return Integer.compare(x, y);
+  }
+
+
+  /// CHECK-START: int Main.compareCharByte(char, byte) intrinsics_recognition (after)
+  /// CHECK-DAG:     <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerCompare
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.compareCharByte(char, byte) instruction_simplifier (after)
+  /// CHECK-DAG:     <<Result:i\d+>> Compare
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.compareCharByte(char, byte) instruction_simplifier (after)
+  /// CHECK-NOT:                     InvokeStaticOrDirect
+
+  public static int compareCharByte(char x, byte y) {
+    return Integer.compare(x, y);
+  }
+
+  /// CHECK-START: int Main.compareCharShort(char, short) intrinsics_recognition (after)
+  /// CHECK-DAG:     <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerCompare
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.compareCharShort(char, short) instruction_simplifier (after)
+  /// CHECK-DAG:     <<Result:i\d+>> Compare
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.compareCharShort(char, short) instruction_simplifier (after)
+  /// CHECK-NOT:                     InvokeStaticOrDirect
+
+  public static int compareCharShort(char x, short y) {
+    return Integer.compare(x, y);
+  }
+
+  /// CHECK-START: int Main.compareCharInt(char, int) intrinsics_recognition (after)
+  /// CHECK-DAG:     <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerCompare
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.compareCharInt(char, int) instruction_simplifier (after)
+  /// CHECK-DAG:     <<Result:i\d+>> Compare
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.compareCharInt(char, int) instruction_simplifier (after)
+  /// CHECK-NOT:                     InvokeStaticOrDirect
+
+  public static int compareCharInt(char x, int y) {
+    return Integer.compare(x, y);
+  }
+
+
+  /// CHECK-START: int Main.compareIntByte(int, byte) intrinsics_recognition (after)
+  /// CHECK-DAG:     <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerCompare
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.compareIntByte(int, byte) instruction_simplifier (after)
+  /// CHECK-DAG:     <<Result:i\d+>> Compare
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.compareIntByte(int, byte) instruction_simplifier (after)
+  /// CHECK-NOT:                     InvokeStaticOrDirect
+
+  public static int compareIntByte(int x, byte y) {
+    return Integer.compare(x, y);
+  }
+
+  /// CHECK-START: int Main.compareIntShort(int, short) intrinsics_recognition (after)
+  /// CHECK-DAG:     <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerCompare
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.compareIntShort(int, short) instruction_simplifier (after)
+  /// CHECK-DAG:     <<Result:i\d+>> Compare
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.compareIntShort(int, short) instruction_simplifier (after)
+  /// CHECK-NOT:                     InvokeStaticOrDirect
+
+  public static int compareIntShort(int x, short y) {
+    return Integer.compare(x, y);
+  }
+
+  /// CHECK-START: int Main.compareIntChar(int, char) intrinsics_recognition (after)
+  /// CHECK-DAG:     <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerCompare
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.compareIntChar(int, char) instruction_simplifier (after)
+  /// CHECK-DAG:     <<Result:i\d+>> Compare
+  /// CHECK-DAG:                     Return [<<Result>>]
+
+  /// CHECK-START: int Main.compareIntChar(int, char) instruction_simplifier (after)
+  /// CHECK-NOT:                     InvokeStaticOrDirect
+
+  public static int compareIntChar(int x, char y) {
+    return Integer.compare(x, y);
+  }
+
+
+  public static void testCompareBooleans() {
+    expectEquals(-1, compareBooleans(false, true));
+
+    expectEquals(0, compareBooleans(false, false));
+    expectEquals(0, compareBooleans(true, true));
+
+    expectEquals(1, compareBooleans(true, false));
+  }
+
+  public static void testCompareBytes() {
+    expectEquals(-1, compareBytes(Byte.MIN_VALUE, (byte)(Byte.MIN_VALUE + 1)));
+    expectEquals(-1, compareBytes(Byte.MIN_VALUE, (byte)-1));
+    expectEquals(-1, compareBytes(Byte.MIN_VALUE, (byte)0));
+    expectEquals(-1, compareBytes(Byte.MIN_VALUE, (byte)1));
+    expectEquals(-1, compareBytes(Byte.MIN_VALUE, Byte.MAX_VALUE));
+    expectEquals(-1, compareBytes((byte)-1, (byte)0));
+    expectEquals(-1, compareBytes((byte)-1, (byte)1));
+    expectEquals(-1, compareBytes((byte)0, (byte)1));
+
+    expectEquals(0, compareBytes(Byte.MIN_VALUE, Byte.MIN_VALUE));
+    expectEquals(0, compareBytes((byte)-1, (byte)-1));
+    expectEquals(0, compareBytes((byte)0, (byte)0));
+    expectEquals(0, compareBytes((byte)1, (byte)1));
+    expectEquals(0, compareBytes(Byte.MAX_VALUE, Byte.MAX_VALUE));
+
+    expectEquals(1, compareBytes((byte)0, (byte)-1));
+    expectEquals(1, compareBytes((byte)1, (byte)-1));
+    expectEquals(1, compareBytes((byte)1, (byte)0));
+    expectEquals(1, compareBytes(Byte.MAX_VALUE, Byte.MIN_VALUE));
+    expectEquals(1, compareBytes(Byte.MAX_VALUE, (byte)-1));
+    expectEquals(1, compareBytes(Byte.MAX_VALUE, (byte)0));
+    expectEquals(1, compareBytes(Byte.MAX_VALUE, (byte)1));
+    expectEquals(1, compareBytes(Byte.MAX_VALUE, (byte)(Byte.MAX_VALUE - 1)));
+
+    for (byte i = -11; i <= 11; i++) {
+      for (byte j = -11; j <= 11; j++) {
+        int expected = 0;
+        if (i < j) expected = -1;
+        else if (i > j) expected = 1;
+        expectEquals(expected, compareBytes(i, j));
+      }
+    }
+  }
+
+  public static void testCompareShorts() {
+    expectEquals(-1, compareShorts(Short.MIN_VALUE, (short)(Short.MIN_VALUE + 1)));
+    expectEquals(-1, compareShorts(Short.MIN_VALUE, (short)-1));
+    expectEquals(-1, compareShorts(Short.MIN_VALUE, (short)0));
+    expectEquals(-1, compareShorts(Short.MIN_VALUE, (short)1));
+    expectEquals(-1, compareShorts(Short.MIN_VALUE, (short)Short.MAX_VALUE));
+    expectEquals(-1, compareShorts((short)-1, (short)0));
+    expectEquals(-1, compareShorts((short)-1, (short)1));
+    expectEquals(-1, compareShorts((short)0, (short)1));
+
+    expectEquals(0, compareShorts(Short.MIN_VALUE, Short.MIN_VALUE));
+    expectEquals(0, compareShorts((short)-1, (short)-1));
+    expectEquals(0, compareShorts((short)0, (short)0));
+    expectEquals(0, compareShorts((short)1, (short)1));
+    expectEquals(0, compareShorts(Short.MAX_VALUE, Short.MAX_VALUE));
+
+    expectEquals(1, compareShorts((short)0, (short)-1));
+    expectEquals(1, compareShorts((short)1, (short)-1));
+    expectEquals(1, compareShorts((short)1, (short)0));
+    expectEquals(1, compareShorts(Short.MAX_VALUE, Short.MIN_VALUE));
+    expectEquals(1, compareShorts(Short.MAX_VALUE, (short)-1));
+    expectEquals(1, compareShorts(Short.MAX_VALUE, (short)0));
+    expectEquals(1, compareShorts(Short.MAX_VALUE, (short)1));
+    expectEquals(1, compareShorts(Short.MAX_VALUE, (short)(Short.MAX_VALUE - 1)));
+
+    for (short i = -11; i <= 11; i++) {
+      for (short j = -11; j <= 11; j++) {
+        int expected = 0;
+        if (i < j) expected = -1;
+        else if (i > j) expected = 1;
+        expectEquals(expected, compareShorts(i, j));
+      }
+    }
+  }
+
+  public static void testCompareChars() {
+    expectEquals(-1, compareChars((char)0, Character.MAX_VALUE));
+    expectEquals(-1, compareChars((char)0, (char)1));
+
+    expectEquals(0, compareChars((char)0, (char)0));
+    expectEquals(0, compareChars((char)1, (char)1));
+    expectEquals(0, compareChars(Character.MAX_VALUE, Character.MAX_VALUE));
+
+    expectEquals(1, compareChars((char)1, (char)0));
+    expectEquals(1, compareChars(Character.MAX_VALUE, (char)0));
+    expectEquals(1, compareChars(Character.MAX_VALUE, (char)1));
+    expectEquals(1, compareChars(Character.MAX_VALUE, (char)(Character.MAX_VALUE - 1)));
+
+    for (char i = 0; i <= 11; i++) {
+      for (char j = 0; j <= 11; j++) {
+        int expected = 0;
+        if (i < j) expected = -1;
+        else if (i > j) expected = 1;
+        expectEquals(expected, compareChars(i, j));
+      }
+    }
+  }
+
+  public static void testCompareInts() {
+    expectEquals(-1, compareInts(Integer.MIN_VALUE, Integer.MIN_VALUE + 1));
+    expectEquals(-1, compareInts(Integer.MIN_VALUE, -1));
+    expectEquals(-1, compareInts(Integer.MIN_VALUE, 0));
+    expectEquals(-1, compareInts(Integer.MIN_VALUE, 1));
+    expectEquals(-1, compareInts(Integer.MIN_VALUE, Integer.MAX_VALUE));
+    expectEquals(-1, compareInts(-1, 0));
+    expectEquals(-1, compareInts(-1, 1));
+    expectEquals(-1, compareInts(0, 1));
+
+    expectEquals(0, compareInts(Integer.MIN_VALUE, Integer.MIN_VALUE));
+    expectEquals(0, compareInts(-1, -1));
+    expectEquals(0, compareInts(0, 0));
+    expectEquals(0, compareInts(1, 1));
+    expectEquals(0, compareInts(Integer.MAX_VALUE, Integer.MAX_VALUE));
+
+    expectEquals(1, compareInts(0, -1));
+    expectEquals(1, compareInts(1, -1));
+    expectEquals(1, compareInts(1, 0));
+    expectEquals(1, compareInts(Integer.MAX_VALUE, Integer.MIN_VALUE));
+    expectEquals(1, compareInts(Integer.MAX_VALUE, -1));
+    expectEquals(1, compareInts(Integer.MAX_VALUE, 0));
+    expectEquals(1, compareInts(Integer.MAX_VALUE, 1));
+    expectEquals(1, compareInts(Integer.MAX_VALUE, Integer.MAX_VALUE - 1));
 
     for (int i = -11; i <= 11; i++) {
       for (int j = -11; j <= 11; j++) {
         int expected = 0;
         if (i < j) expected = -1;
         else if (i > j) expected = 1;
-        expectEquals(expected, compare32(i, j));
+        expectEquals(expected, compareInts(i, j));
       }
     }
+  }
 
-    expectEquals(-1, compare64(Long.MIN_VALUE, Long.MIN_VALUE + 1L));
-    expectEquals(-1, compare64(Long.MIN_VALUE, -1L));
-    expectEquals(-1, compare64(Long.MIN_VALUE, 0L));
-    expectEquals(-1, compare64(Long.MIN_VALUE, 1L));
-    expectEquals(-1, compare64(Long.MIN_VALUE, Long.MAX_VALUE));
-    expectEquals(-1, compare64(-1L, 0L));
-    expectEquals(-1, compare64(-1L, 1L));
-    expectEquals(-1, compare64(0L, 1L));
+  public static void testCompareLongs() {
+    expectEquals(-1, compareLongs(Long.MIN_VALUE, Long.MIN_VALUE + 1L));
+    expectEquals(-1, compareLongs(Long.MIN_VALUE, -1L));
+    expectEquals(-1, compareLongs(Long.MIN_VALUE, 0L));
+    expectEquals(-1, compareLongs(Long.MIN_VALUE, 1L));
+    expectEquals(-1, compareLongs(Long.MIN_VALUE, Long.MAX_VALUE));
+    expectEquals(-1, compareLongs(-1L, 0L));
+    expectEquals(-1, compareLongs(-1L, 1L));
+    expectEquals(-1, compareLongs(0L, 1L));
 
-    expectEquals(0, compare64(Long.MIN_VALUE, Long.MIN_VALUE));
-    expectEquals(0, compare64(-1L, -1L));
-    expectEquals(0, compare64(0L, 0L));
-    expectEquals(0, compare64(1L, 1L));
-    expectEquals(0, compare64(Long.MAX_VALUE, Long.MAX_VALUE));
+    expectEquals(0, compareLongs(Long.MIN_VALUE, Long.MIN_VALUE));
+    expectEquals(0, compareLongs(-1L, -1L));
+    expectEquals(0, compareLongs(0L, 0L));
+    expectEquals(0, compareLongs(1L, 1L));
+    expectEquals(0, compareLongs(Long.MAX_VALUE, Long.MAX_VALUE));
 
-    expectEquals(1, compare64(0L, -1L));
-    expectEquals(1, compare64(1L, -1L));
-    expectEquals(1, compare64(1L, 0L));
-    expectEquals(1, compare64(Long.MAX_VALUE, Long.MIN_VALUE));
-    expectEquals(1, compare64(Long.MAX_VALUE, -1L));
-    expectEquals(1, compare64(Long.MAX_VALUE, 0L));
-    expectEquals(1, compare64(Long.MAX_VALUE, 1L));
-    expectEquals(1, compare64(Long.MAX_VALUE, Long.MAX_VALUE - 1L));
+    expectEquals(1, compareLongs(0L, -1L));
+    expectEquals(1, compareLongs(1L, -1L));
+    expectEquals(1, compareLongs(1L, 0L));
+    expectEquals(1, compareLongs(Long.MAX_VALUE, Long.MIN_VALUE));
+    expectEquals(1, compareLongs(Long.MAX_VALUE, -1L));
+    expectEquals(1, compareLongs(Long.MAX_VALUE, 0L));
+    expectEquals(1, compareLongs(Long.MAX_VALUE, 1L));
+    expectEquals(1, compareLongs(Long.MAX_VALUE, Long.MAX_VALUE - 1L));
 
-    expectEquals(-1, compare64(0x111111117FFFFFFFL, 0x11111111FFFFFFFFL));
-    expectEquals(0, compare64(0x111111117FFFFFFFL, 0x111111117FFFFFFFL));
-    expectEquals(1, compare64(0x11111111FFFFFFFFL, 0x111111117FFFFFFFL));
+    expectEquals(-1, compareLongs(0x111111117FFFFFFFL, 0x11111111FFFFFFFFL));
+    expectEquals(0, compareLongs(0x111111117FFFFFFFL, 0x111111117FFFFFFFL));
+    expectEquals(1, compareLongs(0x11111111FFFFFFFFL, 0x111111117FFFFFFFL));
 
     for (long i = -11L; i <= 11L; i++) {
       for (long j = -11L; j <= 11L; j++) {
         int expected = 0;
         if (i < j) expected = -1;
         else if (i > j) expected = 1;
-        expectEquals(expected, compare64(i, j));
+        expectEquals(expected, compareLongs(i, j));
       }
     }
 
     for (long i = Long.MIN_VALUE; i <= Long.MIN_VALUE + 11L; i++) {
-      expectEquals(-1, compare64(i, 0));
+      expectEquals(-1, compareLongs(i, 0));
     }
 
     for (long i = Long.MAX_VALUE; i >= Long.MAX_VALUE - 11L; i--) {
-      expectEquals(1, compare64(i, 0));
+      expectEquals(1, compareLongs(i, 0));
     }
+  }
+
+
+  public static void testCompareByteShort() {
+    expectEquals(-1, compareByteShort(Byte.MIN_VALUE, (short)-1));
+    expectEquals(-1, compareByteShort(Byte.MIN_VALUE, (short)0));
+    expectEquals(-1, compareByteShort(Byte.MIN_VALUE, (short)1));
+    expectEquals(-1, compareByteShort(Byte.MIN_VALUE, Short.MAX_VALUE));
+    expectEquals(-1, compareByteShort((byte)-1, (short)0));
+    expectEquals(-1, compareByteShort((byte)-1, (short)1));
+    expectEquals(-1, compareByteShort((byte)0, (short)1));
+    expectEquals(-1, compareByteShort(Byte.MAX_VALUE, (short)(Short.MAX_VALUE - 1)));
+    expectEquals(-1, compareByteShort(Byte.MAX_VALUE, Short.MAX_VALUE));
+
+    expectEquals(0, compareByteShort((byte)-1, (short)-1));
+    expectEquals(0, compareByteShort((byte)0, (short)0));
+    expectEquals(0, compareByteShort((byte)1, (short)1));
+
+    expectEquals(1, compareByteShort(Byte.MIN_VALUE, Short.MIN_VALUE));
+    expectEquals(1, compareByteShort(Byte.MIN_VALUE, (short)(Short.MIN_VALUE + 1)));
+    expectEquals(1, compareByteShort((byte)0, (short)-1));
+    expectEquals(1, compareByteShort((byte)1, (short)-1));
+    expectEquals(1, compareByteShort((byte)1, (short)0));
+    expectEquals(1, compareByteShort(Byte.MAX_VALUE, Short.MIN_VALUE));
+    expectEquals(1, compareByteShort(Byte.MAX_VALUE, (short)-1));
+    expectEquals(1, compareByteShort(Byte.MAX_VALUE, (short)0));
+    expectEquals(1, compareByteShort(Byte.MAX_VALUE, (short)1));
+
+    for (byte i = -11; i <= 11; i++) {
+      for (short j = -11; j <= 11; j++) {
+        int expected = 0;
+        if (i < j) expected = -1;
+        else if (i > j) expected = 1;
+        expectEquals(expected, compareByteShort(i, j));
+      }
+    }
+  }
+
+  public static void testCompareByteChar() {
+    expectEquals(-1, compareByteChar(Byte.MIN_VALUE, (char)0));
+    expectEquals(-1, compareByteChar(Byte.MIN_VALUE, (char)1));
+    expectEquals(-1, compareByteChar(Byte.MIN_VALUE, Character.MAX_VALUE));
+    expectEquals(-1, compareByteChar((byte)-1, (char)0));
+    expectEquals(-1, compareByteChar((byte)-1, (char)1));
+    expectEquals(-1, compareByteChar((byte)0, (char)1));
+    expectEquals(-1, compareByteChar(Byte.MAX_VALUE, (char)(Character.MAX_VALUE - 1)));
+    expectEquals(-1, compareByteChar(Byte.MAX_VALUE, Character.MAX_VALUE));
+
+    expectEquals(0, compareByteChar((byte)0, (char)0));
+    expectEquals(0, compareByteChar((byte)1, (char)1));
+
+    expectEquals(1, compareByteChar((byte)1, (char)0));
+    expectEquals(1, compareByteChar(Byte.MAX_VALUE, (char)0));
+    expectEquals(1, compareByteChar(Byte.MAX_VALUE, (char)1));
+
+    for (byte i = -11; i <= 11; i++) {
+      for (char j = 0; j <= 11; j++) {
+        int expected = 0;
+        if (i < j) expected = -1;
+        else if (i > j) expected = 1;
+        expectEquals(expected, compareByteChar(i, j));
+      }
+    }
+  }
+
+  public static void testCompareByteInt() {
+    expectEquals(-1, compareByteInt(Byte.MIN_VALUE, -1));
+    expectEquals(-1, compareByteInt(Byte.MIN_VALUE, 0));
+    expectEquals(-1, compareByteInt(Byte.MIN_VALUE, 1));
+    expectEquals(-1, compareByteInt(Byte.MIN_VALUE, Integer.MAX_VALUE));
+    expectEquals(-1, compareByteInt((byte)-1, 0));
+    expectEquals(-1, compareByteInt((byte)-1, 1));
+    expectEquals(-1, compareByteInt((byte)0, 1));
+    expectEquals(-1, compareByteInt(Byte.MAX_VALUE, Integer.MAX_VALUE - 1));
+    expectEquals(-1, compareByteInt(Byte.MAX_VALUE, Integer.MAX_VALUE));
+
+    expectEquals(0, compareByteInt((byte)-1, -1));
+    expectEquals(0, compareByteInt((byte)0, 0));
+    expectEquals(0, compareByteInt((byte)1, 1));
+
+    expectEquals(1, compareByteInt(Byte.MIN_VALUE, Integer.MIN_VALUE));
+    expectEquals(1, compareByteInt(Byte.MIN_VALUE, Integer.MIN_VALUE + 1));
+    expectEquals(1, compareByteInt((byte)0, -1));
+    expectEquals(1, compareByteInt((byte)1, -1));
+    expectEquals(1, compareByteInt((byte)1, 0));
+    expectEquals(1, compareByteInt(Byte.MAX_VALUE, Integer.MIN_VALUE));
+    expectEquals(1, compareByteInt(Byte.MAX_VALUE, -1));
+    expectEquals(1, compareByteInt(Byte.MAX_VALUE, 0));
+    expectEquals(1, compareByteInt(Byte.MAX_VALUE, 1));
+
+    for (byte i = -11; i <= 11; i++) {
+      for (int j = -11; j <= 11; j++) {
+        int expected = 0;
+        if (i < j) expected = -1;
+        else if (i > j) expected = 1;
+        expectEquals(expected, compareByteInt(i, j));
+      }
+    }
+  }
+
+
+  public static void testCompareShortByte() {
+    expectEquals(-1, compareShortByte(Short.MIN_VALUE, Byte.MIN_VALUE));
+    expectEquals(-1, compareShortByte(Short.MIN_VALUE, (byte)(Byte.MIN_VALUE + 1)));
+    expectEquals(-1, compareShortByte(Short.MIN_VALUE, (byte)-1));
+    expectEquals(-1, compareShortByte(Short.MIN_VALUE, (byte)0));
+    expectEquals(-1, compareShortByte(Short.MIN_VALUE, (byte)1));
+    expectEquals(-1, compareShortByte(Short.MIN_VALUE, Byte.MAX_VALUE));
+    expectEquals(-1, compareShortByte((short)-1, (byte)0));
+    expectEquals(-1, compareShortByte((short)-1, (byte)1));
+    expectEquals(-1, compareShortByte((short)0, (byte)1));
+
+    expectEquals(0, compareShortByte((short)-1, (byte)-1));
+    expectEquals(0, compareShortByte((short)0, (byte)0));
+    expectEquals(0, compareShortByte((short)1, (byte)1));
+
+    expectEquals(1, compareShortByte((short)0, (byte)-1));
+    expectEquals(1, compareShortByte((short)1, (byte)-1));
+    expectEquals(1, compareShortByte((short)1, (byte)0));
+    expectEquals(1, compareShortByte(Short.MAX_VALUE, Byte.MIN_VALUE));
+    expectEquals(1, compareShortByte(Short.MAX_VALUE, (byte)-1));
+    expectEquals(1, compareShortByte(Short.MAX_VALUE, (byte)0));
+    expectEquals(1, compareShortByte(Short.MAX_VALUE, (byte)1));
+    expectEquals(1, compareShortByte(Short.MAX_VALUE, (byte)(Byte.MAX_VALUE - 1)));
+    expectEquals(1, compareShortByte(Short.MAX_VALUE, Byte.MAX_VALUE));
+
+    for (short i = -11; i <= 11; i++) {
+      for (byte j = -11; j <= 11; j++) {
+        int expected = 0;
+        if (i < j) expected = -1;
+        else if (i > j) expected = 1;
+        expectEquals(expected, compareShortByte(i, j));
+      }
+    }
+  }
+
+  public static void testCompareShortChar() {
+    expectEquals(-1, compareShortChar(Short.MIN_VALUE, (char)0));
+    expectEquals(-1, compareShortChar(Short.MIN_VALUE, (char)1));
+    expectEquals(-1, compareShortChar(Short.MIN_VALUE, Character.MAX_VALUE));
+    expectEquals(-1, compareShortChar((short)-1, (char)0));
+    expectEquals(-1, compareShortChar((short)-1, (char)1));
+    expectEquals(-1, compareShortChar((short)0, (char)1));
+    expectEquals(-1, compareShortChar(Short.MAX_VALUE, (char)(Character.MAX_VALUE - 1)));
+    expectEquals(-1, compareShortChar(Short.MAX_VALUE, Character.MAX_VALUE));
+
+    expectEquals(0, compareShortChar((short)0, (char)0));
+    expectEquals(0, compareShortChar((short)1, (char)1));
+
+    expectEquals(1, compareShortChar((short)1, (char)0));
+    expectEquals(1, compareShortChar(Short.MAX_VALUE, (char)0));
+    expectEquals(1, compareShortChar(Short.MAX_VALUE, (char)1));
+
+    for (short i = -11; i <= 11; i++) {
+      for (char j = 0; j <= 11; j++) {
+        int expected = 0;
+        if (i < j) expected = -1;
+        else if (i > j) expected = 1;
+        expectEquals(expected, compareShortChar(i, j));
+      }
+    }
+  }
+
+  public static void testCompareShortInt() {
+    expectEquals(-1, compareShortInt(Short.MIN_VALUE, -1));
+    expectEquals(-1, compareShortInt(Short.MIN_VALUE, 0));
+    expectEquals(-1, compareShortInt(Short.MIN_VALUE, 1));
+    expectEquals(-1, compareShortInt(Short.MIN_VALUE, Integer.MAX_VALUE));
+    expectEquals(-1, compareShortInt((short)-1, 0));
+    expectEquals(-1, compareShortInt((short)-1, 1));
+    expectEquals(-1, compareShortInt((short)0, 1));
+    expectEquals(-1, compareShortInt(Short.MAX_VALUE, Integer.MAX_VALUE - 1));
+    expectEquals(-1, compareShortInt(Short.MAX_VALUE, Integer.MAX_VALUE));
+
+    expectEquals(0, compareShortInt((short)-1, -1));
+    expectEquals(0, compareShortInt((short)0, 0));
+    expectEquals(0, compareShortInt((short)1, 1));
+
+    expectEquals(1, compareShortInt(Short.MIN_VALUE, Integer.MIN_VALUE));
+    expectEquals(1, compareShortInt(Short.MIN_VALUE, Integer.MIN_VALUE + 1));
+    expectEquals(1, compareShortInt((short)0, -1));
+    expectEquals(1, compareShortInt((short)1, -1));
+    expectEquals(1, compareShortInt((short)1, 0));
+    expectEquals(1, compareShortInt(Short.MAX_VALUE, Integer.MIN_VALUE));
+    expectEquals(1, compareShortInt(Short.MAX_VALUE, -1));
+    expectEquals(1, compareShortInt(Short.MAX_VALUE, 0));
+    expectEquals(1, compareShortInt(Short.MAX_VALUE, 1));
+
+    for (short i = -11; i <= 11; i++) {
+      for (int j = -11; j <= 11; j++) {
+        int expected = 0;
+        if (i < j) expected = -1;
+        else if (i > j) expected = 1;
+        expectEquals(expected, compareShortInt(i, j));
+      }
+    }
+  }
+
+
+  public static void testCompareCharByte() {
+    expectEquals(-1, compareCharByte((char)0, (byte)1));
+    expectEquals(-1, compareCharByte((char)0, Byte.MAX_VALUE));
+
+    expectEquals(0, compareCharByte((char)0, (byte)0));
+    expectEquals(0, compareCharByte((char)1, (byte)1));
+
+    expectEquals(1, compareCharByte((char)0, Byte.MIN_VALUE));
+    expectEquals(1, compareCharByte((char)0, (byte)(Byte.MIN_VALUE + 1)));
+    expectEquals(1, compareCharByte((char)0, (byte)-1));
+    expectEquals(1, compareCharByte((char)1, (byte)-1));
+    expectEquals(1, compareCharByte((char)1, (byte)0));
+    expectEquals(1, compareCharByte(Character.MAX_VALUE, Byte.MIN_VALUE));
+    expectEquals(1, compareCharByte(Character.MAX_VALUE, (byte)-1));
+    expectEquals(1, compareCharByte(Character.MAX_VALUE, (byte)0));
+    expectEquals(1, compareCharByte(Character.MAX_VALUE, (byte)1));
+    expectEquals(1, compareCharByte(Character.MAX_VALUE, (byte)(Byte.MAX_VALUE - 1)));
+    expectEquals(1, compareCharByte(Character.MAX_VALUE, Byte.MAX_VALUE));
+
+    for (char i = 0; i <= 11; i++) {
+      for (byte j = -11; j <= 11; j++) {
+        int expected = 0;
+        if (i < j) expected = -1;
+        else if (i > j) expected = 1;
+        expectEquals(expected, compareCharByte(i, j));
+      }
+    }
+  }
+
+  public static void testCompareCharShort() {
+    expectEquals(-1, compareCharShort((char)0, (short)1));
+    expectEquals(-1, compareCharShort((char)0, Short.MAX_VALUE));
+
+    expectEquals(0, compareCharShort((char)0, (short)0));
+    expectEquals(0, compareCharShort((char)1, (short)1));
+
+    expectEquals(1, compareCharShort((char)0, Short.MIN_VALUE));
+    expectEquals(1, compareCharShort((char)0, (short)(Short.MIN_VALUE + 1)));
+    expectEquals(1, compareCharShort((char)0, (short)-1));
+    expectEquals(1, compareCharShort((char)1, (short)-1));
+    expectEquals(1, compareCharShort((char)1, (short)0));
+    expectEquals(1, compareCharShort(Character.MAX_VALUE, Short.MIN_VALUE));
+    expectEquals(1, compareCharShort(Character.MAX_VALUE, (short)-1));
+    expectEquals(1, compareCharShort(Character.MAX_VALUE, (short)0));
+    expectEquals(1, compareCharShort(Character.MAX_VALUE, (short)1));
+    expectEquals(1, compareCharShort(Character.MAX_VALUE, (short)(Short.MAX_VALUE - 1)));
+    expectEquals(1, compareCharShort(Character.MAX_VALUE, Short.MAX_VALUE));
+
+    for (char i = 0; i <= 11; i++) {
+      for (short j = -11; j <= 11; j++) {
+        int expected = 0;
+        if (i < j) expected = -1;
+        else if (i > j) expected = 1;
+        expectEquals(expected, compareCharShort(i, j));
+      }
+    }
+  }
+
+  public static void testCompareCharInt() {
+    expectEquals(-1, compareCharInt((char)0, 1));
+    expectEquals(-1, compareCharInt((char)0, Integer.MAX_VALUE));
+    expectEquals(-1, compareCharInt(Character.MAX_VALUE, Integer.MAX_VALUE - 1));
+    expectEquals(-1, compareCharInt(Character.MAX_VALUE, Integer.MAX_VALUE));
+
+    expectEquals(0, compareCharInt((char)0, 0));
+    expectEquals(0, compareCharInt((char)1, 1));
+
+    expectEquals(1, compareCharInt((char)0, Integer.MIN_VALUE));
+    expectEquals(1, compareCharInt((char)0, Integer.MIN_VALUE + 1));
+    expectEquals(1, compareCharInt((char)0, -1));
+    expectEquals(1, compareCharInt((char)1, -1));
+    expectEquals(1, compareCharInt((char)1, 0));
+    expectEquals(1, compareCharInt(Character.MAX_VALUE, Integer.MIN_VALUE));
+    expectEquals(1, compareCharInt(Character.MAX_VALUE, -1));
+    expectEquals(1, compareCharInt(Character.MAX_VALUE, 0));
+    expectEquals(1, compareCharInt(Character.MAX_VALUE, 1));
+
+    for (char i = 0; i <= 11; i++) {
+      for (int j = -11; j <= 11; j++) {
+        int expected = 0;
+        if (i < j) expected = -1;
+        else if (i > j) expected = 1;
+        expectEquals(expected, compareCharInt(i, j));
+      }
+    }
+  }
+
+
+  public static void testCompareIntByte() {
+    expectEquals(-1, compareIntByte(Integer.MIN_VALUE, Byte.MIN_VALUE));
+    expectEquals(-1, compareIntByte(Integer.MIN_VALUE, (byte)(Byte.MIN_VALUE + 1)));
+    expectEquals(-1, compareIntByte(Integer.MIN_VALUE, (byte)-1));
+    expectEquals(-1, compareIntByte(Integer.MIN_VALUE, (byte)0));
+    expectEquals(-1, compareIntByte(Integer.MIN_VALUE, (byte)1));
+    expectEquals(-1, compareIntByte(Integer.MIN_VALUE, Byte.MAX_VALUE));
+    expectEquals(-1, compareIntByte(-1, (byte)0));
+    expectEquals(-1, compareIntByte(-1, (byte)1));
+    expectEquals(-1, compareIntByte(0, (byte)1));
+
+    expectEquals(0, compareIntByte(-1, (byte)-1));
+    expectEquals(0, compareIntByte(0, (byte)0));
+    expectEquals(0, compareIntByte(1, (byte)1));
+
+    expectEquals(1, compareIntByte(0, (byte)-1));
+    expectEquals(1, compareIntByte(1, (byte)-1));
+    expectEquals(1, compareIntByte(1, (byte)0));
+    expectEquals(1, compareIntByte(Integer.MAX_VALUE, Byte.MIN_VALUE));
+    expectEquals(1, compareIntByte(Integer.MAX_VALUE, (byte)-1));
+    expectEquals(1, compareIntByte(Integer.MAX_VALUE, (byte)0));
+    expectEquals(1, compareIntByte(Integer.MAX_VALUE, (byte)1));
+    expectEquals(1, compareIntByte(Integer.MAX_VALUE, (byte)(Byte.MAX_VALUE - 1)));
+    expectEquals(1, compareIntByte(Integer.MAX_VALUE, Byte.MAX_VALUE));
+
+    for (int i = -11; i <= 11; i++) {
+      for (byte j = -11; j <= 11; j++) {
+        int expected = 0;
+        if (i < j) expected = -1;
+        else if (i > j) expected = 1;
+        expectEquals(expected, compareIntByte(i, j));
+      }
+    }
+  }
+
+  public static void testCompareIntShort() {
+    expectEquals(-1, compareIntShort(Integer.MIN_VALUE, Short.MIN_VALUE));
+    expectEquals(-1, compareIntShort(Integer.MIN_VALUE, (short)(Short.MIN_VALUE + 1)));
+    expectEquals(-1, compareIntShort(Integer.MIN_VALUE, (short)-1));
+    expectEquals(-1, compareIntShort(Integer.MIN_VALUE, (short)0));
+    expectEquals(-1, compareIntShort(Integer.MIN_VALUE, (short)1));
+    expectEquals(-1, compareIntShort(Integer.MIN_VALUE, Short.MAX_VALUE));
+    expectEquals(-1, compareIntShort(-1, (short)0));
+    expectEquals(-1, compareIntShort(-1, (short)1));
+    expectEquals(-1, compareIntShort(0, (short)1));
+
+    expectEquals(0, compareIntShort(-1, (short)-1));
+    expectEquals(0, compareIntShort(0, (short)0));
+    expectEquals(0, compareIntShort(1, (short)1));
+
+    expectEquals(1, compareIntShort(0, (short)-1));
+    expectEquals(1, compareIntShort(1, (short)-1));
+    expectEquals(1, compareIntShort(1, (short)0));
+    expectEquals(1, compareIntShort(Integer.MAX_VALUE, Short.MIN_VALUE));
+    expectEquals(1, compareIntShort(Integer.MAX_VALUE, (short)-1));
+    expectEquals(1, compareIntShort(Integer.MAX_VALUE, (short)0));
+    expectEquals(1, compareIntShort(Integer.MAX_VALUE, (short)1));
+    expectEquals(1, compareIntShort(Integer.MAX_VALUE, (short)(Short.MAX_VALUE - 1)));
+    expectEquals(1, compareIntShort(Integer.MAX_VALUE, Short.MAX_VALUE));
+
+    for (int i = -11; i <= 11; i++) {
+      for (short j = -11; j <= 11; j++) {
+        int expected = 0;
+        if (i < j) expected = -1;
+        else if (i > j) expected = 1;
+        expectEquals(expected, compareIntShort(i, j));
+      }
+    }
+  }
+
+  public static void testCompareIntChar() {
+    expectEquals(-1, compareIntChar(Integer.MIN_VALUE, (char)0));
+    expectEquals(-1, compareIntChar(Integer.MIN_VALUE, (char)1));
+    expectEquals(-1, compareIntChar(Integer.MIN_VALUE, Character.MAX_VALUE));
+    expectEquals(-1, compareIntChar(-1, (char)0));
+    expectEquals(-1, compareIntChar(-1, (char)1));
+    expectEquals(-1, compareIntChar(0, (char)1));
+
+    expectEquals(0, compareIntChar(0, (char)0));
+    expectEquals(0, compareIntChar(1, (char)1));
+
+    expectEquals(1, compareIntChar(1, (char)0));
+    expectEquals(1, compareIntChar(Integer.MAX_VALUE, (char)0));
+    expectEquals(1, compareIntChar(Integer.MAX_VALUE, (char)1));
+    expectEquals(1, compareIntChar(Integer.MAX_VALUE, (char)(Character.MAX_VALUE - 1)));
+    expectEquals(1, compareIntChar(Integer.MAX_VALUE, Character.MAX_VALUE));
+
+    for (int i = -11; i <= 11; i++) {
+      for (char j = 0; j <= 11; j++) {
+        int expected = 0;
+        if (i < j) expected = -1;
+        else if (i > j) expected = 1;
+        expectEquals(expected, compareIntChar(i, j));
+      }
+    }
+  }
+
+
+  public static void main(String args[]) {
+    testCompareBooleans();
+    testCompareBytes();
+    testCompareShorts();
+    testCompareChars();
+    testCompareInts();
+    testCompareLongs();
+
+    testCompareByteShort();
+    testCompareByteChar();
+    testCompareByteInt();
+
+    testCompareShortByte();
+    testCompareShortChar();
+    testCompareShortInt();
+
+    testCompareCharByte();
+    testCompareCharShort();
+    testCompareCharInt();
+
+    testCompareIntByte();
+    testCompareIntShort();
+    testCompareIntChar();
 
     System.out.println("passed");
   }