Revert "ARM: Improve the code generated for HCondition with a constant input"

Reverting to see if that change is responsible for a crash. Will share with ARM if it is.

This reverts commit b404f349d69f940ef2974915fe97c16070364efd.

Change-Id: Idd04f9109447319445ff49f3fd7dc5b069b4883f
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc
index 030b91c..d7cc577 100644
--- a/compiler/optimizing/code_generator_arm.cc
+++ b/compiler/optimizing/code_generator_arm.cc
@@ -1602,34 +1602,6 @@
   }
 }
 
-static int64_t AdjustConstantForCondition(int64_t value,
-                                          IfCondition* condition,
-                                          IfCondition* opposite) {
-  if (value == 1) {
-    if (*condition == kCondB) {
-      value = 0;
-      *condition = kCondEQ;
-      *opposite = kCondNE;
-    } else if (*condition == kCondAE) {
-      value = 0;
-      *condition = kCondNE;
-      *opposite = kCondEQ;
-    }
-  } else if (value == -1) {
-    if (*condition == kCondGT) {
-      value = 0;
-      *condition = kCondGE;
-      *opposite = kCondLT;
-    } else if (*condition == kCondLE) {
-      value = 0;
-      *condition = kCondLT;
-      *opposite = kCondGE;
-    }
-  }
-
-  return value;
-}
-
 static std::pair<Condition, Condition> GenerateLongTestConstant(HCondition* condition,
                                                                 bool invert,
                                                                 CodeGeneratorARM* codegen) {
@@ -1643,7 +1615,7 @@
     std::swap(cond, opposite);
   }
 
-  std::pair<Condition, Condition> ret(EQ, NE);
+  std::pair<Condition, Condition> ret;
   const Location left = locations->InAt(0);
   const Location right = locations->InAt(1);
 
@@ -1651,38 +1623,7 @@
 
   const Register left_high = left.AsRegisterPairHigh<Register>();
   const Register left_low = left.AsRegisterPairLow<Register>();
-  int64_t value = AdjustConstantForCondition(right.GetConstant()->AsLongConstant()->GetValue(),
-                                             &cond,
-                                             &opposite);
-
-  // Comparisons against 0 are common enough to deserve special attention.
-  if (value == 0) {
-    switch (cond) {
-      case kCondNE:
-      // x > 0 iff x != 0 when the comparison is unsigned.
-      case kCondA:
-        ret = std::make_pair(NE, EQ);
-        FALLTHROUGH_INTENDED;
-      case kCondEQ:
-      // x <= 0 iff x == 0 when the comparison is unsigned.
-      case kCondBE:
-        __ orrs(IP, left_low, ShifterOperand(left_high));
-        return ret;
-      case kCondLT:
-      case kCondGE:
-        __ cmp(left_high, ShifterOperand(0));
-        return std::make_pair(ARMCondition(cond), ARMCondition(opposite));
-      // Trivially true or false.
-      case kCondB:
-        ret = std::make_pair(NE, EQ);
-        FALLTHROUGH_INTENDED;
-      case kCondAE:
-        __ cmp(left_low, ShifterOperand(left_low));
-        return ret;
-      default:
-        break;
-    }
-  }
+  int64_t value = right.GetConstant()->AsLongConstant()->GetValue();
 
   switch (cond) {
     case kCondEQ:
@@ -1842,14 +1783,10 @@
 static bool CanGenerateTest(HCondition* condition, ArmAssembler* assembler) {
   if (condition->GetLeft()->GetType() == Primitive::kPrimLong) {
     const LocationSummary* const locations = condition->GetLocations();
+    const IfCondition c = condition->GetCondition();
 
     if (locations->InAt(1).IsConstant()) {
-      IfCondition c = condition->GetCondition();
-      IfCondition opposite = condition->GetOppositeCondition();
-      const int64_t value = AdjustConstantForCondition(
-          Int64FromConstant(locations->InAt(1).GetConstant()),
-          &c,
-          &opposite);
+      const int64_t value = locations->InAt(1).GetConstant()->AsLongConstant()->GetValue();
       ShifterOperand so;
 
       if (c < kCondLT || c > kCondGE) {
@@ -1857,11 +1794,9 @@
         // we check that the least significant half of the first input to be compared
         // is in a low register (the other half is read outside an IT block), and
         // the constant fits in an 8-bit unsigned integer, so that a 16-bit CMP
-        // encoding can be used; 0 is always handled, no matter what registers are
-        // used by the first input.
-        if (value != 0 &&
-            (!ArmAssembler::IsLowRegister(locations->InAt(0).AsRegisterPairLow<Register>()) ||
-             !IsUint<8>(Low32Bits(value)))) {
+        // encoding can be used.
+        if (!ArmAssembler::IsLowRegister(locations->InAt(0).AsRegisterPairLow<Register>()) ||
+            !IsUint<8>(Low32Bits(value))) {
           return false;
         }
       } else if (c == kCondLE || c == kCondGT) {
@@ -1888,329 +1823,6 @@
   return true;
 }
 
-static void GenerateConditionGeneric(HCondition* cond, CodeGeneratorARM* codegen) {
-  DCHECK(CanGenerateTest(cond, codegen->GetAssembler()));
-
-  const Register out = cond->GetLocations()->Out().AsRegister<Register>();
-  const auto condition = GenerateTest(cond, false, codegen);
-
-  __ mov(out, ShifterOperand(0), AL, kCcKeep);
-
-  if (ArmAssembler::IsLowRegister(out)) {
-    __ it(condition.first);
-    __ mov(out, ShifterOperand(1), condition.first);
-  } else {
-    Label done_label;
-    Label* const final_label = codegen->GetFinalLabel(cond, &done_label);
-
-    __ b(final_label, condition.second);
-    __ LoadImmediate(out, 1);
-
-    if (done_label.IsLinked()) {
-      __ Bind(&done_label);
-    }
-  }
-}
-
-static void GenerateEqualLong(HCondition* cond, CodeGeneratorARM* codegen) {
-  DCHECK_EQ(cond->GetLeft()->GetType(), Primitive::kPrimLong);
-
-  const LocationSummary* const locations = cond->GetLocations();
-  IfCondition condition = cond->GetCondition();
-  const Register out = locations->Out().AsRegister<Register>();
-  const Location left = locations->InAt(0);
-  const Location right = locations->InAt(1);
-  Register left_high = left.AsRegisterPairHigh<Register>();
-  Register left_low = left.AsRegisterPairLow<Register>();
-
-  if (right.IsConstant()) {
-    IfCondition opposite = cond->GetOppositeCondition();
-    const int64_t value = AdjustConstantForCondition(Int64FromConstant(right.GetConstant()),
-                                                     &condition,
-                                                     &opposite);
-    int32_t value_high = -High32Bits(value);
-    int32_t value_low = -Low32Bits(value);
-
-    // The output uses Location::kNoOutputOverlap.
-    if (out == left_high) {
-      std::swap(left_low, left_high);
-      std::swap(value_low, value_high);
-    }
-
-    __ AddConstant(out, left_low, value_low);
-    __ AddConstant(IP, left_high, value_high);
-  } else {
-    DCHECK(right.IsRegisterPair());
-    __ sub(IP, left_high, ShifterOperand(right.AsRegisterPairHigh<Register>()));
-    __ sub(out, left_low, ShifterOperand(right.AsRegisterPairLow<Register>()));
-  }
-
-  // Need to check after calling AdjustConstantForCondition().
-  DCHECK(condition == kCondEQ || condition == kCondNE) << condition;
-
-  if (condition == kCondNE && ArmAssembler::IsLowRegister(out)) {
-    __ orrs(out, out, ShifterOperand(IP));
-    __ it(NE);
-    __ mov(out, ShifterOperand(1), NE);
-  } else {
-    __ orr(out, out, ShifterOperand(IP));
-    codegen->GenerateConditionWithZero(condition, out, out, IP);
-  }
-}
-
-static void GenerateLongComparesAndJumps(HCondition* cond,
-                                         Label* true_label,
-                                         Label* false_label,
-                                         CodeGeneratorARM* codegen) {
-  LocationSummary* locations = cond->GetLocations();
-  Location left = locations->InAt(0);
-  Location right = locations->InAt(1);
-  IfCondition if_cond = cond->GetCondition();
-
-  Register left_high = left.AsRegisterPairHigh<Register>();
-  Register left_low = left.AsRegisterPairLow<Register>();
-  IfCondition true_high_cond = if_cond;
-  IfCondition false_high_cond = cond->GetOppositeCondition();
-  Condition final_condition = ARMUnsignedCondition(if_cond);  // unsigned on lower part
-
-  // Set the conditions for the test, remembering that == needs to be
-  // decided using the low words.
-  switch (if_cond) {
-    case kCondEQ:
-    case kCondNE:
-      // Nothing to do.
-      break;
-    case kCondLT:
-      false_high_cond = kCondGT;
-      break;
-    case kCondLE:
-      true_high_cond = kCondLT;
-      break;
-    case kCondGT:
-      false_high_cond = kCondLT;
-      break;
-    case kCondGE:
-      true_high_cond = kCondGT;
-      break;
-    case kCondB:
-      false_high_cond = kCondA;
-      break;
-    case kCondBE:
-      true_high_cond = kCondB;
-      break;
-    case kCondA:
-      false_high_cond = kCondB;
-      break;
-    case kCondAE:
-      true_high_cond = kCondA;
-      break;
-  }
-  if (right.IsConstant()) {
-    int64_t value = right.GetConstant()->AsLongConstant()->GetValue();
-    int32_t val_low = Low32Bits(value);
-    int32_t val_high = High32Bits(value);
-
-    __ CmpConstant(left_high, val_high);
-    if (if_cond == kCondNE) {
-      __ b(true_label, ARMCondition(true_high_cond));
-    } else if (if_cond == kCondEQ) {
-      __ b(false_label, ARMCondition(false_high_cond));
-    } else {
-      __ b(true_label, ARMCondition(true_high_cond));
-      __ b(false_label, ARMCondition(false_high_cond));
-    }
-    // Must be equal high, so compare the lows.
-    __ CmpConstant(left_low, val_low);
-  } else {
-    Register right_high = right.AsRegisterPairHigh<Register>();
-    Register right_low = right.AsRegisterPairLow<Register>();
-
-    __ cmp(left_high, ShifterOperand(right_high));
-    if (if_cond == kCondNE) {
-      __ b(true_label, ARMCondition(true_high_cond));
-    } else if (if_cond == kCondEQ) {
-      __ b(false_label, ARMCondition(false_high_cond));
-    } else {
-      __ b(true_label, ARMCondition(true_high_cond));
-      __ b(false_label, ARMCondition(false_high_cond));
-    }
-    // Must be equal high, so compare the lows.
-    __ cmp(left_low, ShifterOperand(right_low));
-  }
-  // The last comparison might be unsigned.
-  // TODO: optimize cases where this is always true/false
-  __ b(true_label, final_condition);
-}
-
-static void GenerateConditionLong(HCondition* cond, CodeGeneratorARM* codegen) {
-  DCHECK_EQ(cond->GetLeft()->GetType(), Primitive::kPrimLong);
-
-  const LocationSummary* const locations = cond->GetLocations();
-  IfCondition condition = cond->GetCondition();
-  const Register out = locations->Out().AsRegister<Register>();
-  const Location left = locations->InAt(0);
-  const Location right = locations->InAt(1);
-
-  if (right.IsConstant()) {
-    IfCondition opposite = cond->GetOppositeCondition();
-
-    // Comparisons against 0 are common enough to deserve special attention.
-    if (AdjustConstantForCondition(Int64FromConstant(right.GetConstant()),
-                                   &condition,
-                                   &opposite) == 0) {
-      switch (condition) {
-        case kCondNE:
-        case kCondA:
-          if (ArmAssembler::IsLowRegister(out)) {
-            // We only care if both input registers are 0 or not.
-            __ orrs(out,
-                    left.AsRegisterPairLow<Register>(),
-                    ShifterOperand(left.AsRegisterPairHigh<Register>()));
-            __ it(NE);
-            __ mov(out, ShifterOperand(1), NE);
-            return;
-          }
-
-          FALLTHROUGH_INTENDED;
-        case kCondEQ:
-        case kCondBE:
-          // We only care if both input registers are 0 or not.
-          __ orr(out,
-                 left.AsRegisterPairLow<Register>(),
-                 ShifterOperand(left.AsRegisterPairHigh<Register>()));
-          codegen->GenerateConditionWithZero(condition, out, out);
-          return;
-        case kCondLT:
-        case kCondGE:
-          // We only care about the sign bit.
-          FALLTHROUGH_INTENDED;
-        case kCondAE:
-        case kCondB:
-          codegen->GenerateConditionWithZero(condition, out, left.AsRegisterPairHigh<Register>());
-          return;
-        case kCondLE:
-        case kCondGT:
-        default:
-          break;
-      }
-    }
-  }
-
-  if ((condition == kCondEQ || condition == kCondNE) &&
-      // If `out` is a low register, then the GenerateConditionGeneric()
-      // function generates a shorter code sequence that is still branchless.
-      (!ArmAssembler::IsLowRegister(out) || !CanGenerateTest(cond, codegen->GetAssembler()))) {
-    GenerateEqualLong(cond, codegen);
-    return;
-  }
-
-  if (CanGenerateTest(cond, codegen->GetAssembler())) {
-    GenerateConditionGeneric(cond, codegen);
-    return;
-  }
-
-  // Convert the jumps into the result.
-  Label done_label;
-  Label* const final_label = codegen->GetFinalLabel(cond, &done_label);
-  Label true_label, false_label;
-
-  GenerateLongComparesAndJumps(cond, &true_label, &false_label, codegen);
-
-  // False case: result = 0.
-  __ Bind(&false_label);
-  __ mov(out, ShifterOperand(0));
-  __ b(final_label);
-
-  // True case: result = 1.
-  __ Bind(&true_label);
-  __ mov(out, ShifterOperand(1));
-
-  if (done_label.IsLinked()) {
-    __ Bind(&done_label);
-  }
-}
-
-static void GenerateConditionIntegralOrNonPrimitive(HCondition* cond, CodeGeneratorARM* codegen) {
-  const Primitive::Type type = cond->GetLeft()->GetType();
-
-  DCHECK(Primitive::IsIntegralType(type) || type == Primitive::kPrimNot) << type;
-
-  if (type == Primitive::kPrimLong) {
-    GenerateConditionLong(cond, codegen);
-    return;
-  }
-
-  const LocationSummary* const locations = cond->GetLocations();
-  IfCondition condition = cond->GetCondition();
-  Register in = locations->InAt(0).AsRegister<Register>();
-  const Register out = locations->Out().AsRegister<Register>();
-  const Location right = cond->GetLocations()->InAt(1);
-  int64_t value;
-
-  if (right.IsConstant()) {
-    IfCondition opposite = cond->GetOppositeCondition();
-
-    value = AdjustConstantForCondition(Int64FromConstant(right.GetConstant()),
-                                       &condition,
-                                       &opposite);
-
-    // Comparisons against 0 are common enough to deserve special attention.
-    if (value == 0) {
-      switch (condition) {
-        case kCondNE:
-        case kCondA:
-          if (ArmAssembler::IsLowRegister(out) && out == in) {
-            __ cmp(out, ShifterOperand(0));
-            __ it(NE);
-            __ mov(out, ShifterOperand(1), NE);
-            return;
-          }
-
-          FALLTHROUGH_INTENDED;
-        case kCondEQ:
-        case kCondBE:
-        case kCondLT:
-        case kCondGE:
-        case kCondAE:
-        case kCondB:
-          codegen->GenerateConditionWithZero(condition, out, in);
-          return;
-        case kCondLE:
-        case kCondGT:
-        default:
-          break;
-      }
-    }
-  }
-
-  if (condition == kCondEQ || condition == kCondNE) {
-    ShifterOperand operand;
-
-    if (right.IsConstant()) {
-      operand = ShifterOperand(value);
-    } else if (out == right.AsRegister<Register>()) {
-      // Avoid 32-bit instructions if possible.
-      operand = ShifterOperand(in);
-      in = right.AsRegister<Register>();
-    } else {
-      operand = ShifterOperand(right.AsRegister<Register>());
-    }
-
-    if (condition == kCondNE && ArmAssembler::IsLowRegister(out)) {
-      __ subs(out, in, operand);
-      __ it(NE);
-      __ mov(out, ShifterOperand(1), NE);
-    } else {
-      __ sub(out, in, operand);
-      codegen->GenerateConditionWithZero(condition, out, out);
-    }
-
-    return;
-  }
-
-  GenerateConditionGeneric(cond, codegen);
-}
-
 static bool CanEncodeConstantAs8BitImmediate(HConstant* constant) {
   const Primitive::Type type = constant->GetType();
   bool ret = false;
@@ -2816,6 +2428,89 @@
 void InstructionCodeGeneratorARM::VisitExit(HExit* exit ATTRIBUTE_UNUSED) {
 }
 
+void InstructionCodeGeneratorARM::GenerateLongComparesAndJumps(HCondition* cond,
+                                                               Label* true_label,
+                                                               Label* false_label) {
+  LocationSummary* locations = cond->GetLocations();
+  Location left = locations->InAt(0);
+  Location right = locations->InAt(1);
+  IfCondition if_cond = cond->GetCondition();
+
+  Register left_high = left.AsRegisterPairHigh<Register>();
+  Register left_low = left.AsRegisterPairLow<Register>();
+  IfCondition true_high_cond = if_cond;
+  IfCondition false_high_cond = cond->GetOppositeCondition();
+  Condition final_condition = ARMUnsignedCondition(if_cond);  // unsigned on lower part
+
+  // Set the conditions for the test, remembering that == needs to be
+  // decided using the low words.
+  switch (if_cond) {
+    case kCondEQ:
+    case kCondNE:
+      // Nothing to do.
+      break;
+    case kCondLT:
+      false_high_cond = kCondGT;
+      break;
+    case kCondLE:
+      true_high_cond = kCondLT;
+      break;
+    case kCondGT:
+      false_high_cond = kCondLT;
+      break;
+    case kCondGE:
+      true_high_cond = kCondGT;
+      break;
+    case kCondB:
+      false_high_cond = kCondA;
+      break;
+    case kCondBE:
+      true_high_cond = kCondB;
+      break;
+    case kCondA:
+      false_high_cond = kCondB;
+      break;
+    case kCondAE:
+      true_high_cond = kCondA;
+      break;
+  }
+  if (right.IsConstant()) {
+    int64_t value = right.GetConstant()->AsLongConstant()->GetValue();
+    int32_t val_low = Low32Bits(value);
+    int32_t val_high = High32Bits(value);
+
+    __ CmpConstant(left_high, val_high);
+    if (if_cond == kCondNE) {
+      __ b(true_label, ARMCondition(true_high_cond));
+    } else if (if_cond == kCondEQ) {
+      __ b(false_label, ARMCondition(false_high_cond));
+    } else {
+      __ b(true_label, ARMCondition(true_high_cond));
+      __ b(false_label, ARMCondition(false_high_cond));
+    }
+    // Must be equal high, so compare the lows.
+    __ CmpConstant(left_low, val_low);
+  } else {
+    Register right_high = right.AsRegisterPairHigh<Register>();
+    Register right_low = right.AsRegisterPairLow<Register>();
+
+    __ cmp(left_high, ShifterOperand(right_high));
+    if (if_cond == kCondNE) {
+      __ b(true_label, ARMCondition(true_high_cond));
+    } else if (if_cond == kCondEQ) {
+      __ b(false_label, ARMCondition(false_high_cond));
+    } else {
+      __ b(true_label, ARMCondition(true_high_cond));
+      __ b(false_label, ARMCondition(false_high_cond));
+    }
+    // Must be equal high, so compare the lows.
+    __ cmp(left_low, ShifterOperand(right_low));
+  }
+  // The last comparison might be unsigned.
+  // TODO: optimize cases where this is always true/false
+  __ b(true_label, final_condition);
+}
+
 void InstructionCodeGeneratorARM::GenerateCompareTestAndBranch(HCondition* condition,
                                                                Label* true_target_in,
                                                                Label* false_target_in) {
@@ -2850,7 +2545,7 @@
   Label* false_target = false_target_in == nullptr ? &fallthrough_target : false_target_in;
 
   DCHECK_EQ(condition->InputAt(0)->GetType(), Primitive::kPrimLong);
-  GenerateLongComparesAndJumps(condition, true_target, false_target, codegen_);
+  GenerateLongComparesAndJumps(condition, true_target, false_target);
 
   if (false_target != &fallthrough_target) {
     __ b(false_target);
@@ -3162,80 +2857,6 @@
   __ nop();
 }
 
-// `temp` is an extra temporary register that is used for some conditions;
-// callers may not specify it, in which case the method will use a scratch
-// register instead.
-void CodeGeneratorARM::GenerateConditionWithZero(IfCondition condition,
-                                                 Register out,
-                                                 Register in,
-                                                 Register temp) {
-  switch (condition) {
-    case kCondEQ:
-    // x <= 0 iff x == 0 when the comparison is unsigned.
-    case kCondBE:
-      if (temp == kNoRegister || (ArmAssembler::IsLowRegister(out) && out != in)) {
-        temp = out;
-      }
-
-      // Avoid 32-bit instructions if possible; note that `in` and `temp` must be
-      // different as well.
-      if (ArmAssembler::IsLowRegister(in) && ArmAssembler::IsLowRegister(temp) && in != temp) {
-        // temp = - in; only 0 sets the carry flag.
-        __ rsbs(temp, in, ShifterOperand(0));
-
-        if (out == in) {
-          std::swap(in, temp);
-        }
-
-        // out = - in + in + carry = carry
-        __ adc(out, temp, ShifterOperand(in));
-      } else {
-        // If `in` is 0, then it has 32 leading zeros, and less than that otherwise.
-        __ clz(out, in);
-        // Any number less than 32 logically shifted right by 5 bits results in 0;
-        // the same operation on 32 yields 1.
-        __ Lsr(out, out, 5);
-      }
-
-      break;
-    case kCondNE:
-    // x > 0 iff x != 0 when the comparison is unsigned.
-    case kCondA:
-      if (out == in) {
-        if (temp == kNoRegister || in == temp) {
-          temp = IP;
-        }
-      } else if (temp == kNoRegister || !ArmAssembler::IsLowRegister(temp)) {
-        temp = out;
-      }
-
-      // temp = in - 1; only 0 does not set the carry flag.
-      __ subs(temp, in, ShifterOperand(1));
-      // out = in + ~temp + carry = in + (-(in - 1) - 1) + carry = in - in + 1 - 1 + carry = carry
-      __ sbc(out, in, ShifterOperand(temp));
-      break;
-    case kCondGE:
-      __ mvn(out, ShifterOperand(in));
-      in = out;
-      FALLTHROUGH_INTENDED;
-    case kCondLT:
-      // We only care about the sign bit.
-      __ Lsr(out, in, 31);
-      break;
-    case kCondAE:
-      // Trivially true.
-      __ mov(out, ShifterOperand(1));
-      break;
-    case kCondB:
-      // Trivially false.
-      __ mov(out, ShifterOperand(0));
-      break;
-    default:
-      LOG(FATAL) << "Unexpected condition " << condition;
-      UNREACHABLE();
-  }
-}
-
 void LocationsBuilderARM::HandleCondition(HCondition* cond) {
   LocationSummary* locations =
       new (GetGraph()->GetArena()) LocationSummary(cond, LocationSummary::kNoCall);
@@ -3272,42 +2893,48 @@
     return;
   }
 
-  const Primitive::Type type = cond->GetLeft()->GetType();
+  const Register out = cond->GetLocations()->Out().AsRegister<Register>();
 
-  if (Primitive::IsFloatingPointType(type)) {
-    GenerateConditionGeneric(cond, codegen_);
+  if (ArmAssembler::IsLowRegister(out) && CanGenerateTest(cond, codegen_->GetAssembler())) {
+    const auto condition = GenerateTest(cond, false, codegen_);
+
+    __ it(condition.first);
+    __ mov(out, ShifterOperand(1), condition.first);
+    __ it(condition.second);
+    __ mov(out, ShifterOperand(0), condition.second);
     return;
   }
 
-  DCHECK(Primitive::IsIntegralType(type) || type == Primitive::kPrimNot) << type;
+  // Convert the jumps into the result.
+  Label done_label;
+  Label* const final_label = codegen_->GetFinalLabel(cond, &done_label);
 
-  if (type == Primitive::kPrimBoolean) {
-    const LocationSummary* const locations = cond->GetLocations();
-    const IfCondition c = cond->GetCondition();
-    Register left = locations->InAt(0).AsRegister<Register>();
-    const Register out = locations->Out().AsRegister<Register>();
-    const Location right_loc = locations->InAt(1);
+  if (cond->InputAt(0)->GetType() == Primitive::kPrimLong) {
+    Label true_label, false_label;
 
-    // All other cases are handled by the instruction simplifier.
-    DCHECK((c == kCondEQ || c == kCondNE) && !right_loc.IsConstant());
+    GenerateLongComparesAndJumps(cond, &true_label, &false_label);
 
-    Register right = right_loc.AsRegister<Register>();
+    // False case: result = 0.
+    __ Bind(&false_label);
+    __ LoadImmediate(out, 0);
+    __ b(final_label);
 
-    // Avoid 32-bit instructions if possible.
-    if (out == right) {
-      std::swap(left, right);
-    }
+    // True case: result = 1.
+    __ Bind(&true_label);
+    __ LoadImmediate(out, 1);
+  } else {
+    DCHECK(CanGenerateTest(cond, codegen_->GetAssembler()));
 
-    __ eor(out, left, ShifterOperand(right));
+    const auto condition = GenerateTest(cond, false, codegen_);
 
-    if (c == kCondEQ) {
-      __ eor(out, out, ShifterOperand(1));
-    }
-
-    return;
+    __ mov(out, ShifterOperand(0), AL, kCcKeep);
+    __ b(final_label, condition.second);
+    __ LoadImmediate(out, 1);
   }
 
-  GenerateConditionIntegralOrNonPrimitive(cond, codegen_);
+  if (done_label.IsLinked()) {
+    __ Bind(&done_label);
+  }
 }
 
 void LocationsBuilderARM::VisitEqual(HEqual* comp) {
diff --git a/compiler/optimizing/code_generator_arm.h b/compiler/optimizing/code_generator_arm.h
index dedb639..86f2f21 100644
--- a/compiler/optimizing/code_generator_arm.h
+++ b/compiler/optimizing/code_generator_arm.h
@@ -299,6 +299,7 @@
   void GenerateCompareTestAndBranch(HCondition* condition,
                                     Label* true_target,
                                     Label* false_target);
+  void GenerateLongComparesAndJumps(HCondition* cond, Label* true_label, Label* false_label);
   void DivRemOneOrMinusOne(HBinaryOperation* instruction);
   void DivRemByPowerOfTwo(HBinaryOperation* instruction);
   void GenerateDivRemWithAnyConstant(HBinaryOperation* instruction);
@@ -603,14 +604,6 @@
   void GenerateImplicitNullCheck(HNullCheck* instruction) OVERRIDE;
   void GenerateExplicitNullCheck(HNullCheck* instruction) OVERRIDE;
 
-  // `temp` is an extra temporary register that is used for some conditions;
-  // callers may not specify it, in which case the method will use a scratch
-  // register instead.
-  void GenerateConditionWithZero(IfCondition condition,
-                                 Register out,
-                                 Register in,
-                                 Register temp = kNoRegister);
-
  private:
   Register GetInvokeStaticOrDirectExtraParameter(HInvokeStaticOrDirect* invoke, Register temp);
 
diff --git a/compiler/optimizing/code_generator_arm_vixl.cc b/compiler/optimizing/code_generator_arm_vixl.cc
index bbd4d9f..b6678b0 100644
--- a/compiler/optimizing/code_generator_arm_vixl.cc
+++ b/compiler/optimizing/code_generator_arm_vixl.cc
@@ -1687,34 +1687,6 @@
   }
 }
 
-static int64_t AdjustConstantForCondition(int64_t value,
-                                          IfCondition* condition,
-                                          IfCondition* opposite) {
-  if (value == 1) {
-    if (*condition == kCondB) {
-      value = 0;
-      *condition = kCondEQ;
-      *opposite = kCondNE;
-    } else if (*condition == kCondAE) {
-      value = 0;
-      *condition = kCondNE;
-      *opposite = kCondEQ;
-    }
-  } else if (value == -1) {
-    if (*condition == kCondGT) {
-      value = 0;
-      *condition = kCondGE;
-      *opposite = kCondLT;
-    } else if (*condition == kCondLE) {
-      value = 0;
-      *condition = kCondLT;
-      *opposite = kCondGE;
-    }
-  }
-
-  return value;
-}
-
 static std::pair<vixl32::Condition, vixl32::Condition> GenerateLongTestConstant(
     HCondition* condition,
     bool invert,
@@ -1737,37 +1709,7 @@
 
   const vixl32::Register left_high = HighRegisterFrom(left);
   const vixl32::Register left_low = LowRegisterFrom(left);
-  int64_t value = AdjustConstantForCondition(Int64ConstantFrom(right), &cond, &opposite);
-  UseScratchRegisterScope temps(codegen->GetVIXLAssembler());
-
-  // Comparisons against 0 are common enough to deserve special attention.
-  if (value == 0) {
-    switch (cond) {
-      case kCondNE:
-      // x > 0 iff x != 0 when the comparison is unsigned.
-      case kCondA:
-        ret = std::make_pair(ne, eq);
-        FALLTHROUGH_INTENDED;
-      case kCondEQ:
-      // x <= 0 iff x == 0 when the comparison is unsigned.
-      case kCondBE:
-        __ Orrs(temps.Acquire(), left_low, left_high);
-        return ret;
-      case kCondLT:
-      case kCondGE:
-        __ Cmp(left_high, 0);
-        return std::make_pair(ARMCondition(cond), ARMCondition(opposite));
-      // Trivially true or false.
-      case kCondB:
-        ret = std::make_pair(ne, eq);
-        FALLTHROUGH_INTENDED;
-      case kCondAE:
-        __ Cmp(left_low, left_low);
-        return ret;
-      default:
-        break;
-    }
-  }
+  int64_t value = Int64ConstantFrom(right);
 
   switch (cond) {
     case kCondEQ:
@@ -1812,6 +1754,8 @@
       FALLTHROUGH_INTENDED;
     case kCondGE:
     case kCondLT: {
+      UseScratchRegisterScope temps(codegen->GetVIXLAssembler());
+
       __ Cmp(left_low, Low32Bits(value));
       __ Sbcs(temps.Acquire(), left_high, High32Bits(value));
       ret = std::make_pair(ARMCondition(cond), ARMCondition(opposite));
@@ -1929,22 +1873,18 @@
 static bool CanGenerateTest(HCondition* condition, ArmVIXLAssembler* assembler) {
   if (condition->GetLeft()->GetType() == Primitive::kPrimLong) {
     const LocationSummary* const locations = condition->GetLocations();
+    const IfCondition c = condition->GetCondition();
 
     if (locations->InAt(1).IsConstant()) {
-      IfCondition c = condition->GetCondition();
-      IfCondition opposite = condition->GetOppositeCondition();
-      const int64_t value =
-          AdjustConstantForCondition(Int64ConstantFrom(locations->InAt(1)), &c, &opposite);
+      const int64_t value = Int64ConstantFrom(locations->InAt(1));
 
       if (c < kCondLT || c > kCondGE) {
         // Since IT blocks longer than a 16-bit instruction are deprecated by ARMv8,
         // we check that the least significant half of the first input to be compared
         // is in a low register (the other half is read outside an IT block), and
         // the constant fits in an 8-bit unsigned integer, so that a 16-bit CMP
-        // encoding can be used; 0 is always handled, no matter what registers are
-        // used by the first input.
-        if (value != 0 &&
-            (!LowRegisterFrom(locations->InAt(0)).IsLow() || !IsUint<8>(Low32Bits(value)))) {
+        // encoding can be used.
+        if (!LowRegisterFrom(locations->InAt(0)).IsLow() || !IsUint<8>(Low32Bits(value))) {
           return false;
         }
       // TODO(VIXL): The rest of the checks are there to keep the backend in sync with
@@ -1963,353 +1903,6 @@
   return true;
 }
 
-static void GenerateConditionGeneric(HCondition* cond, CodeGeneratorARMVIXL* codegen) {
-  DCHECK(CanGenerateTest(cond, codegen->GetAssembler()));
-
-  const vixl32::Register out = OutputRegister(cond);
-  const auto condition = GenerateTest(cond, false, codegen);
-
-  __ Mov(LeaveFlags, out, 0);
-
-  if (out.IsLow()) {
-    // We use the scope because of the IT block that follows.
-    ExactAssemblyScope guard(codegen->GetVIXLAssembler(),
-                             2 * vixl32::k16BitT32InstructionSizeInBytes,
-                             CodeBufferCheckScope::kExactSize);
-
-    __ it(condition.first);
-    __ mov(condition.first, out, 1);
-  } else {
-    vixl32::Label done_label;
-    vixl32::Label* const final_label = codegen->GetFinalLabel(cond, &done_label);
-
-    __ B(condition.second, final_label, /* far_target */ false);
-    __ Mov(out, 1);
-
-    if (done_label.IsReferenced()) {
-      __ Bind(&done_label);
-    }
-  }
-}
-
-static void GenerateEqualLong(HCondition* cond, CodeGeneratorARMVIXL* codegen) {
-  DCHECK_EQ(cond->GetLeft()->GetType(), Primitive::kPrimLong);
-
-  const LocationSummary* const locations = cond->GetLocations();
-  IfCondition condition = cond->GetCondition();
-  const vixl32::Register out = OutputRegister(cond);
-  const Location left = locations->InAt(0);
-  const Location right = locations->InAt(1);
-  vixl32::Register left_high = HighRegisterFrom(left);
-  vixl32::Register left_low = LowRegisterFrom(left);
-  vixl32::Register temp;
-  UseScratchRegisterScope temps(codegen->GetVIXLAssembler());
-
-  if (right.IsConstant()) {
-    IfCondition opposite = cond->GetOppositeCondition();
-    const int64_t value = AdjustConstantForCondition(Int64ConstantFrom(right),
-                                                     &condition,
-                                                     &opposite);
-    Operand right_high = High32Bits(value);
-    Operand right_low = Low32Bits(value);
-
-    // The output uses Location::kNoOutputOverlap.
-    if (out.Is(left_high)) {
-      std::swap(left_low, left_high);
-      std::swap(right_low, right_high);
-    }
-
-    __ Sub(out, left_low, right_low);
-    temp = temps.Acquire();
-    __ Sub(temp, left_high, right_high);
-  } else {
-    DCHECK(right.IsRegisterPair());
-    temp = temps.Acquire();
-    __ Sub(temp, left_high, HighRegisterFrom(right));
-    __ Sub(out, left_low, LowRegisterFrom(right));
-  }
-
-  // Need to check after calling AdjustConstantForCondition().
-  DCHECK(condition == kCondEQ || condition == kCondNE) << condition;
-
-  if (condition == kCondNE && out.IsLow()) {
-    __ Orrs(out, out, temp);
-
-    // We use the scope because of the IT block that follows.
-    ExactAssemblyScope guard(codegen->GetVIXLAssembler(),
-                             2 * vixl32::k16BitT32InstructionSizeInBytes,
-                             CodeBufferCheckScope::kExactSize);
-
-    __ it(ne);
-    __ mov(ne, out, 1);
-  } else {
-    __ Orr(out, out, temp);
-    codegen->GenerateConditionWithZero(condition, out, out, temp);
-  }
-}
-
-static void GenerateLongComparesAndJumps(HCondition* cond,
-                                         vixl32::Label* true_label,
-                                         vixl32::Label* false_label,
-                                         CodeGeneratorARMVIXL* codegen) {
-  LocationSummary* locations = cond->GetLocations();
-  Location left = locations->InAt(0);
-  Location right = locations->InAt(1);
-  IfCondition if_cond = cond->GetCondition();
-
-  vixl32::Register left_high = HighRegisterFrom(left);
-  vixl32::Register left_low = LowRegisterFrom(left);
-  IfCondition true_high_cond = if_cond;
-  IfCondition false_high_cond = cond->GetOppositeCondition();
-  vixl32::Condition final_condition = ARMUnsignedCondition(if_cond);  // unsigned on lower part
-
-  // Set the conditions for the test, remembering that == needs to be
-  // decided using the low words.
-  switch (if_cond) {
-    case kCondEQ:
-    case kCondNE:
-      // Nothing to do.
-      break;
-    case kCondLT:
-      false_high_cond = kCondGT;
-      break;
-    case kCondLE:
-      true_high_cond = kCondLT;
-      break;
-    case kCondGT:
-      false_high_cond = kCondLT;
-      break;
-    case kCondGE:
-      true_high_cond = kCondGT;
-      break;
-    case kCondB:
-      false_high_cond = kCondA;
-      break;
-    case kCondBE:
-      true_high_cond = kCondB;
-      break;
-    case kCondA:
-      false_high_cond = kCondB;
-      break;
-    case kCondAE:
-      true_high_cond = kCondA;
-      break;
-  }
-  if (right.IsConstant()) {
-    int64_t value = Int64ConstantFrom(right);
-    int32_t val_low = Low32Bits(value);
-    int32_t val_high = High32Bits(value);
-
-    __ Cmp(left_high, val_high);
-    if (if_cond == kCondNE) {
-      __ B(ARMCondition(true_high_cond), true_label);
-    } else if (if_cond == kCondEQ) {
-      __ B(ARMCondition(false_high_cond), false_label);
-    } else {
-      __ B(ARMCondition(true_high_cond), true_label);
-      __ B(ARMCondition(false_high_cond), false_label);
-    }
-    // Must be equal high, so compare the lows.
-    __ Cmp(left_low, val_low);
-  } else {
-    vixl32::Register right_high = HighRegisterFrom(right);
-    vixl32::Register right_low = LowRegisterFrom(right);
-
-    __ Cmp(left_high, right_high);
-    if (if_cond == kCondNE) {
-      __ B(ARMCondition(true_high_cond), true_label);
-    } else if (if_cond == kCondEQ) {
-      __ B(ARMCondition(false_high_cond), false_label);
-    } else {
-      __ B(ARMCondition(true_high_cond), true_label);
-      __ B(ARMCondition(false_high_cond), false_label);
-    }
-    // Must be equal high, so compare the lows.
-    __ Cmp(left_low, right_low);
-  }
-  // The last comparison might be unsigned.
-  // TODO: optimize cases where this is always true/false
-  __ B(final_condition, true_label);
-}
-
-static void GenerateConditionLong(HCondition* cond, CodeGeneratorARMVIXL* codegen) {
-  DCHECK_EQ(cond->GetLeft()->GetType(), Primitive::kPrimLong);
-
-  const LocationSummary* const locations = cond->GetLocations();
-  IfCondition condition = cond->GetCondition();
-  const vixl32::Register out = OutputRegister(cond);
-  const Location left = locations->InAt(0);
-  const Location right = locations->InAt(1);
-
-  if (right.IsConstant()) {
-    IfCondition opposite = cond->GetOppositeCondition();
-
-    // Comparisons against 0 are common enough to deserve special attention.
-    if (AdjustConstantForCondition(Int64ConstantFrom(right), &condition, &opposite) == 0) {
-      switch (condition) {
-        case kCondNE:
-        case kCondA:
-          if (out.IsLow()) {
-            // We only care if both input registers are 0 or not.
-            __ Orrs(out, LowRegisterFrom(left), HighRegisterFrom(left));
-
-            // We use the scope because of the IT block that follows.
-            ExactAssemblyScope guard(codegen->GetVIXLAssembler(),
-                                     2 * vixl32::k16BitT32InstructionSizeInBytes,
-                                     CodeBufferCheckScope::kExactSize);
-
-            __ it(ne);
-            __ mov(ne, out, 1);
-            return;
-          }
-
-          FALLTHROUGH_INTENDED;
-        case kCondEQ:
-        case kCondBE:
-          // We only care if both input registers are 0 or not.
-          __ Orr(out, LowRegisterFrom(left), HighRegisterFrom(left));
-          codegen->GenerateConditionWithZero(condition, out, out);
-          return;
-        case kCondLT:
-        case kCondGE:
-          // We only care about the sign bit.
-          FALLTHROUGH_INTENDED;
-        case kCondAE:
-        case kCondB:
-          codegen->GenerateConditionWithZero(condition, out, HighRegisterFrom(left));
-          return;
-        case kCondLE:
-        case kCondGT:
-        default:
-          break;
-      }
-    }
-  }
-
-  if ((condition == kCondEQ || condition == kCondNE) &&
-      // If `out` is a low register, then the GenerateConditionGeneric()
-      // function generates a shorter code sequence that is still branchless.
-      (!out.IsLow() || !CanGenerateTest(cond, codegen->GetAssembler()))) {
-    GenerateEqualLong(cond, codegen);
-    return;
-  }
-
-  if (CanGenerateTest(cond, codegen->GetAssembler())) {
-    GenerateConditionGeneric(cond, codegen);
-    return;
-  }
-
-  // Convert the jumps into the result.
-  vixl32::Label done_label;
-  vixl32::Label* const final_label = codegen->GetFinalLabel(cond, &done_label);
-  vixl32::Label true_label, false_label;
-
-  GenerateLongComparesAndJumps(cond, &true_label, &false_label, codegen);
-
-  // False case: result = 0.
-  __ Bind(&false_label);
-  __ Mov(out, 0);
-  __ B(final_label);
-
-  // True case: result = 1.
-  __ Bind(&true_label);
-  __ Mov(out, 1);
-
-  if (done_label.IsReferenced()) {
-    __ Bind(&done_label);
-  }
-}
-
-static void GenerateConditionIntegralOrNonPrimitive(HCondition* cond, CodeGeneratorARMVIXL* codegen) {
-  const Primitive::Type type = cond->GetLeft()->GetType();
-
-  DCHECK(Primitive::IsIntegralType(type) || type == Primitive::kPrimNot) << type;
-
-  if (type == Primitive::kPrimLong) {
-    GenerateConditionLong(cond, codegen);
-    return;
-  }
-
-  IfCondition condition = cond->GetCondition();
-  vixl32::Register in = InputRegisterAt(cond, 0);
-  const vixl32::Register out = OutputRegister(cond);
-  const Location right = cond->GetLocations()->InAt(1);
-  int64_t value;
-
-  if (right.IsConstant()) {
-    IfCondition opposite = cond->GetOppositeCondition();
-
-    value = AdjustConstantForCondition(Int64ConstantFrom(right), &condition, &opposite);
-
-    // Comparisons against 0 are common enough to deserve special attention.
-    if (value == 0) {
-      switch (condition) {
-        case kCondNE:
-        case kCondA:
-          if (out.IsLow() && out.Is(in)) {
-            __ Cmp(out, 0);
-
-            // We use the scope because of the IT block that follows.
-            ExactAssemblyScope guard(codegen->GetVIXLAssembler(),
-                                     2 * vixl32::k16BitT32InstructionSizeInBytes,
-                                     CodeBufferCheckScope::kExactSize);
-
-            __ it(ne);
-            __ mov(ne, out, 1);
-            return;
-          }
-
-          FALLTHROUGH_INTENDED;
-        case kCondEQ:
-        case kCondBE:
-        case kCondLT:
-        case kCondGE:
-        case kCondAE:
-        case kCondB:
-          codegen->GenerateConditionWithZero(condition, out, in);
-          return;
-        case kCondLE:
-        case kCondGT:
-        default:
-          break;
-      }
-    }
-  }
-
-  if (condition == kCondEQ || condition == kCondNE) {
-    Operand operand(0);
-
-    if (right.IsConstant()) {
-      operand = Operand::From(value);
-    } else if (out.Is(RegisterFrom(right))) {
-      // Avoid 32-bit instructions if possible.
-      operand = InputOperandAt(cond, 0);
-      in = RegisterFrom(right);
-    } else {
-      operand = InputOperandAt(cond, 1);
-    }
-
-    if (condition == kCondNE && out.IsLow()) {
-      __ Subs(out, in, operand);
-
-      // We use the scope because of the IT block that follows.
-      ExactAssemblyScope guard(codegen->GetVIXLAssembler(),
-                               2 * vixl32::k16BitT32InstructionSizeInBytes,
-                               CodeBufferCheckScope::kExactSize);
-
-      __ it(ne);
-      __ mov(ne, out, 1);
-    } else {
-      __ Sub(out, in, operand);
-      codegen->GenerateConditionWithZero(condition, out, out);
-    }
-
-    return;
-  }
-
-  GenerateConditionGeneric(cond, codegen);
-}
-
 static bool CanEncodeConstantAs8BitImmediate(HConstant* constant) {
   const Primitive::Type type = constant->GetType();
   bool ret = false;
@@ -2869,6 +2462,89 @@
 void InstructionCodeGeneratorARMVIXL::VisitExit(HExit* exit ATTRIBUTE_UNUSED) {
 }
 
+void InstructionCodeGeneratorARMVIXL::GenerateLongComparesAndJumps(HCondition* cond,
+                                                                   vixl32::Label* true_label,
+                                                                   vixl32::Label* false_label) {
+  LocationSummary* locations = cond->GetLocations();
+  Location left = locations->InAt(0);
+  Location right = locations->InAt(1);
+  IfCondition if_cond = cond->GetCondition();
+
+  vixl32::Register left_high = HighRegisterFrom(left);
+  vixl32::Register left_low = LowRegisterFrom(left);
+  IfCondition true_high_cond = if_cond;
+  IfCondition false_high_cond = cond->GetOppositeCondition();
+  vixl32::Condition final_condition = ARMUnsignedCondition(if_cond);  // unsigned on lower part
+
+  // Set the conditions for the test, remembering that == needs to be
+  // decided using the low words.
+  switch (if_cond) {
+    case kCondEQ:
+    case kCondNE:
+      // Nothing to do.
+      break;
+    case kCondLT:
+      false_high_cond = kCondGT;
+      break;
+    case kCondLE:
+      true_high_cond = kCondLT;
+      break;
+    case kCondGT:
+      false_high_cond = kCondLT;
+      break;
+    case kCondGE:
+      true_high_cond = kCondGT;
+      break;
+    case kCondB:
+      false_high_cond = kCondA;
+      break;
+    case kCondBE:
+      true_high_cond = kCondB;
+      break;
+    case kCondA:
+      false_high_cond = kCondB;
+      break;
+    case kCondAE:
+      true_high_cond = kCondA;
+      break;
+  }
+  if (right.IsConstant()) {
+    int64_t value = Int64ConstantFrom(right);
+    int32_t val_low = Low32Bits(value);
+    int32_t val_high = High32Bits(value);
+
+    __ Cmp(left_high, val_high);
+    if (if_cond == kCondNE) {
+      __ B(ARMCondition(true_high_cond), true_label);
+    } else if (if_cond == kCondEQ) {
+      __ B(ARMCondition(false_high_cond), false_label);
+    } else {
+      __ B(ARMCondition(true_high_cond), true_label);
+      __ B(ARMCondition(false_high_cond), false_label);
+    }
+    // Must be equal high, so compare the lows.
+    __ Cmp(left_low, val_low);
+  } else {
+    vixl32::Register right_high = HighRegisterFrom(right);
+    vixl32::Register right_low = LowRegisterFrom(right);
+
+    __ Cmp(left_high, right_high);
+    if (if_cond == kCondNE) {
+      __ B(ARMCondition(true_high_cond), true_label);
+    } else if (if_cond == kCondEQ) {
+      __ B(ARMCondition(false_high_cond), false_label);
+    } else {
+      __ B(ARMCondition(true_high_cond), true_label);
+      __ B(ARMCondition(false_high_cond), false_label);
+    }
+    // Must be equal high, so compare the lows.
+    __ Cmp(left_low, right_low);
+  }
+  // The last comparison might be unsigned.
+  // TODO: optimize cases where this is always true/false
+  __ B(final_condition, true_label);
+}
+
 void InstructionCodeGeneratorARMVIXL::GenerateCompareTestAndBranch(HCondition* condition,
                                                                    vixl32::Label* true_target_in,
                                                                    vixl32::Label* false_target_in) {
@@ -2903,7 +2579,7 @@
   vixl32::Label* false_target = (false_target_in == nullptr) ? &fallthrough : false_target_in;
 
   DCHECK_EQ(condition->InputAt(0)->GetType(), Primitive::kPrimLong);
-  GenerateLongComparesAndJumps(condition, true_target, false_target, codegen_);
+  GenerateLongComparesAndJumps(condition, true_target, false_target);
 
   if (false_target != &fallthrough) {
     __ B(false_target);
@@ -3211,83 +2887,6 @@
   __ Nop();
 }
 
-// `temp` is an extra temporary register that is used for some conditions;
-// callers may not specify it, in which case the method will use a scratch
-// register instead.
-void CodeGeneratorARMVIXL::GenerateConditionWithZero(IfCondition condition,
-                                                     vixl32::Register out,
-                                                     vixl32::Register in,
-                                                     vixl32::Register temp) {
-  switch (condition) {
-    case kCondEQ:
-    // x <= 0 iff x == 0 when the comparison is unsigned.
-    case kCondBE:
-      if (!temp.IsValid() || (out.IsLow() && !out.Is(in))) {
-        temp = out;
-      }
-
-      // Avoid 32-bit instructions if possible; note that `in` and `temp` must be
-      // different as well.
-      if (in.IsLow() && temp.IsLow() && !in.Is(temp)) {
-        // temp = - in; only 0 sets the carry flag.
-        __ Rsbs(temp, in, 0);
-
-        if (out.Is(in)) {
-          std::swap(in, temp);
-        }
-
-        // out = - in + in + carry = carry
-        __ Adc(out, temp, in);
-      } else {
-        // If `in` is 0, then it has 32 leading zeros, and less than that otherwise.
-        __ Clz(out, in);
-        // Any number less than 32 logically shifted right by 5 bits results in 0;
-        // the same operation on 32 yields 1.
-        __ Lsr(out, out, 5);
-      }
-
-      break;
-    case kCondNE:
-    // x > 0 iff x != 0 when the comparison is unsigned.
-    case kCondA: {
-      UseScratchRegisterScope temps(GetVIXLAssembler());
-
-      if (out.Is(in)) {
-        if (!temp.IsValid() || in.Is(temp)) {
-          temp = temps.Acquire();
-        }
-      } else if (!temp.IsValid() || !temp.IsLow()) {
-        temp = out;
-      }
-
-      // temp = in - 1; only 0 does not set the carry flag.
-      __ Subs(temp, in, 1);
-      // out = in + ~temp + carry = in + (-(in - 1) - 1) + carry = in - in + 1 - 1 + carry = carry
-      __ Sbc(out, in, temp);
-      break;
-    }
-    case kCondGE:
-      __ Mvn(out, in);
-      in = out;
-      FALLTHROUGH_INTENDED;
-    case kCondLT:
-      // We only care about the sign bit.
-      __ Lsr(out, in, 31);
-      break;
-    case kCondAE:
-      // Trivially true.
-      __ Mov(out, 1);
-      break;
-    case kCondB:
-      // Trivially false.
-      __ Mov(out, 0);
-      break;
-    default:
-      LOG(FATAL) << "Unexpected condition " << condition;
-      UNREACHABLE();
-  }
-}
-
 void LocationsBuilderARMVIXL::HandleCondition(HCondition* cond) {
   LocationSummary* locations =
       new (GetGraph()->GetArena()) LocationSummary(cond, LocationSummary::kNoCall);
@@ -3324,41 +2923,52 @@
     return;
   }
 
-  const Primitive::Type type = cond->GetLeft()->GetType();
+  const vixl32::Register out = OutputRegister(cond);
 
-  if (Primitive::IsFloatingPointType(type)) {
-    GenerateConditionGeneric(cond, codegen_);
+  if (out.IsLow() && CanGenerateTest(cond, codegen_->GetAssembler())) {
+    const auto condition = GenerateTest(cond, false, codegen_);
+    // We use the scope because of the IT block that follows.
+    ExactAssemblyScope guard(GetVIXLAssembler(),
+                             4 * vixl32::k16BitT32InstructionSizeInBytes,
+                             CodeBufferCheckScope::kExactSize);
+
+    __ it(condition.first);
+    __ mov(condition.first, out, 1);
+    __ it(condition.second);
+    __ mov(condition.second, out, 0);
     return;
   }
 
-  DCHECK(Primitive::IsIntegralType(type) || type == Primitive::kPrimNot) << type;
+  // Convert the jumps into the result.
+  vixl32::Label done_label;
+  vixl32::Label* const final_label = codegen_->GetFinalLabel(cond, &done_label);
 
-  if (type == Primitive::kPrimBoolean) {
-    const IfCondition c = cond->GetCondition();
-    vixl32::Register left = InputRegisterAt(cond, 0);
-    const vixl32::Register out = OutputRegister(cond);
-    const Location right_loc = cond->GetLocations()->InAt(1);
+  if (cond->InputAt(0)->GetType() == Primitive::kPrimLong) {
+    vixl32::Label true_label, false_label;
 
-    // All other cases are handled by the instruction simplifier.
-    DCHECK((c == kCondEQ || c == kCondNE) && !right_loc.IsConstant());
+    GenerateLongComparesAndJumps(cond, &true_label, &false_label);
 
-    vixl32::Register right = RegisterFrom(right_loc);
+    // False case: result = 0.
+    __ Bind(&false_label);
+    __ Mov(out, 0);
+    __ B(final_label);
 
-    // Avoid 32-bit instructions if possible.
-    if (out.Is(right)) {
-      std::swap(left, right);
-    }
+    // True case: result = 1.
+    __ Bind(&true_label);
+    __ Mov(out, 1);
+  } else {
+    DCHECK(CanGenerateTest(cond, codegen_->GetAssembler()));
 
-    __ Eor(out, left, right);
+    const auto condition = GenerateTest(cond, false, codegen_);
 
-    if (c == kCondEQ) {
-      __ Eor(out, out, 1);
-    }
-
-    return;
+    __ Mov(LeaveFlags, out, 0);
+    __ B(condition.second, final_label, /* far_target */ false);
+    __ Mov(out, 1);
   }
 
-  GenerateConditionIntegralOrNonPrimitive(cond, codegen_);
+  if (done_label.IsReferenced()) {
+    __ Bind(&done_label);
+  }
 }
 
 void LocationsBuilderARMVIXL::VisitEqual(HEqual* comp) {
diff --git a/compiler/optimizing/code_generator_arm_vixl.h b/compiler/optimizing/code_generator_arm_vixl.h
index 26416c8..1e9669d 100644
--- a/compiler/optimizing/code_generator_arm_vixl.h
+++ b/compiler/optimizing/code_generator_arm_vixl.h
@@ -401,6 +401,9 @@
   void GenerateCompareTestAndBranch(HCondition* condition,
                                     vixl::aarch32::Label* true_target,
                                     vixl::aarch32::Label* false_target);
+  void GenerateLongComparesAndJumps(HCondition* cond,
+                                    vixl::aarch32::Label* true_label,
+                                    vixl::aarch32::Label* false_label);
   void DivRemOneOrMinusOne(HBinaryOperation* instruction);
   void DivRemByPowerOfTwo(HBinaryOperation* instruction);
   void GenerateDivRemWithAnyConstant(HBinaryOperation* instruction);
@@ -696,14 +699,6 @@
   void EmitMovwMovtPlaceholder(CodeGeneratorARMVIXL::PcRelativePatchInfo* labels,
                                vixl::aarch32::Register out);
 
-  // `temp` is an extra temporary register that is used for some conditions;
-  // callers may not specify it, in which case the method will use a scratch
-  // register instead.
-  void GenerateConditionWithZero(IfCondition condition,
-                                 vixl::aarch32::Register out,
-                                 vixl::aarch32::Register in,
-                                 vixl::aarch32::Register temp = vixl32::Register());
-
  private:
   vixl::aarch32::Register GetInvokeStaticOrDirectExtraParameter(HInvokeStaticOrDirect* invoke,
                                                                 vixl::aarch32::Register temp);
diff --git a/compiler/optimizing/intrinsics_arm.cc b/compiler/optimizing/intrinsics_arm.cc
index 7769b14..750f9cc 100644
--- a/compiler/optimizing/intrinsics_arm.cc
+++ b/compiler/optimizing/intrinsics_arm.cc
@@ -2599,7 +2599,11 @@
   // We don't care about the sign bit, so shift left.
   __ Lsl(out, out, 1);
   __ eor(out, out, ShifterOperand(infinity));
-  codegen_->GenerateConditionWithZero(kCondEQ, out, out);
+  // If the result is 0, then it has 32 leading zeros, and less than that otherwise.
+  __ clz(out, out);
+  // Any number less than 32 logically shifted right by 5 bits results in 0;
+  // the same operation on 32 yields 1.
+  __ Lsr(out, out, 5);
 }
 
 void IntrinsicLocationsBuilderARM::VisitDoubleIsInfinite(HInvoke* invoke) {
@@ -2622,7 +2626,11 @@
   __ eor(out, out, ShifterOperand(infinity_high2));
   // We don't care about the sign bit, so shift left.
   __ orr(out, IP, ShifterOperand(out, LSL, 1));
-  codegen_->GenerateConditionWithZero(kCondEQ, out, out);
+  // If the result is 0, then it has 32 leading zeros, and less than that otherwise.
+  __ clz(out, out);
+  // Any number less than 32 logically shifted right by 5 bits results in 0;
+  // the same operation on 32 yields 1.
+  __ Lsr(out, out, 5);
 }
 
 void IntrinsicLocationsBuilderARM::VisitReferenceGetReferent(HInvoke* invoke) {
diff --git a/compiler/optimizing/intrinsics_arm_vixl.cc b/compiler/optimizing/intrinsics_arm_vixl.cc
index b62c1b5..fd8a37a 100644
--- a/compiler/optimizing/intrinsics_arm_vixl.cc
+++ b/compiler/optimizing/intrinsics_arm_vixl.cc
@@ -2972,7 +2972,11 @@
   // We don't care about the sign bit, so shift left.
   __ Lsl(out, out, 1);
   __ Eor(out, out, infinity);
-  codegen_->GenerateConditionWithZero(kCondEQ, out, out);
+  // If the result is 0, then it has 32 leading zeros, and less than that otherwise.
+  __ Clz(out, out);
+  // Any number less than 32 logically shifted right by 5 bits results in 0;
+  // the same operation on 32 yields 1.
+  __ Lsr(out, out, 5);
 }
 
 void IntrinsicLocationsBuilderARMVIXL::VisitDoubleIsInfinite(HInvoke* invoke) {
@@ -2998,7 +3002,11 @@
   __ Eor(out, out, infinity_high2);
   // We don't care about the sign bit, so shift left.
   __ Orr(out, temp, Operand(out, vixl32::LSL, 1));
-  codegen_->GenerateConditionWithZero(kCondEQ, out, out);
+  // If the result is 0, then it has 32 leading zeros, and less than that otherwise.
+  __ Clz(out, out);
+  // Any number less than 32 logically shifted right by 5 bits results in 0;
+  // the same operation on 32 yields 1.
+  __ Lsr(out, out, 5);
 }
 
 void IntrinsicLocationsBuilderARMVIXL::VisitReferenceGetReferent(HInvoke* invoke) {
diff --git a/test/409-materialized-condition/src/Main.java b/test/409-materialized-condition/src/Main.java
index 8a814a2..0c179a9 100644
--- a/test/409-materialized-condition/src/Main.java
+++ b/test/409-materialized-condition/src/Main.java
@@ -50,36 +50,6 @@
     return b;
   }
 
-  public static boolean $noinline$intEq0(int x) {
-    return x == 0;
-  }
-
-  public static boolean $noinline$intNe0(int x) {
-    return x != 0;
-  }
-
-  public static boolean $noinline$longEq0(long x) {
-    return x == 0;
-  }
-
-  public static boolean $noinline$longNe0(long x) {
-    return x != 0;
-  }
-
-  public static boolean $noinline$longEqCst(long x) {
-    return x == 0x0123456789ABCDEFL;
-  }
-
-  public static boolean $noinline$longNeCst(long x) {
-    return x != 0x0123456789ABCDEFL;
-  }
-
-  public static void assertEqual(boolean expected, boolean actual) {
-    if (expected != actual) {
-      throw new Error("Assertion failed: " + expected + " != " + actual);
-    }
-  }
-
   public static void main(String[] args) {
     System.out.println("foo1");
     int res = foo1();
@@ -92,46 +62,5 @@
     if (res != 42) {
       throw new Error("Unexpected return value for foo2: " + res + ", expected 42.");
     }
-
-    int[] int_inputs = {0, 1, -1, Integer.MIN_VALUE, Integer.MAX_VALUE, 42, -9000};
-    long[] long_inputs = {
-        0L, 1L, -1L, Long.MIN_VALUE, Long.MAX_VALUE, 0x100000000L,
-        0x100000001L, -9000L, 0x0123456789ABCDEFL};
-
-    boolean[] int_eq_0_expected = {true, false, false, false, false, false, false};
-
-    for (int i = 0; i < int_inputs.length; i++) {
-      assertEqual(int_eq_0_expected[i], $noinline$intEq0(int_inputs[i]));
-    }
-
-    boolean[] int_ne_0_expected = {false, true, true, true, true, true, true};
-
-    for (int i = 0; i < int_inputs.length; i++) {
-      assertEqual(int_ne_0_expected[i], $noinline$intNe0(int_inputs[i]));
-    }
-
-    boolean[] long_eq_0_expected = {true, false, false, false, false, false, false, false, false};
-
-    for (int i = 0; i < long_inputs.length; i++) {
-      assertEqual(long_eq_0_expected[i], $noinline$longEq0(long_inputs[i]));
-    }
-
-    boolean[] long_ne_0_expected = {false, true, true, true, true, true, true, true, true};
-
-    for (int i = 0; i < long_inputs.length; i++) {
-      assertEqual(long_ne_0_expected[i], $noinline$longNe0(long_inputs[i]));
-    }
-
-    boolean[] long_eq_cst_expected = {false, false, false, false, false, false, false, false, true};
-
-    for (int i = 0; i < long_inputs.length; i++) {
-      assertEqual(long_eq_cst_expected[i], $noinline$longEqCst(long_inputs[i]));
-    }
-
-    boolean[] long_ne_cst_expected = {true, true, true, true, true, true, true, true, false};
-
-    for (int i = 0; i < long_inputs.length; i++) {
-      assertEqual(long_ne_cst_expected[i], $noinline$longNeCst(long_inputs[i]));
-    }
   }
 }
diff --git a/test/570-checker-select/src/Main.java b/test/570-checker-select/src/Main.java
index 2dad14c..3ac6f89 100644
--- a/test/570-checker-select/src/Main.java
+++ b/test/570-checker-select/src/Main.java
@@ -414,46 +414,6 @@
     return a > 0x7FFFFFFFFFFFFFFFL ? x : y;
   }
 
-  /// CHECK-START-ARM: long Main.$noinline$LongNonmatCondCst_LongVarVar4(long, long, long) disassembly (after)
-  /// CHECK:               Select
-  /// CHECK-NEXT:            orrs ip, {{r\d+}}, {{r\d+}}
-  /// CHECK-NOT:             cmp
-  /// CHECK-NOT:             sbcs
-
-  public static long $noinline$LongNonmatCondCst_LongVarVar4(long a, long x, long y) {
-    return a == 0 ? x : y;
-  }
-
-  /// CHECK-START-ARM: long Main.$noinline$LongNonmatCondCst_LongVarVar5(long, long, long) disassembly (after)
-  /// CHECK:               Select
-  /// CHECK-NEXT:            orrs ip, {{r\d+}}, {{r\d+}}
-  /// CHECK-NOT:             cmp
-  /// CHECK-NOT:             sbcs
-
-  public static long $noinline$LongNonmatCondCst_LongVarVar5(long a, long x, long y) {
-    return a != 0 ? x : y;
-  }
-
-  /// CHECK-START-ARM: long Main.$noinline$LongNonmatCondCst_LongVarVar6(long, long, long) disassembly (after)
-  /// CHECK:               Select
-  /// CHECK-NEXT:            cmp {{r\d+}}, #0
-  /// CHECK-NOT:             cmp
-  /// CHECK-NOT:             sbcs
-
-  public static long $noinline$LongNonmatCondCst_LongVarVar6(long a, long x, long y) {
-    return a >= 0 ? x : y;
-  }
-
-  /// CHECK-START-ARM: long Main.$noinline$LongNonmatCondCst_LongVarVar7(long, long, long) disassembly (after)
-  /// CHECK:               Select
-  /// CHECK-NEXT:            cmp {{r\d+}}, #0
-  /// CHECK-NOT:             cmp
-  /// CHECK-NOT:             sbcs
-
-  public static long $noinline$LongNonmatCondCst_LongVarVar7(long a, long x, long y) {
-    return a < 0 ? x : y;
-  }
-
   /// CHECK-START: long Main.LongMatCond_LongVarVar(long, long, long, long) register (after)
   /// CHECK:            <<Cond:z\d+>> LessThanOrEqual [{{j\d+}},{{j\d+}}]
   /// CHECK:            <<Sel1:j\d+>> Select [{{j\d+}},{{j\d+}},<<Cond>>]
@@ -728,37 +688,6 @@
 
     assertEqual(7L, $noinline$LongNonmatCondCst_LongVarVar3(2L, 5L, 7L));
 
-    long[] long_inputs = {
-        0L, 1L, -1L, Long.MIN_VALUE, Long.MAX_VALUE, 2L, 0x100000000L, 0xFFFFFFFF00000000L, -9000L};
-
-    long[] expected_1 = {5L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L};
-
-    for (int i = 0; i < long_inputs.length; i++) {
-      assertEqual(expected_1[i], $noinline$LongNonmatCondCst_LongVarVar4(long_inputs[i], 5L, 7L));
-    }
-
-    long[] expected_2 = {7L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L};
-
-    for (int i = 0; i < long_inputs.length; i++) {
-      assertEqual(expected_2[i], $noinline$LongNonmatCondCst_LongVarVar5(long_inputs[i], 5L, 7L));
-    }
-
-    long[] expected_3 = {5L, 5L, 7L, 7L, 5L, 5L, 5L, 7L, 7L};
-
-    for (int i = 0; i < long_inputs.length; i++) {
-      assertEqual(expected_3[i], $noinline$LongNonmatCondCst_LongVarVar6(long_inputs[i], 5L, 7L));
-    }
-
-    long[] expected_4 = {7L, 7L, 5L, 5L, 7L, 7L, 7L, 5L, 5L};
-
-    for (int i = 0; i < long_inputs.length; i++) {
-      assertEqual(expected_4[i], $noinline$LongNonmatCondCst_LongVarVar7(long_inputs[i], 5L, 7L));
-    }
-
-    assertEqual(7L, $noinline$LongNonmatCondCst_LongVarVar7(0L, 5L, 7L));
-    assertEqual(7L, $noinline$LongNonmatCondCst_LongVarVar7(2L, 5L, 7L));
-    assertEqual(5L, $noinline$LongNonmatCondCst_LongVarVar7(-9000L, 5L, 7L));
-
     assertEqual(5, FloatLtNonmatCond_IntVarVar(3, 2, 5, 7));
     assertEqual(7, FloatLtNonmatCond_IntVarVar(2, 3, 5, 7));
     assertEqual(7, FloatLtNonmatCond_IntVarVar(Float.NaN, 2, 5, 7));