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 | d0d5e685daf79262e38a5fe7e782c0372b2cf9f4 (patch) | |
| tree | 6c12184afb09aa65d1ef0191a1d80e8553615f6b /llvm/lib | |
| parent | 3c8a7dfada1d39b33a24f58e039d6ba5c6cb3857 (diff) | |
| download | bcm5719-llvm-d0d5e685daf79262e38a5fe7e782c0372b2cf9f4.tar.gz bcm5719-llvm-d0d5e685daf79262e38a5fe7e782c0372b2cf9f4.zip | |
Recognize more opportunities to use SSE min and max instructions,
swapping the operands if necessary.
llvm-svn: 80940
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 13 | ||||
| -rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 26 |
2 files changed, 36 insertions, 3 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 11f12c9475f..0a523fa8dc2 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/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/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 9293755538d..34e53f02ef3 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/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. |

