diff options
author | Dan Gohman <gohman@apple.com> | 2009-09-03 20:34:31 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2009-09-03 20:34:31 +0000 |
commit | 8d44b28bc6f615b9ad79b066987d53b1ea2a2942 (patch) | |
tree | 4bfaf2eca9b8910a15985d9d8c2ddf10625a5f99 /lib | |
parent | 3653b13c52b9bce4fd9e2da3cbb893fc769adaec (diff) |
Recognize more opportunities to use SSE min and max instructions,
swapping the operands if necessary.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@80940 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 13 | ||||
-rw-r--r-- | lib/Target/X86/X86ISelLowering.cpp | 26 |
2 files changed, 36 insertions, 3 deletions
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 11f12c9475..0a523fa8dc 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -2198,6 +2198,19 @@ unsigned SelectionDAG::ComputeNumSignBits(SDValue Op, unsigned Depth) const{ return std::max(FirstAnswer, std::min(VTBits, Mask.countLeadingZeros())); } +bool SelectionDAG::isKnownNeverNaN(SDValue Op) const { + // If we're told that NaNs won't happen, assume they won't. + if (FiniteOnlyFPMath()) + return true; + + // If the value is a constant, we can obviously see if it is a NaN or not. + if (const ConstantFPSDNode *C = dyn_cast<ConstantFPSDNode>(Op)) + return !C->getValueAPF().isNaN(); + + // TODO: Recognize more cases here. + + return false; +} bool SelectionDAG::isVerifiedDebugInfoDesc(SDValue Op) const { GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Op); diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 9293755538..34e53f02ef 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -8250,8 +8250,18 @@ static SDValue PerformSELECTCombine(SDNode *N, SelectionDAG &DAG, } else if (LHS == Cond.getOperand(1) && RHS == Cond.getOperand(0)) { switch (CC) { default: break; - case ISD::SETOGT: // (X > Y) ? Y : X -> min - case ISD::SETUGT: + case ISD::SETOGT: + // This can use a min only if the LHS isn't NaN. + if (DAG.isKnownNeverNaN(LHS)) + Opcode = X86ISD::FMIN; + else if (DAG.isKnownNeverNaN(RHS)) { + Opcode = X86ISD::FMIN; + // Put the potential NaN in the RHS so that SSE will preserve it. + std::swap(LHS, RHS); + } + break; + + case ISD::SETUGT: // (X > Y) ? Y : X -> min case ISD::SETGT: if (!UnsafeFPMath) break; // FALL THROUGH. @@ -8260,8 +8270,18 @@ static SDValue PerformSELECTCombine(SDNode *N, SelectionDAG &DAG, Opcode = X86ISD::FMIN; break; - case ISD::SETOLE: // (X <= Y) ? Y : X -> max case ISD::SETULE: + // This can use a max only if the LHS isn't NaN. + if (DAG.isKnownNeverNaN(LHS)) + Opcode = X86ISD::FMAX; + else if (DAG.isKnownNeverNaN(RHS)) { + Opcode = X86ISD::FMAX; + // Put the potential NaN in the RHS so that SSE will preserve it. + std::swap(LHS, RHS); + } + break; + + case ISD::SETOLE: // (X <= Y) ? Y : X -> max case ISD::SETLE: if (!UnsafeFPMath) break; // FALL THROUGH. |