- // We only do this in unsafe-fp-math, because signed zeros and NaNs are
- // handled differently than the original code sequence.
- if (getTargetMachine().Options.UnsafeFPMath) {
- if (LHS == TrueVal && RHS == FalseVal) {
- if (CC == ISD::SETOGT || CC == ISD::SETUGT)
- return DAG.getNode(ARMISD::VMAXNM, dl, VT, TrueVal, FalseVal);
- if (CC == ISD::SETOLT || CC == ISD::SETULT)
- return DAG.getNode(ARMISD::VMINNM, dl, VT, TrueVal, FalseVal);
- } else if (LHS == FalseVal && RHS == TrueVal) {
- if (CC == ISD::SETOLT || CC == ISD::SETULT)
- return DAG.getNode(ARMISD::VMAXNM, dl, VT, TrueVal, FalseVal);
- if (CC == ISD::SETOGT || CC == ISD::SETUGT)
- return DAG.getNode(ARMISD::VMINNM, dl, VT, TrueVal, FalseVal);
+ // In NoNaNsFPMath the CC will have been changed from, e.g., 'ogt' to 'gt'.
+ bool swapSides = false;
+ if (!getTargetMachine().Options.NoNaNsFPMath) {
+ // transformability may depend on which way around we compare
+ switch (CC) {
+ default:
+ break;
+ case ISD::SETOGT:
+ case ISD::SETOGE:
+ case ISD::SETOLT:
+ case ISD::SETOLE:
+ // the non-NaN should be RHS
+ swapSides = DAG.isKnownNeverNaN(LHS) && !DAG.isKnownNeverNaN(RHS);
+ break;
+ case ISD::SETUGT:
+ case ISD::SETUGE:
+ case ISD::SETULT:
+ case ISD::SETULE:
+ // the non-NaN should be LHS
+ swapSides = DAG.isKnownNeverNaN(RHS) && !DAG.isKnownNeverNaN(LHS);
+ break;
+ }
+ }
+ swapSides = swapSides || (LHS == FalseVal && RHS == TrueVal);
+ if (swapSides) {
+ CC = ISD::getSetCCSwappedOperands(CC);
+ std::swap(LHS, RHS);
+ }
+ if (LHS == TrueVal && RHS == FalseVal) {
+ bool canTransform = true;
+ // FIXME: FastMathFlags::noSignedZeros() doesn't appear reachable from here
+ if (!getTargetMachine().Options.UnsafeFPMath &&
+ !DAG.isKnownNeverZero(LHS) && !DAG.isKnownNeverZero(RHS)) {
+ const ConstantFPSDNode *Zero;
+ switch (CC) {
+ default:
+ break;
+ case ISD::SETOGT:
+ case ISD::SETUGT:
+ case ISD::SETGT:
+ // RHS must not be -0
+ canTransform = (Zero = dyn_cast<ConstantFPSDNode>(RHS)) &&
+ !Zero->isNegative();
+ break;
+ case ISD::SETOGE:
+ case ISD::SETUGE:
+ case ISD::SETGE:
+ // LHS must not be -0
+ canTransform = (Zero = dyn_cast<ConstantFPSDNode>(LHS)) &&
+ !Zero->isNegative();
+ break;
+ case ISD::SETOLT:
+ case ISD::SETULT:
+ case ISD::SETLT:
+ // RHS must not be +0
+ canTransform = (Zero = dyn_cast<ConstantFPSDNode>(RHS)) &&
+ Zero->isNegative();
+ break;
+ case ISD::SETOLE:
+ case ISD::SETULE:
+ case ISD::SETLE:
+ // LHS must not be +0
+ canTransform = (Zero = dyn_cast<ConstantFPSDNode>(LHS)) &&
+ Zero->isNegative();
+ break;
+ }
+ }
+ if (canTransform) {
+ // Note: If one of the elements in a pair is a number and the other
+ // element is NaN, the corresponding result element is the number.
+ // This is consistent with the IEEE 754-2008 standard.
+ // Therefore, a > b ? a : b <=> vmax(a,b), if b is constant and a is NaN
+ switch (CC) {
+ default:
+ break;
+ case ISD::SETOGT:
+ case ISD::SETOGE:
+ if (!DAG.isKnownNeverNaN(RHS))
+ break;
+ return DAG.getNode(ARMISD::VMAXNM, dl, VT, LHS, RHS);
+ case ISD::SETUGT:
+ case ISD::SETUGE:
+ if (!DAG.isKnownNeverNaN(LHS))
+ break;
+ case ISD::SETGT:
+ case ISD::SETGE:
+ return DAG.getNode(ARMISD::VMAXNM, dl, VT, LHS, RHS);
+ case ISD::SETOLT:
+ case ISD::SETOLE:
+ if (!DAG.isKnownNeverNaN(RHS))
+ break;
+ return DAG.getNode(ARMISD::VMINNM, dl, VT, LHS, RHS);
+ case ISD::SETULT:
+ case ISD::SETULE:
+ if (!DAG.isKnownNeverNaN(LHS))
+ break;
+ case ISD::SETLT:
+ case ISD::SETLE:
+ return DAG.getNode(ARMISD::VMINNM, dl, VT, LHS, RHS);
+ }