[PATCH] [AArch64] Codegen VMAX/VMIN for safe math cases

Artyom Skrobov artyom.skrobov at arm.com
Wed May 13 03:49:55 PDT 2015


Renato, thank you for your review!

>> OK to commit?
> Only one nitpick:
>
> +  bool IsUnordered;
> +  switch (CC) {
> +  default: break;
>
> IsUnordered is unused outside of the switch. It won't make any
> difference to declare it just because both cases use it, as opposed to
> declaring it on both.

What do you think of a refactoring like this (instead of the switch and the subsequent code), to take the common code out of the two cases?

==========
  bool IsUnordered = false, IsOrEqual;
  switch (CC) {
  default:
    return SDValue();
  case ISD::SETULT:
  case ISD::SETULE:
    IsUnordered = true;
  case ISD::SETOLT:
  case ISD::SETOLE:
  case ISD::SETLT:
  case ISD::SETLE:
    IsOrEqual = (CC == ISD::SETLE || CC == ISD::SETOLE || CC == ISD::SETULE);
    Opcode = IsReversed ? AArch64ISD::FMAX : AArch64ISD::FMIN;
    break;

  case ISD::SETUGT:
  case ISD::SETUGE:
    IsUnordered = true;
  case ISD::SETOGT:
  case ISD::SETOGE:
  case ISD::SETGT:
  case ISD::SETGE:
    IsOrEqual = (CC == ISD::SETGE || CC == ISD::SETOGE || CC == ISD::SETUGE);
    Opcode = IsReversed ? AArch64ISD::FMIN : AArch64ISD::FMAX;
    break;
  }

  // If LHS is NaN, an ordered comparison will be false and the result will be
  // the RHS, but FMIN(NaN, RHS) = FMAX(NaN, RHS) = NaN. Avoid this by checking
  // that LHS != NaN. Likewise, for unordered comparisons, check for RHS != NaN.
  if (!DAG.isKnownNeverNaN(IsUnordered ? RHS : LHS))
    return SDValue();

  // For xxx-or-equal comparisons, "+0 <= -0" and "-0 >= +0" will both be true,
  // but FMIN will return -0, and FMAX will return +0. So FMIN/FMAX can only be
  // used for unsafe math or if one of the operands is known to be nonzero.
  if (IsOrEqual && !DAG.getTarget().Options.UnsafeFPMath &&
      !(DAG.isKnownNeverZero(LHS) || DAG.isKnownNeverZero(RHS)))
    return SDValue();

  return DAG.getNode(Opcode, SDLoc(N), N->getValueType(0), LHS, RHS);
==========

The same refactoring may be performed in ARMTargetLowering::PerformSELECT_CCCombine, too.







More information about the llvm-commits mailing list