LLVM: lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
25using namespace llvm;
26
27#define DEBUG_TYPE "legalize-types"
28
29
30
31
33 RTLIB::Libcall Call_F32,
34 RTLIB::Libcall Call_F64,
35 RTLIB::Libcall Call_F80,
36 RTLIB::Libcall Call_F128,
37 RTLIB::Libcall Call_PPCF128) {
38 return
39 VT == MVT::f32 ? Call_F32 :
40 VT == MVT::f64 ? Call_F64 :
41 VT == MVT::f80 ? Call_F80 :
42 VT == MVT::f128 ? Call_F128 :
43 VT == MVT::ppcf128 ? Call_PPCF128 :
44 RTLIB::UNKNOWN_LIBCALL;
45}
46
47
48
49
50
51void DAGTypeLegalizer::SoftenFloatResult(SDNode *N, unsigned ResNo) {
52 LLVM_DEBUG(dbgs() << "Soften float result " << ResNo << ": "; N->dump(&DAG));
54
55 switch (N->getOpcode()) {
56
57 default:
58#ifndef NDEBUG
59 dbgs() << "SoftenFloatResult #" << ResNo << ": ";
60 N->dump(&DAG); dbgs() << "\n";
61#endif
63 "operator!");
65 case ISD::ARITH_FENCE: R = SoftenFloatRes_ARITH_FENCE(N); break;
67 case ISD::BITCAST: R = SoftenFloatRes_BITCAST(N); break;
71 R = SoftenFloatRes_EXTRACT_VECTOR_ELT(N, ResNo); break;
72 case ISD::FABS: R = SoftenFloatRes_FABS(N); break;
74 case ISD::FMINNUM: R = SoftenFloatRes_FMINNUM(N); break;
76 case ISD::FMAXNUM: R = SoftenFloatRes_FMAXNUM(N); break;
77 case ISD::FMINIMUMNUM: R = SoftenFloatRes_FMINIMUMNUM(N); break;
78 case ISD::FMAXIMUMNUM: R = SoftenFloatRes_FMAXIMUMNUM(N); break;
79 case ISD::FMINIMUM: R = SoftenFloatRes_FMINIMUM(N); break;
80 case ISD::FMAXIMUM: R = SoftenFloatRes_FMAXIMUM(N); break;
82 case ISD::FADD: R = SoftenFloatRes_FADD(N); break;
84 case ISD::FACOS: R = SoftenFloatRes_FACOS(N); break;
86 case ISD::FASIN: R = SoftenFloatRes_FASIN(N); break;
88 case ISD::FATAN: R = SoftenFloatRes_FATAN(N); break;
90 case ISD::FATAN2: R = SoftenFloatRes_FATAN2(N); break;
91 case ISD::FCBRT: R = SoftenFloatRes_FCBRT(N); break;
93 case ISD::FCEIL: R = SoftenFloatRes_FCEIL(N); break;
96 case ISD::FCOS: R = SoftenFloatRes_FCOS(N); break;
98 case ISD::FCOSH: R = SoftenFloatRes_FCOSH(N); break;
100 case ISD::FDIV: R = SoftenFloatRes_FDIV(N); break;
102 case ISD::FEXP: R = SoftenFloatRes_FEXP(N); break;
104 case ISD::FEXP2: R = SoftenFloatRes_FEXP2(N); break;
105 case ISD::FEXP10: R = SoftenFloatRes_FEXP10(N); break;
107 case ISD::FFLOOR: R = SoftenFloatRes_FFLOOR(N); break;
109 case ISD::FLOG: R = SoftenFloatRes_FLOG(N); break;
111 case ISD::FLOG2: R = SoftenFloatRes_FLOG2(N); break;
113 case ISD::FLOG10: R = SoftenFloatRes_FLOG10(N); break;
115 case ISD::FMA: R = SoftenFloatRes_FMA(N); break;
117 case ISD::FMUL: R = SoftenFloatRes_FMUL(N); break;
119 case ISD::FNEARBYINT: R = SoftenFloatRes_FNEARBYINT(N); break;
120 case ISD::FNEG: R = SoftenFloatRes_FNEG(N); break;
122 case ISD::FP_EXTEND: R = SoftenFloatRes_FP_EXTEND(N); break;
124 case ISD::FP_ROUND: R = SoftenFloatRes_FP_ROUND(N); break;
125 case ISD::FP16_TO_FP: R = SoftenFloatRes_FP16_TO_FP(N); break;
126 case ISD::BF16_TO_FP: R = SoftenFloatRes_BF16_TO_FP(N); break;
128 case ISD::FPOW: R = SoftenFloatRes_FPOW(N); break;
130 case ISD::FPOWI:
131 case ISD::FLDEXP:
133 case ISD::FFREXP: R = SoftenFloatRes_FFREXP(N); break;
134 case ISD::FSINCOS: R = SoftenFloatRes_FSINCOS(N); break;
135 case ISD::FMODF: R = SoftenFloatRes_FMODF(N); break;
137 case ISD::FREM: R = SoftenFloatRes_FREM(N); break;
139 case ISD::FRINT: R = SoftenFloatRes_FRINT(N); break;
141 case ISD::FROUND: R = SoftenFloatRes_FROUND(N); break;
143 case ISD::FROUNDEVEN: R = SoftenFloatRes_FROUNDEVEN(N); break;
145 case ISD::FSIN: R = SoftenFloatRes_FSIN(N); break;
147 case ISD::FSINH: R = SoftenFloatRes_FSINH(N); break;
149 case ISD::FSQRT: R = SoftenFloatRes_FSQRT(N); break;
151 case ISD::FSUB: R = SoftenFloatRes_FSUB(N); break;
153 case ISD::FTAN: R = SoftenFloatRes_FTAN(N); break;
155 case ISD::FTANH: R = SoftenFloatRes_FTANH(N); break;
157 case ISD::FTRUNC: R = SoftenFloatRes_FTRUNC(N); break;
158 case ISD::LOAD: R = SoftenFloatRes_LOAD(N); break;
159 case ISD::ATOMIC_LOAD: R = SoftenFloatRes_ATOMIC_LOAD(N); break;
160 case ISD::ATOMIC_SWAP: R = BitcastToInt_ATOMIC_SWAP(N); break;
161 case ISD::SELECT: R = SoftenFloatRes_SELECT(N); break;
163 case ISD::FREEZE: R = SoftenFloatRes_FREEZE(N); break;
169 case ISD::UNDEF: R = SoftenFloatRes_UNDEF(N); break;
170 case ISD::VAARG: R = SoftenFloatRes_VAARG(N); break;
172 case ISD::VECREDUCE_FADD:
173 case ISD::VECREDUCE_FMUL:
174 case ISD::VECREDUCE_FMIN:
175 case ISD::VECREDUCE_FMAX:
176 case ISD::VECREDUCE_FMAXIMUM:
177 case ISD::VECREDUCE_FMINIMUM: R = SoftenFloatRes_VECREDUCE(N); break;
178 case ISD::VECREDUCE_SEQ_FADD:
179 case ISD::VECREDUCE_SEQ_FMUL: R = SoftenFloatRes_VECREDUCE_SEQ(N); break;
180
181 }
182
183
184 if (R.getNode()) {
186 SetSoftenedFloat(SDValue(N, ResNo), R);
187 }
188}
189
190SDValue DAGTypeLegalizer::SoftenFloatRes_Unary(SDNode *N, RTLIB::Libcall LC) {
192 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
193 unsigned Offset = IsStrict ? 1 : 0;
195 "Unexpected number of operands!");
198 TargetLowering::MakeLibCallOptions CallOptions;
199 EVT OpVT = N->getOperand(0 + Offset).getValueType();
201 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, NVT, Op,
202 CallOptions, SDLoc(N),
203 Chain);
204 if (IsStrict)
205 ReplaceValueWith(SDValue(N, 1), Tmp.second);
206 return Tmp.first;
207}
208
209SDValue DAGTypeLegalizer::SoftenFloatRes_Binary(SDNode *N, RTLIB::Libcall LC) {
210 bool IsStrict = N->isStrictFPOpcode();
211 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
212 unsigned Offset = IsStrict ? 1 : 0;
214 "Unexpected number of operands!");
216 GetSoftenedFloat(N->getOperand(1 + Offset)) };
218 TargetLowering::MakeLibCallOptions CallOptions;
219 EVT OpsVT[2] = { N->getOperand(0 + Offset).getValueType(),
220 N->getOperand(1 + Offset).getValueType() };
222 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, NVT, Ops,
223 CallOptions, SDLoc(N),
224 Chain);
225 if (IsStrict)
226 ReplaceValueWith(SDValue(N, 1), Tmp.second);
227 return Tmp.first;
228}
229
230SDValue DAGTypeLegalizer::SoftenFloatRes_BITCAST(SDNode *N) {
231 return BitConvertToInteger(N->getOperand(0));
232}
233
234SDValue DAGTypeLegalizer::SoftenFloatRes_FREEZE(SDNode *N) {
235 EVT Ty = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
237 GetSoftenedFloat(N->getOperand(0)));
238}
239
240SDValue DAGTypeLegalizer::SoftenFloatRes_ARITH_FENCE(SDNode *N) {
241 EVT Ty = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
242 SDValue NewFence = DAG.getNode(ISD::ARITH_FENCE, SDLoc(N), Ty,
243 GetSoftenedFloat(N->getOperand(0)));
244 return NewFence;
245}
246
247SDValue DAGTypeLegalizer::SoftenFloatRes_MERGE_VALUES(SDNode *N,
248 unsigned ResNo) {
249 SDValue Op = DisintegrateMERGE_VALUES(N, ResNo);
250 return BitConvertToInteger(Op);
251}
252
253SDValue DAGTypeLegalizer::SoftenFloatRes_BUILD_PAIR(SDNode *N) {
254
256 TLI.getTypeToTransformTo(*DAG.getContext(),
257 N->getValueType(0)),
258 BitConvertToInteger(N->getOperand(0)),
259 BitConvertToInteger(N->getOperand(1)));
260}
261
262SDValue DAGTypeLegalizer::SoftenFloatRes_ConstantFP(SDNode *N) {
264
265
266
267
268
269
270
271 if (DAG.getDataLayout().isBigEndian() &&
275 APInt Val(128, words);
276 return DAG.getConstant(Val, SDLoc(CN),
277 TLI.getTypeToTransformTo(*DAG.getContext(),
279 } else {
281 TLI.getTypeToTransformTo(*DAG.getContext(),
283 }
284}
285
286SDValue DAGTypeLegalizer::SoftenFloatRes_EXTRACT_ELEMENT(SDNode *N) {
287 SDValue Src = N->getOperand(0);
288 assert(Src.getValueType() == MVT::ppcf128 &&
289 "In floats only ppcf128 can be extracted by element!");
291 N->getValueType(0).changeTypeToInteger(),
292 DAG.getBitcast(MVT::i128, Src), N->getOperand(1));
293}
294
295SDValue DAGTypeLegalizer::SoftenFloatRes_EXTRACT_VECTOR_ELT(SDNode *N, unsigned ResNo) {
296 SDValue NewOp = BitConvertVectorToIntegerVector(N->getOperand(0));
299 NewOp, N->getOperand(1));
300}
301
302SDValue DAGTypeLegalizer::SoftenFloatRes_FABS(SDNode *N) {
303 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
305
306
309 SDValue Mask = DAG.getConstant(API, SDLoc(N), NVT);
310 SDValue Op = GetSoftenedFloat(N->getOperand(0));
311 return DAG.getNode(ISD::AND, SDLoc(N), NVT, Op, Mask);
312}
313
314SDValue DAGTypeLegalizer::SoftenFloatRes_FMINNUM(SDNode *N) {
315 if (SDValue SelCC = TLI.createSelectForFMINNUM_FMAXNUM(N, DAG))
316 return SoftenFloatRes_SELECT_CC(SelCC.getNode());
317 return SoftenFloatRes_Binary(N, GetFPLibCall(N->getValueType(0),
318 RTLIB::FMIN_F32,
319 RTLIB::FMIN_F64,
320 RTLIB::FMIN_F80,
321 RTLIB::FMIN_F128,
322 RTLIB::FMIN_PPCF128));
323}
324
325SDValue DAGTypeLegalizer::SoftenFloatRes_FMAXNUM(SDNode *N) {
326 if (SDValue SelCC = TLI.createSelectForFMINNUM_FMAXNUM(N, DAG))
327 return SoftenFloatRes_SELECT_CC(SelCC.getNode());
328 return SoftenFloatRes_Binary(N, GetFPLibCall(N->getValueType(0),
329 RTLIB::FMAX_F32,
330 RTLIB::FMAX_F64,
331 RTLIB::FMAX_F80,
332 RTLIB::FMAX_F128,
333 RTLIB::FMAX_PPCF128));
334}
335
336SDValue DAGTypeLegalizer::SoftenFloatRes_FMINIMUMNUM(SDNode *N) {
337 return SoftenFloatRes_Binary(
338 N, GetFPLibCall(N->getValueType(0), RTLIB::FMINIMUM_NUM_F32,
339 RTLIB::FMINIMUM_NUM_F64, RTLIB::FMINIMUM_NUM_F80,
340 RTLIB::FMINIMUM_NUM_F128, RTLIB::FMINIMUM_NUM_PPCF128));
341}
342
343SDValue DAGTypeLegalizer::SoftenFloatRes_FMAXIMUMNUM(SDNode *N) {
344 return SoftenFloatRes_Binary(
345 N, GetFPLibCall(N->getValueType(0), RTLIB::FMAXIMUM_NUM_F32,
346 RTLIB::FMAXIMUM_NUM_F64, RTLIB::FMAXIMUM_NUM_F80,
347 RTLIB::FMAXIMUM_NUM_F128, RTLIB::FMAXIMUM_NUM_PPCF128));
348}
349
350SDValue DAGTypeLegalizer::SoftenFloatRes_FMINIMUM(SDNode *N) {
351 return SoftenFloatRes_Binary(
352 N, GetFPLibCall(N->getValueType(0), RTLIB::FMINIMUM_F32,
353 RTLIB::FMINIMUM_F64, RTLIB::FMINIMUM_F80,
354 RTLIB::FMINIMUM_F128, RTLIB::FMINIMUM_PPCF128));
355}
356
357SDValue DAGTypeLegalizer::SoftenFloatRes_FMAXIMUM(SDNode *N) {
358 return SoftenFloatRes_Binary(
359 N, GetFPLibCall(N->getValueType(0), RTLIB::FMAXIMUM_F32,
360 RTLIB::FMAXIMUM_F64, RTLIB::FMAXIMUM_F80,
361 RTLIB::FMAXIMUM_F128, RTLIB::FMAXIMUM_PPCF128));
362}
363
364SDValue DAGTypeLegalizer::SoftenFloatRes_FADD(SDNode *N) {
365 return SoftenFloatRes_Binary(N, GetFPLibCall(N->getValueType(0),
366 RTLIB::ADD_F32,
367 RTLIB::ADD_F64,
368 RTLIB::ADD_F80,
369 RTLIB::ADD_F128,
370 RTLIB::ADD_PPCF128));
371}
372
373SDValue DAGTypeLegalizer::SoftenFloatRes_FACOS(SDNode *N) {
374 return SoftenFloatRes_Unary(
375 N, GetFPLibCall(N->getValueType(0), RTLIB::ACOS_F32, RTLIB::ACOS_F64,
376 RTLIB::ACOS_F80, RTLIB::ACOS_F128, RTLIB::ACOS_PPCF128));
377}
378
379SDValue DAGTypeLegalizer::SoftenFloatRes_FASIN(SDNode *N) {
380 return SoftenFloatRes_Unary(
381 N, GetFPLibCall(N->getValueType(0), RTLIB::ASIN_F32, RTLIB::ASIN_F64,
382 RTLIB::ASIN_F80, RTLIB::ASIN_F128, RTLIB::ASIN_PPCF128));
383}
384
385SDValue DAGTypeLegalizer::SoftenFloatRes_FATAN(SDNode *N) {
386 return SoftenFloatRes_Unary(
387 N, GetFPLibCall(N->getValueType(0), RTLIB::ATAN_F32, RTLIB::ATAN_F64,
388 RTLIB::ATAN_F80, RTLIB::ATAN_F128, RTLIB::ATAN_PPCF128));
389}
390
391SDValue DAGTypeLegalizer::SoftenFloatRes_FATAN2(SDNode *N) {
392 return SoftenFloatRes_Binary(
393 N,
394 GetFPLibCall(N->getValueType(0), RTLIB::ATAN2_F32, RTLIB::ATAN2_F64,
395 RTLIB::ATAN2_F80, RTLIB::ATAN2_F128, RTLIB::ATAN2_PPCF128));
396}
397
398SDValue DAGTypeLegalizer::SoftenFloatRes_FCBRT(SDNode *N) {
399 return SoftenFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
400 RTLIB::CBRT_F32,
401 RTLIB::CBRT_F64,
402 RTLIB::CBRT_F80,
403 RTLIB::CBRT_F128,
404 RTLIB::CBRT_PPCF128));
405}
406
407SDValue DAGTypeLegalizer::SoftenFloatRes_FCEIL(SDNode *N) {
408 return SoftenFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
409 RTLIB::CEIL_F32,
410 RTLIB::CEIL_F64,
411 RTLIB::CEIL_F80,
412 RTLIB::CEIL_F128,
413 RTLIB::CEIL_PPCF128));
414}
415
416SDValue DAGTypeLegalizer::SoftenFloatRes_FCOPYSIGN(SDNode *N) {
417 SDValue LHS = GetSoftenedFloat(N->getOperand(0));
418 SDValue RHS = BitConvertToInteger(N->getOperand(1));
419 SDLoc dl(N);
420
421 EVT LVT = LHS.getValueType();
422 EVT RVT = RHS.getValueType();
423
426
427
428 SDValue SignBit = DAG.getNode(
429 ISD::SHL, dl, RVT, DAG.getConstant(1, dl, RVT),
430 DAG.getConstant(RSize - 1, dl,
431 TLI.getShiftAmountTy(RVT, DAG.getDataLayout())));
433
434
436 if (SizeDiff > 0) {
437 SignBit =
439 DAG.getConstant(SizeDiff, dl,
441 DAG.getDataLayout())));
443 } else if (SizeDiff < 0) {
445 SignBit =
447 DAG.getConstant(-SizeDiff, dl,
449 DAG.getDataLayout())));
450 }
451
452
454 ISD::SHL, dl, LVT, DAG.getConstant(1, dl, LVT),
455 DAG.getConstant(LSize - 1, dl,
456 TLI.getShiftAmountTy(LVT, DAG.getDataLayout())));
457 Mask = DAG.getNode(ISD::SUB, dl, LVT, Mask, DAG.getConstant(1, dl, LVT));
459
460
461 return DAG.getNode(ISD::OR, dl, LVT, LHS, SignBit);
462}
463
464SDValue DAGTypeLegalizer::SoftenFloatRes_FCOS(SDNode *N) {
465 return SoftenFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
466 RTLIB::COS_F32,
467 RTLIB::COS_F64,
468 RTLIB::COS_F80,
469 RTLIB::COS_F128,
470 RTLIB::COS_PPCF128));
471}
472
473SDValue DAGTypeLegalizer::SoftenFloatRes_FCOSH(SDNode *N) {
474 return SoftenFloatRes_Unary(
475 N, GetFPLibCall(N->getValueType(0), RTLIB::COSH_F32, RTLIB::COSH_F64,
476 RTLIB::COSH_F80, RTLIB::COSH_F128, RTLIB::COSH_PPCF128));
477}
478
479SDValue DAGTypeLegalizer::SoftenFloatRes_FDIV(SDNode *N) {
480 return SoftenFloatRes_Binary(N, GetFPLibCall(N->getValueType(0),
481 RTLIB::DIV_F32,
482 RTLIB::DIV_F64,
483 RTLIB::DIV_F80,
484 RTLIB::DIV_F128,
485 RTLIB::DIV_PPCF128));
486}
487
488SDValue DAGTypeLegalizer::SoftenFloatRes_FEXP(SDNode *N) {
489 return SoftenFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
490 RTLIB::EXP_F32,
491 RTLIB::EXP_F64,
492 RTLIB::EXP_F80,
493 RTLIB::EXP_F128,
494 RTLIB::EXP_PPCF128));
495}
496
497SDValue DAGTypeLegalizer::SoftenFloatRes_FEXP2(SDNode *N) {
498 return SoftenFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
499 RTLIB::EXP2_F32,
500 RTLIB::EXP2_F64,
501 RTLIB::EXP2_F80,
502 RTLIB::EXP2_F128,
503 RTLIB::EXP2_PPCF128));
504}
505
506SDValue DAGTypeLegalizer::SoftenFloatRes_FEXP10(SDNode *N) {
507 return SoftenFloatRes_Unary(
508 N,
509 GetFPLibCall(N->getValueType(0), RTLIB::EXP10_F32, RTLIB::EXP10_F64,
510 RTLIB::EXP10_F80, RTLIB::EXP10_F128, RTLIB::EXP10_PPCF128));
511}
512
513SDValue DAGTypeLegalizer::SoftenFloatRes_FFLOOR(SDNode *N) {
514 return SoftenFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
515 RTLIB::FLOOR_F32,
516 RTLIB::FLOOR_F64,
517 RTLIB::FLOOR_F80,
518 RTLIB::FLOOR_F128,
519 RTLIB::FLOOR_PPCF128));
520}
521
522SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG(SDNode *N) {
523 return SoftenFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
524 RTLIB::LOG_F32,
525 RTLIB::LOG_F64,
526 RTLIB::LOG_F80,
527 RTLIB::LOG_F128,
528 RTLIB::LOG_PPCF128));
529}
530
531SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG2(SDNode *N) {
532 return SoftenFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
533 RTLIB::LOG2_F32,
534 RTLIB::LOG2_F64,
535 RTLIB::LOG2_F80,
536 RTLIB::LOG2_F128,
537 RTLIB::LOG2_PPCF128));
538}
539
540SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG10(SDNode *N) {
541 return SoftenFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
542 RTLIB::LOG10_F32,
543 RTLIB::LOG10_F64,
544 RTLIB::LOG10_F80,
545 RTLIB::LOG10_F128,
546 RTLIB::LOG10_PPCF128));
547}
548
549SDValue DAGTypeLegalizer::SoftenFloatRes_FMA(SDNode *N) {
550 bool IsStrict = N->isStrictFPOpcode();
551 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
552 unsigned Offset = IsStrict ? 1 : 0;
554 GetSoftenedFloat(N->getOperand(1 + Offset)),
555 GetSoftenedFloat(N->getOperand(2 + Offset)) };
557 TargetLowering::MakeLibCallOptions CallOptions;
558 EVT OpsVT[3] = { N->getOperand(0 + Offset).getValueType(),
559 N->getOperand(1 + Offset).getValueType(),
560 N->getOperand(2 + Offset).getValueType() };
562 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG,
564 RTLIB::FMA_F32,
565 RTLIB::FMA_F64,
566 RTLIB::FMA_F80,
567 RTLIB::FMA_F128,
568 RTLIB::FMA_PPCF128),
569 NVT, Ops, CallOptions, SDLoc(N), Chain);
570 if (IsStrict)
571 ReplaceValueWith(SDValue(N, 1), Tmp.second);
572 return Tmp.first;
573}
574
575SDValue DAGTypeLegalizer::SoftenFloatRes_FMUL(SDNode *N) {
576 return SoftenFloatRes_Binary(N, GetFPLibCall(N->getValueType(0),
577 RTLIB::MUL_F32,
578 RTLIB::MUL_F64,
579 RTLIB::MUL_F80,
580 RTLIB::MUL_F128,
581 RTLIB::MUL_PPCF128));
582}
583
584SDValue DAGTypeLegalizer::SoftenFloatRes_FNEARBYINT(SDNode *N) {
585 return SoftenFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
586 RTLIB::NEARBYINT_F32,
587 RTLIB::NEARBYINT_F64,
588 RTLIB::NEARBYINT_F80,
589 RTLIB::NEARBYINT_F128,
590 RTLIB::NEARBYINT_PPCF128));
591}
592
593SDValue DAGTypeLegalizer::SoftenFloatRes_FNEG(SDNode *N) {
594 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
595 SDLoc dl(N);
596
597
599 return DAG.getNode(ISD::XOR, dl, NVT, GetSoftenedFloat(N->getOperand(0)),
600 DAG.getConstant(SignMask, dl, NVT));
601}
602
603SDValue DAGTypeLegalizer::SoftenFloatRes_FP_EXTEND(SDNode *N) {
604 bool IsStrict = N->isStrictFPOpcode();
605 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
606 SDValue Op = N->getOperand(IsStrict ? 1 : 0);
607
609
611 Op = GetPromotedFloat(Op);
612
613
614 if (Op.getValueType() == N->getValueType(0)) {
615 if (IsStrict)
616 ReplaceValueWith(SDValue(N, 1), Chain);
617 return BitConvertToInteger(Op);
618 }
619 }
620
621
622
623
624
625 if ((Op.getValueType() == MVT::f16 || Op.getValueType() == MVT::bf16) &&
626 N->getValueType(0) != MVT::f32) {
627 if (IsStrict) {
629 { MVT::f32, MVT::Other }, { Chain, Op });
630 Chain = Op.getValue(1);
631 } else {
632 Op = DAG.getNode(ISD::FP_EXTEND, SDLoc(N), MVT::f32, Op);
633 }
634 }
635
636 if (Op.getValueType() == MVT::bf16) {
637
638 return SoftenFloatRes_BF16_TO_FP(N);
639 }
640
641 RTLIB::Libcall LC = RTLIB::getFPEXT(Op.getValueType(), N->getValueType(0));
642 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_EXTEND!");
643 TargetLowering::MakeLibCallOptions CallOptions;
644 EVT OpVT = N->getOperand(IsStrict ? 1 : 0).getValueType();
646 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, NVT, Op,
647 CallOptions, SDLoc(N),
648 Chain);
649 if (IsStrict)
650 ReplaceValueWith(SDValue(N, 1), Tmp.second);
651 return Tmp.first;
652}
653
654
655
656SDValue DAGTypeLegalizer::SoftenFloatRes_FP16_TO_FP(SDNode *N) {
657 EVT MidVT = TLI.getTypeToTransformTo(*DAG.getContext(), MVT::f32);
659 TargetLowering::MakeLibCallOptions CallOptions;
660 EVT OpsVT[1] = { N->getOperand(0).getValueType() };
662 SDValue Res32 = TLI.makeLibCall(DAG, RTLIB::FPEXT_F16_F32, MidVT, Op,
663 CallOptions, SDLoc(N)).first;
664 if (N->getValueType(0) == MVT::f32)
665 return Res32;
666
667 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
668 RTLIB::Libcall LC = RTLIB::getFPEXT(MVT::f32, N->getValueType(0));
669 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_EXTEND!");
670 return TLI.makeLibCall(DAG, LC, NVT, Res32, CallOptions, SDLoc(N)).first;
671}
672
673
674
675SDValue DAGTypeLegalizer::SoftenFloatRes_BF16_TO_FP(SDNode *N) {
676 assert(N->getValueType(0) == MVT::f32 &&
677 "Can only soften BF16_TO_FP with f32 result");
678 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), MVT::f32);
682 DAG.getNode(ISD::BITCAST, DL, MVT::i16, Op));
684 DAG.getShiftAmountConstant(16, NVT, DL));
685 return Res;
686}
687
688SDValue DAGTypeLegalizer::SoftenFloatRes_FP_ROUND(SDNode *N) {
689 bool IsStrict = N->isStrictFPOpcode();
690 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
691 SDValue Op = N->getOperand(IsStrict ? 1 : 0);
693 RTLIB::Libcall LC = RTLIB::getFPROUND(Op.getValueType(), N->getValueType(0));
694 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_ROUND!");
695 TargetLowering::MakeLibCallOptions CallOptions;
696 EVT OpVT = N->getOperand(IsStrict ? 1 : 0).getValueType();
698 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, NVT, Op,
699 CallOptions, SDLoc(N),
700 Chain);
701 if (IsStrict)
702 ReplaceValueWith(SDValue(N, 1), Tmp.second);
703 return Tmp.first;
704}
705
706SDValue DAGTypeLegalizer::SoftenFloatRes_FPOW(SDNode *N) {
707 return SoftenFloatRes_Binary(N, RTLIB::getPOW(N->getValueType(0)));
708}
709
710SDValue DAGTypeLegalizer::SoftenFloatRes_ExpOp(SDNode *N) {
711 bool IsStrict = N->isStrictFPOpcode();
712 unsigned Offset = IsStrict ? 1 : 0;
713 bool IsPowI =
715 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
716
717 RTLIB::Libcall LC = IsPowI ? RTLIB::getPOWI(N->getValueType(0))
719 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpected fpowi.");
720 if (TLI.getLibcallImpl(LC) == RTLIB::Unsupported) {
721
722
723 DAG.getContext()->emitError("do not know how to soften fpowi to fpow");
724 if (IsStrict)
725 ReplaceValueWith(SDValue(N, 1), N->getOperand(0));
726 return DAG.getPOISON(NVT);
727 }
728
729 if (DAG.getLibInfo().getIntSize() !=
730 N->getOperand(1 + Offset).getValueType().getSizeInBits()) {
731
732
733 DAG.getContext()->emitError("powi exponent does not match sizeof(int)");
734 if (IsStrict)
735 ReplaceValueWith(SDValue(N, 1), N->getOperand(0));
736 return DAG.getPOISON(NVT);
737 }
738
740 N->getOperand(1 + Offset) };
742 TargetLowering::MakeLibCallOptions CallOptions;
743 EVT OpsVT[2] = { N->getOperand(0 + Offset).getValueType(),
744 N->getOperand(1 + Offset).getValueType() };
746 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, NVT, Ops,
747 CallOptions, SDLoc(N),
748 Chain);
749 if (IsStrict)
750 ReplaceValueWith(SDValue(N, 1), Tmp.second);
751 return Tmp.first;
752}
753
754SDValue DAGTypeLegalizer::SoftenFloatRes_FFREXP(SDNode *N) {
755 assert(->isStrictFPOpcode() && "strictfp not implemented for frexp");
756 EVT VT0 = N->getValueType(0);
757 EVT VT1 = N->getValueType(1);
759 EVT NVT0 = TLI.getTypeToTransformTo(*DAG.getContext(), VT0);
761
762 if (DAG.getLibInfo().getIntSize() != VT1.getSizeInBits()) {
763
764
765
766 DAG.getContext()->emitError("ffrexp exponent does not match sizeof(int)");
767 SDValue PoisonExp = DAG.getPOISON(VT1);
768 ReplaceValueWith(SDValue(N, 1), PoisonExp);
769 return DAG.getMergeValues({DAG.getPOISON(NVT0), PoisonExp}, DL);
770 }
771
772 SDValue StackSlot = DAG.CreateStackTemporary(VT1);
773
775 TargetLowering::MakeLibCallOptions CallOptions;
776 SDValue Ops[2] = {GetSoftenedFloat(N->getOperand(0)), StackSlot};
777 EVT OpsVT[2] = {VT0, StackSlot.getValueType()};
778 Type *CallOpsTypeOverrides[2] = {nullptr, PointerTy};
779
780
781
783 .setOpsTypeOverrides(CallOpsTypeOverrides);
784
785 auto [ReturnVal, Chain] = TLI.makeLibCall(DAG, LC, NVT0, Ops, CallOptions, DL,
788 auto PtrInfo =
790
791 SDValue LoadExp = DAG.getLoad(VT1, DL, Chain, StackSlot, PtrInfo);
792
793 ReplaceValueWith(SDValue(N, 1), LoadExp);
794 return ReturnVal;
795}
796
797bool DAGTypeLegalizer::SoftenFloatRes_UnaryWithTwoFPResults(
798 SDNode *N, RTLIB::Libcall LC, std::optional CallRetResNo) {
799 assert(->isStrictFPOpcode() && "strictfp not implemented");
800 EVT VT = N->getValueType(0);
801
802 assert(VT == N->getValueType(1) &&
803 "expected both return values to have the same type");
804
805 RTLIB::LibcallImpl LCImpl = TLI.getLibcallImpl(LC);
806 if (LCImpl == RTLIB::Unsupported)
807 return false;
808
809 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
810
812
815
816 std::array<SDValue, 2> StackSlots;
819 for (unsigned ResNum = 0; ResNum < N->getNumValues(); ++ResNum) {
820 if (ResNum == CallRetResNo)
821 continue;
822 SDValue StackSlot = DAG.CreateStackTemporary(NVT);
823 Ops.push_back(StackSlot);
825 StackSlots[ResNum] = StackSlot;
827 }
828
829 TargetLowering::MakeLibCallOptions CallOptions;
830
831
833 .setOpsTypeOverrides(CallOpsTypeOverrides);
834
835 auto [ReturnVal, Chain] =
836 TLI.makeLibCall(DAG, LCImpl, NVT, Ops, CallOptions, DL,
838
839 auto CreateStackLoad = [&, Chain = Chain](SDValue StackSlot) {
841 auto PtrInfo =
843 return DAG.getLoad(NVT, DL, Chain, StackSlot, PtrInfo);
844 };
845
846 for (auto [ResNum, SlackSlot] : enumerate(StackSlots)) {
847 if (CallRetResNo == ResNum) {
848 SetSoftenedFloat(SDValue(N, ResNum), ReturnVal);
849 continue;
850 }
851 SetSoftenedFloat(SDValue(N, ResNum), CreateStackLoad(SlackSlot));
852 }
853
854 return true;
855}
856
857SDValue DAGTypeLegalizer::SoftenFloatRes_FSINCOS(SDNode *N) {
858 EVT VT = N->getValueType(0);
859 if (SoftenFloatRes_UnaryWithTwoFPResults(N, RTLIB::getSINCOS(VT)))
861
862
865
866 SDValue SoftSin, SoftCos;
867 if (TLI.getLibcallImpl(SinLC) == RTLIB::Unsupported ||
868 TLI.getLibcallImpl(CosLC) == RTLIB::Unsupported) {
869 DAG.getContext()->emitError("do not know how to soften fsincos");
870
871 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
872 SoftSin = SoftCos = DAG.getPOISON(NVT);
873 } else {
874 SoftSin = SoftenFloatRes_Unary(N, SinLC);
875 SoftCos = SoftenFloatRes_Unary(N, CosLC);
876 }
877
878 SetSoftenedFloat(SDValue(N, 0), SoftSin);
879 SetSoftenedFloat(SDValue(N, 1), SoftCos);
881}
882
883SDValue DAGTypeLegalizer::SoftenFloatRes_FMODF(SDNode *N) {
884 EVT VT = N->getValueType(0);
885 if (SoftenFloatRes_UnaryWithTwoFPResults(N, RTLIB::getMODF(VT),
886 0))
888
889 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
890 DAG.getContext()->emitError("do not know how to soften fmodf");
895}
896
897SDValue DAGTypeLegalizer::SoftenFloatRes_FREM(SDNode *N) {
898 return SoftenFloatRes_Binary(N, GetFPLibCall(N->getValueType(0),
899 RTLIB::REM_F32,
900 RTLIB::REM_F64,
901 RTLIB::REM_F80,
902 RTLIB::REM_F128,
903 RTLIB::REM_PPCF128));
904}
905
906SDValue DAGTypeLegalizer::SoftenFloatRes_FRINT(SDNode *N) {
907 return SoftenFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
908 RTLIB::RINT_F32,
909 RTLIB::RINT_F64,
910 RTLIB::RINT_F80,
911 RTLIB::RINT_F128,
912 RTLIB::RINT_PPCF128));
913}
914
915SDValue DAGTypeLegalizer::SoftenFloatRes_FROUND(SDNode *N) {
916 return SoftenFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
917 RTLIB::ROUND_F32,
918 RTLIB::ROUND_F64,
919 RTLIB::ROUND_F80,
920 RTLIB::ROUND_F128,
921 RTLIB::ROUND_PPCF128));
922}
923
924SDValue DAGTypeLegalizer::SoftenFloatRes_FROUNDEVEN(SDNode *N) {
925 return SoftenFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
926 RTLIB::ROUNDEVEN_F32,
927 RTLIB::ROUNDEVEN_F64,
928 RTLIB::ROUNDEVEN_F80,
929 RTLIB::ROUNDEVEN_F128,
930 RTLIB::ROUNDEVEN_PPCF128));
931}
932
933SDValue DAGTypeLegalizer::SoftenFloatRes_FSIN(SDNode *N) {
934 return SoftenFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
935 RTLIB::SIN_F32,
936 RTLIB::SIN_F64,
937 RTLIB::SIN_F80,
938 RTLIB::SIN_F128,
939 RTLIB::SIN_PPCF128));
940}
941
942SDValue DAGTypeLegalizer::SoftenFloatRes_FSINH(SDNode *N) {
943 return SoftenFloatRes_Unary(
944 N, GetFPLibCall(N->getValueType(0), RTLIB::SINH_F32, RTLIB::SINH_F64,
945 RTLIB::SINH_F80, RTLIB::SINH_F128, RTLIB::SINH_PPCF128));
946}
947
948SDValue DAGTypeLegalizer::SoftenFloatRes_FSQRT(SDNode *N) {
949 return SoftenFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
950 RTLIB::SQRT_F32,
951 RTLIB::SQRT_F64,
952 RTLIB::SQRT_F80,
953 RTLIB::SQRT_F128,
954 RTLIB::SQRT_PPCF128));
955}
956
957SDValue DAGTypeLegalizer::SoftenFloatRes_FSUB(SDNode *N) {
958 return SoftenFloatRes_Binary(N, GetFPLibCall(N->getValueType(0),
959 RTLIB::SUB_F32,
960 RTLIB::SUB_F64,
961 RTLIB::SUB_F80,
962 RTLIB::SUB_F128,
963 RTLIB::SUB_PPCF128));
964}
965
966SDValue DAGTypeLegalizer::SoftenFloatRes_FTAN(SDNode *N) {
967 return SoftenFloatRes_Unary(
968 N, GetFPLibCall(N->getValueType(0), RTLIB::TAN_F32, RTLIB::TAN_F64,
969 RTLIB::TAN_F80, RTLIB::TAN_F128, RTLIB::TAN_PPCF128));
970}
971
972SDValue DAGTypeLegalizer::SoftenFloatRes_FTANH(SDNode *N) {
973 return SoftenFloatRes_Unary(
974 N, GetFPLibCall(N->getValueType(0), RTLIB::TANH_F32, RTLIB::TANH_F64,
975 RTLIB::TANH_F80, RTLIB::TANH_F128, RTLIB::TANH_PPCF128));
976}
977
978SDValue DAGTypeLegalizer::SoftenFloatRes_FTRUNC(SDNode *N) {
979 return SoftenFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
980 RTLIB::TRUNC_F32,
981 RTLIB::TRUNC_F64,
982 RTLIB::TRUNC_F80,
983 RTLIB::TRUNC_F128,
984 RTLIB::TRUNC_PPCF128));
985}
986
987SDValue DAGTypeLegalizer::SoftenFloatRes_LOAD(SDNode *N) {
989 EVT VT = N->getValueType(0);
990 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
991 SDLoc dl(N);
992
993 auto MMOFlags =
994 L->getMemOperand()->getFlags() &
998 NewL = DAG.getLoad(L->getAddressingMode(), L->getExtensionType(), NVT, dl,
999 L->getChain(), L->getBasePtr(), L->getOffset(),
1000 L->getPointerInfo(), NVT, L->getBaseAlign(), MMOFlags,
1001 L->getAAInfo());
1002
1003
1005 return NewL;
1006 }
1007
1008
1009 NewL = DAG.getLoad(L->getAddressingMode(), ISD::NON_EXTLOAD, L->getMemoryVT(),
1010 dl, L->getChain(), L->getBasePtr(), L->getOffset(),
1011 L->getPointerInfo(), L->getMemoryVT(), L->getBaseAlign(),
1012 MMOFlags, L->getAAInfo());
1013
1014
1016 auto ExtendNode = DAG.getNode(ISD::FP_EXTEND, dl, VT, NewL);
1017 return BitConvertToInteger(ExtendNode);
1018}
1019
1020SDValue DAGTypeLegalizer::SoftenFloatRes_ATOMIC_LOAD(SDNode *N) {
1022 EVT VT = N->getValueType(0);
1023 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
1024 SDLoc dl(N);
1025
1028 DAG.getAtomic(ISD::ATOMIC_LOAD, dl, NVT, DAG.getVTList(NVT, MVT::Other),
1029 {L->getChain(), L->getBasePtr()}, L->getMemOperand());
1030
1031
1032
1034 return NewL;
1035 }
1036
1037 report_fatal_error("softening fp extending atomic load not handled");
1038}
1039
1040SDValue DAGTypeLegalizer::SoftenFloatRes_SELECT(SDNode *N) {
1041 SDValue LHS = GetSoftenedFloat(N->getOperand(1));
1042 SDValue RHS = GetSoftenedFloat(N->getOperand(2));
1043 return DAG.getSelect(SDLoc(N),
1044 LHS.getValueType(), N->getOperand(0), LHS, RHS);
1045}
1046
1047SDValue DAGTypeLegalizer::SoftenFloatRes_SELECT_CC(SDNode *N) {
1048 SDValue LHS = GetSoftenedFloat(N->getOperand(2));
1049 SDValue RHS = GetSoftenedFloat(N->getOperand(3));
1051 LHS.getValueType(), N->getOperand(0),
1052 N->getOperand(1), LHS, RHS, N->getOperand(4));
1053}
1054
1055SDValue DAGTypeLegalizer::SoftenFloatRes_UNDEF(SDNode *N) {
1056 return DAG.getUNDEF(TLI.getTypeToTransformTo(*DAG.getContext(),
1057 N->getValueType(0)));
1058}
1059
1060SDValue DAGTypeLegalizer::SoftenFloatRes_VAARG(SDNode *N) {
1063 EVT VT = N->getValueType(0);
1064 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
1065 SDLoc dl(N);
1066
1068 NewVAARG = DAG.getVAArg(NVT, dl, Chain, Ptr, N->getOperand(2),
1069 N->getConstantOperandVal(3));
1070
1071
1072
1075 return NewVAARG;
1076}
1077
1078SDValue DAGTypeLegalizer::SoftenFloatRes_XINT_TO_FP(SDNode *N) {
1079 bool IsStrict = N->isStrictFPOpcode();
1082 EVT SVT = N->getOperand(IsStrict ? 1 : 0).getValueType();
1083 EVT RVT = N->getValueType(0);
1084 EVT NVT = EVT();
1085 SDLoc dl(N);
1086
1087
1088
1089
1090 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
1091 for (unsigned t = MVT::FIRST_INTEGER_VALUETYPE;
1092 t <= MVT::LAST_INTEGER_VALUETYPE && LC == RTLIB::UNKNOWN_LIBCALL; ++t) {
1094
1095 if (NVT.bitsGE(SVT))
1097 }
1098 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported XINT_TO_FP!");
1099
1100 SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
1101
1103 NVT, N->getOperand(IsStrict ? 1 : 0));
1104 TargetLowering::MakeLibCallOptions CallOptions;
1107 std::pair<SDValue, SDValue> Tmp =
1108 TLI.makeLibCall(DAG, LC, TLI.getTypeToTransformTo(*DAG.getContext(), RVT),
1109 Op, CallOptions, dl, Chain);
1110
1111 if (IsStrict)
1112 ReplaceValueWith(SDValue(N, 1), Tmp.second);
1113 return Tmp.first;
1114}
1115
1116SDValue DAGTypeLegalizer::SoftenFloatRes_VECREDUCE(SDNode *N) {
1117
1118 ReplaceValueWith(SDValue(N, 0), TLI.expandVecReduce(N, DAG));
1120}
1121
1122SDValue DAGTypeLegalizer::SoftenFloatRes_VECREDUCE_SEQ(SDNode *N) {
1123 ReplaceValueWith(SDValue(N, 0), TLI.expandVecReduceSeq(N, DAG));
1125}
1126
1127
1128
1129
1130
1131bool DAGTypeLegalizer::SoftenFloatOperand(SDNode *N, unsigned OpNo) {
1132 LLVM_DEBUG(dbgs() << "Soften float operand " << OpNo << ": "; N->dump(&DAG));
1134
1135 switch (N->getOpcode()) {
1136 default:
1137#ifndef NDEBUG
1138 dbgs() << "SoftenFloatOperand Op #" << OpNo << ": ";
1139 N->dump(&DAG); dbgs() << "\n";
1140#endif
1141 report_fatal_error("Do not know how to soften this operator's operand!");
1142
1143 case ISD::BITCAST: Res = SoftenFloatOp_BITCAST(N); break;
1144 case ISD::BR_CC: Res = SoftenFloatOp_BR_CC(N); break;
1145 case ISD::STRICT_FP_TO_FP16:
1146 case ISD::FP_TO_FP16:
1147 case ISD::FP_TO_BF16:
1148 case ISD::STRICT_FP_TO_BF16:
1150 case ISD::FP_ROUND: Res = SoftenFloatOp_FP_ROUND(N); break;
1154 case ISD::FP_TO_UINT: Res = SoftenFloatOp_FP_TO_XINT(N); break;
1157 Res = SoftenFloatOp_FP_TO_XINT_SAT(N); break;
1159 case ISD::LROUND: Res = SoftenFloatOp_LROUND(N); break;
1161 case ISD::LLROUND: Res = SoftenFloatOp_LLROUND(N); break;
1163 case ISD::LRINT: Res = SoftenFloatOp_LRINT(N); break;
1165 case ISD::LLRINT: Res = SoftenFloatOp_LLRINT(N); break;
1166 case ISD::SELECT_CC: Res = SoftenFloatOp_SELECT_CC(N); break;
1169 case ISD::SETCC: Res = SoftenFloatOp_SETCC(N); break;
1170 case ISD::STORE: Res = SoftenFloatOp_STORE(N, OpNo); break;
1171 case ISD::ATOMIC_STORE:
1172 Res = SoftenFloatOp_ATOMIC_STORE(N, OpNo);
1173 break;
1174 case ISD::FCOPYSIGN: Res = SoftenFloatOp_FCOPYSIGN(N); break;
1175 case ISD::FAKE_USE:
1176 Res = SoftenFloatOp_FAKE_USE(N);
1177 break;
1178 case ISD::STACKMAP:
1179 Res = SoftenFloatOp_STACKMAP(N, OpNo);
1180 break;
1181 case ISD::PATCHPOINT:
1182 Res = SoftenFloatOp_PATCHPOINT(N, OpNo);
1183 break;
1184 }
1185
1186
1187 if (!Res.getNode()) return false;
1188
1189
1190
1192 return true;
1193
1194 assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
1195 "Invalid operand softening");
1196
1197 ReplaceValueWith(SDValue(N, 0), Res);
1198 return false;
1199}
1200
1201SDValue DAGTypeLegalizer::SoftenFloatOp_BITCAST(SDNode *N) {
1202 SDValue Op0 = GetSoftenedFloat(N->getOperand(0));
1203
1204 return DAG.getNode(ISD::BITCAST, SDLoc(N), N->getValueType(0), Op0);
1205}
1206
1207SDValue DAGTypeLegalizer::SoftenFloatOp_FP_ROUND(SDNode *N) {
1208
1209
1211 N->getOpcode() == ISD::STRICT_FP_TO_FP16 ||
1212 N->getOpcode() == ISD::FP_TO_BF16 ||
1213 N->getOpcode() == ISD::STRICT_FP_TO_BF16 ||
1215
1216 bool IsStrict = N->isStrictFPOpcode();
1217 SDValue Op = N->getOperand(IsStrict ? 1 : 0);
1218 EVT SVT = Op.getValueType();
1219 EVT RVT = N->getValueType(0);
1220 EVT FloatRVT = RVT;
1221 if (N->getOpcode() == ISD::FP_TO_FP16 ||
1222 N->getOpcode() == ISD::STRICT_FP_TO_FP16)
1223 FloatRVT = MVT::f16;
1224 else if (N->getOpcode() == ISD::FP_TO_BF16 ||
1225 N->getOpcode() == ISD::STRICT_FP_TO_BF16)
1226 FloatRVT = MVT::bf16;
1227
1229 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_ROUND libcall");
1230
1231 SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
1232 Op = GetSoftenedFloat(Op);
1233 TargetLowering::MakeLibCallOptions CallOptions;
1235 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, RVT, Op,
1236 CallOptions, SDLoc(N),
1237 Chain);
1238 if (IsStrict) {
1239 ReplaceValueWith(SDValue(N, 1), Tmp.second);
1240 ReplaceValueWith(SDValue(N, 0), Tmp.first);
1242 }
1243 return Tmp.first;
1244}
1245
1246SDValue DAGTypeLegalizer::SoftenFloatOp_BR_CC(SDNode *N) {
1249
1251 NewLHS = GetSoftenedFloat(NewLHS);
1252 NewRHS = GetSoftenedFloat(NewRHS);
1253 TLI.softenSetCCOperands(DAG, VT, NewLHS, NewRHS, CCCode, SDLoc(N),
1254 N->getOperand(2), N->getOperand(3));
1255
1256
1257
1258 if (!NewRHS.getNode()) {
1259 NewRHS = DAG.getConstant(0, SDLoc(N), NewLHS.getValueType());
1261 }
1262
1263
1264 return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0),
1265 DAG.getCondCode(CCCode), NewLHS, NewRHS,
1266 N->getOperand(4)),
1267 0);
1268}
1269
1270
1271
1272
1275 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
1276 for (unsigned IntVT = MVT::FIRST_INTEGER_VALUETYPE;
1277 IntVT <= MVT::LAST_INTEGER_VALUETYPE && LC == RTLIB::UNKNOWN_LIBCALL;
1278 ++IntVT) {
1280
1281 if (Promoted.bitsGE(RetVT))
1284 }
1285 return LC;
1286}
1287
1288SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_XINT(SDNode *N) {
1289 bool IsStrict = N->isStrictFPOpcode();
1292
1293 SDValue Op = N->getOperand(IsStrict ? 1 : 0);
1294 EVT SVT = Op.getValueType();
1295 EVT RVT = N->getValueType(0);
1296 EVT NVT = EVT();
1297 SDLoc dl(N);
1298
1299
1300
1301
1302
1304 assert(LC != RTLIB::UNKNOWN_LIBCALL && NVT.isSimple() &&
1305 "Unsupported FP_TO_XINT!");
1306
1307 Op = GetSoftenedFloat(Op);
1308 SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
1309 TargetLowering::MakeLibCallOptions CallOptions;
1311 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, NVT, Op,
1312 CallOptions, dl, Chain);
1313
1314
1316
1317 if (!IsStrict)
1318 return Res;
1319
1320 ReplaceValueWith(SDValue(N, 1), Tmp.second);
1321 ReplaceValueWith(SDValue(N, 0), Res);
1323}
1324
1325SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_XINT_SAT(SDNode *N) {
1326 SDValue Res = TLI.expandFP_TO_INT_SAT(N, DAG);
1327 return Res;
1328}
1329
1330SDValue DAGTypeLegalizer::SoftenFloatOp_SELECT_CC(SDNode *N) {
1333
1335 NewLHS = GetSoftenedFloat(NewLHS);
1336 NewRHS = GetSoftenedFloat(NewRHS);
1337 TLI.softenSetCCOperands(DAG, VT, NewLHS, NewRHS, CCCode, SDLoc(N),
1338 N->getOperand(0), N->getOperand(1));
1339
1340
1341
1342 if (!NewRHS.getNode()) {
1343 NewRHS = DAG.getConstant(0, SDLoc(N), NewLHS.getValueType());
1345 }
1346
1347
1348 return SDValue(DAG.UpdateNodeOperands(N, NewLHS, NewRHS,
1349 N->getOperand(2), N->getOperand(3),
1350 DAG.getCondCode(CCCode)),
1351 0);
1352}
1353
1354SDValue DAGTypeLegalizer::SoftenFloatOp_SETCC(SDNode *N) {
1355 bool IsStrict = N->isStrictFPOpcode();
1358 SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
1361
1363 SDValue NewLHS = GetSoftenedFloat(Op0);
1364 SDValue NewRHS = GetSoftenedFloat(Op1);
1365 TLI.softenSetCCOperands(DAG, VT, NewLHS, NewRHS, CCCode, SDLoc(N), Op0, Op1,
1367
1368
1370 if (IsStrict)
1372 NewRHS, DAG.getCondCode(CCCode));
1373 else
1374 return SDValue(DAG.UpdateNodeOperands(N, NewLHS, NewRHS,
1375 DAG.getCondCode(CCCode)), 0);
1376 }
1377
1378
1380 "Unexpected setcc expansion!");
1381
1382 if (IsStrict) {
1383 ReplaceValueWith(SDValue(N, 0), NewLHS);
1384 ReplaceValueWith(SDValue(N, 1), Chain);
1386 }
1387 return NewLHS;
1388}
1389
1390SDValue DAGTypeLegalizer::SoftenFloatOp_STORE(SDNode *N, unsigned OpNo) {
1392 assert(OpNo == 1 && "Can only soften the stored value!");
1395 SDLoc dl(N);
1396
1397 if (ST->isTruncatingStore())
1398
1399 Val = BitConvertToInteger(
1401 DAG.getIntPtrConstant(0, dl, true)));
1402 else
1403 Val = GetSoftenedFloat(Val);
1404
1405 return DAG.getStore(ST->getChain(), dl, Val, ST->getBasePtr(),
1406 ST->getMemOperand());
1407}
1408
1409SDValue DAGTypeLegalizer::SoftenFloatOp_ATOMIC_STORE(SDNode *N, unsigned OpNo) {
1410 assert(OpNo == 1 && "Can only soften the stored value!");
1414 SDLoc dl(N);
1415
1416 assert(ST->getMemoryVT() == VT && "truncating atomic store not handled");
1417
1418 SDValue NewVal = GetSoftenedFloat(Val);
1419 return DAG.getAtomic(ISD::ATOMIC_STORE, dl, VT, ST->getChain(), NewVal,
1420 ST->getBasePtr(), ST->getMemOperand());
1421}
1422
1423SDValue DAGTypeLegalizer::SoftenFloatOp_FCOPYSIGN(SDNode *N) {
1425 SDValue RHS = BitConvertToInteger(N->getOperand(1));
1426 SDLoc dl(N);
1427
1428 EVT LVT = LHS.getValueType();
1430 EVT RVT = RHS.getValueType();
1431
1434
1435
1436 int SizeDiff = RSize - LSize;
1437 if (SizeDiff > 0) {
1440 DAG.getConstant(SizeDiff, dl,
1441 TLI.getShiftAmountTy(RHS.getValueType(),
1442 DAG.getDataLayout())));
1444 } else if (SizeDiff < 0) {
1448 DAG.getConstant(-SizeDiff, dl,
1449 TLI.getShiftAmountTy(RHS.getValueType(),
1450 DAG.getDataLayout())));
1451 }
1452
1453 RHS = DAG.getBitcast(LVT, RHS);
1455}
1456
1457SDValue DAGTypeLegalizer::SoftenFloatOp_Unary(SDNode *N, RTLIB::Libcall LC) {
1458 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
1459 bool IsStrict = N->isStrictFPOpcode();
1460 unsigned Offset = IsStrict ? 1 : 0;
1462 SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
1463 TargetLowering::MakeLibCallOptions CallOptions;
1464 EVT OpVT = N->getOperand(0 + Offset).getValueType();
1466 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, NVT, Op,
1467 CallOptions, SDLoc(N),
1468 Chain);
1469 if (IsStrict) {
1470 ReplaceValueWith(SDValue(N, 1), Tmp.second);
1471 ReplaceValueWith(SDValue(N, 0), Tmp.first);
1473 }
1474
1475 return Tmp.first;
1476}
1477
1478SDValue DAGTypeLegalizer::SoftenFloatOp_LROUND(SDNode *N) {
1479 EVT OpVT = N->getOperand(N->isStrictFPOpcode() ? 1 : 0).getValueType();
1480 return SoftenFloatOp_Unary(N, GetFPLibCall(OpVT,
1481 RTLIB::LROUND_F32,
1482 RTLIB::LROUND_F64,
1483 RTLIB::LROUND_F80,
1484 RTLIB::LROUND_F128,
1485 RTLIB::LROUND_PPCF128));
1486}
1487
1488SDValue DAGTypeLegalizer::SoftenFloatOp_LLROUND(SDNode *N) {
1489 EVT OpVT = N->getOperand(N->isStrictFPOpcode() ? 1 : 0).getValueType();
1490 return SoftenFloatOp_Unary(N, GetFPLibCall(OpVT,
1491 RTLIB::LLROUND_F32,
1492 RTLIB::LLROUND_F64,
1493 RTLIB::LLROUND_F80,
1494 RTLIB::LLROUND_F128,
1495 RTLIB::LLROUND_PPCF128));
1496}
1497
1498SDValue DAGTypeLegalizer::SoftenFloatOp_LRINT(SDNode *N) {
1499 EVT OpVT = N->getOperand(N->isStrictFPOpcode() ? 1 : 0).getValueType();
1500 return SoftenFloatOp_Unary(N, GetFPLibCall(OpVT,
1501 RTLIB::LRINT_F32,
1502 RTLIB::LRINT_F64,
1503 RTLIB::LRINT_F80,
1504 RTLIB::LRINT_F128,
1505 RTLIB::LRINT_PPCF128));
1506}
1507
1508SDValue DAGTypeLegalizer::SoftenFloatOp_LLRINT(SDNode *N) {
1509 EVT OpVT = N->getOperand(N->isStrictFPOpcode() ? 1 : 0).getValueType();
1510 return SoftenFloatOp_Unary(N, GetFPLibCall(OpVT,
1511 RTLIB::LLRINT_F32,
1512 RTLIB::LLRINT_F64,
1513 RTLIB::LLRINT_F80,
1514 RTLIB::LLRINT_F128,
1515 RTLIB::LLRINT_PPCF128));
1516}
1517
1518SDValue DAGTypeLegalizer::SoftenFloatOp_FAKE_USE(SDNode *N) {
1519 SDValue Op1 = BitConvertToInteger(N->getOperand(1));
1520 return DAG.getNode(N->getOpcode(), SDLoc(N), N->getValueType(0),
1521 N->getOperand(0), Op1);
1522}
1523
1524SDValue DAGTypeLegalizer::SoftenFloatOp_STACKMAP(SDNode *N, unsigned OpNo) {
1525 assert(OpNo > 1);
1527 NewOps[OpNo] = GetSoftenedFloat(NewOps[OpNo]);
1528 return SDValue(DAG.UpdateNodeOperands(N, NewOps), 0);
1529}
1530
1531SDValue DAGTypeLegalizer::SoftenFloatOp_PATCHPOINT(SDNode *N, unsigned OpNo) {
1534 NewOps[OpNo] = GetSoftenedFloat(NewOps[OpNo]);
1535 return SDValue(DAG.UpdateNodeOperands(N, NewOps), 0);
1536}
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546void DAGTypeLegalizer::ExpandFloatResult(SDNode *N, unsigned ResNo) {
1547 LLVM_DEBUG(dbgs() << "Expand float result: "; N->dump(&DAG));
1550
1551
1552 if (CustomLowerNode(N, N->getValueType(ResNo), true))
1553 return;
1554
1555 switch (N->getOpcode()) {
1556 default:
1557#ifndef NDEBUG
1558 dbgs() << "ExpandFloatResult #" << ResNo << ": ";
1559 N->dump(&DAG); dbgs() << "\n";
1560#endif
1562 "operator!");
1563
1568
1570 case ISD::BITCAST: ExpandRes_BITCAST(N, Lo, Hi); break;
1574 case ISD::VAARG: ExpandRes_VAARG(N, Lo, Hi); break;
1575
1578 case ISD::FABS: ExpandFloatRes_FABS(N, Lo, Hi); break;
1580 case ISD::FMINNUM: ExpandFloatRes_FMINNUM(N, Lo, Hi); break;
1582 case ISD::FMAXNUM: ExpandFloatRes_FMAXNUM(N, Lo, Hi); break;
1583 case ISD::FMINIMUMNUM: ExpandFloatRes_FMINIMUMNUM(N, Lo, Hi); break;
1584 case ISD::FMAXIMUMNUM: ExpandFloatRes_FMAXIMUMNUM(N, Lo, Hi); break;
1586 case ISD::FADD: ExpandFloatRes_FADD(N, Lo, Hi); break;
1588 case ISD::FACOS: ExpandFloatRes_FACOS(N, Lo, Hi); break;
1590 case ISD::FASIN: ExpandFloatRes_FASIN(N, Lo, Hi); break;
1592 case ISD::FATAN: ExpandFloatRes_FATAN(N, Lo, Hi); break;
1594 case ISD::FATAN2: ExpandFloatRes_FATAN2(N, Lo, Hi); break;
1595 case ISD::FCBRT: ExpandFloatRes_FCBRT(N, Lo, Hi); break;
1597 case ISD::FCEIL: ExpandFloatRes_FCEIL(N, Lo, Hi); break;
1600 case ISD::FCOS: ExpandFloatRes_FCOS(N, Lo, Hi); break;
1602 case ISD::FCOSH: ExpandFloatRes_FCOSH(N, Lo, Hi); break;
1604 case ISD::FDIV: ExpandFloatRes_FDIV(N, Lo, Hi); break;
1606 case ISD::FEXP: ExpandFloatRes_FEXP(N, Lo, Hi); break;
1608 case ISD::FEXP2: ExpandFloatRes_FEXP2(N, Lo, Hi); break;
1609 case ISD::FEXP10: ExpandFloatRes_FEXP10(N, Lo, Hi); break;
1611 case ISD::FFLOOR: ExpandFloatRes_FFLOOR(N, Lo, Hi); break;
1613 case ISD::FLOG: ExpandFloatRes_FLOG(N, Lo, Hi); break;
1615 case ISD::FLOG2: ExpandFloatRes_FLOG2(N, Lo, Hi); break;
1617 case ISD::FLOG10: ExpandFloatRes_FLOG10(N, Lo, Hi); break;
1619 case ISD::FMA: ExpandFloatRes_FMA(N, Lo, Hi); break;
1621 case ISD::FMUL: ExpandFloatRes_FMUL(N, Lo, Hi); break;
1623 case ISD::FNEARBYINT: ExpandFloatRes_FNEARBYINT(N, Lo, Hi); break;
1624 case ISD::FNEG: ExpandFloatRes_FNEG(N, Lo, Hi); break;
1626 case ISD::FP_EXTEND: ExpandFloatRes_FP_EXTEND(N, Lo, Hi); break;
1628 case ISD::FPOW: ExpandFloatRes_FPOW(N, Lo, Hi); break;
1630 case ISD::FPOWI: ExpandFloatRes_FPOWI(N, Lo, Hi); break;
1631 case ISD::FLDEXP:
1635 case ISD::FRINT: ExpandFloatRes_FRINT(N, Lo, Hi); break;
1637 case ISD::FROUND: ExpandFloatRes_FROUND(N, Lo, Hi); break;
1639 case ISD::FROUNDEVEN: ExpandFloatRes_FROUNDEVEN(N, Lo, Hi); break;
1641 case ISD::FSIN: ExpandFloatRes_FSIN(N, Lo, Hi); break;
1643 case ISD::FSINH: ExpandFloatRes_FSINH(N, Lo, Hi); break;
1645 case ISD::FSQRT: ExpandFloatRes_FSQRT(N, Lo, Hi); break;
1647 case ISD::FSUB: ExpandFloatRes_FSUB(N, Lo, Hi); break;
1649 case ISD::FTAN: ExpandFloatRes_FTAN(N, Lo, Hi); break;
1651 case ISD::FTANH: ExpandFloatRes_FTANH(N, Lo, Hi); break;
1653 case ISD::FTRUNC: ExpandFloatRes_FTRUNC(N, Lo, Hi); break;
1654 case ISD::LOAD: ExpandFloatRes_LOAD(N, Lo, Hi); break;
1660 case ISD::FREM: ExpandFloatRes_FREM(N, Lo, Hi); break;
1661 case ISD::FMODF: ExpandFloatRes_FMODF(N); break;
1662 case ISD::FSINCOS: ExpandFloatRes_FSINCOS(N); break;
1663 case ISD::FSINCOSPI: ExpandFloatRes_FSINCOSPI(N); break;
1664
1665 }
1666
1667
1668 if (Lo.getNode())
1669 SetExpandedFloat(SDValue(N, ResNo), Lo, Hi);
1670}
1671
1672void DAGTypeLegalizer::ExpandFloatRes_ConstantFP(SDNode *N, SDValue &Lo,
1674 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
1676 "Do not know how to expand this float constant!");
1678 SDLoc dl(N);
1680 Lo = DAG.getConstantFP(APFloat(Sem, C.extractBits(64, 64)), dl, NVT);
1681 Hi = DAG.getConstantFP(APFloat(Sem, C.extractBits(64, 0)), dl, NVT);
1682}
1683
1684void DAGTypeLegalizer::ExpandFloatRes_Unary(SDNode *N, RTLIB::Libcall LC,
1686 bool IsStrict = N->isStrictFPOpcode();
1687 unsigned Offset = IsStrict ? 1 : 0;
1689 SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
1690 TargetLowering::MakeLibCallOptions CallOptions;
1691 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, N->getValueType(0),
1692 Op, CallOptions, SDLoc(N),
1693 Chain);
1694 if (IsStrict)
1695 ReplaceValueWith(SDValue(N, 1), Tmp.second);
1696 GetPairElements(Tmp.first, Lo, Hi);
1697}
1698
1699void DAGTypeLegalizer::ExpandFloatRes_Binary(SDNode *N, RTLIB::Libcall LC,
1701 bool IsStrict = N->isStrictFPOpcode();
1702 unsigned Offset = IsStrict ? 1 : 0;
1704 SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
1705 TargetLowering::MakeLibCallOptions CallOptions;
1706 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, N->getValueType(0),
1707 Ops, CallOptions, SDLoc(N),
1708 Chain);
1709 if (IsStrict)
1710 ReplaceValueWith(SDValue(N, 1), Tmp.second);
1711 GetPairElements(Tmp.first, Lo, Hi);
1712}
1713
1714void DAGTypeLegalizer::ExpandFloatRes_FMODF(SDNode *N) {
1715 ExpandFloatRes_UnaryWithTwoFPResults(N, RTLIB::getMODF(N->getValueType(0)),
1716 0);
1717}
1718
1719void DAGTypeLegalizer::ExpandFloatRes_FSINCOS(SDNode *N) {
1720 ExpandFloatRes_UnaryWithTwoFPResults(N, RTLIB::getSINCOS(N->getValueType(0)));
1721}
1722
1723void DAGTypeLegalizer::ExpandFloatRes_FSINCOSPI(SDNode *N) {
1724 ExpandFloatRes_UnaryWithTwoFPResults(N,
1726}
1727
1728void DAGTypeLegalizer::ExpandFloatRes_UnaryWithTwoFPResults(
1729 SDNode *N, RTLIB::Libcall LC, std::optional CallRetResNo) {
1730 assert(->isStrictFPOpcode() && "strictfp not implemented");
1732 TLI.expandMultipleResultFPLibCall(DAG, LC, N, Results, CallRetResNo);
1735 GetPairElements(Res, Lo, Hi);
1736 SetExpandedFloat(SDValue(N, ResNo), Lo, Hi);
1737 }
1738}
1739
1740void DAGTypeLegalizer::ExpandFloatRes_FABS(SDNode *N, SDValue &Lo,
1742 assert(N->getValueType(0) == MVT::ppcf128 &&
1743 "Logic only correct for ppcf128!");
1744 SDLoc dl(N);
1746 GetExpandedFloat(N->getOperand(0), Lo, Tmp);
1747 Hi = DAG.getNode(ISD::FABS, dl, Tmp.getValueType(), Tmp);
1748
1749 Lo = DAG.getSelectCC(dl, Tmp, Hi, Lo,
1750 DAG.getNode(ISD::FNEG, dl, Lo.getValueType(), Lo),
1752}
1753
1754void DAGTypeLegalizer::ExpandFloatRes_FMINNUM(SDNode *N, SDValue &Lo,
1756 ExpandFloatRes_Binary(N, GetFPLibCall(N->getValueType(0),
1757 RTLIB::FMIN_F32, RTLIB::FMIN_F64,
1758 RTLIB::FMIN_F80, RTLIB::FMIN_F128,
1759 RTLIB::FMIN_PPCF128), Lo, Hi);
1760}
1761
1762void DAGTypeLegalizer::ExpandFloatRes_FMAXNUM(SDNode *N, SDValue &Lo,
1764 ExpandFloatRes_Binary(N, GetFPLibCall(N->getValueType(0),
1765 RTLIB::FMAX_F32, RTLIB::FMAX_F64,
1766 RTLIB::FMAX_F80, RTLIB::FMAX_F128,
1767 RTLIB::FMAX_PPCF128), Lo, Hi);
1768}
1769
1770void DAGTypeLegalizer::ExpandFloatRes_FMINIMUMNUM(SDNode *N, SDValue &Lo,
1772 ExpandFloatRes_Binary(
1773 N,
1774 GetFPLibCall(N->getValueType(0), RTLIB::FMINIMUM_NUM_F32,
1775 RTLIB::FMINIMUM_NUM_F64, RTLIB::FMINIMUM_NUM_F80,
1776 RTLIB::FMINIMUM_NUM_F128, RTLIB::FMINIMUM_NUM_PPCF128),
1778}
1779
1780void DAGTypeLegalizer::ExpandFloatRes_FMAXIMUMNUM(SDNode *N, SDValue &Lo,
1782 ExpandFloatRes_Binary(
1783 N,
1784 GetFPLibCall(N->getValueType(0), RTLIB::FMAXIMUM_NUM_F32,
1785 RTLIB::FMAXIMUM_NUM_F64, RTLIB::FMAXIMUM_NUM_F80,
1786 RTLIB::FMAXIMUM_NUM_F128, RTLIB::FMAXIMUM_NUM_PPCF128),
1788}
1789
1790void DAGTypeLegalizer::ExpandFloatRes_FADD(SDNode *N, SDValue &Lo,
1792 ExpandFloatRes_Binary(N, GetFPLibCall(N->getValueType(0),
1793 RTLIB::ADD_F32, RTLIB::ADD_F64,
1794 RTLIB::ADD_F80, RTLIB::ADD_F128,
1795 RTLIB::ADD_PPCF128), Lo, Hi);
1796}
1797
1798void DAGTypeLegalizer::ExpandFloatRes_FACOS(SDNode *N, SDValue &Lo,
1800 ExpandFloatRes_Unary(N,
1801 GetFPLibCall(N->getValueType(0), RTLIB::ACOS_F32,
1802 RTLIB::ACOS_F64, RTLIB::ACOS_F80,
1803 RTLIB::ACOS_F128, RTLIB::ACOS_PPCF128),
1805}
1806
1807void DAGTypeLegalizer::ExpandFloatRes_FASIN(SDNode *N, SDValue &Lo,
1809 ExpandFloatRes_Unary(N,
1810 GetFPLibCall(N->getValueType(0), RTLIB::ASIN_F32,
1811 RTLIB::ASIN_F64, RTLIB::ASIN_F80,
1812 RTLIB::ASIN_F128, RTLIB::ASIN_PPCF128),
1814}
1815
1816void DAGTypeLegalizer::ExpandFloatRes_FATAN(SDNode *N, SDValue &Lo,
1818 ExpandFloatRes_Unary(N,
1819 GetFPLibCall(N->getValueType(0), RTLIB::ATAN_F32,
1820 RTLIB::ATAN_F64, RTLIB::ATAN_F80,
1821 RTLIB::ATAN_F128, RTLIB::ATAN_PPCF128),
1823}
1824
1825void DAGTypeLegalizer::ExpandFloatRes_FATAN2(SDNode *N, SDValue &Lo,
1827 ExpandFloatRes_Binary(N,
1828 GetFPLibCall(N->getValueType(0), RTLIB::ATAN2_F32,
1829 RTLIB::ATAN2_F64, RTLIB::ATAN2_F80,
1830 RTLIB::ATAN2_F128, RTLIB::ATAN2_PPCF128),
1832}
1833
1834void DAGTypeLegalizer::ExpandFloatRes_FCBRT(SDNode *N, SDValue &Lo,
1836 ExpandFloatRes_Unary(N, GetFPLibCall(N->getValueType(0), RTLIB::CBRT_F32,
1837 RTLIB::CBRT_F64, RTLIB::CBRT_F80,
1838 RTLIB::CBRT_F128,
1839 RTLIB::CBRT_PPCF128), Lo, Hi);
1840}
1841
1842void DAGTypeLegalizer::ExpandFloatRes_FCEIL(SDNode *N,
1844 ExpandFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
1845 RTLIB::CEIL_F32, RTLIB::CEIL_F64,
1846 RTLIB::CEIL_F80, RTLIB::CEIL_F128,
1847 RTLIB::CEIL_PPCF128), Lo, Hi);
1848}
1849
1850void DAGTypeLegalizer::ExpandFloatRes_FCOPYSIGN(SDNode *N,
1852 ExpandFloatRes_Binary(N, GetFPLibCall(N->getValueType(0),
1853 RTLIB::COPYSIGN_F32,
1854 RTLIB::COPYSIGN_F64,
1855 RTLIB::COPYSIGN_F80,
1856 RTLIB::COPYSIGN_F128,
1857 RTLIB::COPYSIGN_PPCF128), Lo, Hi);
1858}
1859
1860void DAGTypeLegalizer::ExpandFloatRes_FCOS(SDNode *N,
1862 ExpandFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
1863 RTLIB::COS_F32, RTLIB::COS_F64,
1864 RTLIB::COS_F80, RTLIB::COS_F128,
1865 RTLIB::COS_PPCF128), Lo, Hi);
1866}
1867
1868void DAGTypeLegalizer::ExpandFloatRes_FCOSH(SDNode *N, SDValue &Lo,
1870 ExpandFloatRes_Unary(N,
1871 GetFPLibCall(N->getValueType(0), RTLIB::COSH_F32,
1872 RTLIB::COSH_F64, RTLIB::COSH_F80,
1873 RTLIB::COSH_F128, RTLIB::COSH_PPCF128),
1875}
1876
1877void DAGTypeLegalizer::ExpandFloatRes_FDIV(SDNode *N, SDValue &Lo,
1879 ExpandFloatRes_Binary(N, GetFPLibCall(N->getValueType(0),
1880 RTLIB::DIV_F32,
1881 RTLIB::DIV_F64,
1882 RTLIB::DIV_F80,
1883 RTLIB::DIV_F128,
1884 RTLIB::DIV_PPCF128), Lo, Hi);
1885}
1886
1887void DAGTypeLegalizer::ExpandFloatRes_FEXP(SDNode *N,
1889 ExpandFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
1890 RTLIB::EXP_F32, RTLIB::EXP_F64,
1891 RTLIB::EXP_F80, RTLIB::EXP_F128,
1892 RTLIB::EXP_PPCF128), Lo, Hi);
1893}
1894
1895void DAGTypeLegalizer::ExpandFloatRes_FEXP2(SDNode *N,
1897 ExpandFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
1898 RTLIB::EXP2_F32, RTLIB::EXP2_F64,
1899 RTLIB::EXP2_F80, RTLIB::EXP2_F128,
1900 RTLIB::EXP2_PPCF128), Lo, Hi);
1901}
1902
1903void DAGTypeLegalizer::ExpandFloatRes_FEXP10(SDNode *N, SDValue &Lo,
1905 ExpandFloatRes_Unary(N,
1906 GetFPLibCall(N->getValueType(0), RTLIB::EXP10_F32,
1907 RTLIB::EXP10_F64, RTLIB::EXP10_F80,
1908 RTLIB::EXP10_F128, RTLIB::EXP10_PPCF128),
1910}
1911
1912void DAGTypeLegalizer::ExpandFloatRes_FFLOOR(SDNode *N,
1914 ExpandFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
1915 RTLIB::FLOOR_F32, RTLIB::FLOOR_F64,
1916 RTLIB::FLOOR_F80, RTLIB::FLOOR_F128,
1917 RTLIB::FLOOR_PPCF128), Lo, Hi);
1918}
1919
1920void DAGTypeLegalizer::ExpandFloatRes_FLOG(SDNode *N,
1922 ExpandFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
1923 RTLIB::LOG_F32, RTLIB::LOG_F64,
1924 RTLIB::LOG_F80, RTLIB::LOG_F128,
1925 RTLIB::LOG_PPCF128), Lo, Hi);
1926}
1927
1928void DAGTypeLegalizer::ExpandFloatRes_FLOG2(SDNode *N,
1930 ExpandFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
1931 RTLIB::LOG2_F32, RTLIB::LOG2_F64,
1932 RTLIB::LOG2_F80, RTLIB::LOG2_F128,
1933 RTLIB::LOG2_PPCF128), Lo, Hi);
1934}
1935
1936void DAGTypeLegalizer::ExpandFloatRes_FLOG10(SDNode *N,
1938 ExpandFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
1939 RTLIB::LOG10_F32, RTLIB::LOG10_F64,
1940 RTLIB::LOG10_F80, RTLIB::LOG10_F128,
1941 RTLIB::LOG10_PPCF128), Lo, Hi);
1942}
1943
1944void DAGTypeLegalizer::ExpandFloatRes_FMA(SDNode *N, SDValue &Lo,
1946 bool IsStrict = N->isStrictFPOpcode();
1947 unsigned Offset = IsStrict ? 1 : 0;
1949 N->getOperand(2 + Offset) };
1950 SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
1951 TargetLowering::MakeLibCallOptions CallOptions;
1952 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, GetFPLibCall(N->getValueType(0),
1953 RTLIB::FMA_F32,
1954 RTLIB::FMA_F64,
1955 RTLIB::FMA_F80,
1956 RTLIB::FMA_F128,
1957 RTLIB::FMA_PPCF128),
1958 N->getValueType(0), Ops, CallOptions,
1959 SDLoc(N), Chain);
1960 if (IsStrict)
1961 ReplaceValueWith(SDValue(N, 1), Tmp.second);
1962 GetPairElements(Tmp.first, Lo, Hi);
1963}
1964
1965void DAGTypeLegalizer::ExpandFloatRes_FMUL(SDNode *N, SDValue &Lo,
1967 ExpandFloatRes_Binary(N, GetFPLibCall(N->getValueType(0),
1968 RTLIB::MUL_F32,
1969 RTLIB::MUL_F64,
1970 RTLIB::MUL_F80,
1971 RTLIB::MUL_F128,
1972 RTLIB::MUL_PPCF128), Lo, Hi);
1973}
1974
1975void DAGTypeLegalizer::ExpandFloatRes_FNEARBYINT(SDNode *N,
1977 ExpandFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
1978 RTLIB::NEARBYINT_F32,
1979 RTLIB::NEARBYINT_F64,
1980 RTLIB::NEARBYINT_F80,
1981 RTLIB::NEARBYINT_F128,
1982 RTLIB::NEARBYINT_PPCF128), Lo, Hi);
1983}
1984
1985void DAGTypeLegalizer::ExpandFloatRes_FNEG(SDNode *N, SDValue &Lo,
1987 SDLoc dl(N);
1988 GetExpandedFloat(N->getOperand(0), Lo, Hi);
1989 Lo = DAG.getNode(ISD::FNEG, dl, Lo.getValueType(), Lo);
1990 Hi = DAG.getNode(ISD::FNEG, dl, Hi.getValueType(), Hi);
1991}
1992
1993void DAGTypeLegalizer::ExpandFloatRes_AssertNoFPClass(SDNode *N, SDValue &Lo,
1995
1996 SDLoc dl(N);
1997 GetExpandedFloat(N->getOperand(0), Lo, Hi);
1998}
1999
2000void DAGTypeLegalizer::ExpandFloatRes_FP_EXTEND(SDNode *N, SDValue &Lo,
2002 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
2003 SDLoc dl(N);
2004 bool IsStrict = N->isStrictFPOpcode();
2005
2007 if (IsStrict) {
2008
2009 if (NVT == N->getOperand(1).getValueType()) {
2012 } else {
2013
2015 { N->getOperand(0), N->getOperand(1) });
2017 }
2018 } else {
2019 Hi = DAG.getNode(ISD::FP_EXTEND, dl, NVT, N->getOperand(0));
2020 }
2021
2023
2024 if (IsStrict)
2025 ReplaceValueWith(SDValue(N, 1), Chain);
2026}
2027
2028void DAGTypeLegalizer::ExpandFloatRes_FPOW(SDNode *N,
2030 ExpandFloatRes_Binary(N, GetFPLibCall(N->getValueType(0),
2031 RTLIB::POW_F32, RTLIB::POW_F64,
2032 RTLIB::POW_F80, RTLIB::POW_F128,
2033 RTLIB::POW_PPCF128), Lo, Hi);
2034}
2035
2036void DAGTypeLegalizer::ExpandFloatRes_FPOWI(SDNode *N,
2039}
2040
2041void DAGTypeLegalizer::ExpandFloatRes_FLDEXP(SDNode *N, SDValue &Lo,
2044}
2045
2046void DAGTypeLegalizer::ExpandFloatRes_FREEZE(SDNode *N,
2048 assert(N->getValueType(0) == MVT::ppcf128 &&
2049 "Logic only correct for ppcf128!");
2050
2051 SDLoc dl(N);
2052 GetExpandedFloat(N->getOperand(0), Lo, Hi);
2055}
2056
2057void DAGTypeLegalizer::ExpandFloatRes_FREM(SDNode *N,
2059 ExpandFloatRes_Binary(N, GetFPLibCall(N->getValueType(0),
2060 RTLIB::REM_F32, RTLIB::REM_F64,
2061 RTLIB::REM_F80, RTLIB::REM_F128,
2062 RTLIB::REM_PPCF128), Lo, Hi);
2063}
2064
2065void DAGTypeLegalizer::ExpandFloatRes_FRINT(SDNode *N,
2067 ExpandFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
2068 RTLIB::RINT_F32, RTLIB::RINT_F64,
2069 RTLIB::RINT_F80, RTLIB::RINT_F128,
2070 RTLIB::RINT_PPCF128), Lo, Hi);
2071}
2072
2073void DAGTypeLegalizer::ExpandFloatRes_FROUND(SDNode *N,
2075 ExpandFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
2076 RTLIB::ROUND_F32,
2077 RTLIB::ROUND_F64,
2078 RTLIB::ROUND_F80,
2079 RTLIB::ROUND_F128,
2080 RTLIB::ROUND_PPCF128), Lo, Hi);
2081}
2082
2083void DAGTypeLegalizer::ExpandFloatRes_FROUNDEVEN(SDNode *N,
2085 ExpandFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
2086 RTLIB::ROUNDEVEN_F32,
2087 RTLIB::ROUNDEVEN_F64,
2088 RTLIB::ROUNDEVEN_F80,
2089 RTLIB::ROUNDEVEN_F128,
2090 RTLIB::ROUNDEVEN_PPCF128), Lo, Hi);
2091}
2092
2093void DAGTypeLegalizer::ExpandFloatRes_FSIN(SDNode *N,
2095 ExpandFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
2096 RTLIB::SIN_F32, RTLIB::SIN_F64,
2097 RTLIB::SIN_F80, RTLIB::SIN_F128,
2098 RTLIB::SIN_PPCF128), Lo, Hi);
2099}
2100
2101void DAGTypeLegalizer::ExpandFloatRes_FSINH(SDNode *N, SDValue &Lo,
2103 ExpandFloatRes_Unary(N,
2104 GetFPLibCall(N->getValueType(0), RTLIB::SINH_F32,
2105 RTLIB::SINH_F64, RTLIB::SINH_F80,
2106 RTLIB::SINH_F128, RTLIB::SINH_PPCF128),
2108}
2109
2110void DAGTypeLegalizer::ExpandFloatRes_FSQRT(SDNode *N,
2112 ExpandFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
2113 RTLIB::SQRT_F32, RTLIB::SQRT_F64,
2114 RTLIB::SQRT_F80, RTLIB::SQRT_F128,
2115 RTLIB::SQRT_PPCF128), Lo, Hi);
2116}
2117
2118void DAGTypeLegalizer::ExpandFloatRes_FSUB(SDNode *N, SDValue &Lo,
2120 ExpandFloatRes_Binary(N, GetFPLibCall(N->getValueType(0),
2121 RTLIB::SUB_F32,
2122 RTLIB::SUB_F64,
2123 RTLIB::SUB_F80,
2124 RTLIB::SUB_F128,
2125 RTLIB::SUB_PPCF128), Lo, Hi);
2126}
2127
2128void DAGTypeLegalizer::ExpandFloatRes_FTAN(SDNode *N, SDValue &Lo,
2130 ExpandFloatRes_Unary(N,
2131 GetFPLibCall(N->getValueType(0), RTLIB::TAN_F32,
2132 RTLIB::TAN_F64, RTLIB::TAN_F80,
2133 RTLIB::TAN_F128, RTLIB::TAN_PPCF128),
2135}
2136
2137void DAGTypeLegalizer::ExpandFloatRes_FTANH(SDNode *N, SDValue &Lo,
2139 ExpandFloatRes_Unary(N,
2140 GetFPLibCall(N->getValueType(0), RTLIB::TANH_F32,
2141 RTLIB::TANH_F64, RTLIB::TANH_F80,
2142 RTLIB::TANH_F128, RTLIB::TANH_PPCF128),
2144}
2145
2146void DAGTypeLegalizer::ExpandFloatRes_FTRUNC(SDNode *N,
2148 ExpandFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
2149 RTLIB::TRUNC_F32, RTLIB::TRUNC_F64,
2150 RTLIB::TRUNC_F80, RTLIB::TRUNC_F128,
2151 RTLIB::TRUNC_PPCF128), Lo, Hi);
2152}
2153
2154void DAGTypeLegalizer::ExpandFloatRes_LOAD(SDNode *N, SDValue &Lo,
2157 ExpandRes_NormalLoad(N, Lo, Hi);
2158 return;
2159 }
2160
2165 SDLoc dl(N);
2166
2167 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), LD->getValueType(0));
2169 assert(LD->getMemoryVT().bitsLE(NVT) && "Float type not round?");
2170
2171 Hi = DAG.getExtLoad(LD->getExtensionType(), dl, NVT, Chain, Ptr,
2172 LD->getMemoryVT(), LD->getMemOperand());
2173
2174
2176
2177
2179
2180
2181
2182 ReplaceValueWith(SDValue(LD, 1), Chain);
2183}
2184
2185void DAGTypeLegalizer::ExpandFloatRes_XINT_TO_FP(SDNode *N, SDValue &Lo,
2187 assert(N->getValueType(0) == MVT::ppcf128 && "Unsupported XINT_TO_FP!");
2188 EVT VT = N->getValueType(0);
2189 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
2190 bool Strict = N->isStrictFPOpcode();
2191 SDValue Src = N->getOperand(Strict ? 1 : 0);
2192 EVT SrcVT = Src.getValueType();
2195 SDLoc dl(N);
2196 SDValue Chain = Strict ? N->getOperand(0) : DAG.getEntryNode();
2197
2198
2199 SDNodeFlags Flags;
2200 Flags.setNoFPExcept(N->getFlags().hasNoFPExcept());
2201
2202
2203
2204
2205 if (SrcVT.bitsLE(MVT::i32)) {
2206
2208 if (Strict) {
2209 Hi = DAG.getNode(N->getOpcode(), dl, DAG.getVTList(NVT, MVT::Other),
2210 {Chain, Src}, Flags);
2212 } else
2213 Hi = DAG.getNode(N->getOpcode(), dl, NVT, Src);
2214 } else {
2215 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
2216 if (SrcVT.bitsLE(MVT::i64)) {
2218 MVT::i64, Src);
2219 LC = RTLIB::SINTTOFP_I64_PPCF128;
2220 } else if (SrcVT.bitsLE(MVT::i128)) {
2222 LC = RTLIB::SINTTOFP_I128_PPCF128;
2223 }
2224 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported XINT_TO_FP!");
2225
2226 TargetLowering::MakeLibCallOptions CallOptions;
2228 std::pair<SDValue, SDValue> Tmp =
2229 TLI.makeLibCall(DAG, LC, VT, Src, CallOptions, dl, Chain);
2230 if (Strict)
2231 Chain = Tmp.second;
2232 GetPairElements(Tmp.first, Lo, Hi);
2233 }
2234
2235
2237 if (Strict)
2238 ReplaceValueWith(SDValue(N, 1), Chain);
2239
2240 return;
2241 }
2242
2243
2244
2245
2246
2248 SrcVT = Src.getValueType();
2249
2250
2251 static const uint64_t TwoE32[] = { 0x41f0000000000000LL, 0 };
2252 static const uint64_t TwoE64[] = { 0x43f0000000000000LL, 0 };
2253 static const uint64_t TwoE128[] = { 0x47f0000000000000LL, 0 };
2254 ArrayRef<uint64_t> Parts;
2255
2257 default:
2259 case MVT::i32:
2260 Parts = TwoE32;
2261 break;
2262 case MVT::i64:
2263 Parts = TwoE64;
2264 break;
2265 case MVT::i128:
2266 Parts = TwoE128;
2267 break;
2268 }
2269
2270
2271 SDValue NewLo = DAG.getConstantFP(
2273 if (Strict) {
2274 Lo = DAG.getNode(ISD::STRICT_FADD, dl, DAG.getVTList(VT, MVT::Other),
2275 {Chain, Hi, NewLo}, Flags);
2277 ReplaceValueWith(SDValue(N, 1), Chain);
2278 } else
2280 Lo = DAG.getSelectCC(dl, Src, DAG.getConstant(0, dl, SrcVT),
2282 GetPairElements(Lo, Lo, Hi);
2283}
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294bool DAGTypeLegalizer::ExpandFloatOperand(SDNode *N, unsigned OpNo) {
2295 LLVM_DEBUG(dbgs() << "Expand float operand: "; N->dump(&DAG));
2297
2298
2299 if (CustomLowerNode(N, N->getOperand(OpNo).getValueType(), false))
2300 return false;
2301
2302 switch (N->getOpcode()) {
2303 default:
2304#ifndef NDEBUG
2305 dbgs() << "ExpandFloatOperand Op #" << OpNo << ": ";
2306 N->dump(&DAG); dbgs() << "\n";
2307#endif
2308 report_fatal_error("Do not know how to expand this operator's operand!");
2309
2310 case ISD::BITCAST: Res = ExpandOp_BITCAST(N); break;
2313
2314 case ISD::BR_CC: Res = ExpandFloatOp_BR_CC(N); break;
2315 case ISD::FCOPYSIGN: Res = ExpandFloatOp_FCOPYSIGN(N); break;
2317 case ISD::FP_ROUND: Res = ExpandFloatOp_FP_ROUND(N); break;
2321 case ISD::FP_TO_UINT: Res = ExpandFloatOp_FP_TO_XINT(N); break;
2322 case ISD::LROUND: Res = ExpandFloatOp_LROUND(N); break;
2323 case ISD::LLROUND: Res = ExpandFloatOp_LLROUND(N); break;
2324 case ISD::LRINT: Res = ExpandFloatOp_LRINT(N); break;
2325 case ISD::LLRINT: Res = ExpandFloatOp_LLRINT(N); break;
2326 case ISD::SELECT_CC: Res = ExpandFloatOp_SELECT_CC(N); break;
2329 case ISD::SETCC: Res = ExpandFloatOp_SETCC(N); break;
2331 OpNo); break;
2332 }
2333
2334
2335 if (!Res.getNode()) return false;
2336
2337
2338
2340 return true;
2341
2342 assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
2343 "Invalid operand expansion");
2344
2345 ReplaceValueWith(SDValue(N, 0), Res);
2346 return false;
2347}
2348
2349
2350
2351void DAGTypeLegalizer::FloatExpandSetCCOperands(SDValue &NewLHS,
2355 bool IsSignaling) {
2356 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
2357 GetExpandedFloat(NewLHS, LHSLo, LHSHi);
2358 GetExpandedFloat(NewRHS, RHSLo, RHSHi);
2359
2360 assert(NewLHS.getValueType() == MVT::ppcf128 && "Unsupported setcc type!");
2361
2362
2363
2364
2365
2366
2367 SDValue Tmp1, Tmp2, Tmp3, OutputChain;
2368 Tmp1 = DAG.getSetCC(dl, getSetCCResultType(LHSHi.getValueType()), LHSHi,
2369 RHSHi, ISD::SETOEQ, Chain, IsSignaling);
2371 Tmp2 = DAG.getSetCC(dl, getSetCCResultType(LHSLo.getValueType()), LHSLo,
2372 RHSLo, CCCode, OutputChain, IsSignaling);
2375 Tmp1 =
2376 DAG.getSetCC(dl, getSetCCResultType(LHSHi.getValueType()), LHSHi, RHSHi,
2379 Tmp2 = DAG.getSetCC(dl, getSetCCResultType(LHSHi.getValueType()), LHSHi,
2380 RHSHi, CCCode, OutputChain, IsSignaling);
2384 NewRHS = SDValue();
2385 Chain = OutputChain;
2386}
2387
2388SDValue DAGTypeLegalizer::ExpandFloatOp_BR_CC(SDNode *N) {
2392 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(N), Chain);
2393
2394
2395
2396 if (!NewRHS.getNode()) {
2397 NewRHS = DAG.getConstant(0, SDLoc(N), NewLHS.getValueType());
2399 }
2400
2401
2402 return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0),
2403 DAG.getCondCode(CCCode), NewLHS, NewRHS,
2404 N->getOperand(4)), 0);
2405}
2406
2407SDValue DAGTypeLegalizer::ExpandFloatOp_FCOPYSIGN(SDNode *N) {
2408 assert(N->getOperand(1).getValueType() == MVT::ppcf128 &&
2409 "Logic only correct for ppcf128!");
2411 GetExpandedFloat(N->getOperand(1), Lo, Hi);
2412
2413
2415 N->getValueType(0), N->getOperand(0), Hi);
2416}
2417
2418SDValue DAGTypeLegalizer::ExpandFloatOp_FP_ROUND(SDNode *N) {
2419 bool IsStrict = N->isStrictFPOpcode();
2420 assert(N->getOperand(IsStrict ? 1 : 0).getValueType() == MVT::ppcf128 &&
2421 "Logic only correct for ppcf128!");
2423 GetExpandedFloat(N->getOperand(IsStrict ? 1 : 0), Lo, Hi);
2424
2425 if (!IsStrict)
2426
2428 N->getValueType(0), Hi, N->getOperand(1));
2429
2430
2431
2432 if (Hi.getValueType() == N->getValueType(0)) {
2433
2434 ReplaceValueWith(SDValue(N, 1), N->getOperand(0));
2435 ReplaceValueWith(SDValue(N, 0), Hi);
2437 }
2438
2440 {N->getValueType(0), MVT::Other},
2441 {N->getOperand(0), Hi, N->getOperand(2)});
2445}
2446
2447SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_XINT(SDNode *N) {
2448 EVT RVT = N->getValueType(0);
2449 SDLoc dl(N);
2450
2451 bool IsStrict = N->isStrictFPOpcode();
2454 SDValue Op = N->getOperand(IsStrict ? 1 : 0);
2455 SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
2456
2457 EVT NVT;
2459 assert(LC != RTLIB::UNKNOWN_LIBCALL && NVT.isSimple() &&
2460 "Unsupported FP_TO_XINT!");
2461 TargetLowering::MakeLibCallOptions CallOptions;
2462 std::pair<SDValue, SDValue> Tmp =
2463 TLI.makeLibCall(DAG, LC, NVT, Op, CallOptions, dl, Chain);
2464 if (!IsStrict)
2465 return Tmp.first;
2466
2467 ReplaceValueWith(SDValue(N, 1), Tmp.second);
2468 ReplaceValueWith(SDValue(N, 0), Tmp.first);
2470}
2471
2472SDValue DAGTypeLegalizer::ExpandFloatOp_SELECT_CC(SDNode *N) {
2476 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(N), Chain);
2477
2478
2479
2480 if (!NewRHS.getNode()) {
2481 NewRHS = DAG.getConstant(0, SDLoc(N), NewLHS.getValueType());
2483 }
2484
2485
2486 return SDValue(DAG.UpdateNodeOperands(N, NewLHS, NewRHS,
2487 N->getOperand(2), N->getOperand(3),
2488 DAG.getCondCode(CCCode)), 0);
2489}
2490
2491SDValue DAGTypeLegalizer::ExpandFloatOp_SETCC(SDNode *N) {
2492 bool IsStrict = N->isStrictFPOpcode();
2495 SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
2498 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(N), Chain,
2500
2501
2502 assert(!NewRHS.getNode() && "Expect to return scalar");
2504 "Unexpected setcc expansion!");
2505 if (Chain) {
2506 ReplaceValueWith(SDValue(N, 0), NewLHS);
2507 ReplaceValueWith(SDValue(N, 1), Chain);
2509 }
2510 return NewLHS;
2511}
2512
2513SDValue DAGTypeLegalizer::ExpandFloatOp_STORE(SDNode *N, unsigned OpNo) {
2515 return ExpandOp_NormalStore(N, OpNo);
2516
2518 assert(OpNo == 1 && "Can only expand the stored value so far");
2520
2523
2524 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
2525 ST->getValue().getValueType());
2527 assert(ST->getMemoryVT().bitsLE(NVT) && "Float type not round?");
2528 (void)NVT;
2529
2531 GetExpandedOp(ST->getValue(), Lo, Hi);
2532
2533 return DAG.getTruncStore(Chain, SDLoc(N), Hi, Ptr,
2534 ST->getMemoryVT(), ST->getMemOperand());
2535}
2536
2537SDValue DAGTypeLegalizer::ExpandFloatOp_LROUND(SDNode *N) {
2538 EVT RVT = N->getValueType(0);
2539 EVT RetVT = N->getOperand(0).getValueType();
2540 TargetLowering::MakeLibCallOptions CallOptions;
2541 return TLI.makeLibCall(DAG, GetFPLibCall(RetVT,
2542 RTLIB::LROUND_F32,
2543 RTLIB::LROUND_F64,
2544 RTLIB::LROUND_F80,
2545 RTLIB::LROUND_F128,
2546 RTLIB::LROUND_PPCF128),
2547 RVT, N->getOperand(0), CallOptions, SDLoc(N)).first;
2548}
2549
2550SDValue DAGTypeLegalizer::ExpandFloatOp_LLROUND(SDNode *N) {
2551 EVT RVT = N->getValueType(0);
2552 EVT RetVT = N->getOperand(0).getValueType();
2553 TargetLowering::MakeLibCallOptions CallOptions;
2554 return TLI.makeLibCall(DAG, GetFPLibCall(RetVT,
2555 RTLIB::LLROUND_F32,
2556 RTLIB::LLROUND_F64,
2557 RTLIB::LLROUND_F80,
2558 RTLIB::LLROUND_F128,
2559 RTLIB::LLROUND_PPCF128),
2560 RVT, N->getOperand(0), CallOptions, SDLoc(N)).first;
2561}
2562
2563SDValue DAGTypeLegalizer::ExpandFloatOp_LRINT(SDNode *N) {
2564 EVT RVT = N->getValueType(0);
2565 EVT RetVT = N->getOperand(0).getValueType();
2566 TargetLowering::MakeLibCallOptions CallOptions;
2567 return TLI.makeLibCall(DAG, GetFPLibCall(RetVT,
2568 RTLIB::LRINT_F32,
2569 RTLIB::LRINT_F64,
2570 RTLIB::LRINT_F80,
2571 RTLIB::LRINT_F128,
2572 RTLIB::LRINT_PPCF128),
2573 RVT, N->getOperand(0), CallOptions, SDLoc(N)).first;
2574}
2575
2576SDValue DAGTypeLegalizer::ExpandFloatOp_LLRINT(SDNode *N) {
2577 EVT RVT = N->getValueType(0);
2578 EVT RetVT = N->getOperand(0).getValueType();
2579 TargetLowering::MakeLibCallOptions CallOptions;
2580 return TLI.makeLibCall(DAG, GetFPLibCall(RetVT,
2581 RTLIB::LLRINT_F32,
2582 RTLIB::LLRINT_F64,
2583 RTLIB::LLRINT_F80,
2584 RTLIB::LLRINT_F128,
2585 RTLIB::LLRINT_PPCF128),
2586 RVT, N->getOperand(0), CallOptions, SDLoc(N)).first;
2587}
2588
2589
2590
2591
2592
2593
2595 if (OpVT == MVT::f16)
2596 return ISD::FP16_TO_FP;
2597 if (RetVT == MVT::f16)
2598 return ISD::FP_TO_FP16;
2599 if (OpVT == MVT::bf16)
2600 return ISD::BF16_TO_FP;
2601 if (RetVT == MVT::bf16)
2602 return ISD::FP_TO_BF16;
2603 report_fatal_error("Attempt at an invalid promotion-related conversion");
2604}
2605
2607 if (OpVT == MVT::f16)
2608 return ISD::STRICT_FP16_TO_FP;
2609 if (RetVT == MVT::f16)
2610 return ISD::STRICT_FP_TO_FP16;
2611 if (OpVT == MVT::bf16)
2612 return ISD::STRICT_BF16_TO_FP;
2613 if (RetVT == MVT::bf16)
2614 return ISD::STRICT_FP_TO_BF16;
2615 report_fatal_error("Attempt at an invalid promotion-related conversion");
2616}
2617
2618bool DAGTypeLegalizer::PromoteFloatOperand(SDNode *N, unsigned OpNo) {
2619 LLVM_DEBUG(dbgs() << "Promote float operand " << OpNo << ": "; N->dump(&DAG));
2621
2622 if (CustomLowerNode(N, N->getOperand(OpNo).getValueType(), false)) {
2623 LLVM_DEBUG(dbgs() << "Node has been custom lowered, done\n");
2624 return false;
2625 }
2626
2627
2628
2629
2630
2631
2632
2633 switch (N->getOpcode()) {
2634 default:
2635 #ifndef NDEBUG
2636 dbgs() << "PromoteFloatOperand Op #" << OpNo << ": ";
2637 N->dump(&DAG); dbgs() << "\n";
2638 #endif
2639 report_fatal_error("Do not know how to promote this operator's operand!");
2640
2641 case ISD::BITCAST: R = PromoteFloatOp_BITCAST(N, OpNo); break;
2642 case ISD::FAKE_USE:
2643 R = PromoteFloatOp_FAKE_USE(N, OpNo);
2644 break;
2645 case ISD::FCOPYSIGN: R = PromoteFloatOp_FCOPYSIGN(N, OpNo); break;
2648 case ISD::LROUND:
2649 case ISD::LLROUND:
2650 case ISD::LRINT:
2651 case ISD::LLRINT: R = PromoteFloatOp_UnaryOp(N, OpNo); break;
2655 R = PromoteFloatOp_FP_TO_XINT_SAT(N, OpNo); break;
2656 case ISD::FP_EXTEND: R = PromoteFloatOp_FP_EXTEND(N, OpNo); break;
2658 R = PromoteFloatOp_STRICT_FP_EXTEND(N, OpNo);
2659 break;
2660 case ISD::SELECT_CC: R = PromoteFloatOp_SELECT_CC(N, OpNo); break;
2661 case ISD::SETCC: R = PromoteFloatOp_SETCC(N, OpNo); break;
2662 case ISD::STORE: R = PromoteFloatOp_STORE(N, OpNo); break;
2663 case ISD::ATOMIC_STORE: R = PromoteFloatOp_ATOMIC_STORE(N, OpNo); break;
2664 }
2665
2666
2667 if (R.getNode())
2668 ReplaceValueWith(SDValue(N, 0), R);
2669 return false;
2670}
2671
2672SDValue DAGTypeLegalizer::PromoteFloatOp_BITCAST(SDNode *N, unsigned OpNo) {
2674 EVT OpVT = Op->getValueType(0);
2675
2676 SDValue Promoted = GetPromotedFloat(N->getOperand(0));
2678
2679
2682 IVT, Promoted);
2683
2684
2685 return DAG.getBitcast(N->getValueType(0), Convert);
2686}
2687
2688SDValue DAGTypeLegalizer::PromoteFloatOp_FAKE_USE(SDNode *N, unsigned OpNo) {
2689 assert(OpNo == 1 && "Only Operand 1 must need promotion here");
2690 SDValue Op = GetPromotedFloat(N->getOperand(OpNo));
2691 return DAG.getNode(N->getOpcode(), SDLoc(N), MVT::Other, N->getOperand(0),
2692 Op);
2693}
2694
2695
2696
2697SDValue DAGTypeLegalizer::PromoteFloatOp_FCOPYSIGN(SDNode *N, unsigned OpNo) {
2698 assert (OpNo == 1 && "Only Operand 1 must need promotion here");
2699 SDValue Op1 = GetPromotedFloat(N->getOperand(1));
2700
2701 return DAG.getNode(N->getOpcode(), SDLoc(N), N->getValueType(0),
2702 N->getOperand(0), Op1);
2703}
2704
2705
2706SDValue DAGTypeLegalizer::PromoteFloatOp_UnaryOp(SDNode *N, unsigned OpNo) {
2707 SDValue Op = GetPromotedFloat(N->getOperand(0));
2708 return DAG.getNode(N->getOpcode(), SDLoc(N), N->getValueType(0), Op);
2709}
2710
2711
2712SDValue DAGTypeLegalizer::PromoteFloatOp_AssertNoFPClass(SDNode *N,
2713 unsigned OpNo) {
2714 return GetPromotedFloat(N->getOperand(0));
2715}
2716
2717SDValue DAGTypeLegalizer::PromoteFloatOp_FP_TO_XINT_SAT(SDNode *N,
2718 unsigned OpNo) {
2719 SDValue Op = GetPromotedFloat(N->getOperand(0));
2720 return DAG.getNode(N->getOpcode(), SDLoc(N), N->getValueType(0), Op,
2721 N->getOperand(1));
2722}
2723
2724SDValue DAGTypeLegalizer::PromoteFloatOp_FP_EXTEND(SDNode *N, unsigned OpNo) {
2725 SDValue Op = GetPromotedFloat(N->getOperand(0));
2726 EVT VT = N->getValueType(0);
2727
2728
2729 if (VT == Op->getValueType(0))
2730 return Op;
2731
2732
2733 return DAG.getNode(ISD::FP_EXTEND, SDLoc(N), VT, Op);
2734}
2735
2736SDValue DAGTypeLegalizer::PromoteFloatOp_STRICT_FP_EXTEND(SDNode *N,
2737 unsigned OpNo) {
2738 assert(OpNo == 1 && "Promoting unpromotable operand");
2739
2740 SDValue Op = GetPromotedFloat(N->getOperand(1));
2741 EVT VT = N->getValueType(0);
2742
2743
2744 if (VT == Op->getValueType(0)) {
2745 ReplaceValueWith(SDValue(N, 1), N->getOperand(0));
2746 return Op;
2747 }
2748
2749
2753 return Res;
2754}
2755
2756
2757
2758
2759SDValue DAGTypeLegalizer::PromoteFloatOp_SELECT_CC(SDNode *N, unsigned OpNo) {
2760 SDValue LHS = GetPromotedFloat(N->getOperand(0));
2761 SDValue RHS = GetPromotedFloat(N->getOperand(1));
2762
2763 return DAG.getNode(ISD::SELECT_CC, SDLoc(N), N->getValueType(0),
2764 LHS, RHS, N->getOperand(2), N->getOperand(3),
2765 N->getOperand(4));
2766}
2767
2768
2769
2770SDValue DAGTypeLegalizer::PromoteFloatOp_SETCC(SDNode *N, unsigned OpNo) {
2771 EVT VT = N->getValueType(0);
2772 SDValue Op0 = GetPromotedFloat(N->getOperand(0));
2773 SDValue Op1 = GetPromotedFloat(N->getOperand(1));
2775
2776 return DAG.getSetCC(SDLoc(N), VT, Op0, Op1, CCCode);
2777
2778}
2779
2780
2781
2782SDValue DAGTypeLegalizer::PromoteFloatOp_STORE(SDNode *N, unsigned OpNo) {
2786
2787 SDValue Promoted = GetPromotedFloat(Val);
2788 EVT VT = ST->getOperand(1).getValueType();
2790
2793 IVT, Promoted);
2794
2795 return DAG.getStore(ST->getChain(), DL, NewVal, ST->getBasePtr(),
2796 ST->getMemOperand());
2797}
2798
2799SDValue DAGTypeLegalizer::PromoteFloatOp_ATOMIC_STORE(SDNode *N,
2800 unsigned OpNo) {
2804
2805 SDValue Promoted = GetPromotedFloat(Val);
2806 EVT VT = ST->getOperand(1).getValueType();
2808
2810 DL, IVT, Promoted);
2811
2812 return DAG.getAtomic(ISD::ATOMIC_STORE, DL, IVT, ST->getChain(), NewVal,
2813 ST->getBasePtr(), ST->getMemOperand());
2814}
2815
2816
2817
2818
2819
2820void DAGTypeLegalizer::PromoteFloatResult(SDNode *N, unsigned ResNo) {
2821 LLVM_DEBUG(dbgs() << "Promote float result " << ResNo << ": "; N->dump(&DAG));
2823
2824
2825 if (CustomLowerNode(N, N->getValueType(ResNo), true)) {
2826 LLVM_DEBUG(dbgs() << "Node has been custom expanded, done\n");
2827 return;
2828 }
2829
2830 switch (N->getOpcode()) {
2831
2832
2833 case ISD::FP16_TO_FP:
2834 case ISD::FP_TO_FP16:
2835 default:
2836#ifndef NDEBUG
2837 dbgs() << "PromoteFloatResult #" << ResNo << ": ";
2838 N->dump(&DAG); dbgs() << "\n";
2839#endif
2840 report_fatal_error("Do not know how to promote this operator's result!");
2841
2842 case ISD::BITCAST:
2843 R = PromoteFloatRes_BITCAST(N);
2844 break;
2846 R = PromoteFloatRes_FREEZE(N);
2847 break;
2850 R = PromoteFloatRes_EXTRACT_VECTOR_ELT(N); break;
2851 case ISD::FCOPYSIGN: R = PromoteFloatRes_FCOPYSIGN(N); break;
2852
2853
2854 case ISD::FABS:
2855 case ISD::FACOS:
2856 case ISD::FASIN:
2857 case ISD::FATAN:
2858 case ISD::FCBRT:
2859 case ISD::FCEIL:
2860 case ISD::FCOS:
2861 case ISD::FCOSH:
2862 case ISD::FEXP:
2863 case ISD::FEXP2:
2864 case ISD::FEXP10:
2865 case ISD::FFLOOR:
2866 case ISD::FLOG:
2867 case ISD::FLOG2:
2868 case ISD::FLOG10:
2869 case ISD::FNEARBYINT:
2870 case ISD::FNEG:
2871 case ISD::FRINT:
2872 case ISD::FROUND:
2873 case ISD::FROUNDEVEN:
2874 case ISD::FSIN:
2875 case ISD::FSINH:
2876 case ISD::FSQRT:
2877 case ISD::FTRUNC:
2878 case ISD::FTAN:
2879 case ISD::FTANH:
2882 R = PromoteFloatRes_AssertNoFPClass(N);
2883 break;
2884
2885
2888 case ISD::FMAXIMUM:
2889 case ISD::FMINIMUM:
2890 case ISD::FMAXIMUMNUM:
2891 case ISD::FMINIMUMNUM:
2892 case ISD::FMAXNUM:
2893 case ISD::FMINNUM:
2894 case ISD::FMAXNUM_IEEE:
2895 case ISD::FMINNUM_IEEE:
2897 case ISD::FPOW:
2898 case ISD::FATAN2:
2900 case ISD::FSUB: R = PromoteFloatRes_BinOp(N); break;
2901
2902 case ISD::FMA:
2903 case ISD::FMAD: R = PromoteFloatRes_FMAD(N); break;
2904
2905 case ISD::FPOWI:
2906 case ISD::FLDEXP: R = PromoteFloatRes_ExpOp(N); break;
2907 case ISD::FFREXP: R = PromoteFloatRes_FFREXP(N); break;
2908
2909 case ISD::FMODF:
2910 case ISD::FSINCOS:
2911 case ISD::FSINCOSPI:
2912 R = PromoteFloatRes_UnaryWithTwoFPResults(N);
2913 break;
2914 case ISD::FP_ROUND: R = PromoteFloatRes_FP_ROUND(N); break;
2916 R = PromoteFloatRes_STRICT_FP_ROUND(N);
2917 break;
2918 case ISD::LOAD: R = PromoteFloatRes_LOAD(N); break;
2919 case ISD::ATOMIC_LOAD:
2920 R = PromoteFloatRes_ATOMIC_LOAD(N);
2921 break;
2922 case ISD::SELECT: R = PromoteFloatRes_SELECT(N); break;
2923 case ISD::SELECT_CC: R = PromoteFloatRes_SELECT_CC(N); break;
2924
2928 case ISD::UNDEF: R = PromoteFloatRes_UNDEF(N); break;
2929 case ISD::ATOMIC_SWAP: R = BitcastToInt_ATOMIC_SWAP(N); break;
2930 case ISD::VECREDUCE_FADD:
2931 case ISD::VECREDUCE_FMUL:
2932 case ISD::VECREDUCE_FMIN:
2933 case ISD::VECREDUCE_FMAX:
2934 case ISD::VECREDUCE_FMAXIMUM:
2935 case ISD::VECREDUCE_FMINIMUM:
2936 R = PromoteFloatRes_VECREDUCE(N);
2937 break;
2938 case ISD::VECREDUCE_SEQ_FADD:
2939 case ISD::VECREDUCE_SEQ_FMUL:
2940 R = PromoteFloatRes_VECREDUCE_SEQ(N);
2941 break;
2942 }
2943
2944 if (R.getNode())
2945 SetPromotedFloat(SDValue(N, ResNo), R);
2946}
2947
2948
2949
2950
2951
2952
2953SDValue DAGTypeLegalizer::PromoteFloatRes_BITCAST(SDNode *N) {
2954 EVT VT = N->getValueType(0);
2955 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
2956
2957
2959 N->getOperand(0).getValueType().getSizeInBits());
2960 SDValue Cast = DAG.getBitcast(IVT, N->getOperand(0));
2962}
2963
2964SDValue DAGTypeLegalizer::PromoteFloatRes_FREEZE(SDNode *N) {
2965 EVT VT = N->getValueType(0);
2966 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
2967
2968
2970 N->getOperand(0).getValueType().getSizeInBits());
2971 SDValue Cast = DAG.getBitcast(IVT, N->getOperand(0));
2973 DAG.getFreeze(Cast));
2974}
2975
2976SDValue DAGTypeLegalizer::PromoteFloatRes_ConstantFP(SDNode *N) {
2978 EVT VT = N->getValueType(0);
2980
2981
2984 IVT);
2985
2986
2987
2988
2989 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
2991}
2992
2993
2994
2995
2996
2997SDValue DAGTypeLegalizer::PromoteFloatRes_EXTRACT_VECTOR_ELT(SDNode *N) {
2999
3000
3001
3003 SDValue Vec = N->getOperand(0);
3004 SDValue Idx = N->getOperand(1);
3007
3009
3010 switch (getTypeAction(VecVT)) {
3011 default: break;
3013 SDValue Res = GetScalarizedVector(N->getOperand(0));
3014 ReplaceValueWith(SDValue(N, 0), Res);
3016 }
3018 Vec = GetWidenedVector(Vec);
3020 ReplaceValueWith(SDValue(N, 0), Res);
3022 }
3025 GetSplitVector(Vec, Lo, Hi);
3026
3027 uint64_t LoElts = Lo.getValueType().getVectorNumElements();
3029 if (IdxVal < LoElts)
3030 Res = DAG.getNode(N->getOpcode(), DL, EltVT, Lo, Idx);
3031 else
3032 Res = DAG.getNode(N->getOpcode(), DL, EltVT, Hi,
3033 DAG.getConstant(IdxVal - LoElts, DL,
3035 ReplaceValueWith(SDValue(N, 0), Res);
3037 }
3038
3039 }
3040 }
3041
3042
3043 SDValue NewOp = BitConvertVectorToIntegerVector(N->getOperand(0));
3045
3046
3048 NewOp, N->getOperand(1));
3049
3050
3051 EVT VT = N->getValueType(0);
3052 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
3054}
3055
3056
3057
3058
3059SDValue DAGTypeLegalizer::PromoteFloatRes_FCOPYSIGN(SDNode *N) {
3060 EVT VT = N->getValueType(0);
3061 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
3062 SDValue Op0 = GetPromotedFloat(N->getOperand(0));
3063
3065
3066 return DAG.getNode(N->getOpcode(), SDLoc(N), NVT, Op0, Op1);
3067}
3068
3069
3070
3071
3072SDValue DAGTypeLegalizer::PromoteFloatRes_UnaryOp(SDNode *N) {
3073 EVT VT = N->getValueType(0);
3074 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
3075 SDValue Op = GetPromotedFloat(N->getOperand(0));
3076 return DAG.getNode(N->getOpcode(), SDLoc(N), NVT, Op);
3077}
3078
3079
3080
3081
3082SDValue DAGTypeLegalizer::PromoteFloatRes_AssertNoFPClass(SDNode *N) {
3083 return GetPromotedFloat(N->getOperand(0));
3084}
3085
3086
3087
3088
3089SDValue DAGTypeLegalizer::PromoteFloatRes_BinOp(SDNode *N) {
3090 EVT VT = N->getValueType(0);
3091 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
3092 SDValue Op0 = GetPromotedFloat(N->getOperand(0));
3093 SDValue Op1 = GetPromotedFloat(N->getOperand(1));
3094 return DAG.getNode(N->getOpcode(), SDLoc(N), NVT, Op0, Op1, N->getFlags());
3095}
3096
3097SDValue DAGTypeLegalizer::PromoteFloatRes_FMAD(SDNode *N) {
3098 EVT VT = N->getValueType(0);
3099 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
3100 SDValue Op0 = GetPromotedFloat(N->getOperand(0));
3101 SDValue Op1 = GetPromotedFloat(N->getOperand(1));
3102 SDValue Op2 = GetPromotedFloat(N->getOperand(2));
3103
3104 return DAG.getNode(N->getOpcode(), SDLoc(N), NVT, Op0, Op1, Op2);
3105}
3106
3107
3108SDValue DAGTypeLegalizer::PromoteFloatRes_ExpOp(SDNode *N) {
3109 EVT VT = N->getValueType(0);
3110 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
3111 SDValue Op0 = GetPromotedFloat(N->getOperand(0));
3113
3114 return DAG.getNode(N->getOpcode(), SDLoc(N), NVT, Op0, Op1);
3115}
3116
3117SDValue DAGTypeLegalizer::PromoteFloatRes_FFREXP(SDNode *N) {
3118 EVT VT = N->getValueType(0);
3119 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
3120 SDValue Op = GetPromotedFloat(N->getOperand(0));
3122 DAG.getNode(N->getOpcode(), SDLoc(N), {NVT, N->getValueType(1)}, Op);
3123
3125 return Res;
3126}
3127
3128SDValue DAGTypeLegalizer::PromoteFloatRes_UnaryWithTwoFPResults(SDNode *N) {
3129 EVT VT = N->getValueType(0);
3130 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
3131 SDValue Op = GetPromotedFloat(N->getOperand(0));
3132 SDValue Res = DAG.getNode(N->getOpcode(), SDLoc(N), {NVT, NVT}, Op);
3133
3134 for (unsigned ResNum = 0, NumValues = N->getNumValues(); ResNum < NumValues;
3135 ++ResNum) {
3137 }
3138
3140}
3141
3142
3143
3144SDValue DAGTypeLegalizer::PromoteFloatRes_FP_ROUND(SDNode *N) {
3146
3148 EVT VT = N->getValueType(0);
3149 EVT OpVT = Op->getValueType(0);
3150 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
3152
3153
3155
3157}
3158
3159
3160
3161SDValue DAGTypeLegalizer::PromoteFloatRes_STRICT_FP_ROUND(SDNode *N) {
3163
3166 EVT VT = N->getValueType(0);
3167 EVT OpVT = Op->getValueType(0);
3168 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
3170
3171
3173 DAG.getVTList(IVT, MVT::Other), Chain, Op);
3174
3177 DAG.getVTList(NVT, MVT::Other), Round.getValue(1), Round);
3179 return Res;
3180}
3181
3182SDValue DAGTypeLegalizer::PromoteFloatRes_LOAD(SDNode *N) {
3184 EVT VT = N->getValueType(0);
3185
3186
3188 SDValue newL = DAG.getLoad(
3189 L->getAddressingMode(), L->getExtensionType(), IVT, SDLoc(N),
3190 L->getChain(), L->getBasePtr(), L->getOffset(), L->getPointerInfo(), IVT,
3191 L->getBaseAlign(), L->getMemOperand()->getFlags(), L->getAAInfo());
3192
3193
3195
3196
3197 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
3199}
3200
3201SDValue DAGTypeLegalizer::PromoteFloatRes_ATOMIC_LOAD(SDNode *N) {
3204
3205
3207 SDValue newL = DAG.getAtomic(
3208 ISD::ATOMIC_LOAD, SDLoc(N), IVT, DAG.getVTList(IVT, MVT::Other),
3209 {AM->getChain(), AM->getBasePtr()}, AM->getMemOperand());
3210
3211
3212
3214
3215
3216 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
3218}
3219
3220
3221SDValue DAGTypeLegalizer::PromoteFloatRes_SELECT(SDNode *N) {
3224
3226 N->getOperand(0), TrueVal, FalseVal);
3227}
3228
3229
3230
3231SDValue DAGTypeLegalizer::PromoteFloatRes_SELECT_CC(SDNode *N) {
3234
3236 TrueVal.getNode()->getValueType(0), N->getOperand(0),
3237 N->getOperand(1), TrueVal, FalseVal, N->getOperand(4));
3238}
3239
3240
3241
3242SDValue DAGTypeLegalizer::PromoteFloatRes_XINT_TO_FP(SDNode *N) {
3244 EVT VT = N->getValueType(0);
3245 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
3246 SDValue NV = DAG.getNode(N->getOpcode(), DL, NVT, N->getOperand(0));
3247
3248 return DAG.getNode(
3249 ISD::FP_EXTEND, DL, NVT,
3251 DAG.getIntPtrConstant(0, DL, true)));
3252}
3253
3254SDValue DAGTypeLegalizer::PromoteFloatRes_UNDEF(SDNode *N) {
3255 return DAG.getUNDEF(TLI.getTypeToTransformTo(*DAG.getContext(),
3256 N->getValueType(0)));
3257}
3258
3259SDValue DAGTypeLegalizer::PromoteFloatRes_VECREDUCE(SDNode *N) {
3260
3261
3262
3263
3264 ReplaceValueWith(SDValue(N, 0), TLI.expandVecReduce(N, DAG));
3266}
3267
3268SDValue DAGTypeLegalizer::PromoteFloatRes_VECREDUCE_SEQ(SDNode *N) {
3269 ReplaceValueWith(SDValue(N, 0), TLI.expandVecReduceSeq(N, DAG));
3271}
3272
3273SDValue DAGTypeLegalizer::BitcastToInt_ATOMIC_SWAP(SDNode *N) {
3274 EVT VT = N->getValueType(0);
3275
3277 SDLoc SL(N);
3278
3279 SDValue CastVal = BitConvertToInteger(AM->getVal());
3281
3283 = DAG.getAtomic(ISD::ATOMIC_SWAP, SL, CastVT,
3284 DAG.getVTList(CastVT, MVT::Other),
3285 { AM->getChain(), AM->getBasePtr(), CastVal },
3287
3289
3291 EVT NFPVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
3293 NewAtomic);
3294 }
3295
3296
3297
3299
3301
3302}
3303
3304
3305
3306
3307
3308void DAGTypeLegalizer::SoftPromoteHalfResult(SDNode *N, unsigned ResNo) {
3309 LLVM_DEBUG(dbgs() << "Soft promote half result " << ResNo << ": ";
3310 N->dump(&DAG));
3312
3313
3314 if (CustomLowerNode(N, N->getValueType(ResNo), true)) {
3315 LLVM_DEBUG(dbgs() << "Node has been custom expanded, done\n");
3316 return;
3317 }
3318
3319 switch (N->getOpcode()) {
3320 default:
3321#ifndef NDEBUG
3322 dbgs() << "SoftPromoteHalfResult #" << ResNo << ": ";
3323 N->dump(&DAG); dbgs() << "\n";
3324#endif
3325 report_fatal_error("Do not know how to soft promote this operator's "
3326 "result!");
3327
3328 case ISD::ARITH_FENCE:
3329 R = SoftPromoteHalfRes_ARITH_FENCE(N); break;
3330 case ISD::BITCAST: R = SoftPromoteHalfRes_BITCAST(N); break;
3331 case ISD::ConstantFP: R = SoftPromoteHalfRes_ConstantFP(N); break;
3333 R = SoftPromoteHalfRes_EXTRACT_VECTOR_ELT(N); break;
3334 case ISD::FCOPYSIGN: R = SoftPromoteHalfRes_FCOPYSIGN(N); break;
3336 case ISD::FP_ROUND: R = SoftPromoteHalfRes_FP_ROUND(N); break;
3337
3338
3339 case ISD::FACOS:
3340 case ISD::FASIN:
3341 case ISD::FATAN:
3342 case ISD::FCBRT:
3343 case ISD::FCEIL:
3344 case ISD::FCOS:
3345 case ISD::FCOSH:
3346 case ISD::FEXP:
3347 case ISD::FEXP2:
3348 case ISD::FEXP10:
3349 case ISD::FFLOOR:
3350 case ISD::FLOG:
3351 case ISD::FLOG2:
3352 case ISD::FLOG10:
3353 case ISD::FNEARBYINT:
3355 case ISD::FRINT:
3356 case ISD::FROUND:
3357 case ISD::FROUNDEVEN:
3358 case ISD::FSIN:
3359 case ISD::FSINH:
3360 case ISD::FSQRT:
3361 case ISD::FTRUNC:
3362 case ISD::FTAN:
3363 case ISD::FTANH:
3365 case ISD::FABS:
3366 R = SoftPromoteHalfRes_FABS(N);
3367 break;
3368 case ISD::FNEG:
3369 R = SoftPromoteHalfRes_FNEG(N);
3370 break;
3372 R = SoftPromoteHalfRes_AssertNoFPClass(N);
3373 break;
3374
3375
3378 case ISD::FMAXIMUM:
3379 case ISD::FMINIMUM:
3380 case ISD::FMAXIMUMNUM:
3381 case ISD::FMINIMUMNUM:
3382 case ISD::FMAXNUM:
3383 case ISD::FMINNUM:
3385 case ISD::FPOW:
3386 case ISD::FATAN2:
3388 case ISD::FSUB: R = SoftPromoteHalfRes_BinOp(N); break;
3389
3390 case ISD::FMA:
3391 case ISD::FMAD: R = SoftPromoteHalfRes_FMAD(N); break;
3392
3393 case ISD::FPOWI:
3394 case ISD::FLDEXP: R = SoftPromoteHalfRes_ExpOp(N); break;
3395
3396 case ISD::FFREXP: R = SoftPromoteHalfRes_FFREXP(N); break;
3397
3398 case ISD::FMODF:
3399 case ISD::FSINCOS:
3400 case ISD::FSINCOSPI:
3401 R = SoftPromoteHalfRes_UnaryWithTwoFPResults(N);
3402 break;
3403
3404 case ISD::LOAD: R = SoftPromoteHalfRes_LOAD(N); break;
3405 case ISD::ATOMIC_LOAD:
3406 R = SoftPromoteHalfRes_ATOMIC_LOAD(N);
3407 break;
3408 case ISD::SELECT: R = SoftPromoteHalfRes_SELECT(N); break;
3409 case ISD::SELECT_CC: R = SoftPromoteHalfRes_SELECT_CC(N); break;
3413 case ISD::UINT_TO_FP: R = SoftPromoteHalfRes_XINT_TO_FP(N); break;
3415 case ISD::UNDEF: R = SoftPromoteHalfRes_UNDEF(N); break;
3416 case ISD::ATOMIC_SWAP: R = BitcastToInt_ATOMIC_SWAP(N); break;
3417 case ISD::VECREDUCE_FADD:
3418 case ISD::VECREDUCE_FMUL:
3419 case ISD::VECREDUCE_FMIN:
3420 case ISD::VECREDUCE_FMAX:
3421 case ISD::VECREDUCE_FMAXIMUM:
3422 case ISD::VECREDUCE_FMINIMUM:
3423 R = SoftPromoteHalfRes_VECREDUCE(N);
3424 break;
3425 case ISD::VECREDUCE_SEQ_FADD:
3426 case ISD::VECREDUCE_SEQ_FMUL:
3427 R = SoftPromoteHalfRes_VECREDUCE_SEQ(N);
3428 break;
3429 }
3430
3431 if (R.getNode())
3432 SetSoftPromotedHalf(SDValue(N, ResNo), R);
3433}
3434
3435SDValue DAGTypeLegalizer::SoftPromoteHalfRes_ARITH_FENCE(SDNode *N) {
3436 return DAG.getNode(ISD::ARITH_FENCE, SDLoc(N), MVT::i16,
3437 BitConvertToInteger(N->getOperand(0)));
3438}
3439
3440SDValue DAGTypeLegalizer::SoftPromoteHalfRes_BITCAST(SDNode *N) {
3441 return BitConvertToInteger(N->getOperand(0));
3442}
3443
3444SDValue DAGTypeLegalizer::SoftPromoteHalfRes_ConstantFP(SDNode *N) {
3446
3447
3449 MVT::i16);
3450}
3451
3452SDValue DAGTypeLegalizer::SoftPromoteHalfRes_EXTRACT_VECTOR_ELT(SDNode *N) {
3453 SDValue NewOp = BitConvertVectorToIntegerVector(N->getOperand(0));
3456 N->getOperand(1));
3457}
3458
3459SDValue DAGTypeLegalizer::SoftPromoteHalfRes_FCOPYSIGN(SDNode *N) {
3460 SDValue LHS = GetSoftPromotedHalf(N->getOperand(0));
3461 SDValue RHS = BitConvertToInteger(N->getOperand(1));
3462 SDLoc dl(N);
3463
3464 EVT LVT = LHS.getValueType();
3465 EVT RVT = RHS.getValueType();
3466
3469
3470
3472 ISD::SHL, dl, RVT, DAG.getConstant(1, dl, RVT),
3473 DAG.getConstant(RSize - 1, dl,
3474 TLI.getShiftAmountTy(RVT, DAG.getDataLayout())));
3476
3477
3479 if (SizeDiff > 0) {
3480 SignBit =
3482 DAG.getConstant(SizeDiff, dl,
3483 TLI.getShiftAmountTy(SignBit.getValueType(),
3484 DAG.getDataLayout())));
3486 } else if (SizeDiff < 0) {
3488 SignBit =
3490 DAG.getConstant(-SizeDiff, dl,
3491 TLI.getShiftAmountTy(SignBit.getValueType(),
3492 DAG.getDataLayout())));
3493 }
3494
3495
3497 ISD::SHL, dl, LVT, DAG.getConstant(1, dl, LVT),
3498 DAG.getConstant(LSize - 1, dl,
3499 TLI.getShiftAmountTy(LVT, DAG.getDataLayout())));
3500 Mask = DAG.getNode(ISD::SUB, dl, LVT, Mask, DAG.getConstant(1, dl, LVT));
3502
3503
3504 return DAG.getNode(ISD::OR, dl, LVT, LHS, SignBit);
3505}
3506
3507SDValue DAGTypeLegalizer::SoftPromoteHalfRes_FMAD(SDNode *N) {
3509 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
3510 SDValue Op0 = GetSoftPromotedHalf(N->getOperand(0));
3511 SDValue Op1 = GetSoftPromotedHalf(N->getOperand(1));
3512 SDValue Op2 = GetSoftPromotedHalf(N->getOperand(2));
3513 SDLoc dl(N);
3514
3515
3517 Op0 = DAG.getNode(PromotionOpcode, dl, NVT, Op0);
3518 Op1 = DAG.getNode(PromotionOpcode, dl, NVT, Op1);
3519 Op2 = DAG.getNode(PromotionOpcode, dl, NVT, Op2);
3520
3521 SDValue Res = DAG.getNode(N->getOpcode(), dl, NVT, Op0, Op1, Op2);
3522
3523
3524 return DAG.getNode(GetPromotionOpcode(NVT, OVT), dl, MVT::i16, Res);
3525}
3526
3527SDValue DAGTypeLegalizer::SoftPromoteHalfRes_ExpOp(SDNode *N) {
3528 EVT OVT = N->getValueType(0);
3529 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
3530 SDValue Op0 = GetSoftPromotedHalf(N->getOperand(0));
3532 SDLoc dl(N);
3533
3534
3536
3537 SDValue Res = DAG.getNode(N->getOpcode(), dl, NVT, Op0, Op1);
3538
3539
3540 return DAG.getNode(GetPromotionOpcode(NVT, OVT), dl, MVT::i16, Res);
3541}
3542
3543SDValue DAGTypeLegalizer::SoftPromoteHalfRes_FFREXP(SDNode *N) {
3544 EVT OVT = N->getValueType(0);
3545 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
3546 SDValue Op = GetSoftPromotedHalf(N->getOperand(0));
3547 SDLoc dl(N);
3548
3549
3551
3553 DAG.getVTList(NVT, N->getValueType(1)), Op);
3554
3556
3557
3558 return DAG.getNode(GetPromotionOpcode(NVT, OVT), dl, MVT::i16, Res);
3559}
3560
3561SDValue DAGTypeLegalizer::SoftPromoteHalfRes_UnaryWithTwoFPResults(SDNode *N) {
3562 EVT OVT = N->getValueType(0);
3563 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
3564 SDValue Op = GetSoftPromotedHalf(N->getOperand(0));
3565 SDLoc dl(N);
3566
3567
3569 SDValue Res = DAG.getNode(N->getOpcode(), dl, DAG.getVTList(NVT, NVT), Op);
3570
3571
3573 for (unsigned ResNum = 0, NumValues = N->getNumValues(); ResNum < NumValues;
3574 ++ResNum) {
3575 SDValue Trunc = DAG.getNode(Truncate, dl, MVT::i16, Res.getValue(ResNum));
3576 SetSoftPromotedHalf(SDValue(N, ResNum), Trunc);
3577 }
3578
3580}
3581
3582SDValue DAGTypeLegalizer::SoftPromoteHalfRes_FP_ROUND(SDNode *N) {
3583 EVT RVT = N->getValueType(0);
3584 bool IsStrict = N->isStrictFPOpcode();
3585 SDValue Op = N->getOperand(IsStrict ? 1 : 0);
3586 EVT SVT = Op.getValueType();
3587
3588
3589
3592 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_ROUND libcall");
3593
3594 SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
3595 Op = GetSoftenedFloat(Op);
3596 TargetLowering::MakeLibCallOptions CallOptions;
3598 std::pair<SDValue, SDValue> Tmp =
3599 TLI.makeLibCall(DAG, LC, RVT, Op, CallOptions, SDLoc(N), Chain);
3600 if (IsStrict)
3601 ReplaceValueWith(SDValue(N, 1), Tmp.second);
3602 return DAG.getNode(ISD::BITCAST, SDLoc(N), MVT::i16, Tmp.first);
3603 }
3604
3605 if (IsStrict) {
3607 {MVT::i16, MVT::Other}, {N->getOperand(0), Op});
3609 return Res;
3610 }
3611
3613 N->getOperand(0));
3614}
3615
3616SDValue DAGTypeLegalizer::SoftPromoteHalfRes_LOAD(SDNode *N) {
3618
3619
3622 DAG.getLoad(L->getAddressingMode(), L->getExtensionType(), MVT::i16,
3623 SDLoc(N), L->getChain(), L->getBasePtr(), L->getOffset(),
3624 L->getPointerInfo(), MVT::i16, L->getBaseAlign(),
3625 L->getMemOperand()->getFlags(), L->getAAInfo());
3626
3627
3629 return NewL;
3630}
3631
3632SDValue DAGTypeLegalizer::SoftPromoteHalfRes_ATOMIC_LOAD(SDNode *N) {
3634
3635
3636 SDValue NewL = DAG.getAtomic(
3637 ISD::ATOMIC_LOAD, SDLoc(N), MVT::i16, DAG.getVTList(MVT::i16, MVT::Other),
3638 {AM->getChain(), AM->getBasePtr()}, AM->getMemOperand());
3639
3640
3641
3643 return NewL;
3644}
3645
3646SDValue DAGTypeLegalizer::SoftPromoteHalfRes_SELECT(SDNode *N) {
3647 SDValue Op1 = GetSoftPromotedHalf(N->getOperand(1));
3648 SDValue Op2 = GetSoftPromotedHalf(N->getOperand(2));
3649 return DAG.getSelect(SDLoc(N), Op1.getValueType(), N->getOperand(0), Op1,
3650 Op2);
3651}
3652
3653SDValue DAGTypeLegalizer::SoftPromoteHalfRes_SELECT_CC(SDNode *N) {
3654 SDValue Op2 = GetSoftPromotedHalf(N->getOperand(2));
3655 SDValue Op3 = GetSoftPromotedHalf(N->getOperand(3));
3657 N->getOperand(0), N->getOperand(1), Op2, Op3,
3658 N->getOperand(4));
3659}
3660
3661SDValue DAGTypeLegalizer::SoftPromoteHalfRes_XINT_TO_FP(SDNode *N) {
3662 EVT OVT = N->getValueType(0);
3663 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
3664 SDLoc dl(N);
3665
3666 if (N->isStrictFPOpcode()) {
3667 SDValue Op = DAG.getNode(N->getOpcode(), dl, {NVT, MVT::Other},
3668 {N->getOperand(0), N->getOperand(1)});
3670 {MVT::i16, MVT::Other}, {Op.getValue(1), Op});
3671 ReplaceValueWith(SDValue(N, 1), Op.getValue(1));
3672 return Op;
3673 }
3674
3675 SDValue Res = DAG.getNode(N->getOpcode(), dl, NVT, N->getOperand(0));
3676
3677
3678 return DAG.getNode(GetPromotionOpcode(NVT, OVT), dl, MVT::i16, Res);
3679}
3680
3681SDValue DAGTypeLegalizer::SoftPromoteHalfRes_UNDEF(SDNode *N) {
3682 return DAG.getUNDEF(MVT::i16);
3683}
3684
3685SDValue DAGTypeLegalizer::SoftPromoteHalfRes_UnaryOp(SDNode *N) {
3686 EVT OVT = N->getValueType(0);
3687 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
3688 SDValue Op = GetSoftPromotedHalf(N->getOperand(0));
3689 SDLoc dl(N);
3690
3691
3693
3695
3696
3697 return DAG.getNode(GetPromotionOpcode(NVT, OVT), dl, MVT::i16, Res);
3698}
3699
3700SDValue DAGTypeLegalizer::SoftPromoteHalfRes_FABS(SDNode *N) {
3701 SDValue Op = GetSoftPromotedHalf(N->getOperand(0));
3702 SDLoc dl(N);
3703
3704
3705 return DAG.getNode(ISD::AND, dl, MVT::i16, Op,
3706 DAG.getConstant(0x7fff, dl, MVT::i16));
3707}
3708
3709SDValue DAGTypeLegalizer::SoftPromoteHalfRes_FNEG(SDNode *N) {
3710 SDValue Op = GetSoftPromotedHalf(N->getOperand(0));
3711 SDLoc dl(N);
3712
3713
3714 return DAG.getNode(ISD::XOR, dl, MVT::i16, Op,
3715 DAG.getConstant(0x8000, dl, MVT::i16));
3716}
3717
3718SDValue DAGTypeLegalizer::SoftPromoteHalfRes_AssertNoFPClass(SDNode *N) {
3719 return GetSoftPromotedHalf(N->getOperand(0));
3720}
3721
3722SDValue DAGTypeLegalizer::SoftPromoteHalfRes_BinOp(SDNode *N) {
3723 EVT OVT = N->getValueType(0);
3724 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
3725 SDValue Op0 = GetSoftPromotedHalf(N->getOperand(0));
3726 SDValue Op1 = GetSoftPromotedHalf(N->getOperand(1));
3727 SDLoc dl(N);
3728
3729
3731 Op0 = DAG.getNode(PromotionOpcode, dl, NVT, Op0);
3732 Op1 = DAG.getNode(PromotionOpcode, dl, NVT, Op1);
3733
3734 SDValue Res = DAG.getNode(N->getOpcode(), dl, NVT, Op0, Op1);
3735
3736
3737 return DAG.getNode(GetPromotionOpcode(NVT, OVT), dl, MVT::i16, Res);
3738}
3739
3740SDValue DAGTypeLegalizer::SoftPromoteHalfRes_VECREDUCE(SDNode *N) {
3741
3742 ReplaceValueWith(SDValue(N, 0), TLI.expandVecReduce(N, DAG));
3744}
3745
3746SDValue DAGTypeLegalizer::SoftPromoteHalfRes_VECREDUCE_SEQ(SDNode *N) {
3747
3748 ReplaceValueWith(SDValue(N, 0), TLI.expandVecReduceSeq(N, DAG));
3750}
3751
3752
3753
3754
3755
3756bool DAGTypeLegalizer::SoftPromoteHalfOperand(SDNode *N, unsigned OpNo) {
3757 LLVM_DEBUG(dbgs() << "Soft promote half operand " << OpNo << ": ";
3758 N->dump(&DAG));
3760
3761 if (CustomLowerNode(N, N->getOperand(OpNo).getValueType(), false)) {
3762 LLVM_DEBUG(dbgs() << "Node has been custom lowered, done\n");
3763 return false;
3764 }
3765
3766
3767
3768
3769
3770
3771 switch (N->getOpcode()) {
3772 default:
3773 #ifndef NDEBUG
3774 dbgs() << "SoftPromoteHalfOperand Op #" << OpNo << ": ";
3775 N->dump(&DAG); dbgs() << "\n";
3776 #endif
3777 report_fatal_error("Do not know how to soft promote this operator's "
3778 "operand!");
3779
3780 case ISD::BITCAST: Res = SoftPromoteHalfOp_BITCAST(N); break;
3781 case ISD::FAKE_USE:
3782 Res = SoftPromoteHalfOp_FAKE_USE(N, OpNo);
3783 break;
3784 case ISD::FCOPYSIGN: Res = SoftPromoteHalfOp_FCOPYSIGN(N, OpNo); break;
3789 case ISD::LRINT:
3790 case ISD::LLRINT:
3791 case ISD::LROUND:
3792 case ISD::LLROUND:
3793 Res = SoftPromoteHalfOp_Op0WithStrict(N);
3794 break;
3797 Res = SoftPromoteHalfOp_FP_TO_XINT_SAT(N); break;
3799 case ISD::FP_EXTEND: Res = SoftPromoteHalfOp_FP_EXTEND(N); break;
3800 case ISD::SELECT_CC: Res = SoftPromoteHalfOp_SELECT_CC(N, OpNo); break;
3801 case ISD::SETCC: Res = SoftPromoteHalfOp_SETCC(N); break;
3802 case ISD::STORE: Res = SoftPromoteHalfOp_STORE(N, OpNo); break;
3803 case ISD::ATOMIC_STORE:
3804 Res = SoftPromoteHalfOp_ATOMIC_STORE(N, OpNo);
3805 break;
3806 case ISD::STACKMAP:
3807 Res = SoftPromoteHalfOp_STACKMAP(N, OpNo);
3808 break;
3809 case ISD::PATCHPOINT:
3810 Res = SoftPromoteHalfOp_PATCHPOINT(N, OpNo);
3811 break;
3812 }
3813
3815 return false;
3816
3817 assert(Res.getNode() != N && "Expected a new node!");
3818
3819 assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
3820 "Invalid operand expansion");
3821
3822 ReplaceValueWith(SDValue(N, 0), Res);
3823 return false;
3824}
3825
3826SDValue DAGTypeLegalizer::SoftPromoteHalfOp_BITCAST(SDNode *N) {
3827 SDValue Op0 = GetSoftPromotedHalf(N->getOperand(0));
3828
3829 return DAG.getNode(ISD::BITCAST, SDLoc(N), N->getValueType(0), Op0);
3830}
3831
3832SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FAKE_USE(SDNode *N, unsigned OpNo) {
3833 assert(OpNo == 1 && "Only Operand 1 must need promotion here");
3834 SDValue Op = GetSoftPromotedHalf(N->getOperand(OpNo));
3835 return DAG.getNode(N->getOpcode(), SDLoc(N), MVT::Other, N->getOperand(0),
3836 Op);
3837}
3838
3839SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FCOPYSIGN(SDNode *N,
3840 unsigned OpNo) {
3841 assert(OpNo == 1 && "Only Operand 1 must need promotion here");
3844 SDLoc dl(N);
3845
3846 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), Op1.getValueType());
3847
3848 Op1 = GetSoftPromotedHalf(Op1);
3850
3851 return DAG.getNode(N->getOpcode(), dl, N->getValueType(0), N->getOperand(0),
3852 Op1);
3853}
3854
3855SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FP_EXTEND(SDNode *N) {
3856 EVT RVT = N->getValueType(0);
3857 bool IsStrict = N->isStrictFPOpcode();
3858 SDValue Op = N->getOperand(IsStrict ? 1 : 0);
3859 EVT SVT = Op.getValueType();
3860 Op = GetSoftPromotedHalf(N->getOperand(IsStrict ? 1 : 0));
3861
3862 if (IsStrict) {
3864 {RVT, MVT::Other}, {N->getOperand(0), Op});
3866 ReplaceValueWith(SDValue(N, 0), Res);
3868 }
3869
3871}
3872
3873SDValue DAGTypeLegalizer::SoftPromoteHalfOp_Op0WithStrict(SDNode *N) {
3874 EVT RVT = N->getValueType(0);
3875 bool IsStrict = N->isStrictFPOpcode();
3876 SDValue Op = N->getOperand(IsStrict ? 1 : 0);
3877 EVT SVT = Op.getValueType();
3878 SDLoc dl(N);
3879
3880 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), SVT);
3881 Op = GetSoftPromotedHalf(Op);
3882
3883 if (IsStrict) {
3886 Op = DAG.getNode(N->getOpcode(), dl, {RVT, MVT::Other},
3887 {Op.getValue(1), Op});
3888 ReplaceValueWith(SDValue(N, 1), Op.getValue(1));
3889 ReplaceValueWith(SDValue(N, 0), Op);
3891 }
3892
3894 return DAG.getNode(N->getOpcode(), dl, RVT, Res);
3895}
3896
3897SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FP_TO_XINT_SAT(SDNode *N) {
3898 EVT RVT = N->getValueType(0);
3900 EVT SVT = Op.getValueType();
3901 SDLoc dl(N);
3902
3903 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), Op.getValueType());
3904
3905 Op = GetSoftPromotedHalf(Op);
3906
3908
3909 return DAG.getNode(N->getOpcode(), dl, N->getValueType(0), Res,
3910 N->getOperand(1));
3911}
3912
3913SDValue DAGTypeLegalizer::SoftPromoteHalfOp_SELECT_CC(SDNode *N,
3914 unsigned OpNo) {
3915 assert(OpNo == 0 && "Can only soften the comparison values");
3918 SDLoc dl(N);
3919
3921 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), SVT);
3922
3923 Op0 = GetSoftPromotedHalf(Op0);
3924 Op1 = GetSoftPromotedHalf(Op1);
3925
3926
3928 Op0 = DAG.getNode(PromotionOpcode, dl, NVT, Op0);
3929 Op1 = DAG.getNode(PromotionOpcode, dl, NVT, Op1);
3930
3931 return DAG.getNode(ISD::SELECT_CC, SDLoc(N), N->getValueType(0), Op0, Op1,
3932 N->getOperand(2), N->getOperand(3), N->getOperand(4));
3933}
3934
3935SDValue DAGTypeLegalizer::SoftPromoteHalfOp_SETCC(SDNode *N) {
3939 SDLoc dl(N);
3940
3942 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), Op0.getValueType());
3943
3944 Op0 = GetSoftPromotedHalf(Op0);
3945 Op1 = GetSoftPromotedHalf(Op1);
3946
3947
3949 Op0 = DAG.getNode(PromotionOpcode, dl, NVT, Op0);
3950 Op1 = DAG.getNode(PromotionOpcode, dl, NVT, Op1);
3951
3952 return DAG.getSetCC(SDLoc(N), N->getValueType(0), Op0, Op1, CCCode);
3953}
3954
3955SDValue DAGTypeLegalizer::SoftPromoteHalfOp_STORE(SDNode *N, unsigned OpNo) {
3956 assert(OpNo == 1 && "Can only soften the stored value!");
3959 SDLoc dl(N);
3960
3961 assert(->isTruncatingStore() && "Unexpected truncating store.");
3962 SDValue Promoted = GetSoftPromotedHalf(Val);
3963 return DAG.getStore(ST->getChain(), dl, Promoted, ST->getBasePtr(),
3964 ST->getMemOperand());
3965}
3966
3967SDValue DAGTypeLegalizer::SoftPromoteHalfOp_ATOMIC_STORE(SDNode *N,
3968 unsigned OpNo) {
3969 assert(OpNo == 1 && "Can only soften the stored value!");
3972 SDLoc dl(N);
3973
3974 SDValue Promoted = GetSoftPromotedHalf(Val);
3975 return DAG.getAtomic(ISD::ATOMIC_STORE, dl, Promoted.getValueType(),
3976 ST->getChain(), Promoted, ST->getBasePtr(),
3977 ST->getMemOperand());
3978}
3979
3980SDValue DAGTypeLegalizer::SoftPromoteHalfOp_STACKMAP(SDNode *N, unsigned OpNo) {
3981 assert(OpNo > 1);
3984 NewOps[OpNo] = GetSoftPromotedHalf(Op);
3986 DAG.getNode(N->getOpcode(), SDLoc(N), N->getVTList(), NewOps);
3987
3988 for (unsigned ResNum = 0; ResNum < N->getNumValues(); ResNum++)
3989 ReplaceValueWith(SDValue(N, ResNum), NewNode.getValue(ResNum));
3990
3991 return SDValue();
3992}
3993
3994SDValue DAGTypeLegalizer::SoftPromoteHalfOp_PATCHPOINT(SDNode *N,
3995 unsigned OpNo) {
3999 NewOps[OpNo] = GetSoftPromotedHalf(Op);
4001 DAG.getNode(N->getOpcode(), SDLoc(N), N->getVTList(), NewOps);
4002
4003 for (unsigned ResNum = 0; ResNum < N->getNumValues(); ResNum++)
4004 ReplaceValueWith(SDValue(N, ResNum), NewNode.getValue(ResNum));
4005
4006 return SDValue();
4007}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis Results
static bool isSigned(unsigned int Opcode)
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static RTLIB::Libcall findFPToIntLibcall(EVT SrcVT, EVT RetVT, EVT &Promoted, bool Signed)
Definition LegalizeFloatTypes.cpp:1273
static RTLIB::Libcall GetFPLibCall(EVT VT, RTLIB::Libcall Call_F32, RTLIB::Libcall Call_F64, RTLIB::Libcall Call_F80, RTLIB::Libcall Call_F128, RTLIB::Libcall Call_PPCF128)
GetFPLibCall - Return the right libcall for the given floating point type.
Definition LegalizeFloatTypes.cpp:32
static ISD::NodeType GetPromotionOpcode(EVT OpVT, EVT RetVT)
Definition LegalizeFloatTypes.cpp:2594
static ISD::NodeType GetPromotionOpcodeStrict(EVT OpVT, EVT RetVT)
Definition LegalizeFloatTypes.cpp:2606
static Type * getValueType(Value *V)
Returns the type of the given value/instruction V.
static const fltSemantics & PPCDoubleDouble()
APInt bitcastToAPInt() const
static APFloat getZero(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative Zero.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
void clearBit(unsigned BitPosition)
Set a given bit to 0.
static APInt getSignMask(unsigned BitWidth)
Get the SignMask for a specific bit width.
const uint64_t * getRawData() const
This function returns a pointer to the internal storage of the APInt.
const SDValue & getVal() const
const APFloat & getValueAPF() const
@ NewNode
This is a new node, not before seen, that was created in the process of legalizing some other node.
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
@ MOInvariant
The memory access always returns the same value (or traps).
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
bool isStrictFPOpcode()
Test if this node is a strict floating point pseudo-op.
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
const SDValue & getOperand(unsigned Num) const
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
void push_back(const T &Elt)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ C
The default llvm calling convention, compatible with C.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
@ POISON
POISON - A poison node.
@ FMAD
FMAD - Perform a * b + c, while getting the same result as the separately rounded operations.
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
@ FADD
Simple binary floating point operators.
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
@ STRICT_FSQRT
Constrained versions of libm-equivalent floating point intrinsics.
@ SIGN_EXTEND
Conversion operators.
@ FCANONICALIZE
Returns platform specific canonical encoding of a floating point number.
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ UNDEF
UNDEF - An undefined node.
@ EXTRACT_ELEMENT
EXTRACT_ELEMENT - This is used to get the lower or upper (determined by a Constant,...
@ SHL
Shift and rotation operations.
@ AssertNoFPClass
AssertNoFPClass - These nodes record if a register contains a float value that is known to be not som...
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ STRICT_FADD
Constrained versions of the binary floating point operators.
@ FREEZE
FREEZE - FREEZE(VAL) returns an arbitrary value if VAL is UNDEF (or is evaluated to UNDEF),...
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ FP_TO_SINT_SAT
FP_TO_[US]INT_SAT - Convert floating point value in operand 0 to a signed or unsigned scalar integer ...
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
bool isNormalStore(const SDNode *N)
Returns true if the specified node is a non-truncating and unindexed store.
bool isUNINDEXEDLoad(const SDNode *N)
Returns true if the specified node is an unindexed load.
bool isUNINDEXEDStore(const SDNode *N)
Returns true if the specified node is an unindexed store.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
bool isNormalLoad(const SDNode *N)
Returns true if the specified node is a non-extending and unindexed load.
LLVM_ABI Libcall getPOWI(EVT RetVT)
getPOWI - Return the POWI_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getSINTTOFP(EVT OpVT, EVT RetVT)
getSINTTOFP - Return the SINTTOFP_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getLDEXP(EVT RetVT)
getLDEXP - Return the LDEXP_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getUINTTOFP(EVT OpVT, EVT RetVT)
getUINTTOFP - Return the UINTTOFP_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getFREXP(EVT RetVT)
getFREXP - Return the FREXP_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getSINCOSPI(EVT RetVT)
getSINCOSPI - Return the SINCOSPI_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getFPTOUINT(EVT OpVT, EVT RetVT)
getFPTOUINT - Return the FPTOUINT_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getCOS(EVT RetVT)
Return the COS_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getMODF(EVT VT)
getMODF - Return the MODF_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getFPTOSINT(EVT OpVT, EVT RetVT)
getFPTOSINT - Return the FPTOSINT_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getFPEXT(EVT OpVT, EVT RetVT)
getFPEXT - Return the FPEXT_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getFPROUND(EVT OpVT, EVT RetVT)
getFPROUND - Return the FPROUND_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getSIN(EVT RetVT)
Return the SIN_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getPOW(EVT RetVT)
getPOW - Return the POW_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getSINCOS(EVT RetVT)
getSINCOS - Return the SINCOS_* value for the given types, or UNKNOWN_LIBCALL if there is none.
DiagnosticInfoOptimizationBase::Argument NV
This is an optimization pass for GlobalISel generic memory operations.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa - Return true if the parameter to the template is an instance of one of the template type argu...
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
bool isByteSized() const
Return true if the bit size is a multiple of 8.
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
bool bitsGE(EVT VT) const
Return true if this has no less bits than VT.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
LLVM_ABI const fltSemantics & getFltSemantics() const
Returns an APFloat semantics tag appropriate for the value type.
bool bitsLE(EVT VT) const
Return true if this has no more bits than VT.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
MakeLibCallOptions & setTypeListBeforeSoften(ArrayRef< EVT > OpsVT, EVT RetVT)
MakeLibCallOptions & setIsSigned(bool Value=true)