maxval = (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (mode) - 1)) - 1;
+ /* For floating-point comparisons, prefer >= and > over <= and < since
+ the former are supported by VSEL on some architectures. Only do this
+ if both operands are registers. */
+ if (GET_MODE_CLASS (mode) == MODE_FLOAT
+ && (*code == LE
+ || *code == LT
+ || *code == UNGT
+ || *code == UNGE)
+ && register_operand (*op0, mode)
+ && register_operand (*op1, mode))
+ {
+ std::swap (*op0, *op1);
+ *code = (int) swap_condition ((rtx_code)*code);
+ return;
+ }
+
/* For DImode, we have GE/LT/GEU/LTU comparisons (with cmp/sbc). In
ARM mode we can also use cmp/cmpeq for GTU/LEU. GT/LE must be
either reversed or (for constant OP1) adjusted to GE/LT.
case E_HFmode:
if (!TARGET_VFP_FP16INST)
break;
+ if (!arm_vsel_comparison_operator (*comparison, mode))
+ return false;
+
/* FP16 comparisons are done in SF mode. */
mode = SFmode;
*op1 = convert_to_mode (mode, *op1, 1);
}
/* { dg-final { scan-assembler-times {vseleq\.f16\ts[0-9]+, s[0-9]+, s[0-9]+} 4 } } */
-/* { dg-final { scan-assembler-times {vselgt\.f16\ts[0-9]+, s[0-9]+, s[0-9]+} 1 } } */
-/* { dg-final { scan-assembler-times {vselge\.f16\ts[0-9]+, s[0-9]+, s[0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {vselgt\.f16\ts[0-9]+, s[0-9]+, s[0-9]+} 2 } } */
+/* { dg-final { scan-assembler-times {vselge\.f16\ts[0-9]+, s[0-9]+, s[0-9]+} 2 } } */
/* { dg-final { scan-assembler-not {vmov\.f16} } } */