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);

680 SDLoc DL(N);

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(N->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);

760 SDLoc DL(N);

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(N->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

811 SDLoc DL(N);

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(N->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()) {

2010 Hi = N->getOperand(1);

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

2751 N->getOperand(0), Op);

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) {

2785 SDLoc DL(N);

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) {

2803 SDLoc DL(N);

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);

2979 SDLoc DL(N);

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) {

2998 SDLoc DL(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) {

3145 SDLoc DL(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) {

3162 SDLoc DL(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) {

3243 SDLoc DL(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) {

3885 {N->getOperand(0), Op});

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(ST->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)