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));
