/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===-------- LegalizeFloatTypes.cpp - Legalization of float types --------===// |
2 | | // |
3 | | // The LLVM Compiler Infrastructure |
4 | | // |
5 | | // This file is distributed under the University of Illinois Open Source |
6 | | // License. See LICENSE.TXT for details. |
7 | | // |
8 | | //===----------------------------------------------------------------------===// |
9 | | // |
10 | | // This file implements float type expansion and softening for LegalizeTypes. |
11 | | // Softening is the act of turning a computation in an illegal floating point |
12 | | // type into a computation in an integer type of the same size; also known as |
13 | | // "soft float". For example, turning f32 arithmetic into operations using i32. |
14 | | // The resulting integer value is the same as what you would get by performing |
15 | | // the floating point operation and bitcasting the result to the integer type. |
16 | | // Expansion is the act of changing a computation in an illegal type to be a |
17 | | // computation in two identical registers of a smaller type. For example, |
18 | | // implementing ppcf128 arithmetic in two f64 registers. |
19 | | // |
20 | | //===----------------------------------------------------------------------===// |
21 | | |
22 | | #include "LegalizeTypes.h" |
23 | | #include "llvm/Support/ErrorHandling.h" |
24 | | #include "llvm/Support/raw_ostream.h" |
25 | | using namespace llvm; |
26 | | |
27 | | #define DEBUG_TYPE "legalize-types" |
28 | | |
29 | | /// GetFPLibCall - Return the right libcall for the given floating point type. |
30 | | static RTLIB::Libcall GetFPLibCall(EVT VT, |
31 | | RTLIB::Libcall Call_F32, |
32 | | RTLIB::Libcall Call_F64, |
33 | | RTLIB::Libcall Call_F80, |
34 | | RTLIB::Libcall Call_F128, |
35 | 1.42k | RTLIB::Libcall Call_PPCF128) { |
36 | 1.42k | return |
37 | 562 | VT == MVT::f32 ? Call_F32 : |
38 | 858 | VT == MVT::f64 ? 858 Call_F64666 : |
39 | 192 | VT == MVT::f80 ? 192 Call_F800 : |
40 | 192 | VT == MVT::f128 ? 192 Call_F128145 : |
41 | 47 | VT == MVT::ppcf128 ? 47 Call_PPCF12847 : |
42 | 0 | RTLIB::UNKNOWN_LIBCALL; |
43 | 1.42k | } |
44 | | |
45 | | //===----------------------------------------------------------------------===// |
46 | | // Convert Float Results to Integer for Non-HW-supported Operations. |
47 | | //===----------------------------------------------------------------------===// |
48 | | |
49 | 6.58k | bool DAGTypeLegalizer::SoftenFloatResult(SDNode *N, unsigned ResNo) { |
50 | 6.58k | DEBUG(dbgs() << "Soften float result " << ResNo << ": "; N->dump(&DAG); |
51 | 6.58k | dbgs() << "\n"); |
52 | 6.58k | SDValue R = SDValue(); |
53 | 6.58k | |
54 | 6.58k | switch (N->getOpcode()) { |
55 | 0 | default: |
56 | | #ifndef NDEBUG |
57 | | dbgs() << "SoftenFloatResult #" << ResNo << ": "; |
58 | | N->dump(&DAG); dbgs() << "\n"; |
59 | | #endif |
60 | 0 | llvm_unreachable("Do not know how to soften the result of this operator!"); |
61 | 6.58k | |
62 | 458 | case ISD::Register: |
63 | 458 | case ISD::CopyFromReg: |
64 | 458 | case ISD::CopyToReg: |
65 | 458 | assert(isLegalInHWReg(N->getValueType(ResNo)) && |
66 | 458 | "Unsupported SoftenFloatRes opcode!"); |
67 | 458 | // Only when isLegalInHWReg, we can skip check of the operands. |
68 | 458 | R = SDValue(N, ResNo); |
69 | 458 | break; |
70 | 0 | case ISD::MERGE_VALUES:R = SoftenFloatRes_MERGE_VALUES(N, ResNo); break; |
71 | 2.06k | case ISD::BITCAST: R = SoftenFloatRes_BITCAST(N, ResNo); break; |
72 | 0 | case ISD::BUILD_PAIR: R = SoftenFloatRes_BUILD_PAIR(N); break; |
73 | 659 | case ISD::ConstantFP: R = SoftenFloatRes_ConstantFP(N, ResNo); break; |
74 | 33 | case ISD::EXTRACT_VECTOR_ELT: |
75 | 33 | R = SoftenFloatRes_EXTRACT_VECTOR_ELT(N, ResNo); break; |
76 | 10 | case ISD::FABS: R = SoftenFloatRes_FABS(N, ResNo); break; |
77 | 2 | case ISD::FMINNUM: R = SoftenFloatRes_FMINNUM(N); break; |
78 | 18 | case ISD::FMAXNUM: R = SoftenFloatRes_FMAXNUM(N); break; |
79 | 335 | case ISD::FADD: R = SoftenFloatRes_FADD(N); break; |
80 | 11 | case ISD::FCEIL: R = SoftenFloatRes_FCEIL(N); break; |
81 | 288 | case ISD::FCOPYSIGN: R = SoftenFloatRes_FCOPYSIGN(N, ResNo); break; |
82 | 6 | case ISD::FCOS: R = SoftenFloatRes_FCOS(N); break; |
83 | 138 | case ISD::FDIV: R = SoftenFloatRes_FDIV(N); break; |
84 | 5 | case ISD::FEXP: R = SoftenFloatRes_FEXP(N); break; |
85 | 5 | case ISD::FEXP2: R = SoftenFloatRes_FEXP2(N); break; |
86 | 12 | case ISD::FFLOOR: R = SoftenFloatRes_FFLOOR(N); break; |
87 | 5 | case ISD::FLOG: R = SoftenFloatRes_FLOG(N); break; |
88 | 5 | case ISD::FLOG2: R = SoftenFloatRes_FLOG2(N); break; |
89 | 5 | case ISD::FLOG10: R = SoftenFloatRes_FLOG10(N); break; |
90 | 7 | case ISD::FMA: R = SoftenFloatRes_FMA(N); break; |
91 | 625 | case ISD::FMUL: R = SoftenFloatRes_FMUL(N); break; |
92 | 11 | case ISD::FNEARBYINT: R = SoftenFloatRes_FNEARBYINT(N); break; |
93 | 2 | case ISD::FNEG: R = SoftenFloatRes_FNEG(N, ResNo); break; |
94 | 150 | case ISD::FP_EXTEND: R = SoftenFloatRes_FP_EXTEND(N); break; |
95 | 31 | case ISD::FP_ROUND: R = SoftenFloatRes_FP_ROUND(N); break; |
96 | 121 | case ISD::FP16_TO_FP: R = SoftenFloatRes_FP16_TO_FP(N); break; |
97 | 7 | case ISD::FPOW: R = SoftenFloatRes_FPOW(N); break; |
98 | 12 | case ISD::FPOWI: R = SoftenFloatRes_FPOWI(N); break; |
99 | 4 | case ISD::FREM: R = SoftenFloatRes_FREM(N); break; |
100 | 10 | case ISD::FRINT: R = SoftenFloatRes_FRINT(N); break; |
101 | 12 | case ISD::FROUND: R = SoftenFloatRes_FROUND(N); break; |
102 | 7 | case ISD::FSIN: R = SoftenFloatRes_FSIN(N); break; |
103 | 7 | case ISD::FSQRT: R = SoftenFloatRes_FSQRT(N); break; |
104 | 122 | case ISD::FSUB: R = SoftenFloatRes_FSUB(N); break; |
105 | 6 | case ISD::FTRUNC: R = SoftenFloatRes_FTRUNC(N); break; |
106 | 758 | case ISD::LOAD: R = SoftenFloatRes_LOAD(N, ResNo); break; |
107 | 276 | case ISD::SELECT: R = SoftenFloatRes_SELECT(N, ResNo); break; |
108 | 19 | case ISD::SELECT_CC: R = SoftenFloatRes_SELECT_CC(N, ResNo); break; |
109 | 330 | case ISD::SINT_TO_FP: |
110 | 330 | case ISD::UINT_TO_FP: R = SoftenFloatRes_XINT_TO_FP(N); break; |
111 | 6 | case ISD::UNDEF: R = SoftenFloatRes_UNDEF(N); break; |
112 | 1 | case ISD::VAARG: R = SoftenFloatRes_VAARG(N); break; |
113 | 6.58k | } |
114 | 6.58k | |
115 | 6.58k | if (6.58k R.getNode() && 6.58k R.getNode() != N6.58k ) { |
116 | 6.00k | SetSoftenedFloat(SDValue(N, ResNo), R); |
117 | 6.00k | // Return true only if the node is changed, assuming that the operands |
118 | 6.00k | // are also converted when necessary. |
119 | 6.00k | return true; |
120 | 6.00k | } |
121 | 572 | |
122 | 572 | // Otherwise, return false to tell caller to scan operands. |
123 | 572 | return false; |
124 | 572 | } |
125 | | |
126 | 2.06k | SDValue DAGTypeLegalizer::SoftenFloatRes_BITCAST(SDNode *N, unsigned ResNo) { |
127 | 2.06k | if (isLegalInHWReg(N->getValueType(ResNo))) |
128 | 14 | return SDValue(N, ResNo); |
129 | 2.04k | return BitConvertToInteger(N->getOperand(0)); |
130 | 2.04k | } |
131 | | |
132 | | SDValue DAGTypeLegalizer::SoftenFloatRes_MERGE_VALUES(SDNode *N, |
133 | 0 | unsigned ResNo) { |
134 | 0 | SDValue Op = DisintegrateMERGE_VALUES(N, ResNo); |
135 | 0 | return BitConvertToInteger(Op); |
136 | 0 | } |
137 | | |
138 | 0 | SDValue DAGTypeLegalizer::SoftenFloatRes_BUILD_PAIR(SDNode *N) { |
139 | 0 | // Convert the inputs to integers, and build a new pair out of them. |
140 | 0 | return DAG.getNode(ISD::BUILD_PAIR, SDLoc(N), |
141 | 0 | TLI.getTypeToTransformTo(*DAG.getContext(), |
142 | 0 | N->getValueType(0)), |
143 | 0 | BitConvertToInteger(N->getOperand(0)), |
144 | 0 | BitConvertToInteger(N->getOperand(1))); |
145 | 0 | } |
146 | | |
147 | 659 | SDValue DAGTypeLegalizer::SoftenFloatRes_ConstantFP(SDNode *N, unsigned ResNo) { |
148 | 659 | // When LegalInHWReg, we can load better from the constant pool. |
149 | 659 | if (isLegalInHWReg(N->getValueType(ResNo))) |
150 | 9 | return SDValue(N, ResNo); |
151 | 650 | ConstantFPSDNode *CN = cast<ConstantFPSDNode>(N); |
152 | 650 | // In ppcf128, the high 64 bits are always first in memory regardless |
153 | 650 | // of Endianness. LLVM's APFloat representation is not Endian sensitive, |
154 | 650 | // and so always converts into a 128-bit APInt in a non-Endian-sensitive |
155 | 650 | // way. However, APInt's are serialized in an Endian-sensitive fashion, |
156 | 650 | // so on big-Endian targets, the two doubles are output in the wrong |
157 | 650 | // order. Fix this by manually flipping the order of the high 64 bits |
158 | 650 | // and the low 64 bits here. |
159 | 650 | if (DAG.getDataLayout().isBigEndian() && |
160 | 650 | CN->getValueType(0).getSimpleVT() == llvm::MVT::ppcf1285 ) { |
161 | 1 | uint64_t words[2] = { CN->getValueAPF().bitcastToAPInt().getRawData()[1], |
162 | 1 | CN->getValueAPF().bitcastToAPInt().getRawData()[0] }; |
163 | 1 | APInt Val(128, words); |
164 | 1 | return DAG.getConstant(Val, SDLoc(CN), |
165 | 1 | TLI.getTypeToTransformTo(*DAG.getContext(), |
166 | 1 | CN->getValueType(0))); |
167 | 0 | } else { |
168 | 649 | return DAG.getConstant(CN->getValueAPF().bitcastToAPInt(), SDLoc(CN), |
169 | 649 | TLI.getTypeToTransformTo(*DAG.getContext(), |
170 | 649 | CN->getValueType(0))); |
171 | 649 | } |
172 | 0 | } |
173 | | |
174 | 33 | SDValue DAGTypeLegalizer::SoftenFloatRes_EXTRACT_VECTOR_ELT(SDNode *N, unsigned ResNo) { |
175 | 33 | // When LegalInHWReg, keep the extracted value in register. |
176 | 33 | if (isLegalInHWReg(N->getValueType(ResNo))) |
177 | 8 | return SDValue(N, ResNo); |
178 | 25 | SDValue NewOp = BitConvertVectorToIntegerVector(N->getOperand(0)); |
179 | 25 | return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(N), |
180 | 25 | NewOp.getValueType().getVectorElementType(), |
181 | 25 | NewOp, N->getOperand(1)); |
182 | 25 | } |
183 | | |
184 | 10 | SDValue DAGTypeLegalizer::SoftenFloatRes_FABS(SDNode *N, unsigned ResNo) { |
185 | 10 | // When LegalInHWReg, FABS can be implemented as native bitwise operations. |
186 | 10 | if (isLegalInHWReg(N->getValueType(ResNo))) |
187 | 5 | return SDValue(N, ResNo); |
188 | 5 | EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); |
189 | 5 | unsigned Size = NVT.getSizeInBits(); |
190 | 5 | |
191 | 5 | // Mask = ~(1 << (Size-1)) |
192 | 5 | APInt API = APInt::getAllOnesValue(Size); |
193 | 5 | API.clearBit(Size - 1); |
194 | 5 | SDValue Mask = DAG.getConstant(API, SDLoc(N), NVT); |
195 | 5 | SDValue Op = GetSoftenedFloat(N->getOperand(0)); |
196 | 5 | return DAG.getNode(ISD::AND, SDLoc(N), NVT, Op, Mask); |
197 | 5 | } |
198 | | |
199 | 2 | SDValue DAGTypeLegalizer::SoftenFloatRes_FMINNUM(SDNode *N) { |
200 | 2 | EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); |
201 | 2 | SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), |
202 | 2 | GetSoftenedFloat(N->getOperand(1)) }; |
203 | 2 | return TLI.makeLibCall(DAG, GetFPLibCall(N->getValueType(0), |
204 | 2 | RTLIB::FMIN_F32, |
205 | 2 | RTLIB::FMIN_F64, |
206 | 2 | RTLIB::FMIN_F80, |
207 | 2 | RTLIB::FMIN_F128, |
208 | 2 | RTLIB::FMIN_PPCF128), |
209 | 2 | NVT, Ops, false, SDLoc(N)).first; |
210 | 2 | } |
211 | | |
212 | 18 | SDValue DAGTypeLegalizer::SoftenFloatRes_FMAXNUM(SDNode *N) { |
213 | 18 | EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); |
214 | 18 | SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), |
215 | 18 | GetSoftenedFloat(N->getOperand(1)) }; |
216 | 18 | return TLI.makeLibCall(DAG, GetFPLibCall(N->getValueType(0), |
217 | 18 | RTLIB::FMAX_F32, |
218 | 18 | RTLIB::FMAX_F64, |
219 | 18 | RTLIB::FMAX_F80, |
220 | 18 | RTLIB::FMAX_F128, |
221 | 18 | RTLIB::FMAX_PPCF128), |
222 | 18 | NVT, Ops, false, SDLoc(N)).first; |
223 | 18 | } |
224 | | |
225 | 335 | SDValue DAGTypeLegalizer::SoftenFloatRes_FADD(SDNode *N) { |
226 | 335 | EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); |
227 | 335 | SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), |
228 | 335 | GetSoftenedFloat(N->getOperand(1)) }; |
229 | 335 | return TLI.makeLibCall(DAG, GetFPLibCall(N->getValueType(0), |
230 | 335 | RTLIB::ADD_F32, |
231 | 335 | RTLIB::ADD_F64, |
232 | 335 | RTLIB::ADD_F80, |
233 | 335 | RTLIB::ADD_F128, |
234 | 335 | RTLIB::ADD_PPCF128), |
235 | 335 | NVT, Ops, false, SDLoc(N)).first; |
236 | 335 | } |
237 | | |
238 | 11 | SDValue DAGTypeLegalizer::SoftenFloatRes_FCEIL(SDNode *N) { |
239 | 11 | EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); |
240 | 11 | SDValue Op = GetSoftenedFloat(N->getOperand(0)); |
241 | 11 | return TLI.makeLibCall(DAG, GetFPLibCall(N->getValueType(0), |
242 | 11 | RTLIB::CEIL_F32, |
243 | 11 | RTLIB::CEIL_F64, |
244 | 11 | RTLIB::CEIL_F80, |
245 | 11 | RTLIB::CEIL_F128, |
246 | 11 | RTLIB::CEIL_PPCF128), |
247 | 11 | NVT, Op, false, SDLoc(N)).first; |
248 | 11 | } |
249 | | |
250 | 288 | SDValue DAGTypeLegalizer::SoftenFloatRes_FCOPYSIGN(SDNode *N, unsigned ResNo) { |
251 | 288 | // When LegalInHWReg, FCOPYSIGN can be implemented as native bitwise operations. |
252 | 288 | if (isLegalInHWReg(N->getValueType(ResNo))) |
253 | 3 | return SDValue(N, ResNo); |
254 | 285 | SDValue LHS = GetSoftenedFloat(N->getOperand(0)); |
255 | 285 | SDValue RHS = BitConvertToInteger(N->getOperand(1)); |
256 | 285 | SDLoc dl(N); |
257 | 285 | |
258 | 285 | EVT LVT = LHS.getValueType(); |
259 | 285 | EVT RVT = RHS.getValueType(); |
260 | 285 | |
261 | 285 | unsigned LSize = LVT.getSizeInBits(); |
262 | 285 | unsigned RSize = RVT.getSizeInBits(); |
263 | 285 | |
264 | 285 | // First get the sign bit of second operand. |
265 | 285 | SDValue SignBit = DAG.getNode( |
266 | 285 | ISD::SHL, dl, RVT, DAG.getConstant(1, dl, RVT), |
267 | 285 | DAG.getConstant(RSize - 1, dl, |
268 | 285 | TLI.getShiftAmountTy(RVT, DAG.getDataLayout()))); |
269 | 285 | SignBit = DAG.getNode(ISD::AND, dl, RVT, RHS, SignBit); |
270 | 285 | |
271 | 285 | // Shift right or sign-extend it if the two operands have different types. |
272 | 285 | int SizeDiff = RVT.getSizeInBits() - LVT.getSizeInBits(); |
273 | 285 | if (SizeDiff > 0285 ) { |
274 | 0 | SignBit = |
275 | 0 | DAG.getNode(ISD::SRL, dl, RVT, SignBit, |
276 | 0 | DAG.getConstant(SizeDiff, dl, |
277 | 0 | TLI.getShiftAmountTy(SignBit.getValueType(), |
278 | 0 | DAG.getDataLayout()))); |
279 | 0 | SignBit = DAG.getNode(ISD::TRUNCATE, dl, LVT, SignBit); |
280 | 285 | } else if (285 SizeDiff < 0285 ) { |
281 | 2 | SignBit = DAG.getNode(ISD::ANY_EXTEND, dl, LVT, SignBit); |
282 | 2 | SignBit = |
283 | 2 | DAG.getNode(ISD::SHL, dl, LVT, SignBit, |
284 | 2 | DAG.getConstant(-SizeDiff, dl, |
285 | 2 | TLI.getShiftAmountTy(SignBit.getValueType(), |
286 | 2 | DAG.getDataLayout()))); |
287 | 2 | } |
288 | 288 | |
289 | 288 | // Clear the sign bit of the first operand. |
290 | 288 | SDValue Mask = DAG.getNode( |
291 | 288 | ISD::SHL, dl, LVT, DAG.getConstant(1, dl, LVT), |
292 | 288 | DAG.getConstant(LSize - 1, dl, |
293 | 288 | TLI.getShiftAmountTy(LVT, DAG.getDataLayout()))); |
294 | 288 | Mask = DAG.getNode(ISD::SUB, dl, LVT, Mask, DAG.getConstant(1, dl, LVT)); |
295 | 288 | LHS = DAG.getNode(ISD::AND, dl, LVT, LHS, Mask); |
296 | 288 | |
297 | 288 | // Or the value with the sign bit. |
298 | 288 | return DAG.getNode(ISD::OR, dl, LVT, LHS, SignBit); |
299 | 288 | } |
300 | | |
301 | 6 | SDValue DAGTypeLegalizer::SoftenFloatRes_FCOS(SDNode *N) { |
302 | 6 | EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); |
303 | 6 | SDValue Op = GetSoftenedFloat(N->getOperand(0)); |
304 | 6 | return TLI.makeLibCall(DAG, GetFPLibCall(N->getValueType(0), |
305 | 6 | RTLIB::COS_F32, |
306 | 6 | RTLIB::COS_F64, |
307 | 6 | RTLIB::COS_F80, |
308 | 6 | RTLIB::COS_F128, |
309 | 6 | RTLIB::COS_PPCF128), |
310 | 6 | NVT, Op, false, SDLoc(N)).first; |
311 | 6 | } |
312 | | |
313 | 138 | SDValue DAGTypeLegalizer::SoftenFloatRes_FDIV(SDNode *N) { |
314 | 138 | EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); |
315 | 138 | SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), |
316 | 138 | GetSoftenedFloat(N->getOperand(1)) }; |
317 | 138 | return TLI.makeLibCall(DAG, GetFPLibCall(N->getValueType(0), |
318 | 138 | RTLIB::DIV_F32, |
319 | 138 | RTLIB::DIV_F64, |
320 | 138 | RTLIB::DIV_F80, |
321 | 138 | RTLIB::DIV_F128, |
322 | 138 | RTLIB::DIV_PPCF128), |
323 | 138 | NVT, Ops, false, SDLoc(N)).first; |
324 | 138 | } |
325 | | |
326 | 5 | SDValue DAGTypeLegalizer::SoftenFloatRes_FEXP(SDNode *N) { |
327 | 5 | EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); |
328 | 5 | SDValue Op = GetSoftenedFloat(N->getOperand(0)); |
329 | 5 | return TLI.makeLibCall(DAG, GetFPLibCall(N->getValueType(0), |
330 | 5 | RTLIB::EXP_F32, |
331 | 5 | RTLIB::EXP_F64, |
332 | 5 | RTLIB::EXP_F80, |
333 | 5 | RTLIB::EXP_F128, |
334 | 5 | RTLIB::EXP_PPCF128), |
335 | 5 | NVT, Op, false, SDLoc(N)).first; |
336 | 5 | } |
337 | | |
338 | 5 | SDValue DAGTypeLegalizer::SoftenFloatRes_FEXP2(SDNode *N) { |
339 | 5 | EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); |
340 | 5 | SDValue Op = GetSoftenedFloat(N->getOperand(0)); |
341 | 5 | return TLI.makeLibCall(DAG, GetFPLibCall(N->getValueType(0), |
342 | 5 | RTLIB::EXP2_F32, |
343 | 5 | RTLIB::EXP2_F64, |
344 | 5 | RTLIB::EXP2_F80, |
345 | 5 | RTLIB::EXP2_F128, |
346 | 5 | RTLIB::EXP2_PPCF128), |
347 | 5 | NVT, Op, false, SDLoc(N)).first; |
348 | 5 | } |
349 | | |
350 | 12 | SDValue DAGTypeLegalizer::SoftenFloatRes_FFLOOR(SDNode *N) { |
351 | 12 | EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); |
352 | 12 | SDValue Op = GetSoftenedFloat(N->getOperand(0)); |
353 | 12 | return TLI.makeLibCall(DAG, GetFPLibCall(N->getValueType(0), |
354 | 12 | RTLIB::FLOOR_F32, |
355 | 12 | RTLIB::FLOOR_F64, |
356 | 12 | RTLIB::FLOOR_F80, |
357 | 12 | RTLIB::FLOOR_F128, |
358 | 12 | RTLIB::FLOOR_PPCF128), |
359 | 12 | NVT, Op, false, SDLoc(N)).first; |
360 | 12 | } |
361 | | |
362 | 5 | SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG(SDNode *N) { |
363 | 5 | EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); |
364 | 5 | SDValue Op = GetSoftenedFloat(N->getOperand(0)); |
365 | 5 | return TLI.makeLibCall(DAG, GetFPLibCall(N->getValueType(0), |
366 | 5 | RTLIB::LOG_F32, |
367 | 5 | RTLIB::LOG_F64, |
368 | 5 | RTLIB::LOG_F80, |
369 | 5 | RTLIB::LOG_F128, |
370 | 5 | RTLIB::LOG_PPCF128), |
371 | 5 | NVT, Op, false, SDLoc(N)).first; |
372 | 5 | } |
373 | | |
374 | 5 | SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG2(SDNode *N) { |
375 | 5 | EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); |
376 | 5 | SDValue Op = GetSoftenedFloat(N->getOperand(0)); |
377 | 5 | return TLI.makeLibCall(DAG, GetFPLibCall(N->getValueType(0), |
378 | 5 | RTLIB::LOG2_F32, |
379 | 5 | RTLIB::LOG2_F64, |
380 | 5 | RTLIB::LOG2_F80, |
381 | 5 | RTLIB::LOG2_F128, |
382 | 5 | RTLIB::LOG2_PPCF128), |
383 | 5 | NVT, Op, false, SDLoc(N)).first; |
384 | 5 | } |
385 | | |
386 | 5 | SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG10(SDNode *N) { |
387 | 5 | EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); |
388 | 5 | SDValue Op = GetSoftenedFloat(N->getOperand(0)); |
389 | 5 | return TLI.makeLibCall(DAG, GetFPLibCall(N->getValueType(0), |
390 | 5 | RTLIB::LOG10_F32, |
391 | 5 | RTLIB::LOG10_F64, |
392 | 5 | RTLIB::LOG10_F80, |
393 | 5 | RTLIB::LOG10_F128, |
394 | 5 | RTLIB::LOG10_PPCF128), |
395 | 5 | NVT, Op, false, SDLoc(N)).first; |
396 | 5 | } |
397 | | |
398 | 7 | SDValue DAGTypeLegalizer::SoftenFloatRes_FMA(SDNode *N) { |
399 | 7 | EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); |
400 | 7 | SDValue Ops[3] = { GetSoftenedFloat(N->getOperand(0)), |
401 | 7 | GetSoftenedFloat(N->getOperand(1)), |
402 | 7 | GetSoftenedFloat(N->getOperand(2)) }; |
403 | 7 | return TLI.makeLibCall(DAG, GetFPLibCall(N->getValueType(0), |
404 | 7 | RTLIB::FMA_F32, |
405 | 7 | RTLIB::FMA_F64, |
406 | 7 | RTLIB::FMA_F80, |
407 | 7 | RTLIB::FMA_F128, |
408 | 7 | RTLIB::FMA_PPCF128), |
409 | 7 | NVT, Ops, false, SDLoc(N)).first; |
410 | 7 | } |
411 | | |
412 | 625 | SDValue DAGTypeLegalizer::SoftenFloatRes_FMUL(SDNode *N) { |
413 | 625 | EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); |
414 | 625 | SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), |
415 | 625 | GetSoftenedFloat(N->getOperand(1)) }; |
416 | 625 | return TLI.makeLibCall(DAG, GetFPLibCall(N->getValueType(0), |
417 | 625 | RTLIB::MUL_F32, |
418 | 625 | RTLIB::MUL_F64, |
419 | 625 | RTLIB::MUL_F80, |
420 | 625 | RTLIB::MUL_F128, |
421 | 625 | RTLIB::MUL_PPCF128), |
422 | 625 | NVT, Ops, false, SDLoc(N)).first; |
423 | 625 | } |
424 | | |
425 | 11 | SDValue DAGTypeLegalizer::SoftenFloatRes_FNEARBYINT(SDNode *N) { |
426 | 11 | EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); |
427 | 11 | SDValue Op = GetSoftenedFloat(N->getOperand(0)); |
428 | 11 | return TLI.makeLibCall(DAG, GetFPLibCall(N->getValueType(0), |
429 | 11 | RTLIB::NEARBYINT_F32, |
430 | 11 | RTLIB::NEARBYINT_F64, |
431 | 11 | RTLIB::NEARBYINT_F80, |
432 | 11 | RTLIB::NEARBYINT_F128, |
433 | 11 | RTLIB::NEARBYINT_PPCF128), |
434 | 11 | NVT, Op, false, SDLoc(N)).first; |
435 | 11 | } |
436 | | |
437 | 2 | SDValue DAGTypeLegalizer::SoftenFloatRes_FNEG(SDNode *N, unsigned ResNo) { |
438 | 2 | // When LegalInHWReg, FNEG can be implemented as native bitwise operations. |
439 | 2 | if (isLegalInHWReg(N->getValueType(ResNo))) |
440 | 2 | return SDValue(N, ResNo); |
441 | 0 | EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); |
442 | 0 | SDLoc dl(N); |
443 | 0 | // Expand Y = FNEG(X) -> Y = SUB -0.0, X |
444 | 0 | SDValue Ops[2] = { DAG.getConstantFP(-0.0, dl, N->getValueType(0)), |
445 | 0 | GetSoftenedFloat(N->getOperand(0)) }; |
446 | 0 | return TLI.makeLibCall(DAG, GetFPLibCall(N->getValueType(0), |
447 | 0 | RTLIB::SUB_F32, |
448 | 0 | RTLIB::SUB_F64, |
449 | 0 | RTLIB::SUB_F80, |
450 | 0 | RTLIB::SUB_F128, |
451 | 0 | RTLIB::SUB_PPCF128), |
452 | 0 | NVT, Ops, false, dl).first; |
453 | 0 | } |
454 | | |
455 | 150 | SDValue DAGTypeLegalizer::SoftenFloatRes_FP_EXTEND(SDNode *N) { |
456 | 150 | EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); |
457 | 150 | SDValue Op = N->getOperand(0); |
458 | 150 | |
459 | 150 | // There's only a libcall for f16 -> f32, so proceed in two stages. Also, it's |
460 | 150 | // entirely possible for both f16 and f32 to be legal, so use the fully |
461 | 150 | // hard-float FP_EXTEND rather than FP16_TO_FP. |
462 | 150 | if (Op.getValueType() == MVT::f16 && 150 N->getValueType(0) != MVT::f3232 ) { |
463 | 7 | Op = DAG.getNode(ISD::FP_EXTEND, SDLoc(N), MVT::f32, Op); |
464 | 7 | if (getTypeAction(MVT::f32) == TargetLowering::TypeSoftenFloat) |
465 | 7 | AddToWorklist(Op.getNode()); |
466 | 7 | } |
467 | 150 | |
468 | 150 | if (getTypeAction(Op.getValueType()) == TargetLowering::TypePromoteFloat150 ) { |
469 | 25 | Op = GetPromotedFloat(Op); |
470 | 25 | // If the promotion did the FP_EXTEND to the destination type for us, |
471 | 25 | // there's nothing left to do here. |
472 | 25 | if (Op.getValueType() == N->getValueType(0)25 ) { |
473 | 25 | return BitConvertToInteger(Op); |
474 | 25 | } |
475 | 125 | } |
476 | 125 | |
477 | 125 | RTLIB::Libcall LC = RTLIB::getFPEXT(Op.getValueType(), N->getValueType(0)); |
478 | 125 | assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_EXTEND!"); |
479 | 125 | return TLI.makeLibCall(DAG, LC, NVT, Op, false, SDLoc(N)).first; |
480 | 125 | } |
481 | | |
482 | | // FIXME: Should we just use 'normal' FP_EXTEND / FP_TRUNC instead of special |
483 | | // nodes? |
484 | 121 | SDValue DAGTypeLegalizer::SoftenFloatRes_FP16_TO_FP(SDNode *N) { |
485 | 121 | EVT MidVT = TLI.getTypeToTransformTo(*DAG.getContext(), MVT::f32); |
486 | 121 | SDValue Op = N->getOperand(0); |
487 | 121 | SDValue Res32 = TLI.makeLibCall(DAG, RTLIB::FPEXT_F16_F32, MidVT, Op, |
488 | 121 | false, SDLoc(N)).first; |
489 | 121 | if (N->getValueType(0) == MVT::f32) |
490 | 121 | return Res32; |
491 | 0 |
|
492 | 0 | EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); |
493 | 0 | RTLIB::Libcall LC = RTLIB::getFPEXT(MVT::f32, N->getValueType(0)); |
494 | 0 | assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_EXTEND!"); |
495 | 0 | return TLI.makeLibCall(DAG, LC, NVT, Res32, false, SDLoc(N)).first; |
496 | 0 | } |
497 | | |
498 | 31 | SDValue DAGTypeLegalizer::SoftenFloatRes_FP_ROUND(SDNode *N) { |
499 | 31 | EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); |
500 | 31 | SDValue Op = N->getOperand(0); |
501 | 31 | if (N->getValueType(0) == MVT::f1631 ) { |
502 | 0 | // Semi-soften first, to FP_TO_FP16, so that targets which support f16 as a |
503 | 0 | // storage-only type get a chance to select things. |
504 | 0 | return DAG.getNode(ISD::FP_TO_FP16, SDLoc(N), NVT, Op); |
505 | 0 | } |
506 | 31 | |
507 | 31 | RTLIB::Libcall LC = RTLIB::getFPROUND(Op.getValueType(), N->getValueType(0)); |
508 | 31 | assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_ROUND!"); |
509 | 31 | return TLI.makeLibCall(DAG, LC, NVT, Op, false, SDLoc(N)).first; |
510 | 31 | } |
511 | | |
512 | 7 | SDValue DAGTypeLegalizer::SoftenFloatRes_FPOW(SDNode *N) { |
513 | 7 | EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); |
514 | 7 | SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), |
515 | 7 | GetSoftenedFloat(N->getOperand(1)) }; |
516 | 7 | return TLI.makeLibCall(DAG, GetFPLibCall(N->getValueType(0), |
517 | 7 | RTLIB::POW_F32, |
518 | 7 | RTLIB::POW_F64, |
519 | 7 | RTLIB::POW_F80, |
520 | 7 | RTLIB::POW_F128, |
521 | 7 | RTLIB::POW_PPCF128), |
522 | 7 | NVT, Ops, false, SDLoc(N)).first; |
523 | 7 | } |
524 | | |
525 | 12 | SDValue DAGTypeLegalizer::SoftenFloatRes_FPOWI(SDNode *N) { |
526 | 12 | assert(N->getOperand(1).getValueType() == MVT::i32 && |
527 | 12 | "Unsupported power type!"); |
528 | 12 | EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); |
529 | 12 | SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), N->getOperand(1) }; |
530 | 12 | return TLI.makeLibCall(DAG, GetFPLibCall(N->getValueType(0), |
531 | 12 | RTLIB::POWI_F32, |
532 | 12 | RTLIB::POWI_F64, |
533 | 12 | RTLIB::POWI_F80, |
534 | 12 | RTLIB::POWI_F128, |
535 | 12 | RTLIB::POWI_PPCF128), |
536 | 12 | NVT, Ops, false, SDLoc(N)).first; |
537 | 12 | } |
538 | | |
539 | 4 | SDValue DAGTypeLegalizer::SoftenFloatRes_FREM(SDNode *N) { |
540 | 4 | EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); |
541 | 4 | SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), |
542 | 4 | GetSoftenedFloat(N->getOperand(1)) }; |
543 | 4 | return TLI.makeLibCall(DAG, GetFPLibCall(N->getValueType(0), |
544 | 4 | RTLIB::REM_F32, |
545 | 4 | RTLIB::REM_F64, |
546 | 4 | RTLIB::REM_F80, |
547 | 4 | RTLIB::REM_F128, |
548 | 4 | RTLIB::REM_PPCF128), |
549 | 4 | NVT, Ops, false, SDLoc(N)).first; |
550 | 4 | } |
551 | | |
552 | 10 | SDValue DAGTypeLegalizer::SoftenFloatRes_FRINT(SDNode *N) { |
553 | 10 | EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); |
554 | 10 | SDValue Op = GetSoftenedFloat(N->getOperand(0)); |
555 | 10 | return TLI.makeLibCall(DAG, GetFPLibCall(N->getValueType(0), |
556 | 10 | RTLIB::RINT_F32, |
557 | 10 | RTLIB::RINT_F64, |
558 | 10 | RTLIB::RINT_F80, |
559 | 10 | RTLIB::RINT_F128, |
560 | 10 | RTLIB::RINT_PPCF128), |
561 | 10 | NVT, Op, false, SDLoc(N)).first; |
562 | 10 | } |
563 | | |
564 | 12 | SDValue DAGTypeLegalizer::SoftenFloatRes_FROUND(SDNode *N) { |
565 | 12 | EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); |
566 | 12 | SDValue Op = GetSoftenedFloat(N->getOperand(0)); |
567 | 12 | return TLI.makeLibCall(DAG, GetFPLibCall(N->getValueType(0), |
568 | 12 | RTLIB::ROUND_F32, |
569 | 12 | RTLIB::ROUND_F64, |
570 | 12 | RTLIB::ROUND_F80, |
571 | 12 | RTLIB::ROUND_F128, |
572 | 12 | RTLIB::ROUND_PPCF128), |
573 | 12 | NVT, Op, false, SDLoc(N)).first; |
574 | 12 | } |
575 | | |
576 | 7 | SDValue DAGTypeLegalizer::SoftenFloatRes_FSIN(SDNode *N) { |
577 | 7 | EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); |
578 | 7 | SDValue Op = GetSoftenedFloat(N->getOperand(0)); |
579 | 7 | return TLI.makeLibCall(DAG, GetFPLibCall(N->getValueType(0), |
580 | 7 | RTLIB::SIN_F32, |
581 | 7 | RTLIB::SIN_F64, |
582 | 7 | RTLIB::SIN_F80, |
583 | 7 | RTLIB::SIN_F128, |
584 | 7 | RTLIB::SIN_PPCF128), |
585 | 7 | NVT, Op, false, SDLoc(N)).first; |
586 | 7 | } |
587 | | |
588 | 7 | SDValue DAGTypeLegalizer::SoftenFloatRes_FSQRT(SDNode *N) { |
589 | 7 | EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); |
590 | 7 | SDValue Op = GetSoftenedFloat(N->getOperand(0)); |
591 | 7 | return TLI.makeLibCall(DAG, GetFPLibCall(N->getValueType(0), |
592 | 7 | RTLIB::SQRT_F32, |
593 | 7 | RTLIB::SQRT_F64, |
594 | 7 | RTLIB::SQRT_F80, |
595 | 7 | RTLIB::SQRT_F128, |
596 | 7 | RTLIB::SQRT_PPCF128), |
597 | 7 | NVT, Op, false, SDLoc(N)).first; |
598 | 7 | } |
599 | | |
600 | 122 | SDValue DAGTypeLegalizer::SoftenFloatRes_FSUB(SDNode *N) { |
601 | 122 | EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); |
602 | 122 | SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), |
603 | 122 | GetSoftenedFloat(N->getOperand(1)) }; |
604 | 122 | return TLI.makeLibCall(DAG, GetFPLibCall(N->getValueType(0), |
605 | 122 | RTLIB::SUB_F32, |
606 | 122 | RTLIB::SUB_F64, |
607 | 122 | RTLIB::SUB_F80, |
608 | 122 | RTLIB::SUB_F128, |
609 | 122 | RTLIB::SUB_PPCF128), |
610 | 122 | NVT, Ops, false, SDLoc(N)).first; |
611 | 122 | } |
612 | | |
613 | 6 | SDValue DAGTypeLegalizer::SoftenFloatRes_FTRUNC(SDNode *N) { |
614 | 6 | EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); |
615 | 6 | if (N->getValueType(0) == MVT::f16) |
616 | 0 | return DAG.getNode(ISD::FP_TO_FP16, SDLoc(N), NVT, N->getOperand(0)); |
617 | 6 | |
618 | 6 | SDValue Op = GetSoftenedFloat(N->getOperand(0)); |
619 | 6 | return TLI.makeLibCall(DAG, GetFPLibCall(N->getValueType(0), |
620 | 6 | RTLIB::TRUNC_F32, |
621 | 6 | RTLIB::TRUNC_F64, |
622 | 6 | RTLIB::TRUNC_F80, |
623 | 6 | RTLIB::TRUNC_F128, |
624 | 6 | RTLIB::TRUNC_PPCF128), |
625 | 6 | NVT, Op, false, SDLoc(N)).first; |
626 | 6 | } |
627 | | |
628 | 758 | SDValue DAGTypeLegalizer::SoftenFloatRes_LOAD(SDNode *N, unsigned ResNo) { |
629 | 758 | bool LegalInHWReg = isLegalInHWReg(N->getValueType(ResNo)); |
630 | 758 | LoadSDNode *L = cast<LoadSDNode>(N); |
631 | 758 | EVT VT = N->getValueType(0); |
632 | 758 | EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT); |
633 | 758 | SDLoc dl(N); |
634 | 758 | |
635 | 758 | auto MMOFlags = |
636 | 758 | L->getMemOperand()->getFlags() & |
637 | 758 | ~(MachineMemOperand::MOInvariant | MachineMemOperand::MODereferenceable); |
638 | 758 | SDValue NewL; |
639 | 758 | if (L->getExtensionType() == ISD::NON_EXTLOAD758 ) { |
640 | 744 | NewL = DAG.getLoad(L->getAddressingMode(), L->getExtensionType(), NVT, dl, |
641 | 744 | L->getChain(), L->getBasePtr(), L->getOffset(), |
642 | 744 | L->getPointerInfo(), NVT, L->getAlignment(), MMOFlags, |
643 | 744 | L->getAAInfo()); |
644 | 744 | // Legalized the chain result - switch anything that used the old chain to |
645 | 744 | // use the new one. |
646 | 744 | if (N != NewL.getValue(1).getNode()) |
647 | 690 | ReplaceValueWith(SDValue(N, 1), NewL.getValue(1)); |
648 | 744 | return NewL; |
649 | 744 | } |
650 | 14 | |
651 | 14 | // Do a non-extending load followed by FP_EXTEND. |
652 | 14 | NewL = DAG.getLoad(L->getAddressingMode(), ISD::NON_EXTLOAD, L->getMemoryVT(), |
653 | 14 | dl, L->getChain(), L->getBasePtr(), L->getOffset(), |
654 | 14 | L->getPointerInfo(), L->getMemoryVT(), L->getAlignment(), |
655 | 14 | MMOFlags, L->getAAInfo()); |
656 | 14 | // Legalized the chain result - switch anything that used the old chain to |
657 | 14 | // use the new one. |
658 | 14 | ReplaceValueWith(SDValue(N, 1), NewL.getValue(1)); |
659 | 14 | auto ExtendNode = DAG.getNode(ISD::FP_EXTEND, dl, VT, NewL); |
660 | 14 | if (LegalInHWReg) |
661 | 6 | return ExtendNode; |
662 | 8 | return BitConvertToInteger(ExtendNode); |
663 | 8 | } |
664 | | |
665 | 276 | SDValue DAGTypeLegalizer::SoftenFloatRes_SELECT(SDNode *N, unsigned ResNo) { |
666 | 276 | if (isLegalInHWReg(N->getValueType(ResNo))) |
667 | 19 | return SDValue(N, ResNo); |
668 | 257 | SDValue LHS = GetSoftenedFloat(N->getOperand(1)); |
669 | 257 | SDValue RHS = GetSoftenedFloat(N->getOperand(2)); |
670 | 257 | return DAG.getSelect(SDLoc(N), |
671 | 257 | LHS.getValueType(), N->getOperand(0), LHS, RHS); |
672 | 257 | } |
673 | | |
674 | 19 | SDValue DAGTypeLegalizer::SoftenFloatRes_SELECT_CC(SDNode *N, unsigned ResNo) { |
675 | 19 | if (isLegalInHWReg(N->getValueType(ResNo))) |
676 | 0 | return SDValue(N, ResNo); |
677 | 19 | SDValue LHS = GetSoftenedFloat(N->getOperand(2)); |
678 | 19 | SDValue RHS = GetSoftenedFloat(N->getOperand(3)); |
679 | 19 | return DAG.getNode(ISD::SELECT_CC, SDLoc(N), |
680 | 19 | LHS.getValueType(), N->getOperand(0), |
681 | 19 | N->getOperand(1), LHS, RHS, N->getOperand(4)); |
682 | 19 | } |
683 | | |
684 | 6 | SDValue DAGTypeLegalizer::SoftenFloatRes_UNDEF(SDNode *N) { |
685 | 6 | return DAG.getUNDEF(TLI.getTypeToTransformTo(*DAG.getContext(), |
686 | 6 | N->getValueType(0))); |
687 | 6 | } |
688 | | |
689 | 1 | SDValue DAGTypeLegalizer::SoftenFloatRes_VAARG(SDNode *N) { |
690 | 1 | SDValue Chain = N->getOperand(0); // Get the chain. |
691 | 1 | SDValue Ptr = N->getOperand(1); // Get the pointer. |
692 | 1 | EVT VT = N->getValueType(0); |
693 | 1 | EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT); |
694 | 1 | SDLoc dl(N); |
695 | 1 | |
696 | 1 | SDValue NewVAARG; |
697 | 1 | NewVAARG = DAG.getVAArg(NVT, dl, Chain, Ptr, N->getOperand(2), |
698 | 1 | N->getConstantOperandVal(3)); |
699 | 1 | |
700 | 1 | // Legalized the chain result - switch anything that used the old chain to |
701 | 1 | // use the new one. |
702 | 1 | if (N != NewVAARG.getValue(1).getNode()) |
703 | 1 | ReplaceValueWith(SDValue(N, 1), NewVAARG.getValue(1)); |
704 | 1 | return NewVAARG; |
705 | 1 | } |
706 | | |
707 | 330 | SDValue DAGTypeLegalizer::SoftenFloatRes_XINT_TO_FP(SDNode *N) { |
708 | 330 | bool Signed = N->getOpcode() == ISD::SINT_TO_FP; |
709 | 330 | EVT SVT = N->getOperand(0).getValueType(); |
710 | 330 | EVT RVT = N->getValueType(0); |
711 | 330 | EVT NVT = EVT(); |
712 | 330 | SDLoc dl(N); |
713 | 330 | |
714 | 330 | // If the input is not legal, eg: i1 -> fp, then it needs to be promoted to |
715 | 330 | // a larger type, eg: i8 -> fp. Even if it is legal, no libcall may exactly |
716 | 330 | // match. Look for an appropriate libcall. |
717 | 330 | RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; |
718 | 330 | for (unsigned t = MVT::FIRST_INTEGER_VALUETYPE; |
719 | 1.74k | t <= MVT::LAST_INTEGER_VALUETYPE && 1.74k LC == RTLIB::UNKNOWN_LIBCALL1.74k ; ++t1.41k ) { |
720 | 1.41k | NVT = (MVT::SimpleValueType)t; |
721 | 1.41k | // The source needs to big enough to hold the operand. |
722 | 1.41k | if (NVT.bitsGE(SVT)) |
723 | 600 | LC = Signed ? 600 RTLIB::getSINTTOFP(NVT, RVT)131 :RTLIB::getUINTTOFP (NVT, RVT)469 ; |
724 | 1.41k | } |
725 | 330 | assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported XINT_TO_FP!"); |
726 | 330 | |
727 | 330 | // Sign/zero extend the argument if the libcall takes a larger type. |
728 | 330 | SDValue Op = DAG.getNode(Signed ? ISD::SIGN_EXTEND119 : ISD::ZERO_EXTEND211 , dl, |
729 | 330 | NVT, N->getOperand(0)); |
730 | 330 | return TLI.makeLibCall(DAG, LC, |
731 | 330 | TLI.getTypeToTransformTo(*DAG.getContext(), RVT), |
732 | 330 | Op, Signed, dl).first; |
733 | 330 | } |
734 | | |
735 | | |
736 | | //===----------------------------------------------------------------------===// |
737 | | // Convert Float Operand to Integer for Non-HW-supported Operations. |
738 | | //===----------------------------------------------------------------------===// |
739 | | |
740 | 2.76k | bool DAGTypeLegalizer::SoftenFloatOperand(SDNode *N, unsigned OpNo) { |
741 | 2.76k | DEBUG(dbgs() << "Soften float operand " << OpNo << ": "; N->dump(&DAG); |
742 | 2.76k | dbgs() << "\n"); |
743 | 2.76k | SDValue Res = SDValue(); |
744 | 2.76k | |
745 | 2.76k | switch (N->getOpcode()) { |
746 | 289 | default: |
747 | 289 | if (CanSkipSoftenFloatOperand(N, OpNo)) |
748 | 289 | return false; |
749 | | #ifndef NDEBUG |
750 | | dbgs() << "SoftenFloatOperand Op #" << OpNo << ": "; |
751 | | N->dump(&DAG); dbgs() << "\n"; |
752 | | #endif |
753 | 0 | llvm_unreachable0 ("Do not know how to soften this operator's operand!"); |
754 | 0 |
|
755 | 640 | case ISD::BITCAST: Res = SoftenFloatOp_BITCAST(N); break; |
756 | 206 | case ISD::CopyToReg: Res = SoftenFloatOp_COPY_TO_REG(N); break; |
757 | 0 | case ISD::BR_CC: Res = SoftenFloatOp_BR_CC(N); break; |
758 | 5 | case ISD::FABS: Res = SoftenFloatOp_FABS(N); break; |
759 | 3 | case ISD::FCOPYSIGN: Res = SoftenFloatOp_FCOPYSIGN(N); break; |
760 | 2 | case ISD::FNEG: Res = SoftenFloatOp_FNEG(N); break; |
761 | 0 | case ISD::FP_EXTEND: Res = SoftenFloatOp_FP_EXTEND(N); break; |
762 | 107 | case ISD::FP_TO_FP16: // Same as FP_ROUND for softening purposes |
763 | 107 | case ISD::FP_ROUND: Res = SoftenFloatOp_FP_ROUND(N); break; |
764 | 215 | case ISD::FP_TO_SINT: |
765 | 215 | case ISD::FP_TO_UINT: Res = SoftenFloatOp_FP_TO_XINT(N); break; |
766 | 10 | case ISD::SELECT: Res = SoftenFloatOp_SELECT(N); break; |
767 | 23 | case ISD::SELECT_CC: Res = SoftenFloatOp_SELECT_CC(N); break; |
768 | 840 | case ISD::SETCC: Res = SoftenFloatOp_SETCC(N); break; |
769 | 422 | case ISD::STORE: |
770 | 422 | Res = SoftenFloatOp_STORE(N, OpNo); |
771 | 422 | // Do not try to analyze or soften this node again if the value is |
772 | 422 | // or can be held in a register. In that case, Res.getNode() should |
773 | 422 | // be equal to N. |
774 | 422 | if (Res.getNode() == N && |
775 | 60 | isLegalInHWReg(N->getOperand(OpNo).getValueType())) |
776 | 60 | return false; |
777 | 362 | // Otherwise, we need to reanalyze and lower the new Res nodes. |
778 | 362 | break; |
779 | 2.41k | } |
780 | 2.41k | |
781 | 2.41k | // If the result is null, the sub-method took care of registering results etc. |
782 | 2.41k | if (2.41k !Res.getNode()2.41k ) return false204 ; |
783 | 2.20k | |
784 | 2.20k | // If the result is N, the sub-method updated N in place. Tell the legalizer |
785 | 2.20k | // core about this to re-analyze. |
786 | 2.20k | if (2.20k Res.getNode() == N2.20k ) |
787 | 798 | return true; |
788 | 1.41k | |
789 | 2.20k | assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 && |
790 | 1.41k | "Invalid operand expansion"); |
791 | 1.41k | |
792 | 1.41k | ReplaceValueWith(SDValue(N, 0), Res); |
793 | 1.41k | return false; |
794 | 1.41k | } |
795 | | |
796 | 289 | bool DAGTypeLegalizer::CanSkipSoftenFloatOperand(SDNode *N, unsigned OpNo) { |
797 | 289 | if (!isLegalInHWReg(N->getOperand(OpNo).getValueType())) |
798 | 0 | return false; |
799 | 289 | |
800 | 289 | // When the operand type can be kept in registers there is nothing to do for |
801 | 289 | // the following opcodes. |
802 | 289 | switch (N->getOperand(OpNo).getOpcode()) { |
803 | 289 | case ISD::BITCAST: |
804 | 289 | case ISD::ConstantFP: |
805 | 289 | case ISD::CopyFromReg: |
806 | 289 | case ISD::CopyToReg: |
807 | 289 | case ISD::FABS: |
808 | 289 | case ISD::FCOPYSIGN: |
809 | 289 | case ISD::FNEG: |
810 | 289 | case ISD::Register: |
811 | 289 | case ISD::SELECT: |
812 | 289 | case ISD::SELECT_CC: |
813 | 289 | return true; |
814 | 0 | } |
815 | 0 |
|
816 | 0 | switch (N->getOpcode()) { |
817 | 0 | case ISD::ConstantFP: // Leaf node. |
818 | 0 | case ISD::CopyFromReg: // Operand is a register that we know to be left |
819 | 0 | // unchanged by SoftenFloatResult(). |
820 | 0 | case ISD::Register: // Leaf node. |
821 | 0 | return true; |
822 | 0 | } |
823 | 0 | return false; |
824 | 0 | } |
825 | | |
826 | 640 | SDValue DAGTypeLegalizer::SoftenFloatOp_BITCAST(SDNode *N) { |
827 | 640 | return DAG.getNode(ISD::BITCAST, SDLoc(N), N->getValueType(0), |
828 | 640 | GetSoftenedFloat(N->getOperand(0))); |
829 | 640 | } |
830 | | |
831 | 206 | SDValue DAGTypeLegalizer::SoftenFloatOp_COPY_TO_REG(SDNode *N) { |
832 | 206 | SDValue Op1 = GetSoftenedFloat(N->getOperand(1)); |
833 | 206 | SDValue Op2 = GetSoftenedFloat(N->getOperand(2)); |
834 | 206 | |
835 | 206 | if (Op1 == N->getOperand(1) && 206 Op2 == N->getOperand(2)206 ) |
836 | 186 | return SDValue(); |
837 | 20 | |
838 | 20 | if (20 N->getNumOperands() == 320 ) |
839 | 20 | return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0), Op1, Op2), 0); |
840 | 0 |
|
841 | 0 | return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0), Op1, Op2, |
842 | 0 | N->getOperand(3)), |
843 | 0 | 0); |
844 | 0 | } |
845 | | |
846 | 0 | SDValue DAGTypeLegalizer::SoftenFloatOp_FP_EXTEND(SDNode *N) { |
847 | 0 | // If we get here, the result must be legal but the source illegal. |
848 | 0 | EVT SVT = N->getOperand(0).getValueType(); |
849 | 0 | EVT RVT = N->getValueType(0); |
850 | 0 | SDValue Op = GetSoftenedFloat(N->getOperand(0)); |
851 | 0 |
|
852 | 0 | if (SVT == MVT::f16) |
853 | 0 | return DAG.getNode(ISD::FP16_TO_FP, SDLoc(N), RVT, Op); |
854 | 0 |
|
855 | 0 | RTLIB::Libcall LC = RTLIB::getFPEXT(SVT, RVT); |
856 | 0 | assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_EXTEND libcall"); |
857 | 0 |
|
858 | 0 | return TLI.makeLibCall(DAG, LC, RVT, Op, false, SDLoc(N)).first; |
859 | 0 | } |
860 | | |
861 | | |
862 | 107 | SDValue DAGTypeLegalizer::SoftenFloatOp_FP_ROUND(SDNode *N) { |
863 | 107 | // We actually deal with the partially-softened FP_TO_FP16 node too, which |
864 | 107 | // returns an i16 so doesn't meet the constraints necessary for FP_ROUND. |
865 | 107 | assert(N->getOpcode() == ISD::FP_ROUND || N->getOpcode() == ISD::FP_TO_FP16); |
866 | 107 | |
867 | 107 | EVT SVT = N->getOperand(0).getValueType(); |
868 | 107 | EVT RVT = N->getValueType(0); |
869 | 107 | EVT FloatRVT = N->getOpcode() == ISD::FP_TO_FP16 ? MVT::f1695 : RVT12 ; |
870 | 107 | |
871 | 107 | RTLIB::Libcall LC = RTLIB::getFPROUND(SVT, FloatRVT); |
872 | 107 | assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_ROUND libcall"); |
873 | 107 | |
874 | 107 | SDValue Op = GetSoftenedFloat(N->getOperand(0)); |
875 | 107 | return TLI.makeLibCall(DAG, LC, RVT, Op, false, SDLoc(N)).first; |
876 | 107 | } |
877 | | |
878 | 0 | SDValue DAGTypeLegalizer::SoftenFloatOp_BR_CC(SDNode *N) { |
879 | 0 | SDValue NewLHS = N->getOperand(2), NewRHS = N->getOperand(3); |
880 | 0 | ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(1))->get(); |
881 | 0 |
|
882 | 0 | EVT VT = NewLHS.getValueType(); |
883 | 0 | NewLHS = GetSoftenedFloat(NewLHS); |
884 | 0 | NewRHS = GetSoftenedFloat(NewRHS); |
885 | 0 | TLI.softenSetCCOperands(DAG, VT, NewLHS, NewRHS, CCCode, SDLoc(N)); |
886 | 0 |
|
887 | 0 | // If softenSetCCOperands returned a scalar, we need to compare the result |
888 | 0 | // against zero to select between true and false values. |
889 | 0 | if (!NewRHS.getNode()0 ) { |
890 | 0 | NewRHS = DAG.getConstant(0, SDLoc(N), NewLHS.getValueType()); |
891 | 0 | CCCode = ISD::SETNE; |
892 | 0 | } |
893 | 0 |
|
894 | 0 | // Update N to have the operands specified. |
895 | 0 | return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0), |
896 | 0 | DAG.getCondCode(CCCode), NewLHS, NewRHS, |
897 | 0 | N->getOperand(4)), |
898 | 0 | 0); |
899 | 0 | } |
900 | | |
901 | 5 | SDValue DAGTypeLegalizer::SoftenFloatOp_FABS(SDNode *N) { |
902 | 5 | SDValue Op = GetSoftenedFloat(N->getOperand(0)); |
903 | 5 | |
904 | 5 | if (Op == N->getOperand(0)) |
905 | 5 | return SDValue(); |
906 | 0 |
|
907 | 0 | return SDValue(DAG.UpdateNodeOperands(N, Op), 0); |
908 | 0 | } |
909 | | |
910 | 3 | SDValue DAGTypeLegalizer::SoftenFloatOp_FCOPYSIGN(SDNode *N) { |
911 | 3 | SDValue Op0 = GetSoftenedFloat(N->getOperand(0)); |
912 | 3 | SDValue Op1 = GetSoftenedFloat(N->getOperand(1)); |
913 | 3 | |
914 | 3 | if (Op0 == N->getOperand(0) && 3 Op1 == N->getOperand(1)3 ) |
915 | 3 | return SDValue(); |
916 | 0 |
|
917 | 0 | return SDValue(DAG.UpdateNodeOperands(N, Op0, Op1), 0); |
918 | 0 | } |
919 | | |
920 | 2 | SDValue DAGTypeLegalizer::SoftenFloatOp_FNEG(SDNode *N) { |
921 | 2 | SDValue Op = GetSoftenedFloat(N->getOperand(0)); |
922 | 2 | |
923 | 2 | if (Op == N->getOperand(0)) |
924 | 1 | return SDValue(); |
925 | 1 | |
926 | 1 | return SDValue(DAG.UpdateNodeOperands(N, Op), 0); |
927 | 1 | } |
928 | | |
929 | 215 | SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_XINT(SDNode *N) { |
930 | 215 | bool Signed = N->getOpcode() == ISD::FP_TO_SINT; |
931 | 215 | EVT SVT = N->getOperand(0).getValueType(); |
932 | 215 | EVT RVT = N->getValueType(0); |
933 | 215 | EVT NVT = EVT(); |
934 | 215 | SDLoc dl(N); |
935 | 215 | |
936 | 215 | // If the result is not legal, eg: fp -> i1, then it needs to be promoted to |
937 | 215 | // a larger type, eg: fp -> i32. Even if it is legal, no libcall may exactly |
938 | 215 | // match, eg. we don't have fp -> i8 conversions. |
939 | 215 | // Look for an appropriate libcall. |
940 | 215 | RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; |
941 | 215 | for (unsigned IntVT = MVT::FIRST_INTEGER_VALUETYPE; |
942 | 1.11k | IntVT <= MVT::LAST_INTEGER_VALUETYPE && 1.11k LC == RTLIB::UNKNOWN_LIBCALL1.11k ; |
943 | 898 | ++IntVT898 ) { |
944 | 898 | NVT = (MVT::SimpleValueType)IntVT; |
945 | 898 | // The type needs to big enough to hold the result. |
946 | 898 | if (NVT.bitsGE(RVT)) |
947 | 227 | LC = Signed ? 227 RTLIB::getFPTOSINT(SVT, NVT)125 :RTLIB::getFPTOUINT(SVT, NVT)102 ; |
948 | 898 | } |
949 | 215 | assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_XINT!"); |
950 | 215 | |
951 | 215 | SDValue Op = GetSoftenedFloat(N->getOperand(0)); |
952 | 215 | SDValue Res = TLI.makeLibCall(DAG, LC, NVT, Op, false, dl).first; |
953 | 215 | |
954 | 215 | // Truncate the result if the libcall returns a larger type. |
955 | 215 | return DAG.getNode(ISD::TRUNCATE, dl, RVT, Res); |
956 | 215 | } |
957 | | |
958 | 10 | SDValue DAGTypeLegalizer::SoftenFloatOp_SELECT(SDNode *N) { |
959 | 10 | SDValue Op1 = GetSoftenedFloat(N->getOperand(1)); |
960 | 10 | SDValue Op2 = GetSoftenedFloat(N->getOperand(2)); |
961 | 10 | |
962 | 10 | if (Op1 == N->getOperand(1) && 10 Op2 == N->getOperand(2)9 ) |
963 | 9 | return SDValue(); |
964 | 1 | |
965 | 1 | return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0), Op1, Op2), |
966 | 1 | 0); |
967 | 1 | } |
968 | | |
969 | 23 | SDValue DAGTypeLegalizer::SoftenFloatOp_SELECT_CC(SDNode *N) { |
970 | 23 | SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1); |
971 | 23 | ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(4))->get(); |
972 | 23 | |
973 | 23 | EVT VT = NewLHS.getValueType(); |
974 | 23 | NewLHS = GetSoftenedFloat(NewLHS); |
975 | 23 | NewRHS = GetSoftenedFloat(NewRHS); |
976 | 23 | TLI.softenSetCCOperands(DAG, VT, NewLHS, NewRHS, CCCode, SDLoc(N)); |
977 | 23 | |
978 | 23 | // If softenSetCCOperands returned a scalar, we need to compare the result |
979 | 23 | // against zero to select between true and false values. |
980 | 23 | if (!NewRHS.getNode()23 ) { |
981 | 3 | NewRHS = DAG.getConstant(0, SDLoc(N), NewLHS.getValueType()); |
982 | 3 | CCCode = ISD::SETNE; |
983 | 3 | } |
984 | 23 | |
985 | 23 | // Update N to have the operands specified. |
986 | 23 | return SDValue(DAG.UpdateNodeOperands(N, NewLHS, NewRHS, |
987 | 23 | N->getOperand(2), N->getOperand(3), |
988 | 23 | DAG.getCondCode(CCCode)), |
989 | 23 | 0); |
990 | 23 | } |
991 | | |
992 | 840 | SDValue DAGTypeLegalizer::SoftenFloatOp_SETCC(SDNode *N) { |
993 | 840 | SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1); |
994 | 840 | ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(2))->get(); |
995 | 840 | |
996 | 840 | EVT VT = NewLHS.getValueType(); |
997 | 840 | NewLHS = GetSoftenedFloat(NewLHS); |
998 | 840 | NewRHS = GetSoftenedFloat(NewRHS); |
999 | 840 | TLI.softenSetCCOperands(DAG, VT, NewLHS, NewRHS, CCCode, SDLoc(N)); |
1000 | 840 | |
1001 | 840 | // If softenSetCCOperands returned a scalar, use it. |
1002 | 840 | if (!NewRHS.getNode()840 ) { |
1003 | 87 | assert(NewLHS.getValueType() == N->getValueType(0) && |
1004 | 87 | "Unexpected setcc expansion!"); |
1005 | 87 | return NewLHS; |
1006 | 87 | } |
1007 | 753 | |
1008 | 753 | // Otherwise, update N to have the operands specified. |
1009 | 753 | return SDValue(DAG.UpdateNodeOperands(N, NewLHS, NewRHS, |
1010 | 753 | DAG.getCondCode(CCCode)), |
1011 | 753 | 0); |
1012 | 753 | } |
1013 | | |
1014 | 422 | SDValue DAGTypeLegalizer::SoftenFloatOp_STORE(SDNode *N, unsigned OpNo) { |
1015 | 422 | assert(ISD::isUNINDEXEDStore(N) && "Indexed store during type legalization!"); |
1016 | 422 | assert(OpNo == 1 && "Can only soften the stored value!"); |
1017 | 422 | StoreSDNode *ST = cast<StoreSDNode>(N); |
1018 | 422 | SDValue Val = ST->getValue(); |
1019 | 422 | SDLoc dl(N); |
1020 | 422 | |
1021 | 422 | if (ST->isTruncatingStore()) |
1022 | 422 | // Do an FP_ROUND followed by a non-truncating store. |
1023 | 4 | Val = BitConvertToInteger(DAG.getNode(ISD::FP_ROUND, dl, ST->getMemoryVT(), |
1024 | 4 | Val, DAG.getIntPtrConstant(0, dl))); |
1025 | 422 | else |
1026 | 418 | Val = GetSoftenedFloat(Val); |
1027 | 422 | |
1028 | 422 | return DAG.getStore(ST->getChain(), dl, Val, ST->getBasePtr(), |
1029 | 422 | ST->getMemOperand()); |
1030 | 422 | } |
1031 | | |
1032 | | |
1033 | | //===----------------------------------------------------------------------===// |
1034 | | // Float Result Expansion |
1035 | | //===----------------------------------------------------------------------===// |
1036 | | |
1037 | | /// ExpandFloatResult - This method is called when the specified result of the |
1038 | | /// specified node is found to need expansion. At this point, the node may also |
1039 | | /// have invalid operands or may have other results that need promotion, we just |
1040 | | /// know that (at least) one result needs expansion. |
1041 | 254 | void DAGTypeLegalizer::ExpandFloatResult(SDNode *N, unsigned ResNo) { |
1042 | 254 | DEBUG(dbgs() << "Expand float result: "; N->dump(&DAG); dbgs() << "\n"); |
1043 | 254 | SDValue Lo, Hi; |
1044 | 254 | Lo = Hi = SDValue(); |
1045 | 254 | |
1046 | 254 | // See if the target wants to custom expand this node. |
1047 | 254 | if (CustomLowerNode(N, N->getValueType(ResNo), true)) |
1048 | 8 | return; |
1049 | 246 | |
1050 | 246 | switch (N->getOpcode()) { |
1051 | 0 | default: |
1052 | | #ifndef NDEBUG |
1053 | | dbgs() << "ExpandFloatResult #" << ResNo << ": "; |
1054 | | N->dump(&DAG); dbgs() << "\n"; |
1055 | | #endif |
1056 | 0 | llvm_unreachable("Do not know how to expand the result of this operator!"); |
1057 | 246 | |
1058 | 3 | case ISD::UNDEF: SplitRes_UNDEF(N, Lo, Hi); break; |
1059 | 3 | case ISD::SELECT: SplitRes_SELECT(N, Lo, Hi); break; |
1060 | 3 | case ISD::SELECT_CC: SplitRes_SELECT_CC(N, Lo, Hi); break; |
1061 | 246 | |
1062 | 0 | case ISD::MERGE_VALUES: ExpandRes_MERGE_VALUES(N, ResNo, Lo, Hi); break; |
1063 | 1 | case ISD::BITCAST: ExpandRes_BITCAST(N, Lo, Hi); break; |
1064 | 129 | case ISD::BUILD_PAIR: ExpandRes_BUILD_PAIR(N, Lo, Hi); break; |
1065 | 0 | case ISD::EXTRACT_ELEMENT: ExpandRes_EXTRACT_ELEMENT(N, Lo, Hi); break; |
1066 | 4 | case ISD::EXTRACT_VECTOR_ELT: ExpandRes_EXTRACT_VECTOR_ELT(N, Lo, Hi); break; |
1067 | 1 | case ISD::VAARG: ExpandRes_VAARG(N, Lo, Hi); break; |
1068 | 246 | |
1069 | 32 | case ISD::ConstantFP: ExpandFloatRes_ConstantFP(N, Lo, Hi); break; |
1070 | 1 | case ISD::FABS: ExpandFloatRes_FABS(N, Lo, Hi); break; |
1071 | 2 | case ISD::FMINNUM: ExpandFloatRes_FMINNUM(N, Lo, Hi); break; |
1072 | 2 | case ISD::FMAXNUM: ExpandFloatRes_FMAXNUM(N, Lo, Hi); break; |
1073 | 12 | case ISD::FADD: ExpandFloatRes_FADD(N, Lo, Hi); break; |
1074 | 0 | case ISD::FCEIL: ExpandFloatRes_FCEIL(N, Lo, Hi); break; |
1075 | 7 | case ISD::FCOPYSIGN: ExpandFloatRes_FCOPYSIGN(N, Lo, Hi); break; |
1076 | 0 | case ISD::FCOS: ExpandFloatRes_FCOS(N, Lo, Hi); break; |
1077 | 5 | case ISD::FDIV: ExpandFloatRes_FDIV(N, Lo, Hi); break; |
1078 | 0 | case ISD::FEXP: ExpandFloatRes_FEXP(N, Lo, Hi); break; |
1079 | 0 | case ISD::FEXP2: ExpandFloatRes_FEXP2(N, Lo, Hi); break; |
1080 | 0 | case ISD::FFLOOR: ExpandFloatRes_FFLOOR(N, Lo, Hi); break; |
1081 | 0 | case ISD::FLOG: ExpandFloatRes_FLOG(N, Lo, Hi); break; |
1082 | 0 | case ISD::FLOG2: ExpandFloatRes_FLOG2(N, Lo, Hi); break; |
1083 | 0 | case ISD::FLOG10: ExpandFloatRes_FLOG10(N, Lo, Hi); break; |
1084 | 0 | case ISD::FMA: ExpandFloatRes_FMA(N, Lo, Hi); break; |
1085 | 4 | case ISD::FMUL: ExpandFloatRes_FMUL(N, Lo, Hi); break; |
1086 | 0 | case ISD::FNEARBYINT: ExpandFloatRes_FNEARBYINT(N, Lo, Hi); break; |
1087 | 1 | case ISD::FNEG: ExpandFloatRes_FNEG(N, Lo, Hi); break; |
1088 | 10 | case ISD::FP_EXTEND: ExpandFloatRes_FP_EXTEND(N, Lo, Hi); break; |
1089 | 1 | case ISD::FPOW: ExpandFloatRes_FPOW(N, Lo, Hi); break; |
1090 | 0 | case ISD::FPOWI: ExpandFloatRes_FPOWI(N, Lo, Hi); break; |
1091 | 0 | case ISD::FRINT: ExpandFloatRes_FRINT(N, Lo, Hi); break; |
1092 | 0 | case ISD::FROUND: ExpandFloatRes_FROUND(N, Lo, Hi); break; |
1093 | 0 | case ISD::FSIN: ExpandFloatRes_FSIN(N, Lo, Hi); break; |
1094 | 1 | case ISD::FSQRT: ExpandFloatRes_FSQRT(N, Lo, Hi); break; |
1095 | 8 | case ISD::FSUB: ExpandFloatRes_FSUB(N, Lo, Hi); break; |
1096 | 0 | case ISD::FTRUNC: ExpandFloatRes_FTRUNC(N, Lo, Hi); break; |
1097 | 9 | case ISD::LOAD: ExpandFloatRes_LOAD(N, Lo, Hi); break; |
1098 | 6 | case ISD::SINT_TO_FP: |
1099 | 6 | case ISD::UINT_TO_FP: ExpandFloatRes_XINT_TO_FP(N, Lo, Hi); break; |
1100 | 1 | case ISD::FREM: ExpandFloatRes_FREM(N, Lo, Hi); break; |
1101 | 246 | } |
1102 | 246 | |
1103 | 246 | // If Lo/Hi is null, the sub-method took care of registering results etc. |
1104 | 246 | if (246 Lo.getNode()246 ) |
1105 | 246 | SetExpandedFloat(SDValue(N, ResNo), Lo, Hi); |
1106 | 254 | } |
1107 | | |
1108 | | void DAGTypeLegalizer::ExpandFloatRes_ConstantFP(SDNode *N, SDValue &Lo, |
1109 | 32 | SDValue &Hi) { |
1110 | 32 | EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); |
1111 | 32 | assert(NVT.getSizeInBits() == 64 && |
1112 | 32 | "Do not know how to expand this float constant!"); |
1113 | 32 | APInt C = cast<ConstantFPSDNode>(N)->getValueAPF().bitcastToAPInt(); |
1114 | 32 | SDLoc dl(N); |
1115 | 32 | Lo = DAG.getConstantFP(APFloat(DAG.EVTToAPFloatSemantics(NVT), |
1116 | 32 | APInt(64, C.getRawData()[1])), |
1117 | 32 | dl, NVT); |
1118 | 32 | Hi = DAG.getConstantFP(APFloat(DAG.EVTToAPFloatSemantics(NVT), |
1119 | 32 | APInt(64, C.getRawData()[0])), |
1120 | 32 | dl, NVT); |
1121 | 32 | } |
1122 | | |
1123 | | void DAGTypeLegalizer::ExpandFloatRes_FABS(SDNode *N, SDValue &Lo, |
1124 | 1 | SDValue &Hi) { |
1125 | 1 | assert(N->getValueType(0) == MVT::ppcf128 && |
1126 | 1 | "Logic only correct for ppcf128!"); |
1127 | 1 | SDLoc dl(N); |
1128 | 1 | SDValue Tmp; |
1129 | 1 | GetExpandedFloat(N->getOperand(0), Lo, Tmp); |
1130 | 1 | Hi = DAG.getNode(ISD::FABS, dl, Tmp.getValueType(), Tmp); |
1131 | 1 | // Lo = Hi==fabs(Hi) ? Lo : -Lo; |
1132 | 1 | Lo = DAG.getSelectCC(dl, Tmp, Hi, Lo, |
1133 | 1 | DAG.getNode(ISD::FNEG, dl, Lo.getValueType(), Lo), |
1134 | 1 | ISD::SETEQ); |
1135 | 1 | } |
1136 | | |
1137 | | void DAGTypeLegalizer::ExpandFloatRes_FMINNUM(SDNode *N, SDValue &Lo, |
1138 | 2 | SDValue &Hi) { |
1139 | 2 | SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), |
1140 | 2 | RTLIB::FMIN_F32, RTLIB::FMIN_F64, |
1141 | 2 | RTLIB::FMIN_F80, RTLIB::FMIN_F128, |
1142 | 2 | RTLIB::FMIN_PPCF128), |
1143 | 2 | N, false); |
1144 | 2 | GetPairElements(Call, Lo, Hi); |
1145 | 2 | } |
1146 | | |
1147 | | void DAGTypeLegalizer::ExpandFloatRes_FMAXNUM(SDNode *N, SDValue &Lo, |
1148 | 2 | SDValue &Hi) { |
1149 | 2 | SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), |
1150 | 2 | RTLIB::FMAX_F32, RTLIB::FMAX_F64, |
1151 | 2 | RTLIB::FMAX_F80, RTLIB::FMAX_F128, |
1152 | 2 | RTLIB::FMAX_PPCF128), |
1153 | 2 | N, false); |
1154 | 2 | GetPairElements(Call, Lo, Hi); |
1155 | 2 | } |
1156 | | |
1157 | | void DAGTypeLegalizer::ExpandFloatRes_FADD(SDNode *N, SDValue &Lo, |
1158 | 12 | SDValue &Hi) { |
1159 | 12 | SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), |
1160 | 12 | RTLIB::ADD_F32, RTLIB::ADD_F64, |
1161 | 12 | RTLIB::ADD_F80, RTLIB::ADD_F128, |
1162 | 12 | RTLIB::ADD_PPCF128), |
1163 | 12 | N, false); |
1164 | 12 | GetPairElements(Call, Lo, Hi); |
1165 | 12 | } |
1166 | | |
1167 | | void DAGTypeLegalizer::ExpandFloatRes_FCEIL(SDNode *N, |
1168 | 0 | SDValue &Lo, SDValue &Hi) { |
1169 | 0 | SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), |
1170 | 0 | RTLIB::CEIL_F32, RTLIB::CEIL_F64, |
1171 | 0 | RTLIB::CEIL_F80, RTLIB::CEIL_F128, |
1172 | 0 | RTLIB::CEIL_PPCF128), |
1173 | 0 | N, false); |
1174 | 0 | GetPairElements(Call, Lo, Hi); |
1175 | 0 | } |
1176 | | |
1177 | | void DAGTypeLegalizer::ExpandFloatRes_FCOPYSIGN(SDNode *N, |
1178 | 7 | SDValue &Lo, SDValue &Hi) { |
1179 | 7 | SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), |
1180 | 7 | RTLIB::COPYSIGN_F32, |
1181 | 7 | RTLIB::COPYSIGN_F64, |
1182 | 7 | RTLIB::COPYSIGN_F80, |
1183 | 7 | RTLIB::COPYSIGN_F128, |
1184 | 7 | RTLIB::COPYSIGN_PPCF128), |
1185 | 7 | N, false); |
1186 | 7 | GetPairElements(Call, Lo, Hi); |
1187 | 7 | } |
1188 | | |
1189 | | void DAGTypeLegalizer::ExpandFloatRes_FCOS(SDNode *N, |
1190 | 0 | SDValue &Lo, SDValue &Hi) { |
1191 | 0 | SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), |
1192 | 0 | RTLIB::COS_F32, RTLIB::COS_F64, |
1193 | 0 | RTLIB::COS_F80, RTLIB::COS_F128, |
1194 | 0 | RTLIB::COS_PPCF128), |
1195 | 0 | N, false); |
1196 | 0 | GetPairElements(Call, Lo, Hi); |
1197 | 0 | } |
1198 | | |
1199 | | void DAGTypeLegalizer::ExpandFloatRes_FDIV(SDNode *N, SDValue &Lo, |
1200 | 5 | SDValue &Hi) { |
1201 | 5 | SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) }; |
1202 | 5 | SDValue Call = TLI.makeLibCall(DAG, GetFPLibCall(N->getValueType(0), |
1203 | 5 | RTLIB::DIV_F32, |
1204 | 5 | RTLIB::DIV_F64, |
1205 | 5 | RTLIB::DIV_F80, |
1206 | 5 | RTLIB::DIV_F128, |
1207 | 5 | RTLIB::DIV_PPCF128), |
1208 | 5 | N->getValueType(0), Ops, false, |
1209 | 5 | SDLoc(N)).first; |
1210 | 5 | GetPairElements(Call, Lo, Hi); |
1211 | 5 | } |
1212 | | |
1213 | | void DAGTypeLegalizer::ExpandFloatRes_FEXP(SDNode *N, |
1214 | 0 | SDValue &Lo, SDValue &Hi) { |
1215 | 0 | SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), |
1216 | 0 | RTLIB::EXP_F32, RTLIB::EXP_F64, |
1217 | 0 | RTLIB::EXP_F80, RTLIB::EXP_F128, |
1218 | 0 | RTLIB::EXP_PPCF128), |
1219 | 0 | N, false); |
1220 | 0 | GetPairElements(Call, Lo, Hi); |
1221 | 0 | } |
1222 | | |
1223 | | void DAGTypeLegalizer::ExpandFloatRes_FEXP2(SDNode *N, |
1224 | 0 | SDValue &Lo, SDValue &Hi) { |
1225 | 0 | SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), |
1226 | 0 | RTLIB::EXP2_F32, RTLIB::EXP2_F64, |
1227 | 0 | RTLIB::EXP2_F80, RTLIB::EXP2_F128, |
1228 | 0 | RTLIB::EXP2_PPCF128), |
1229 | 0 | N, false); |
1230 | 0 | GetPairElements(Call, Lo, Hi); |
1231 | 0 | } |
1232 | | |
1233 | | void DAGTypeLegalizer::ExpandFloatRes_FFLOOR(SDNode *N, |
1234 | 0 | SDValue &Lo, SDValue &Hi) { |
1235 | 0 | SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), |
1236 | 0 | RTLIB::FLOOR_F32, RTLIB::FLOOR_F64, |
1237 | 0 | RTLIB::FLOOR_F80, RTLIB::FLOOR_F128, |
1238 | 0 | RTLIB::FLOOR_PPCF128), |
1239 | 0 | N, false); |
1240 | 0 | GetPairElements(Call, Lo, Hi); |
1241 | 0 | } |
1242 | | |
1243 | | void DAGTypeLegalizer::ExpandFloatRes_FLOG(SDNode *N, |
1244 | 0 | SDValue &Lo, SDValue &Hi) { |
1245 | 0 | SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), |
1246 | 0 | RTLIB::LOG_F32, RTLIB::LOG_F64, |
1247 | 0 | RTLIB::LOG_F80, RTLIB::LOG_F128, |
1248 | 0 | RTLIB::LOG_PPCF128), |
1249 | 0 | N, false); |
1250 | 0 | GetPairElements(Call, Lo, Hi); |
1251 | 0 | } |
1252 | | |
1253 | | void DAGTypeLegalizer::ExpandFloatRes_FLOG2(SDNode *N, |
1254 | 0 | SDValue &Lo, SDValue &Hi) { |
1255 | 0 | SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), |
1256 | 0 | RTLIB::LOG2_F32, RTLIB::LOG2_F64, |
1257 | 0 | RTLIB::LOG2_F80, RTLIB::LOG2_F128, |
1258 | 0 | RTLIB::LOG2_PPCF128), |
1259 | 0 | N, false); |
1260 | 0 | GetPairElements(Call, Lo, Hi); |
1261 | 0 | } |
1262 | | |
1263 | | void DAGTypeLegalizer::ExpandFloatRes_FLOG10(SDNode *N, |
1264 | 0 | SDValue &Lo, SDValue &Hi) { |
1265 | 0 | SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), |
1266 | 0 | RTLIB::LOG10_F32, RTLIB::LOG10_F64, |
1267 | 0 | RTLIB::LOG10_F80, RTLIB::LOG10_F128, |
1268 | 0 | RTLIB::LOG10_PPCF128), |
1269 | 0 | N, false); |
1270 | 0 | GetPairElements(Call, Lo, Hi); |
1271 | 0 | } |
1272 | | |
1273 | | void DAGTypeLegalizer::ExpandFloatRes_FMA(SDNode *N, SDValue &Lo, |
1274 | 0 | SDValue &Hi) { |
1275 | 0 | SDValue Ops[3] = { N->getOperand(0), N->getOperand(1), N->getOperand(2) }; |
1276 | 0 | SDValue Call = TLI.makeLibCall(DAG, GetFPLibCall(N->getValueType(0), |
1277 | 0 | RTLIB::FMA_F32, |
1278 | 0 | RTLIB::FMA_F64, |
1279 | 0 | RTLIB::FMA_F80, |
1280 | 0 | RTLIB::FMA_F128, |
1281 | 0 | RTLIB::FMA_PPCF128), |
1282 | 0 | N->getValueType(0), Ops, false, |
1283 | 0 | SDLoc(N)).first; |
1284 | 0 | GetPairElements(Call, Lo, Hi); |
1285 | 0 | } |
1286 | | |
1287 | | void DAGTypeLegalizer::ExpandFloatRes_FMUL(SDNode *N, SDValue &Lo, |
1288 | 4 | SDValue &Hi) { |
1289 | 4 | SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) }; |
1290 | 4 | SDValue Call = TLI.makeLibCall(DAG, GetFPLibCall(N->getValueType(0), |
1291 | 4 | RTLIB::MUL_F32, |
1292 | 4 | RTLIB::MUL_F64, |
1293 | 4 | RTLIB::MUL_F80, |
1294 | 4 | RTLIB::MUL_F128, |
1295 | 4 | RTLIB::MUL_PPCF128), |
1296 | 4 | N->getValueType(0), Ops, false, |
1297 | 4 | SDLoc(N)).first; |
1298 | 4 | GetPairElements(Call, Lo, Hi); |
1299 | 4 | } |
1300 | | |
1301 | | void DAGTypeLegalizer::ExpandFloatRes_FNEARBYINT(SDNode *N, |
1302 | 0 | SDValue &Lo, SDValue &Hi) { |
1303 | 0 | SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), |
1304 | 0 | RTLIB::NEARBYINT_F32, |
1305 | 0 | RTLIB::NEARBYINT_F64, |
1306 | 0 | RTLIB::NEARBYINT_F80, |
1307 | 0 | RTLIB::NEARBYINT_F128, |
1308 | 0 | RTLIB::NEARBYINT_PPCF128), |
1309 | 0 | N, false); |
1310 | 0 | GetPairElements(Call, Lo, Hi); |
1311 | 0 | } |
1312 | | |
1313 | | void DAGTypeLegalizer::ExpandFloatRes_FNEG(SDNode *N, SDValue &Lo, |
1314 | 1 | SDValue &Hi) { |
1315 | 1 | SDLoc dl(N); |
1316 | 1 | GetExpandedFloat(N->getOperand(0), Lo, Hi); |
1317 | 1 | Lo = DAG.getNode(ISD::FNEG, dl, Lo.getValueType(), Lo); |
1318 | 1 | Hi = DAG.getNode(ISD::FNEG, dl, Hi.getValueType(), Hi); |
1319 | 1 | } |
1320 | | |
1321 | | void DAGTypeLegalizer::ExpandFloatRes_FP_EXTEND(SDNode *N, SDValue &Lo, |
1322 | 10 | SDValue &Hi) { |
1323 | 10 | EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); |
1324 | 10 | SDLoc dl(N); |
1325 | 10 | Hi = DAG.getNode(ISD::FP_EXTEND, dl, NVT, N->getOperand(0)); |
1326 | 10 | Lo = DAG.getConstantFP(APFloat(DAG.EVTToAPFloatSemantics(NVT), |
1327 | 10 | APInt(NVT.getSizeInBits(), 0)), dl, NVT); |
1328 | 10 | } |
1329 | | |
1330 | | void DAGTypeLegalizer::ExpandFloatRes_FPOW(SDNode *N, |
1331 | 1 | SDValue &Lo, SDValue &Hi) { |
1332 | 1 | SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), |
1333 | 1 | RTLIB::POW_F32, RTLIB::POW_F64, |
1334 | 1 | RTLIB::POW_F80, RTLIB::POW_F128, |
1335 | 1 | RTLIB::POW_PPCF128), |
1336 | 1 | N, false); |
1337 | 1 | GetPairElements(Call, Lo, Hi); |
1338 | 1 | } |
1339 | | |
1340 | | void DAGTypeLegalizer::ExpandFloatRes_FPOWI(SDNode *N, |
1341 | 0 | SDValue &Lo, SDValue &Hi) { |
1342 | 0 | SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), |
1343 | 0 | RTLIB::POWI_F32, RTLIB::POWI_F64, |
1344 | 0 | RTLIB::POWI_F80, RTLIB::POWI_F128, |
1345 | 0 | RTLIB::POWI_PPCF128), |
1346 | 0 | N, false); |
1347 | 0 | GetPairElements(Call, Lo, Hi); |
1348 | 0 | } |
1349 | | |
1350 | | void DAGTypeLegalizer::ExpandFloatRes_FREM(SDNode *N, |
1351 | 1 | SDValue &Lo, SDValue &Hi) { |
1352 | 1 | SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), |
1353 | 1 | RTLIB::REM_F32, RTLIB::REM_F64, |
1354 | 1 | RTLIB::REM_F80, RTLIB::REM_F128, |
1355 | 1 | RTLIB::REM_PPCF128), |
1356 | 1 | N, false); |
1357 | 1 | GetPairElements(Call, Lo, Hi); |
1358 | 1 | } |
1359 | | |
1360 | | void DAGTypeLegalizer::ExpandFloatRes_FRINT(SDNode *N, |
1361 | 0 | SDValue &Lo, SDValue &Hi) { |
1362 | 0 | SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), |
1363 | 0 | RTLIB::RINT_F32, RTLIB::RINT_F64, |
1364 | 0 | RTLIB::RINT_F80, RTLIB::RINT_F128, |
1365 | 0 | RTLIB::RINT_PPCF128), |
1366 | 0 | N, false); |
1367 | 0 | GetPairElements(Call, Lo, Hi); |
1368 | 0 | } |
1369 | | |
1370 | | void DAGTypeLegalizer::ExpandFloatRes_FROUND(SDNode *N, |
1371 | 0 | SDValue &Lo, SDValue &Hi) { |
1372 | 0 | SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), |
1373 | 0 | RTLIB::ROUND_F32, |
1374 | 0 | RTLIB::ROUND_F64, |
1375 | 0 | RTLIB::ROUND_F80, |
1376 | 0 | RTLIB::ROUND_F128, |
1377 | 0 | RTLIB::ROUND_PPCF128), |
1378 | 0 | N, false); |
1379 | 0 | GetPairElements(Call, Lo, Hi); |
1380 | 0 | } |
1381 | | |
1382 | | void DAGTypeLegalizer::ExpandFloatRes_FSIN(SDNode *N, |
1383 | 0 | SDValue &Lo, SDValue &Hi) { |
1384 | 0 | SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), |
1385 | 0 | RTLIB::SIN_F32, RTLIB::SIN_F64, |
1386 | 0 | RTLIB::SIN_F80, RTLIB::SIN_F128, |
1387 | 0 | RTLIB::SIN_PPCF128), |
1388 | 0 | N, false); |
1389 | 0 | GetPairElements(Call, Lo, Hi); |
1390 | 0 | } |
1391 | | |
1392 | | void DAGTypeLegalizer::ExpandFloatRes_FSQRT(SDNode *N, |
1393 | 1 | SDValue &Lo, SDValue &Hi) { |
1394 | 1 | SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), |
1395 | 1 | RTLIB::SQRT_F32, RTLIB::SQRT_F64, |
1396 | 1 | RTLIB::SQRT_F80, RTLIB::SQRT_F128, |
1397 | 1 | RTLIB::SQRT_PPCF128), |
1398 | 1 | N, false); |
1399 | 1 | GetPairElements(Call, Lo, Hi); |
1400 | 1 | } |
1401 | | |
1402 | | void DAGTypeLegalizer::ExpandFloatRes_FSUB(SDNode *N, SDValue &Lo, |
1403 | 8 | SDValue &Hi) { |
1404 | 8 | SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) }; |
1405 | 8 | SDValue Call = TLI.makeLibCall(DAG, GetFPLibCall(N->getValueType(0), |
1406 | 8 | RTLIB::SUB_F32, |
1407 | 8 | RTLIB::SUB_F64, |
1408 | 8 | RTLIB::SUB_F80, |
1409 | 8 | RTLIB::SUB_F128, |
1410 | 8 | RTLIB::SUB_PPCF128), |
1411 | 8 | N->getValueType(0), Ops, false, |
1412 | 8 | SDLoc(N)).first; |
1413 | 8 | GetPairElements(Call, Lo, Hi); |
1414 | 8 | } |
1415 | | |
1416 | | void DAGTypeLegalizer::ExpandFloatRes_FTRUNC(SDNode *N, |
1417 | 0 | SDValue &Lo, SDValue &Hi) { |
1418 | 0 | SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), |
1419 | 0 | RTLIB::TRUNC_F32, RTLIB::TRUNC_F64, |
1420 | 0 | RTLIB::TRUNC_F80, RTLIB::TRUNC_F128, |
1421 | 0 | RTLIB::TRUNC_PPCF128), |
1422 | 0 | N, false); |
1423 | 0 | GetPairElements(Call, Lo, Hi); |
1424 | 0 | } |
1425 | | |
1426 | | void DAGTypeLegalizer::ExpandFloatRes_LOAD(SDNode *N, SDValue &Lo, |
1427 | 9 | SDValue &Hi) { |
1428 | 9 | if (ISD::isNormalLoad(N)9 ) { |
1429 | 8 | ExpandRes_NormalLoad(N, Lo, Hi); |
1430 | 8 | return; |
1431 | 8 | } |
1432 | 1 | |
1433 | 9 | assert(ISD::isUNINDEXEDLoad(N) && "Indexed load during type legalization!"); |
1434 | 1 | LoadSDNode *LD = cast<LoadSDNode>(N); |
1435 | 1 | SDValue Chain = LD->getChain(); |
1436 | 1 | SDValue Ptr = LD->getBasePtr(); |
1437 | 1 | SDLoc dl(N); |
1438 | 1 | |
1439 | 1 | EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), LD->getValueType(0)); |
1440 | 1 | assert(NVT.isByteSized() && "Expanded type not byte sized!"); |
1441 | 1 | assert(LD->getMemoryVT().bitsLE(NVT) && "Float type not round?"); |
1442 | 1 | |
1443 | 1 | Hi = DAG.getExtLoad(LD->getExtensionType(), dl, NVT, Chain, Ptr, |
1444 | 1 | LD->getMemoryVT(), LD->getMemOperand()); |
1445 | 1 | |
1446 | 1 | // Remember the chain. |
1447 | 1 | Chain = Hi.getValue(1); |
1448 | 1 | |
1449 | 1 | // The low part is zero. |
1450 | 1 | Lo = DAG.getConstantFP(APFloat(DAG.EVTToAPFloatSemantics(NVT), |
1451 | 1 | APInt(NVT.getSizeInBits(), 0)), dl, NVT); |
1452 | 1 | |
1453 | 1 | // Modified the chain - switch anything that used the old chain to use the |
1454 | 1 | // new one. |
1455 | 1 | ReplaceValueWith(SDValue(LD, 1), Chain); |
1456 | 1 | } |
1457 | | |
1458 | | void DAGTypeLegalizer::ExpandFloatRes_XINT_TO_FP(SDNode *N, SDValue &Lo, |
1459 | 6 | SDValue &Hi) { |
1460 | 6 | assert(N->getValueType(0) == MVT::ppcf128 && "Unsupported XINT_TO_FP!"); |
1461 | 6 | EVT VT = N->getValueType(0); |
1462 | 6 | EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT); |
1463 | 6 | SDValue Src = N->getOperand(0); |
1464 | 6 | EVT SrcVT = Src.getValueType(); |
1465 | 6 | bool isSigned = N->getOpcode() == ISD::SINT_TO_FP; |
1466 | 6 | SDLoc dl(N); |
1467 | 6 | |
1468 | 6 | // First do an SINT_TO_FP, whether the original was signed or unsigned. |
1469 | 6 | // When promoting partial word types to i32 we must honor the signedness, |
1470 | 6 | // though. |
1471 | 6 | if (SrcVT.bitsLE(MVT::i32)6 ) { |
1472 | 1 | // The integer can be represented exactly in an f64. |
1473 | 1 | Src = DAG.getNode(isSigned ? ISD::SIGN_EXTEND0 : ISD::ZERO_EXTEND1 , dl, |
1474 | 1 | MVT::i32, Src); |
1475 | 1 | Lo = DAG.getConstantFP(APFloat(DAG.EVTToAPFloatSemantics(NVT), |
1476 | 1 | APInt(NVT.getSizeInBits(), 0)), dl, NVT); |
1477 | 1 | Hi = DAG.getNode(ISD::SINT_TO_FP, dl, NVT, Src); |
1478 | 6 | } else { |
1479 | 5 | RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; |
1480 | 5 | if (SrcVT.bitsLE(MVT::i64)5 ) { |
1481 | 4 | Src = DAG.getNode(isSigned ? ISD::SIGN_EXTEND3 : ISD::ZERO_EXTEND1 , dl, |
1482 | 4 | MVT::i64, Src); |
1483 | 4 | LC = RTLIB::SINTTOFP_I64_PPCF128; |
1484 | 5 | } else if (1 SrcVT.bitsLE(MVT::i128)1 ) { |
1485 | 1 | Src = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::i128, Src); |
1486 | 1 | LC = RTLIB::SINTTOFP_I128_PPCF128; |
1487 | 1 | } |
1488 | 5 | assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported XINT_TO_FP!"); |
1489 | 5 | |
1490 | 5 | Hi = TLI.makeLibCall(DAG, LC, VT, Src, true, dl).first; |
1491 | 5 | GetPairElements(Hi, Lo, Hi); |
1492 | 5 | } |
1493 | 6 | |
1494 | 6 | if (isSigned) |
1495 | 3 | return; |
1496 | 3 | |
1497 | 3 | // Unsigned - fix up the SINT_TO_FP value just calculated. |
1498 | 3 | Hi = DAG.getNode(ISD::BUILD_PAIR, dl, VT, Lo, Hi); |
1499 | 3 | SrcVT = Src.getValueType(); |
1500 | 3 | |
1501 | 3 | // x>=0 ? (ppcf128)(iN)x : (ppcf128)(iN)x + 2^N; N=32,64,128. |
1502 | 3 | static const uint64_t TwoE32[] = { 0x41f0000000000000LL, 0 }; |
1503 | 3 | static const uint64_t TwoE64[] = { 0x43f0000000000000LL, 0 }; |
1504 | 3 | static const uint64_t TwoE128[] = { 0x47f0000000000000LL, 0 }; |
1505 | 3 | ArrayRef<uint64_t> Parts; |
1506 | 3 | |
1507 | 3 | switch (SrcVT.getSimpleVT().SimpleTy) { |
1508 | 0 | default: |
1509 | 0 | llvm_unreachable("Unsupported UINT_TO_FP!"); |
1510 | 1 | case MVT::i32: |
1511 | 1 | Parts = TwoE32; |
1512 | 1 | break; |
1513 | 1 | case MVT::i64: |
1514 | 1 | Parts = TwoE64; |
1515 | 1 | break; |
1516 | 1 | case MVT::i128: |
1517 | 1 | Parts = TwoE128; |
1518 | 1 | break; |
1519 | 3 | } |
1520 | 3 | |
1521 | 3 | // TODO: Are there fast-math-flags to propagate to this FADD? |
1522 | 3 | Lo = DAG.getNode(ISD::FADD, dl, VT, Hi, |
1523 | 3 | DAG.getConstantFP(APFloat(APFloat::PPCDoubleDouble(), |
1524 | 3 | APInt(128, Parts)), |
1525 | 3 | dl, MVT::ppcf128)); |
1526 | 3 | Lo = DAG.getSelectCC(dl, Src, DAG.getConstant(0, dl, SrcVT), |
1527 | 3 | Lo, Hi, ISD::SETLT); |
1528 | 3 | GetPairElements(Lo, Lo, Hi); |
1529 | 3 | } |
1530 | | |
1531 | | |
1532 | | //===----------------------------------------------------------------------===// |
1533 | | // Float Operand Expansion |
1534 | | //===----------------------------------------------------------------------===// |
1535 | | |
1536 | | /// ExpandFloatOperand - This method is called when the specified operand of the |
1537 | | /// specified node is found to need expansion. At this point, all of the result |
1538 | | /// types of the node are known to be legal, but other operands of the node may |
1539 | | /// need promotion or expansion as well as the specified one. |
1540 | 92 | bool DAGTypeLegalizer::ExpandFloatOperand(SDNode *N, unsigned OpNo) { |
1541 | 92 | DEBUG(dbgs() << "Expand float operand: "; N->dump(&DAG); dbgs() << "\n"); |
1542 | 92 | SDValue Res = SDValue(); |
1543 | 92 | |
1544 | 92 | // See if the target wants to custom expand this node. |
1545 | 92 | if (CustomLowerNode(N, N->getOperand(OpNo).getValueType(), false)) |
1546 | 0 | return false; |
1547 | 92 | |
1548 | 92 | switch (N->getOpcode()) { |
1549 | 0 | default: |
1550 | | #ifndef NDEBUG |
1551 | | dbgs() << "ExpandFloatOperand Op #" << OpNo << ": "; |
1552 | | N->dump(&DAG); dbgs() << "\n"; |
1553 | | #endif |
1554 | 0 | llvm_unreachable("Do not know how to expand this operator's operand!"); |
1555 | 92 | |
1556 | 4 | case ISD::BITCAST: Res = ExpandOp_BITCAST(N); break; |
1557 | 0 | case ISD::BUILD_VECTOR: Res = ExpandOp_BUILD_VECTOR(N); break; |
1558 | 18 | case ISD::EXTRACT_ELEMENT: Res = ExpandOp_EXTRACT_ELEMENT(N); break; |
1559 | 92 | |
1560 | 0 | case ISD::BR_CC: Res = ExpandFloatOp_BR_CC(N); break; |
1561 | 4 | case ISD::FCOPYSIGN: Res = ExpandFloatOp_FCOPYSIGN(N); break; |
1562 | 18 | case ISD::FP_ROUND: Res = ExpandFloatOp_FP_ROUND(N); break; |
1563 | 9 | case ISD::FP_TO_SINT: Res = ExpandFloatOp_FP_TO_SINT(N); break; |
1564 | 5 | case ISD::FP_TO_UINT: Res = ExpandFloatOp_FP_TO_UINT(N); break; |
1565 | 6 | case ISD::SELECT_CC: Res = ExpandFloatOp_SELECT_CC(N); break; |
1566 | 7 | case ISD::SETCC: Res = ExpandFloatOp_SETCC(N); break; |
1567 | 21 | case ISD::STORE: Res = ExpandFloatOp_STORE(cast<StoreSDNode>(N), |
1568 | 21 | OpNo); break; |
1569 | 92 | } |
1570 | 92 | |
1571 | 92 | // If the result is null, the sub-method took care of registering results etc. |
1572 | 92 | if (92 !Res.getNode()92 ) return false0 ; |
1573 | 92 | |
1574 | 92 | // If the result is N, the sub-method updated N in place. Tell the legalizer |
1575 | 92 | // core about this. |
1576 | 92 | if (92 Res.getNode() == N92 ) |
1577 | 6 | return true; |
1578 | 86 | |
1579 | 92 | assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 && |
1580 | 86 | "Invalid operand expansion"); |
1581 | 86 | |
1582 | 86 | ReplaceValueWith(SDValue(N, 0), Res); |
1583 | 86 | return false; |
1584 | 86 | } |
1585 | | |
1586 | | /// FloatExpandSetCCOperands - Expand the operands of a comparison. This code |
1587 | | /// is shared among BR_CC, SELECT_CC, and SETCC handlers. |
1588 | | void DAGTypeLegalizer::FloatExpandSetCCOperands(SDValue &NewLHS, |
1589 | | SDValue &NewRHS, |
1590 | | ISD::CondCode &CCCode, |
1591 | 13 | const SDLoc &dl) { |
1592 | 13 | SDValue LHSLo, LHSHi, RHSLo, RHSHi; |
1593 | 13 | GetExpandedFloat(NewLHS, LHSLo, LHSHi); |
1594 | 13 | GetExpandedFloat(NewRHS, RHSLo, RHSHi); |
1595 | 13 | |
1596 | 13 | assert(NewLHS.getValueType() == MVT::ppcf128 && "Unsupported setcc type!"); |
1597 | 13 | |
1598 | 13 | // FIXME: This generated code sucks. We want to generate |
1599 | 13 | // FCMPU crN, hi1, hi2 |
1600 | 13 | // BNE crN, L: |
1601 | 13 | // FCMPU crN, lo1, lo2 |
1602 | 13 | // The following can be improved, but not that much. |
1603 | 13 | SDValue Tmp1, Tmp2, Tmp3; |
1604 | 13 | Tmp1 = DAG.getSetCC(dl, getSetCCResultType(LHSHi.getValueType()), |
1605 | 13 | LHSHi, RHSHi, ISD::SETOEQ); |
1606 | 13 | Tmp2 = DAG.getSetCC(dl, getSetCCResultType(LHSLo.getValueType()), |
1607 | 13 | LHSLo, RHSLo, CCCode); |
1608 | 13 | Tmp3 = DAG.getNode(ISD::AND, dl, Tmp1.getValueType(), Tmp1, Tmp2); |
1609 | 13 | Tmp1 = DAG.getSetCC(dl, getSetCCResultType(LHSHi.getValueType()), |
1610 | 13 | LHSHi, RHSHi, ISD::SETUNE); |
1611 | 13 | Tmp2 = DAG.getSetCC(dl, getSetCCResultType(LHSHi.getValueType()), |
1612 | 13 | LHSHi, RHSHi, CCCode); |
1613 | 13 | Tmp1 = DAG.getNode(ISD::AND, dl, Tmp1.getValueType(), Tmp1, Tmp2); |
1614 | 13 | NewLHS = DAG.getNode(ISD::OR, dl, Tmp1.getValueType(), Tmp1, Tmp3); |
1615 | 13 | NewRHS = SDValue(); // LHS is the result, not a compare. |
1616 | 13 | } |
1617 | | |
1618 | 0 | SDValue DAGTypeLegalizer::ExpandFloatOp_BR_CC(SDNode *N) { |
1619 | 0 | SDValue NewLHS = N->getOperand(2), NewRHS = N->getOperand(3); |
1620 | 0 | ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(1))->get(); |
1621 | 0 | FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(N)); |
1622 | 0 |
|
1623 | 0 | // If ExpandSetCCOperands returned a scalar, we need to compare the result |
1624 | 0 | // against zero to select between true and false values. |
1625 | 0 | if (!NewRHS.getNode()0 ) { |
1626 | 0 | NewRHS = DAG.getConstant(0, SDLoc(N), NewLHS.getValueType()); |
1627 | 0 | CCCode = ISD::SETNE; |
1628 | 0 | } |
1629 | 0 |
|
1630 | 0 | // Update N to have the operands specified. |
1631 | 0 | return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0), |
1632 | 0 | DAG.getCondCode(CCCode), NewLHS, NewRHS, |
1633 | 0 | N->getOperand(4)), 0); |
1634 | 0 | } |
1635 | | |
1636 | 4 | SDValue DAGTypeLegalizer::ExpandFloatOp_FCOPYSIGN(SDNode *N) { |
1637 | 4 | assert(N->getOperand(1).getValueType() == MVT::ppcf128 && |
1638 | 4 | "Logic only correct for ppcf128!"); |
1639 | 4 | SDValue Lo, Hi; |
1640 | 4 | GetExpandedFloat(N->getOperand(1), Lo, Hi); |
1641 | 4 | // The ppcf128 value is providing only the sign; take it from the |
1642 | 4 | // higher-order double (which must have the larger magnitude). |
1643 | 4 | return DAG.getNode(ISD::FCOPYSIGN, SDLoc(N), |
1644 | 4 | N->getValueType(0), N->getOperand(0), Hi); |
1645 | 4 | } |
1646 | | |
1647 | 18 | SDValue DAGTypeLegalizer::ExpandFloatOp_FP_ROUND(SDNode *N) { |
1648 | 18 | assert(N->getOperand(0).getValueType() == MVT::ppcf128 && |
1649 | 18 | "Logic only correct for ppcf128!"); |
1650 | 18 | SDValue Lo, Hi; |
1651 | 18 | GetExpandedFloat(N->getOperand(0), Lo, Hi); |
1652 | 18 | // Round it the rest of the way (e.g. to f32) if needed. |
1653 | 18 | return DAG.getNode(ISD::FP_ROUND, SDLoc(N), |
1654 | 18 | N->getValueType(0), Hi, N->getOperand(1)); |
1655 | 18 | } |
1656 | | |
1657 | 9 | SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_SINT(SDNode *N) { |
1658 | 9 | EVT RVT = N->getValueType(0); |
1659 | 9 | SDLoc dl(N); |
1660 | 9 | |
1661 | 9 | // Expand ppcf128 to i32 by hand for the benefit of llvm-gcc bootstrap on |
1662 | 9 | // PPC (the libcall is not available). FIXME: Do this in a less hacky way. |
1663 | 9 | if (RVT == MVT::i329 ) { |
1664 | 8 | assert(N->getOperand(0).getValueType() == MVT::ppcf128 && |
1665 | 8 | "Logic only correct for ppcf128!"); |
1666 | 8 | SDValue Res = DAG.getNode(ISD::FP_ROUND_INREG, dl, MVT::ppcf128, |
1667 | 8 | N->getOperand(0), DAG.getValueType(MVT::f64)); |
1668 | 8 | Res = DAG.getNode(ISD::FP_ROUND, dl, MVT::f64, Res, |
1669 | 8 | DAG.getIntPtrConstant(1, dl)); |
1670 | 8 | return DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32, Res); |
1671 | 8 | } |
1672 | 1 | |
1673 | 1 | RTLIB::Libcall LC = RTLIB::getFPTOSINT(N->getOperand(0).getValueType(), RVT); |
1674 | 1 | assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_SINT!"); |
1675 | 1 | return TLI.makeLibCall(DAG, LC, RVT, N->getOperand(0), false, dl).first; |
1676 | 1 | } |
1677 | | |
1678 | 5 | SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_UINT(SDNode *N) { |
1679 | 5 | EVT RVT = N->getValueType(0); |
1680 | 5 | SDLoc dl(N); |
1681 | 5 | |
1682 | 5 | // Expand ppcf128 to i32 by hand for the benefit of llvm-gcc bootstrap on |
1683 | 5 | // PPC (the libcall is not available). FIXME: Do this in a less hacky way. |
1684 | 5 | if (RVT == MVT::i325 ) { |
1685 | 4 | assert(N->getOperand(0).getValueType() == MVT::ppcf128 && |
1686 | 4 | "Logic only correct for ppcf128!"); |
1687 | 4 | const uint64_t TwoE31[] = {0x41e0000000000000LL, 0}; |
1688 | 4 | APFloat APF = APFloat(APFloat::PPCDoubleDouble(), APInt(128, TwoE31)); |
1689 | 4 | SDValue Tmp = DAG.getConstantFP(APF, dl, MVT::ppcf128); |
1690 | 4 | // X>=2^31 ? (int)(X-2^31)+0x80000000 : (int)X |
1691 | 4 | // FIXME: generated code sucks. |
1692 | 4 | // TODO: Are there fast-math-flags to propagate to this FSUB? |
1693 | 4 | return DAG.getSelectCC(dl, N->getOperand(0), Tmp, |
1694 | 4 | DAG.getNode(ISD::ADD, dl, MVT::i32, |
1695 | 4 | DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32, |
1696 | 4 | DAG.getNode(ISD::FSUB, dl, |
1697 | 4 | MVT::ppcf128, |
1698 | 4 | N->getOperand(0), |
1699 | 4 | Tmp)), |
1700 | 4 | DAG.getConstant(0x80000000, dl, |
1701 | 4 | MVT::i32)), |
1702 | 4 | DAG.getNode(ISD::FP_TO_SINT, dl, |
1703 | 4 | MVT::i32, N->getOperand(0)), |
1704 | 4 | ISD::SETGE); |
1705 | 4 | } |
1706 | 1 | |
1707 | 1 | RTLIB::Libcall LC = RTLIB::getFPTOUINT(N->getOperand(0).getValueType(), RVT); |
1708 | 1 | assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_UINT!"); |
1709 | 1 | return TLI.makeLibCall(DAG, LC, N->getValueType(0), N->getOperand(0), |
1710 | 1 | false, dl).first; |
1711 | 1 | } |
1712 | | |
1713 | 6 | SDValue DAGTypeLegalizer::ExpandFloatOp_SELECT_CC(SDNode *N) { |
1714 | 6 | SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1); |
1715 | 6 | ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(4))->get(); |
1716 | 6 | FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(N)); |
1717 | 6 | |
1718 | 6 | // If ExpandSetCCOperands returned a scalar, we need to compare the result |
1719 | 6 | // against zero to select between true and false values. |
1720 | 6 | if (!NewRHS.getNode()6 ) { |
1721 | 6 | NewRHS = DAG.getConstant(0, SDLoc(N), NewLHS.getValueType()); |
1722 | 6 | CCCode = ISD::SETNE; |
1723 | 6 | } |
1724 | 6 | |
1725 | 6 | // Update N to have the operands specified. |
1726 | 6 | return SDValue(DAG.UpdateNodeOperands(N, NewLHS, NewRHS, |
1727 | 6 | N->getOperand(2), N->getOperand(3), |
1728 | 6 | DAG.getCondCode(CCCode)), 0); |
1729 | 6 | } |
1730 | | |
1731 | 7 | SDValue DAGTypeLegalizer::ExpandFloatOp_SETCC(SDNode *N) { |
1732 | 7 | SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1); |
1733 | 7 | ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(2))->get(); |
1734 | 7 | FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(N)); |
1735 | 7 | |
1736 | 7 | // If ExpandSetCCOperands returned a scalar, use it. |
1737 | 7 | if (!NewRHS.getNode()7 ) { |
1738 | 7 | assert(NewLHS.getValueType() == N->getValueType(0) && |
1739 | 7 | "Unexpected setcc expansion!"); |
1740 | 7 | return NewLHS; |
1741 | 7 | } |
1742 | 0 |
|
1743 | 0 | // Otherwise, update N to have the operands specified. |
1744 | 0 | return SDValue(DAG.UpdateNodeOperands(N, NewLHS, NewRHS, |
1745 | 0 | DAG.getCondCode(CCCode)), 0); |
1746 | 0 | } |
1747 | | |
1748 | 21 | SDValue DAGTypeLegalizer::ExpandFloatOp_STORE(SDNode *N, unsigned OpNo) { |
1749 | 21 | if (ISD::isNormalStore(N)) |
1750 | 21 | return ExpandOp_NormalStore(N, OpNo); |
1751 | 0 |
|
1752 | 21 | assert(ISD::isUNINDEXEDStore(N) && "Indexed store during type legalization!"); |
1753 | 0 | assert(OpNo == 1 && "Can only expand the stored value so far"); |
1754 | 0 | StoreSDNode *ST = cast<StoreSDNode>(N); |
1755 | 0 |
|
1756 | 0 | SDValue Chain = ST->getChain(); |
1757 | 0 | SDValue Ptr = ST->getBasePtr(); |
1758 | 0 |
|
1759 | 0 | EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), |
1760 | 0 | ST->getValue().getValueType()); |
1761 | 0 | assert(NVT.isByteSized() && "Expanded type not byte sized!"); |
1762 | 0 | assert(ST->getMemoryVT().bitsLE(NVT) && "Float type not round?"); |
1763 | 0 | (void)NVT; |
1764 | 0 |
|
1765 | 0 | SDValue Lo, Hi; |
1766 | 0 | GetExpandedOp(ST->getValue(), Lo, Hi); |
1767 | 0 |
|
1768 | 0 | return DAG.getTruncStore(Chain, SDLoc(N), Hi, Ptr, |
1769 | 0 | ST->getMemoryVT(), ST->getMemOperand()); |
1770 | 0 | } |
1771 | | |
1772 | | //===----------------------------------------------------------------------===// |
1773 | | // Float Operand Promotion |
1774 | | //===----------------------------------------------------------------------===// |
1775 | | // |
1776 | | |
1777 | 4.99k | static ISD::NodeType GetPromotionOpcode(EVT OpVT, EVT RetVT) { |
1778 | 4.99k | if (OpVT == MVT::f164.99k ) { |
1779 | 3.02k | return ISD::FP16_TO_FP; |
1780 | 1.96k | } else if (1.96k RetVT == MVT::f161.96k ) { |
1781 | 1.96k | return ISD::FP_TO_FP16; |
1782 | 1.96k | } |
1783 | 0 |
|
1784 | 0 | report_fatal_error("Attempt at an invalid promotion-related conversion"); |
1785 | 0 | } |
1786 | | |
1787 | 1.97k | bool DAGTypeLegalizer::PromoteFloatOperand(SDNode *N, unsigned OpNo) { |
1788 | 1.97k | SDValue R = SDValue(); |
1789 | 1.97k | |
1790 | 1.97k | // Nodes that use a promotion-requiring floating point operand, but doesn't |
1791 | 1.97k | // produce a promotion-requiring floating point result, need to be legalized |
1792 | 1.97k | // to use the promoted float operand. Nodes that produce at least one |
1793 | 1.97k | // promotion-requiring floating point result have their operands legalized as |
1794 | 1.97k | // a part of PromoteFloatResult. |
1795 | 1.97k | switch (N->getOpcode()) { |
1796 | 0 | default: |
1797 | 0 | llvm_unreachable("Do not know how to promote this operator's operand!"); |
1798 | 1.97k | |
1799 | 317 | case ISD::BITCAST: R = PromoteFloatOp_BITCAST(N, OpNo); break; |
1800 | 16 | case ISD::FCOPYSIGN: R = PromoteFloatOp_FCOPYSIGN(N, OpNo); break; |
1801 | 48 | case ISD::FP_TO_SINT: |
1802 | 48 | case ISD::FP_TO_UINT: R = PromoteFloatOp_FP_TO_XINT(N, OpNo); break; |
1803 | 900 | case ISD::FP_EXTEND: R = PromoteFloatOp_FP_EXTEND(N, OpNo); break; |
1804 | 0 | case ISD::SELECT_CC: R = PromoteFloatOp_SELECT_CC(N, OpNo); break; |
1805 | 72 | case ISD::SETCC: R = PromoteFloatOp_SETCC(N, OpNo); break; |
1806 | 617 | case ISD::STORE: R = PromoteFloatOp_STORE(N, OpNo); break; |
1807 | 1.97k | } |
1808 | 1.97k | |
1809 | 1.97k | if (1.97k R.getNode()1.97k ) |
1810 | 1.97k | ReplaceValueWith(SDValue(N, 0), R); |
1811 | 1.97k | return false; |
1812 | 1.97k | } |
1813 | | |
1814 | 317 | SDValue DAGTypeLegalizer::PromoteFloatOp_BITCAST(SDNode *N, unsigned OpNo) { |
1815 | 317 | SDValue Op = N->getOperand(0); |
1816 | 317 | EVT OpVT = Op->getValueType(0); |
1817 | 317 | |
1818 | 317 | EVT IVT = EVT::getIntegerVT(*DAG.getContext(), OpVT.getSizeInBits()); |
1819 | 317 | assert (IVT == N->getValueType(0) && "Bitcast to type of different size"); |
1820 | 317 | |
1821 | 317 | SDValue Promoted = GetPromotedFloat(N->getOperand(0)); |
1822 | 317 | EVT PromotedVT = Promoted->getValueType(0); |
1823 | 317 | |
1824 | 317 | // Convert the promoted float value to the desired IVT. |
1825 | 317 | return DAG.getNode(GetPromotionOpcode(PromotedVT, OpVT), SDLoc(N), IVT, |
1826 | 317 | Promoted); |
1827 | 317 | } |
1828 | | |
1829 | | // Promote Operand 1 of FCOPYSIGN. Operand 0 ought to be handled by |
1830 | | // PromoteFloatRes_FCOPYSIGN. |
1831 | 16 | SDValue DAGTypeLegalizer::PromoteFloatOp_FCOPYSIGN(SDNode *N, unsigned OpNo) { |
1832 | 16 | assert (OpNo == 1 && "Only Operand 1 must need promotion here"); |
1833 | 16 | SDValue Op1 = GetPromotedFloat(N->getOperand(1)); |
1834 | 16 | |
1835 | 16 | return DAG.getNode(N->getOpcode(), SDLoc(N), N->getValueType(0), |
1836 | 16 | N->getOperand(0), Op1); |
1837 | 16 | } |
1838 | | |
1839 | | // Convert the promoted float value to the desired integer type |
1840 | 48 | SDValue DAGTypeLegalizer::PromoteFloatOp_FP_TO_XINT(SDNode *N, unsigned OpNo) { |
1841 | 48 | SDValue Op = GetPromotedFloat(N->getOperand(0)); |
1842 | 48 | return DAG.getNode(N->getOpcode(), SDLoc(N), N->getValueType(0), Op); |
1843 | 48 | } |
1844 | | |
1845 | 900 | SDValue DAGTypeLegalizer::PromoteFloatOp_FP_EXTEND(SDNode *N, unsigned OpNo) { |
1846 | 900 | SDValue Op = GetPromotedFloat(N->getOperand(0)); |
1847 | 900 | EVT VT = N->getValueType(0); |
1848 | 900 | |
1849 | 900 | // Desired VT is same as promoted type. Use promoted float directly. |
1850 | 900 | if (VT == Op->getValueType(0)) |
1851 | 640 | return Op; |
1852 | 260 | |
1853 | 260 | // Else, extend the promoted float value to the desired VT. |
1854 | 260 | return DAG.getNode(ISD::FP_EXTEND, SDLoc(N), VT, Op); |
1855 | 260 | } |
1856 | | |
1857 | | // Promote the float operands used for comparison. The true- and false- |
1858 | | // operands have the same type as the result and are promoted, if needed, by |
1859 | | // PromoteFloatRes_SELECT_CC |
1860 | 0 | SDValue DAGTypeLegalizer::PromoteFloatOp_SELECT_CC(SDNode *N, unsigned OpNo) { |
1861 | 0 | SDValue LHS = GetPromotedFloat(N->getOperand(0)); |
1862 | 0 | SDValue RHS = GetPromotedFloat(N->getOperand(1)); |
1863 | 0 |
|
1864 | 0 | return DAG.getNode(ISD::SELECT_CC, SDLoc(N), N->getValueType(0), |
1865 | 0 | LHS, RHS, N->getOperand(2), N->getOperand(3), |
1866 | 0 | N->getOperand(4)); |
1867 | 0 | } |
1868 | | |
1869 | | // Construct a SETCC that compares the promoted values and sets the conditional |
1870 | | // code. |
1871 | 72 | SDValue DAGTypeLegalizer::PromoteFloatOp_SETCC(SDNode *N, unsigned OpNo) { |
1872 | 72 | EVT VT = N->getValueType(0); |
1873 | 72 | EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT); |
1874 | 72 | SDValue Op0 = GetPromotedFloat(N->getOperand(0)); |
1875 | 72 | SDValue Op1 = GetPromotedFloat(N->getOperand(1)); |
1876 | 72 | ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(2))->get(); |
1877 | 72 | |
1878 | 72 | return DAG.getSetCC(SDLoc(N), NVT, Op0, Op1, CCCode); |
1879 | 72 | |
1880 | 72 | } |
1881 | | |
1882 | | // Lower the promoted Float down to the integer value of same size and construct |
1883 | | // a STORE of the integer value. |
1884 | 617 | SDValue DAGTypeLegalizer::PromoteFloatOp_STORE(SDNode *N, unsigned OpNo) { |
1885 | 617 | StoreSDNode *ST = cast<StoreSDNode>(N); |
1886 | 617 | SDValue Val = ST->getValue(); |
1887 | 617 | SDLoc DL(N); |
1888 | 617 | |
1889 | 617 | SDValue Promoted = GetPromotedFloat(Val); |
1890 | 617 | EVT VT = ST->getOperand(1)->getValueType(0); |
1891 | 617 | EVT IVT = EVT::getIntegerVT(*DAG.getContext(), VT.getSizeInBits()); |
1892 | 617 | |
1893 | 617 | SDValue NewVal; |
1894 | 617 | NewVal = DAG.getNode(GetPromotionOpcode(Promoted.getValueType(), VT), DL, |
1895 | 617 | IVT, Promoted); |
1896 | 617 | |
1897 | 617 | return DAG.getStore(ST->getChain(), DL, NewVal, ST->getBasePtr(), |
1898 | 617 | ST->getMemOperand()); |
1899 | 617 | } |
1900 | | |
1901 | | //===----------------------------------------------------------------------===// |
1902 | | // Float Result Promotion |
1903 | | //===----------------------------------------------------------------------===// |
1904 | | |
1905 | 4.62k | void DAGTypeLegalizer::PromoteFloatResult(SDNode *N, unsigned ResNo) { |
1906 | 4.62k | SDValue R = SDValue(); |
1907 | 4.62k | |
1908 | 4.62k | switch (N->getOpcode()) { |
1909 | 4.62k | // These opcodes cannot appear if promotion of FP16 is done in the backend |
1910 | 4.62k | // instead of Clang |
1911 | 0 | case ISD::FP16_TO_FP: |
1912 | 0 | case ISD::FP_TO_FP16: |
1913 | 0 | default: |
1914 | 0 | llvm_unreachable("Do not know how to promote this operator's result!"); |
1915 | 0 |
|
1916 | 817 | case ISD::BITCAST: R = PromoteFloatRes_BITCAST(N); break; |
1917 | 281 | case ISD::ConstantFP: R = PromoteFloatRes_ConstantFP(N); break; |
1918 | 832 | case ISD::EXTRACT_VECTOR_ELT: |
1919 | 832 | R = PromoteFloatRes_EXTRACT_VECTOR_ELT(N); break; |
1920 | 17 | case ISD::FCOPYSIGN: R = PromoteFloatRes_FCOPYSIGN(N); break; |
1921 | 0 |
|
1922 | 0 | // Unary FP Operations |
1923 | 152 | case ISD::FABS: |
1924 | 152 | case ISD::FCEIL: |
1925 | 152 | case ISD::FCOS: |
1926 | 152 | case ISD::FEXP: |
1927 | 152 | case ISD::FEXP2: |
1928 | 152 | case ISD::FFLOOR: |
1929 | 152 | case ISD::FLOG: |
1930 | 152 | case ISD::FLOG2: |
1931 | 152 | case ISD::FLOG10: |
1932 | 152 | case ISD::FNEARBYINT: |
1933 | 152 | case ISD::FNEG: |
1934 | 152 | case ISD::FRINT: |
1935 | 152 | case ISD::FROUND: |
1936 | 152 | case ISD::FSIN: |
1937 | 152 | case ISD::FSQRT: |
1938 | 152 | case ISD::FTRUNC: R = PromoteFloatRes_UnaryOp(N); break; |
1939 | 152 | |
1940 | 152 | // Binary FP Operations |
1941 | 490 | case ISD::FADD: |
1942 | 490 | case ISD::FDIV: |
1943 | 490 | case ISD::FMAXNAN: |
1944 | 490 | case ISD::FMINNAN: |
1945 | 490 | case ISD::FMAXNUM: |
1946 | 490 | case ISD::FMINNUM: |
1947 | 490 | case ISD::FMUL: |
1948 | 490 | case ISD::FPOW: |
1949 | 490 | case ISD::FREM: |
1950 | 490 | case ISD::FSUB: R = PromoteFloatRes_BinOp(N); break; |
1951 | 490 | |
1952 | 15 | case ISD::FMA: // FMA is same as FMAD |
1953 | 15 | case ISD::FMAD: R = PromoteFloatRes_FMAD(N); break; |
1954 | 15 | |
1955 | 3 | case ISD::FPOWI: R = PromoteFloatRes_FPOWI(N); break; |
1956 | 15 | |
1957 | 1.03k | case ISD::FP_ROUND: R = PromoteFloatRes_FP_ROUND(N); break; |
1958 | 890 | case ISD::LOAD: R = PromoteFloatRes_LOAD(N); break; |
1959 | 17 | case ISD::SELECT: R = PromoteFloatRes_SELECT(N); break; |
1960 | 0 | case ISD::SELECT_CC: R = PromoteFloatRes_SELECT_CC(N); break; |
1961 | 15 | |
1962 | 59 | case ISD::SINT_TO_FP: |
1963 | 59 | case ISD::UINT_TO_FP: R = PromoteFloatRes_XINT_TO_FP(N); break; |
1964 | 18 | case ISD::UNDEF: R = PromoteFloatRes_UNDEF(N); break; |
1965 | 4.62k | |
1966 | 4.62k | } |
1967 | 4.62k | |
1968 | 4.62k | if (4.62k R.getNode()4.62k ) |
1969 | 3.79k | SetPromotedFloat(SDValue(N, ResNo), R); |
1970 | 4.62k | } |
1971 | | |
1972 | | // Bitcast from i16 to f16: convert the i16 to a f32 value instead. |
1973 | | // At this point, it is not possible to determine if the bitcast value is |
1974 | | // eventually stored to memory or promoted to f32 or promoted to a floating |
1975 | | // point at a higher precision. Some of these cases are handled by FP_EXTEND, |
1976 | | // STORE promotion handlers. |
1977 | 817 | SDValue DAGTypeLegalizer::PromoteFloatRes_BITCAST(SDNode *N) { |
1978 | 817 | EVT VT = N->getValueType(0); |
1979 | 817 | EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT); |
1980 | 817 | return DAG.getNode(GetPromotionOpcode(VT, NVT), SDLoc(N), NVT, |
1981 | 817 | N->getOperand(0)); |
1982 | 817 | } |
1983 | | |
1984 | 281 | SDValue DAGTypeLegalizer::PromoteFloatRes_ConstantFP(SDNode *N) { |
1985 | 281 | ConstantFPSDNode *CFPNode = cast<ConstantFPSDNode>(N); |
1986 | 281 | EVT VT = N->getValueType(0); |
1987 | 281 | SDLoc DL(N); |
1988 | 281 | |
1989 | 281 | // Get the (bit-cast) APInt of the APFloat and build an integer constant |
1990 | 281 | EVT IVT = EVT::getIntegerVT(*DAG.getContext(), VT.getSizeInBits()); |
1991 | 281 | SDValue C = DAG.getConstant(CFPNode->getValueAPF().bitcastToAPInt(), DL, |
1992 | 281 | IVT); |
1993 | 281 | |
1994 | 281 | // Convert the Constant to the desired FP type |
1995 | 281 | // FIXME We might be able to do the conversion during compilation and get rid |
1996 | 281 | // of it from the object code |
1997 | 281 | EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT); |
1998 | 281 | return DAG.getNode(GetPromotionOpcode(VT, NVT), DL, NVT, C); |
1999 | 281 | } |
2000 | | |
2001 | | // If the Index operand is a constant, try to redirect the extract operation to |
2002 | | // the correct legalized vector. If not, bit-convert the input vector to |
2003 | | // equivalent integer vector. Extract the element as an (bit-cast) integer |
2004 | | // value and convert it to the promoted type. |
2005 | 832 | SDValue DAGTypeLegalizer::PromoteFloatRes_EXTRACT_VECTOR_ELT(SDNode *N) { |
2006 | 832 | SDLoc DL(N); |
2007 | 832 | |
2008 | 832 | // If the index is constant, try to extract the value from the legalized |
2009 | 832 | // vector type. |
2010 | 832 | if (isa<ConstantSDNode>(N->getOperand(1))832 ) { |
2011 | 825 | SDValue Vec = N->getOperand(0); |
2012 | 825 | SDValue Idx = N->getOperand(1); |
2013 | 825 | EVT VecVT = Vec->getValueType(0); |
2014 | 825 | EVT EltVT = VecVT.getVectorElementType(); |
2015 | 825 | |
2016 | 825 | uint64_t IdxVal = cast<ConstantSDNode>(Idx)->getZExtValue(); |
2017 | 825 | |
2018 | 825 | switch (getTypeAction(VecVT)) { |
2019 | 0 | default: break; |
2020 | 396 | case TargetLowering::TypeScalarizeVector: { |
2021 | 396 | SDValue Res = GetScalarizedVector(N->getOperand(0)); |
2022 | 396 | ReplaceValueWith(SDValue(N, 0), Res); |
2023 | 396 | return SDValue(); |
2024 | 825 | } |
2025 | 9 | case TargetLowering::TypeWidenVector: { |
2026 | 9 | Vec = GetWidenedVector(Vec); |
2027 | 9 | SDValue Res = DAG.getNode(N->getOpcode(), DL, EltVT, Vec, Idx); |
2028 | 9 | ReplaceValueWith(SDValue(N, 0), Res); |
2029 | 9 | return SDValue(); |
2030 | 825 | } |
2031 | 420 | case TargetLowering::TypeSplitVector: { |
2032 | 420 | SDValue Lo, Hi; |
2033 | 420 | GetSplitVector(Vec, Lo, Hi); |
2034 | 420 | |
2035 | 420 | uint64_t LoElts = Lo.getValueType().getVectorNumElements(); |
2036 | 420 | SDValue Res; |
2037 | 420 | if (IdxVal < LoElts) |
2038 | 213 | Res = DAG.getNode(N->getOpcode(), DL, EltVT, Lo, Idx); |
2039 | 420 | else |
2040 | 207 | Res = DAG.getNode(N->getOpcode(), DL, EltVT, Hi, |
2041 | 207 | DAG.getConstant(IdxVal - LoElts, DL, |
2042 | 207 | Idx.getValueType())); |
2043 | 420 | ReplaceValueWith(SDValue(N, 0), Res); |
2044 | 420 | return SDValue(); |
2045 | 7 | } |
2046 | 7 | |
2047 | 7 | } |
2048 | 7 | } |
2049 | 7 | |
2050 | 7 | // Bit-convert the input vector to the equivalent integer vector |
2051 | 7 | SDValue NewOp = BitConvertVectorToIntegerVector(N->getOperand(0)); |
2052 | 7 | EVT IVT = NewOp.getValueType().getVectorElementType(); |
2053 | 7 | |
2054 | 7 | // Extract the element as an (bit-cast) integer value |
2055 | 7 | SDValue NewVal = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, IVT, |
2056 | 7 | NewOp, N->getOperand(1)); |
2057 | 7 | |
2058 | 7 | // Convert the element to the desired FP type |
2059 | 7 | EVT VT = N->getValueType(0); |
2060 | 7 | EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT); |
2061 | 7 | return DAG.getNode(GetPromotionOpcode(VT, NVT), SDLoc(N), NVT, NewVal); |
2062 | 7 | } |
2063 | | |
2064 | | // FCOPYSIGN(X, Y) returns the value of X with the sign of Y. If the result |
2065 | | // needs promotion, so does the argument X. Note that Y, if needed, will be |
2066 | | // handled during operand promotion. |
2067 | 17 | SDValue DAGTypeLegalizer::PromoteFloatRes_FCOPYSIGN(SDNode *N) { |
2068 | 17 | EVT VT = N->getValueType(0); |
2069 | 17 | EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT); |
2070 | 17 | SDValue Op0 = GetPromotedFloat(N->getOperand(0)); |
2071 | 17 | |
2072 | 17 | SDValue Op1 = N->getOperand(1); |
2073 | 17 | |
2074 | 17 | return DAG.getNode(N->getOpcode(), SDLoc(N), NVT, Op0, Op1); |
2075 | 17 | } |
2076 | | |
2077 | | // Unary operation where the result and the operand have PromoteFloat type |
2078 | | // action. Construct a new SDNode with the promoted float value of the old |
2079 | | // operand. |
2080 | 152 | SDValue DAGTypeLegalizer::PromoteFloatRes_UnaryOp(SDNode *N) { |
2081 | 152 | EVT VT = N->getValueType(0); |
2082 | 152 | EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT); |
2083 | 152 | SDValue Op = GetPromotedFloat(N->getOperand(0)); |
2084 | 152 | |
2085 | 152 | return DAG.getNode(N->getOpcode(), SDLoc(N), NVT, Op); |
2086 | 152 | } |
2087 | | |
2088 | | // Binary operations where the result and both operands have PromoteFloat type |
2089 | | // action. Construct a new SDNode with the promoted float values of the old |
2090 | | // operands. |
2091 | 490 | SDValue DAGTypeLegalizer::PromoteFloatRes_BinOp(SDNode *N) { |
2092 | 490 | EVT VT = N->getValueType(0); |
2093 | 490 | EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT); |
2094 | 490 | SDValue Op0 = GetPromotedFloat(N->getOperand(0)); |
2095 | 490 | SDValue Op1 = GetPromotedFloat(N->getOperand(1)); |
2096 | 490 | return DAG.getNode(N->getOpcode(), SDLoc(N), NVT, Op0, Op1, N->getFlags()); |
2097 | 490 | } |
2098 | | |
2099 | 15 | SDValue DAGTypeLegalizer::PromoteFloatRes_FMAD(SDNode *N) { |
2100 | 15 | EVT VT = N->getValueType(0); |
2101 | 15 | EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT); |
2102 | 15 | SDValue Op0 = GetPromotedFloat(N->getOperand(0)); |
2103 | 15 | SDValue Op1 = GetPromotedFloat(N->getOperand(1)); |
2104 | 15 | SDValue Op2 = GetPromotedFloat(N->getOperand(2)); |
2105 | 15 | |
2106 | 15 | return DAG.getNode(N->getOpcode(), SDLoc(N), NVT, Op0, Op1, Op2); |
2107 | 15 | } |
2108 | | |
2109 | | // Promote the Float (first) operand and retain the Integer (second) operand |
2110 | 3 | SDValue DAGTypeLegalizer::PromoteFloatRes_FPOWI(SDNode *N) { |
2111 | 3 | EVT VT = N->getValueType(0); |
2112 | 3 | EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT); |
2113 | 3 | SDValue Op0 = GetPromotedFloat(N->getOperand(0)); |
2114 | 3 | SDValue Op1 = N->getOperand(1); |
2115 | 3 | |
2116 | 3 | return DAG.getNode(N->getOpcode(), SDLoc(N), NVT, Op0, Op1); |
2117 | 3 | } |
2118 | | |
2119 | | // Explicit operation to reduce precision. Reduce the value to half precision |
2120 | | // and promote it back to the legal type. |
2121 | 1.03k | SDValue DAGTypeLegalizer::PromoteFloatRes_FP_ROUND(SDNode *N) { |
2122 | 1.03k | SDLoc DL(N); |
2123 | 1.03k | |
2124 | 1.03k | SDValue Op = N->getOperand(0); |
2125 | 1.03k | EVT VT = N->getValueType(0); |
2126 | 1.03k | EVT OpVT = Op->getValueType(0); |
2127 | 1.03k | EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); |
2128 | 1.03k | EVT IVT = EVT::getIntegerVT(*DAG.getContext(), VT.getSizeInBits()); |
2129 | 1.03k | |
2130 | 1.03k | // Round promoted float to desired precision |
2131 | 1.03k | SDValue Round = DAG.getNode(GetPromotionOpcode(OpVT, VT), DL, IVT, Op); |
2132 | 1.03k | // Promote it back to the legal output type |
2133 | 1.03k | return DAG.getNode(GetPromotionOpcode(VT, NVT), DL, NVT, Round); |
2134 | 1.03k | } |
2135 | | |
2136 | 890 | SDValue DAGTypeLegalizer::PromoteFloatRes_LOAD(SDNode *N) { |
2137 | 890 | LoadSDNode *L = cast<LoadSDNode>(N); |
2138 | 890 | EVT VT = N->getValueType(0); |
2139 | 890 | |
2140 | 890 | // Load the value as an integer value with the same number of bits. |
2141 | 890 | EVT IVT = EVT::getIntegerVT(*DAG.getContext(), VT.getSizeInBits()); |
2142 | 890 | auto MMOFlags = |
2143 | 890 | L->getMemOperand()->getFlags() & |
2144 | 890 | ~(MachineMemOperand::MOInvariant | MachineMemOperand::MODereferenceable); |
2145 | 890 | SDValue newL = DAG.getLoad(L->getAddressingMode(), L->getExtensionType(), IVT, |
2146 | 890 | SDLoc(N), L->getChain(), L->getBasePtr(), |
2147 | 890 | L->getOffset(), L->getPointerInfo(), IVT, |
2148 | 890 | L->getAlignment(), MMOFlags, L->getAAInfo()); |
2149 | 890 | // Legalize the chain result by replacing uses of the old value chain with the |
2150 | 890 | // new one |
2151 | 890 | ReplaceValueWith(SDValue(N, 1), newL.getValue(1)); |
2152 | 890 | |
2153 | 890 | // Convert the integer value to the desired FP type |
2154 | 890 | EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT); |
2155 | 890 | return DAG.getNode(GetPromotionOpcode(VT, NVT), SDLoc(N), NVT, newL); |
2156 | 890 | } |
2157 | | |
2158 | | // Construct a new SELECT node with the promoted true- and false- values. |
2159 | 17 | SDValue DAGTypeLegalizer::PromoteFloatRes_SELECT(SDNode *N) { |
2160 | 17 | SDValue TrueVal = GetPromotedFloat(N->getOperand(1)); |
2161 | 17 | SDValue FalseVal = GetPromotedFloat(N->getOperand(2)); |
2162 | 17 | |
2163 | 17 | return DAG.getNode(ISD::SELECT, SDLoc(N), TrueVal->getValueType(0), |
2164 | 17 | N->getOperand(0), TrueVal, FalseVal); |
2165 | 17 | } |
2166 | | |
2167 | | // Construct a new SELECT_CC node with the promoted true- and false- values. |
2168 | | // The operands used for comparison are promoted by PromoteFloatOp_SELECT_CC. |
2169 | 0 | SDValue DAGTypeLegalizer::PromoteFloatRes_SELECT_CC(SDNode *N) { |
2170 | 0 | SDValue TrueVal = GetPromotedFloat(N->getOperand(2)); |
2171 | 0 | SDValue FalseVal = GetPromotedFloat(N->getOperand(3)); |
2172 | 0 |
|
2173 | 0 | return DAG.getNode(ISD::SELECT_CC, SDLoc(N), N->getValueType(0), |
2174 | 0 | N->getOperand(0), N->getOperand(1), TrueVal, FalseVal, |
2175 | 0 | N->getOperand(4)); |
2176 | 0 | } |
2177 | | |
2178 | | // Construct a SDNode that transforms the SINT or UINT operand to the promoted |
2179 | | // float type. |
2180 | 59 | SDValue DAGTypeLegalizer::PromoteFloatRes_XINT_TO_FP(SDNode *N) { |
2181 | 59 | SDLoc DL(N); |
2182 | 59 | EVT VT = N->getValueType(0); |
2183 | 59 | EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT); |
2184 | 59 | SDValue NV = DAG.getNode(N->getOpcode(), DL, NVT, N->getOperand(0)); |
2185 | 59 | // Round the value to the desired precision (that of the source type). |
2186 | 59 | return DAG.getNode( |
2187 | 59 | ISD::FP_EXTEND, DL, NVT, |
2188 | 59 | DAG.getNode(ISD::FP_ROUND, DL, VT, NV, DAG.getIntPtrConstant(0, DL))); |
2189 | 59 | } |
2190 | | |
2191 | 18 | SDValue DAGTypeLegalizer::PromoteFloatRes_UNDEF(SDNode *N) { |
2192 | 18 | return DAG.getUNDEF(TLI.getTypeToTransformTo(*DAG.getContext(), |
2193 | 18 | N->getValueType(0))); |
2194 | 18 | } |
2195 | | |