llvm.org GIT mirror llvm / 8d44b28
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 Dan Gohman 11 years ago
4 changed file(s) with 112 addition(s) and 3 deletion(s). Raw diff Collapse all Expand all
839839 /// class to allow target nodes to be understood.
840840 unsigned ComputeNumSignBits(SDValue Op, unsigned Depth = 0) const;
841841
842 /// isKnownNeverNan - Test whether the given SDValue is known to never be NaN.
843 bool isKnownNeverNaN(SDValue Op) const;
844
842845 /// isVerifiedDebugInfoDesc - Returns true if the specified SDValue has
843846 /// been verified as a debug information descriptor.
844847 bool isVerifiedDebugInfoDesc(SDValue Op) const;
21972197 return std::max(FirstAnswer, std::min(VTBits, Mask.countLeadingZeros()));
21982198 }
21992199
2200 bool SelectionDAG::isKnownNeverNaN(SDValue Op) const {
2201 // If we're told that NaNs won't happen, assume they won't.
2202 if (FiniteOnlyFPMath())
2203 return true;
2204
2205 // If the value is a constant, we can obviously see if it is a NaN or not.
2206 if (const ConstantFPSDNode *C = dyn_cast(Op))
2207 return !C->getValueAPF().isNaN();
2208
2209 // TODO: Recognize more cases here.
2210
2211 return false;
2212 }
22002213
22012214 bool SelectionDAG::isVerifiedDebugInfoDesc(SDValue Op) const {
22022215 GlobalAddressSDNode *GA = dyn_cast(Op);
82498249 } else if (LHS == Cond.getOperand(1) && RHS == Cond.getOperand(0)) {
82508250 switch (CC) {
82518251 default: break;
8252 case ISD::SETOGT: // (X > Y) ? Y : X -> min
8253 case ISD::SETUGT:
8252 case ISD::SETOGT:
8253 // This can use a min only if the LHS isn't NaN.
8254 if (DAG.isKnownNeverNaN(LHS))
8255 Opcode = X86ISD::FMIN;
8256 else if (DAG.isKnownNeverNaN(RHS)) {
8257 Opcode = X86ISD::FMIN;
8258 // Put the potential NaN in the RHS so that SSE will preserve it.
8259 std::swap(LHS, RHS);
8260 }
8261 break;
8262
8263 case ISD::SETUGT: // (X > Y) ? Y : X -> min
82548264 case ISD::SETGT:
82558265 if (!UnsafeFPMath) break;
82568266 // FALL THROUGH.
82598269 Opcode = X86ISD::FMIN;
82608270 break;
82618271
8272 case ISD::SETULE:
8273 // This can use a max only if the LHS isn't NaN.
8274 if (DAG.isKnownNeverNaN(LHS))
8275 Opcode = X86ISD::FMAX;
8276 else if (DAG.isKnownNeverNaN(RHS)) {
8277 Opcode = X86ISD::FMAX;
8278 // Put the potential NaN in the RHS so that SSE will preserve it.
8279 std::swap(LHS, RHS);
8280 }
8281 break;
8282
82628283 case ISD::SETOLE: // (X <= Y) ? Y : X -> max
8263 case ISD::SETULE:
82648284 case ISD::SETLE:
82658285 if (!UnsafeFPMath) break;
82668286 // FALL THROUGH.
0 ; RUN: llvm-as < %s | llc -march=x86-64 | FileCheck %s
1
2 ; CHECK: clampTo3k_a:
3 ; CHECK: minsd
4 define double @clampTo3k_a(double %x) nounwind readnone {
5 entry:
6 %0 = fcmp ogt double %x, 3.000000e+03 ; [#uses=1]
7 %x_addr.0 = select i1 %0, double 3.000000e+03, double %x ; [#uses=1]
8 ret double %x_addr.0
9 }
10
11 ; CHECK: clampTo3k_b:
12 ; CHECK: minsd
13 define double @clampTo3k_b(double %x) nounwind readnone {
14 entry:
15 %0 = fcmp uge double %x, 3.000000e+03 ; [#uses=1]
16 %x_addr.0 = select i1 %0, double 3.000000e+03, double %x ; [#uses=1]
17 ret double %x_addr.0
18 }
19
20 ; CHECK: clampTo3k_c:
21 ; CHECK: maxsd
22 define double @clampTo3k_c(double %x) nounwind readnone {
23 entry:
24 %0 = fcmp olt double %x, 3.000000e+03 ; [#uses=1]
25 %x_addr.0 = select i1 %0, double 3.000000e+03, double %x ; [#uses=1]
26 ret double %x_addr.0
27 }
28
29 ; CHECK: clampTo3k_d:
30 ; CHECK: maxsd
31 define double @clampTo3k_d(double %x) nounwind readnone {
32 entry:
33 %0 = fcmp ule double %x, 3.000000e+03 ; [#uses=1]
34 %x_addr.0 = select i1 %0, double 3.000000e+03, double %x ; [#uses=1]
35 ret double %x_addr.0
36 }
37
38 ; CHECK: clampTo3k_e:
39 ; CHECK: maxsd
40 define double @clampTo3k_e(double %x) nounwind readnone {
41 entry:
42 %0 = fcmp olt double %x, 3.000000e+03 ; [#uses=1]
43 %x_addr.0 = select i1 %0, double 3.000000e+03, double %x ; [#uses=1]
44 ret double %x_addr.0
45 }
46
47 ; CHECK: clampTo3k_f:
48 ; CHECK: maxsd
49 define double @clampTo3k_f(double %x) nounwind readnone {
50 entry:
51 %0 = fcmp ule double %x, 3.000000e+03 ; [#uses=1]
52 %x_addr.0 = select i1 %0, double 3.000000e+03, double %x ; [#uses=1]
53 ret double %x_addr.0
54 }
55
56 ; CHECK: clampTo3k_g:
57 ; CHECK: minsd
58 define double @clampTo3k_g(double %x) nounwind readnone {
59 entry:
60 %0 = fcmp ogt double %x, 3.000000e+03 ; [#uses=1]
61 %x_addr.0 = select i1 %0, double 3.000000e+03, double %x ; [#uses=1]
62 ret double %x_addr.0
63 }
64
65 ; CHECK: clampTo3k_h:
66 ; CHECK: minsd
67 define double @clampTo3k_h(double %x) nounwind readnone {
68 entry:
69 %0 = fcmp uge double %x, 3.000000e+03 ; [#uses=1]
70 %x_addr.0 = select i1 %0, double 3.000000e+03, double %x ; [#uses=1]
71 ret double %x_addr.0
72 }