summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2009-09-03 20:34:31 +0000
committerDan Gohman <gohman@apple.com>2009-09-03 20:34:31 +0000
commitd0d5e685daf79262e38a5fe7e782c0372b2cf9f4 (patch)
tree6c12184afb09aa65d1ef0191a1d80e8553615f6b /llvm/lib
parent3c8a7dfada1d39b33a24f58e039d6ba5c6cb3857 (diff)
downloadbcm5719-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.cpp13
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.cpp26
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.
OpenPOWER on IntegriCloud