clang: lib/CodeGen/TargetBuiltins/RISCV.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

15#include "llvm/IR/IntrinsicsRISCV.h"

16#include "llvm/TargetParser/RISCVISAInfo.h"

17#include "llvm/TargetParser/RISCVTargetParser.h"

18

19using namespace clang;

21using namespace llvm;

22

23

24

25static constexpr unsigned RVV_VTA = 0x1;

26static constexpr unsigned RVV_VMA = 0x2;

27

28

29

30

31static LLVM_ATTRIBUTE_NOINLINE Value *

35 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {

36 auto &Builder = CGF->Builder;

37 auto &CGM = CGF->CGM;

39 if (IsMasked) {

40

41 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);

42 if ((PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA))

43 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));

44 Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));

45 IntrinsicTypes = {ResultType, Ops[4]->getType(), Ops[2]->getType()};

46 } else {

47 if (PolicyAttrs & RVV_VTA)

48 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));

49 IntrinsicTypes = {ResultType, Ops[3]->getType(), Ops[1]->getType()};

50 }

51 Value *NewVL = Ops[2];

52 Ops.erase(Ops.begin() + 2);

53 llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);

54 llvm::Value *LoadValue = Builder.CreateCall(F, Ops, "");

55 llvm::Value *V = Builder.CreateExtractValue(LoadValue, {0});

56

58 if (IsMasked)

59 Align = CGM.getNaturalPointeeTypeAlignment(

61 else

62 Align = CGM.getNaturalPointeeTypeAlignment(E->getArg(1)->getType());

63 llvm::Value *Val = Builder.CreateExtractValue(LoadValue, {1});

64 Builder.CreateStore(Val, Address(NewVL, Val->getType(), Align));

65 return V;

66}

67

68static LLVM_ATTRIBUTE_NOINLINE Value *

72 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {

73 auto &Builder = CGF->Builder;

74 auto &CGM = CGF->CGM;

76 if (IsMasked) {

77

78

79 std::swap(Ops[0], Ops[3]);

80 } else {

81

82 std::rotate(Ops.begin(), Ops.begin() + 2, Ops.begin() + 3);

83 }

84 if (IsMasked)

85 IntrinsicTypes = {Ops[0]->getType(), Ops[1]->getType(), Ops[4]->getType()};

86 else

87 IntrinsicTypes = {Ops[0]->getType(), Ops[1]->getType(), Ops[3]->getType()};

88 llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);

89 return Builder.CreateCall(F, Ops, "");

90}

91

95 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {

96 auto &Builder = CGF->Builder;

97 auto &CGM = CGF->CGM;

99 if (IsMasked) {

100

101

102 std::swap(Ops[0], Ops[3]);

103 } else {

104

105

106 std::rotate(Ops.begin(), Ops.begin() + 2, Ops.begin() + 3);

107 }

108 if (IsMasked)

109 IntrinsicTypes = {Ops[0]->getType(), Ops[1]->getType(), Ops[2]->getType(),

110 Ops[4]->getType()};

111 else

112 IntrinsicTypes = {Ops[0]->getType(), Ops[1]->getType(), Ops[2]->getType(),

113 Ops[3]->getType()};

114 llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);

115 return Builder.CreateCall(F, Ops, "");

116}

117

118static LLVM_ATTRIBUTE_NOINLINE Value *

122 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {

123 auto &Builder = CGF->Builder;

124 auto &CGM = CGF->CGM;

126 if (IsMasked) {

127 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);

128 if ((PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA))

129 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));

130 } else {

131 if (PolicyAttrs & RVV_VTA)

132 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));

133 }

135 Ops.insert(Ops.begin() + 2, llvm::Constant::getNullValue(ElemTy));

136 if (IsMasked) {

137 Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));

138

139 IntrinsicTypes = {ResultType, ElemTy, Ops[4]->getType()};

140 } else {

141

142 IntrinsicTypes = {ResultType, ElemTy, Ops[3]->getType()};

143 }

144 llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);

145 return Builder.CreateCall(F, Ops, "");

146}

147

148static LLVM_ATTRIBUTE_NOINLINE Value *

152 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {

153 auto &Builder = CGF->Builder;

154 auto &CGM = CGF->CGM;

156 if (IsMasked) {

157 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);

158 if ((PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA))

159 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));

160 } else {

161 if (PolicyAttrs & RVV_VTA)

162 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));

163 }

165 Ops.insert(Ops.begin() + 2, llvm::Constant::getAllOnesValue(ElemTy));

166 if (IsMasked) {

167 Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));

168

169 IntrinsicTypes = {ResultType, ElemTy, Ops[4]->getType()};

170 } else {

171

172 IntrinsicTypes = {ResultType, ElemTy, Ops[3]->getType()};

173 }

174 llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);

175 return Builder.CreateCall(F, Ops, "");

176}

177

178static LLVM_ATTRIBUTE_NOINLINE Value *

182 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {

183 auto &Builder = CGF->Builder;

184 auto &CGM = CGF->CGM;

186

187 IntrinsicTypes = {ResultType, Ops[1]->getType()};

188 Ops.insert(Ops.begin() + 1, Ops[0]);

189 llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);

190 return Builder.CreateCall(F, Ops, "");

191}

192

196 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {

197 auto &Builder = CGF->Builder;

198 auto &CGM = CGF->CGM;

200 if (IsMasked) {

201 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);

202 if ((PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA))

203 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));

204 Ops.insert(Ops.begin() + 2, Ops[1]);

205 Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));

206

207 IntrinsicTypes = {ResultType, Ops[2]->getType(), Ops.back()->getType()};

208 } else {

209 if (PolicyAttrs & RVV_VTA)

210 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));

211

212 IntrinsicTypes = {ResultType, Ops[1]->getType(), Ops[2]->getType()};

213 Ops.insert(Ops.begin() + 2, Ops[1]);

214 }

215 llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);

216 return Builder.CreateCall(F, Ops, "");

217}

218

219static LLVM_ATTRIBUTE_NOINLINE Value *

223 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {

224 auto &Builder = CGF->Builder;

225 auto &CGM = CGF->CGM;

227 if (IsMasked) {

228 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);

229 if ((PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA))

230 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));

231 } else {

232 if (PolicyAttrs & RVV_VTA)

233 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));

234 }

236 Ops.insert(Ops.begin() + 2, llvm::Constant::getNullValue(ElemTy));

237 if (IsMasked) {

238 Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));

239

240 IntrinsicTypes = {ResultType, Ops[1]->getType(), ElemTy, Ops[4]->getType()};

241 } else {

242

243 IntrinsicTypes = {ResultType, Ops[1]->getType(), ElemTy, Ops[3]->getType()};

244 }

245 llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);

246 return Builder.CreateCall(F, Ops, "");

247}

248

249static LLVM_ATTRIBUTE_NOINLINE Value *

253 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {

254 auto &Builder = CGF->Builder;

255 auto &CGM = CGF->CGM;

257 if (IsMasked) {

258 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);

259 if ((PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA))

260 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));

261 } else {

262 if (PolicyAttrs & RVV_VTA)

263 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));

264 }

265 Ops.insert(Ops.begin() + 2,

266 llvm::Constant::getNullValue(Ops.back()->getType()));

267 if (IsMasked) {

268 Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));

269

270 IntrinsicTypes = {ResultType, Ops[1]->getType(), Ops[4]->getType(),

271 Ops[4]->getType()};

272 } else {

273

274 IntrinsicTypes = {ResultType, Ops[1]->getType(), Ops[3]->getType(),

275 Ops[3]->getType()};

276 }

277 llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);

278 return Builder.CreateCall(F, Ops, "");

279}

280

281static LLVM_ATTRIBUTE_NOINLINE Value *

285 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {

286 auto &Builder = CGF->Builder;

287 auto &CGM = CGF->CGM;

289 llvm::MDBuilder MDHelper(Context);

290 llvm::Metadata *OpsMD[] = {llvm::MDString::get(Context, "vlenb")};

291 llvm::MDNode *RegName = llvm::MDNode::get(Context, OpsMD);

292 llvm::Value *Metadata = llvm::MetadataAsValue::get(Context, RegName);

293 llvm::Function *F =

294 CGM.getIntrinsic(llvm::Intrinsic::read_register, {CGF->SizeTy});

295 return Builder.CreateCall(F, Metadata);

296}

297

298static LLVM_ATTRIBUTE_NOINLINE Value *

302 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {

303 auto &Builder = CGF->Builder;

304 auto &CGM = CGF->CGM;

305 llvm::Function *F = CGM.getIntrinsic(ID, {ResultType});

306 return Builder.CreateCall(F, Ops, "");

307}

308

309static LLVM_ATTRIBUTE_NOINLINE Value *

313 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {

314 auto &Builder = CGF->Builder;

315 auto &CGM = CGF->CGM;

317 if (IsMasked) {

318

319

320 std::swap(Ops[0], Ops[2]);

321 } else {

322

323

324 std::swap(Ops[0], Ops[1]);

325 }

326 if (IsMasked)

327 IntrinsicTypes = {Ops[0]->getType(), Ops[1]->getType(), Ops[3]->getType()};

328 else

329 IntrinsicTypes = {Ops[0]->getType(), Ops[1]->getType(), Ops[2]->getType()};

330 llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);

331 return Builder.CreateCall(F, Ops, "");

332}

333

337 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {

338 auto &Builder = CGF->Builder;

339 auto &CGM = CGF->CGM;

341 bool NoPassthru =

342 (IsMasked && (PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA)) |

343 (!IsMasked && (PolicyAttrs & RVV_VTA));

344 unsigned Offset = IsMasked ? NoPassthru ? 1 : 2 : NoPassthru ? 0 : 1;

345 if (IsMasked)

346 IntrinsicTypes = {ResultType, Ops[Offset]->getType(), Ops[0]->getType(),

347 Ops.back()->getType()};

348 else

349 IntrinsicTypes = {ResultType, Ops[Offset]->getType(),

350 Ops.back()->getType()};

351 if (IsMasked)

352 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);

353 if (NoPassthru)

354 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));

355 if (IsMasked)

356 Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));

357 Ops.push_back(ConstantInt::get(Ops.back()->getType(), SegInstSEW));

358 llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);

359 llvm::Value *LoadValue = Builder.CreateCall(F, Ops, "");

360 if (ReturnValue.isNull())

361 return LoadValue;

362 return Builder.CreateStore(LoadValue, ReturnValue.getValue());

363}

364

368 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {

369 auto &Builder = CGF->Builder;

370 auto &CGM = CGF->CGM;

372

373

374

375

376

377

378 if (IsMasked)

379 std::swap(Ops[0], Ops[2]);

380 else

381 std::swap(Ops[0], Ops[1]);

382 Ops.push_back(ConstantInt::get(Ops.back()->getType(), SegInstSEW));

383 if (IsMasked)

384 IntrinsicTypes = {Ops[0]->getType(), Ops[1]->getType(), Ops[2]->getType(),

385 Ops[3]->getType()};

386 else

387 IntrinsicTypes = {Ops[0]->getType(), Ops[1]->getType(), Ops[2]->getType()};

388 llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);

389 return Builder.CreateCall(F, Ops, "");

390}

391

395 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {

396 auto &Builder = CGF->Builder;

397 auto &CGM = CGF->CGM;

399 bool NoPassthru =

400 (IsMasked && (PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA)) |

401 (!IsMasked && (PolicyAttrs & RVV_VTA));

402 unsigned Offset = IsMasked ? NoPassthru ? 1 : 2 : NoPassthru ? 0 : 1;

403 if (IsMasked)

404 IntrinsicTypes = {ResultType, Ops.back()->getType(), Ops[Offset]->getType(),

405 Ops[0]->getType()};

406 else

407 IntrinsicTypes = {ResultType, Ops.back()->getType(),

408 Ops[Offset]->getType()};

409 if (IsMasked)

410 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);

411 if (NoPassthru)

412 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));

413 if (IsMasked)

414 Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));

415 Ops.push_back(ConstantInt::get(Ops.back()->getType(), SegInstSEW));

416 Value *NewVL = Ops[2];

417 Ops.erase(Ops.begin() + 2);

418 llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);

419 llvm::Value *LoadValue = Builder.CreateCall(F, Ops, "");

420

422 CGM.getNaturalPointeeTypeAlignment(E->getArg(Offset + 1)->getType());

423 llvm::Value *ReturnTuple = Builder.CreateExtractValue(LoadValue, 0);

424

425 llvm::Value *V = Builder.CreateExtractValue(LoadValue, 1);

426 Builder.CreateStore(V, Address(NewVL, V->getType(), Align));

427 if (ReturnValue.isNull())

428 return ReturnTuple;

429 return Builder.CreateStore(ReturnTuple, ReturnValue.getValue());

430}

431

435 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {

436 auto &Builder = CGF->Builder;

437 auto &CGM = CGF->CGM;

439 bool NoPassthru =

440 (IsMasked && (PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA)) |

441 (!IsMasked && (PolicyAttrs & RVV_VTA));

442 unsigned Offset = IsMasked ? NoPassthru ? 1 : 2 : NoPassthru ? 0 : 1;

443 if (IsMasked)

444 IntrinsicTypes = {ResultType, Ops[Offset]->getType(), Ops.back()->getType(),

445 Ops[0]->getType()};

446 else

447 IntrinsicTypes = {ResultType, Ops[Offset]->getType(),

448 Ops.back()->getType()};

449 if (IsMasked)

450 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);

451 if (NoPassthru)

452 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));

453 if (IsMasked)

454 Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));

455 Ops.push_back(ConstantInt::get(Ops.back()->getType(), SegInstSEW));

456 llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);

457 llvm::Value *LoadValue = Builder.CreateCall(F, Ops, "");

458 if (ReturnValue.isNull())

459 return LoadValue;

460 return Builder.CreateStore(LoadValue, ReturnValue.getValue());

461}

462

466 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {

467 auto &Builder = CGF->Builder;

468 auto &CGM = CGF->CGM;

470

471

472

473

474

475

476 if (IsMasked)

477 std::swap(Ops[0], Ops[3]);

478 else

479 std::rotate(Ops.begin(), Ops.begin() + 2, Ops.begin() + 3);

480 Ops.push_back(ConstantInt::get(Ops.back()->getType(), SegInstSEW));

481 if (IsMasked)

482 IntrinsicTypes = {Ops[0]->getType(), Ops[1]->getType(), Ops[4]->getType(),

483 Ops[3]->getType()};

484 else

485 IntrinsicTypes = {Ops[0]->getType(), Ops[1]->getType(), Ops[3]->getType()};

486 llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);

487 return Builder.CreateCall(F, Ops, "");

488}

489

490static LLVM_ATTRIBUTE_NOINLINE Value *

494 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {

495 auto &Builder = CGF->Builder;

496 auto &CGM = CGF->CGM;

497

498

499

500

501

502 bool HasMaskedOff =

503 !((IsMasked && (PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA)) ||

504 (!IsMasked && PolicyAttrs & RVV_VTA));

505

506 if (IsMasked)

507 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 2);

508

509 if (!HasMaskedOff)

510 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));

511

512 if (IsMasked)

513 Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));

514

515 llvm::Function *F = CGM.getIntrinsic(

516 ID, {ResultType, Ops[2]->getType(), Ops.back()->getType()});

517 return Builder.CreateCall(F, Ops, "");

518}

519

523 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {

524 auto &Builder = CGF->Builder;

525 auto &CGM = CGF->CGM;

526

527

528

529

530

531 bool HasMaskedOff =

532 !((IsMasked && (PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA)) ||

533 (!IsMasked && PolicyAttrs & RVV_VTA));

534

535 if (IsMasked)

536 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 2);

537

538 if (!HasMaskedOff)

539 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));

540

541 if (IsMasked)

542 Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));

543

544 llvm::Function *F =

545 CGM.getIntrinsic(ID, {ResultType, Ops[1]->getType(), Ops[2]->getType(),

546 Ops.back()->getType()});

547 return Builder.CreateCall(F, Ops, "");

548}

549

553 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {

554 auto &Builder = CGF->Builder;

555 auto &CGM = CGF->CGM;

556

557

558

559

560 bool HasMaskedOff =

561 !((IsMasked && (PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA)) ||

562 (!IsMasked && PolicyAttrs & RVV_VTA));

563 bool HasRoundModeOp =

564 IsMasked ? (HasMaskedOff ? Ops.size() == 6 : Ops.size() == 5)

565 : (HasMaskedOff ? Ops.size() == 5 : Ops.size() == 4);

566

567 if (!HasRoundModeOp)

568 Ops.insert(Ops.end() - 1,

569 ConstantInt::get(Ops.back()->getType(), 7));

570

571 if (IsMasked)

572 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 2);

573

574 if (!HasMaskedOff)

575 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));

576

577 if (IsMasked)

578 Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));

579

580 llvm::Function *F = CGM.getIntrinsic(

581 ID, {ResultType, Ops[2]->getType(), Ops.back()->getType()});

582 return Builder.CreateCall(F, Ops, "");

583}

584

588 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {

589 auto &Builder = CGF->Builder;

590 auto &CGM = CGF->CGM;

591

592

593

594

595 bool HasMaskedOff =

596 !((IsMasked && (PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA)) ||

597 (!IsMasked && PolicyAttrs & RVV_VTA));

598 bool HasRoundModeOp =

599 IsMasked ? (HasMaskedOff ? Ops.size() == 6 : Ops.size() == 5)

600 : (HasMaskedOff ? Ops.size() == 5 : Ops.size() == 4);

601

602 if (!HasRoundModeOp)

603 Ops.insert(Ops.end() - 1,

604 ConstantInt::get(Ops.back()->getType(), 7));

605

606 if (IsMasked)

607 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 2);

608

609 if (!HasMaskedOff)

610 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));

611

612 if (IsMasked)

613 Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));

614

615 llvm::Function *F =

616 CGM.getIntrinsic(ID, {ResultType, Ops[1]->getType(), Ops[2]->getType(),

617 Ops.back()->getType()});

618 return Builder.CreateCall(F, Ops, "");

619}

620

624 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {

625 auto &Builder = CGF->Builder;

626 auto &CGM = CGF->CGM;

628

629 bool NoPassthru =

630 (IsMasked && (PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA)) |

631 (!IsMasked && (PolicyAttrs & RVV_VTA));

632

633 if (IsMasked)

634 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);

635 if (NoPassthru)

636 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));

637

638 if (IsMasked)

639 Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));

640 Ops.push_back(ConstantInt::get(Ops.back()->getType(), SegInstSEW));

641

642 if (IsMasked)

643 IntrinsicTypes = {ResultType, Ops[1]->getType(), Ops[2]->getType(),

644 Ops[3]->getType(), Ops[4]->getType()};

645 else

646 IntrinsicTypes = {ResultType, Ops[1]->getType(), Ops[2]->getType(),

647 Ops[3]->getType()};

648 llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);

649 llvm::Value *LoadValue = Builder.CreateCall(F, Ops, "");

650

651 if (ReturnValue.isNull())

652 return LoadValue;

653 return Builder.CreateStore(LoadValue, ReturnValue.getValue());

654}

655

659 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {

660 auto &Builder = CGF->Builder;

661 auto &CGM = CGF->CGM;

663

664

665

666

667

668

669

670 if (IsMasked)

671 std::swap(Ops[0], Ops[3]);

672 else

673 std::rotate(Ops.begin(), Ops.begin() + 2, Ops.begin() + 3);

674

675 Ops.push_back(ConstantInt::get(Ops.back()->getType(), SegInstSEW));

676

677 if (IsMasked)

678 IntrinsicTypes = {Ops[0]->getType(), Ops[1]->getType(), Ops[2]->getType(),

679 Ops[3]->getType(), Ops[4]->getType()};

680 else

681 IntrinsicTypes = {Ops[0]->getType(), Ops[1]->getType(), Ops[2]->getType(),

682 Ops[3]->getType()};

683 llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);

684 return Builder.CreateCall(F, Ops, "");

685}

686

687static LLVM_ATTRIBUTE_NOINLINE Value *

691 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {

692 auto &Builder = CGF->Builder;

693 auto &CGM = CGF->CGM;

694

695

696

697

698

699

700 bool HasRoundModeOp = IsMasked ? Ops.size() == 6 : Ops.size() == 5;

701

702 if (!HasRoundModeOp)

703 Ops.insert(Ops.end() - 1,

704 ConstantInt::get(Ops.back()->getType(), 7));

705

706 if (IsMasked)

707 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 2);

708

709 Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));

710

711 llvm::Function *F = CGM.getIntrinsic(

712 ID, {ResultType, Ops[1]->getType(), Ops.back()->getType()});

713 return Builder.CreateCall(F, Ops, "");

714}

715

716static LLVM_ATTRIBUTE_NOINLINE Value *

720 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {

721 auto &Builder = CGF->Builder;

722 auto &CGM = CGF->CGM;

723

724

725

726

727

728 bool HasRoundModeOp = IsMasked ? Ops.size() == 6 : Ops.size() == 5;

729

730 if (!HasRoundModeOp)

731 Ops.insert(Ops.end() - 1,

732 ConstantInt::get(Ops.back()->getType(), 7));

733

734 if (IsMasked)

735 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.begin() + 4);

736

737 Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));

738

739 llvm::Function *F =

740 CGM.getIntrinsic(ID, {ResultType, Ops[1]->getType(), Ops[2]->getType(),

741 Ops.back()->getType()});

742 return Builder.CreateCall(F, Ops, "");

743}

744

748 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {

749 auto &Builder = CGF->Builder;

750 auto &CGM = CGF->CGM;

752

753

754

755

756 bool HasMaskedOff =

757 !((IsMasked && (PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA)) ||

758 (!IsMasked && PolicyAttrs & RVV_VTA));

759 bool HasRoundModeOp =

760 IsMasked ? (HasMaskedOff ? Ops.size() == 5 : Ops.size() == 4)

761 : (HasMaskedOff ? Ops.size() == 4 : Ops.size() == 3);

762

763 if (!HasRoundModeOp)

764 Ops.insert(Ops.end() - 1,

765 ConstantInt::get(Ops.back()->getType(), 7));

766

767 if (IsMasked)

768 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 2);

769

770 if (!HasMaskedOff)

771 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));

772

773 if (IsMasked)

774 Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));

775

776 IntrinsicTypes = {ResultType, Ops.back()->getType()};

777 llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);

778 return Builder.CreateCall(F, Ops, "");

779}

780

784 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {

785 auto &Builder = CGF->Builder;

786 auto &CGM = CGF->CGM;

787

788

789

790 bool HasMaskedOff =

791 !((IsMasked && (PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA)) ||

792 (!IsMasked && PolicyAttrs & RVV_VTA));

793 bool HasRoundModeOp =

794 IsMasked ? (HasMaskedOff ? Ops.size() == 5 : Ops.size() == 4)

795 : (HasMaskedOff ? Ops.size() == 4 : Ops.size() == 3);

796

797 if (!HasRoundModeOp)

798 Ops.insert(Ops.end() - 1,

799 ConstantInt::get(Ops.back()->getType(), 7));

800

801 if (IsMasked)

802 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 2);

803

804 if (!HasMaskedOff)

805 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));

806

807 if (IsMasked)

808 Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));

809

810 llvm::Function *F = CGM.getIntrinsic(

811 ID, {ResultType, Ops[1]->getType(), Ops.back()->getType()});

812 return Builder.CreateCall(F, Ops, "");

813}

814

818 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {

819 auto &Builder = CGF->Builder;

820 auto &CGM = CGF->CGM;

821

822

823

824

825 bool HasMaskedOff =

826 !((IsMasked && (PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA)) ||

827 (!IsMasked && PolicyAttrs & RVV_VTA));

828 bool HasRoundModeOp =

829 IsMasked ? (HasMaskedOff ? Ops.size() == 6 : Ops.size() == 5)

830 : (HasMaskedOff ? Ops.size() == 5 : Ops.size() == 4);

831

832 if (!HasRoundModeOp)

833 Ops.insert(Ops.end() - 1,

834 ConstantInt::get(Ops.back()->getType(), 7));

835

836 if (IsMasked)

837 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 2);

838

839 if (!HasMaskedOff)

840 Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));

841

842 llvm::Function *F = CGM.getIntrinsic(

843 ID, {ResultType, Ops[1]->getType(), Ops.back()->getType()});

844 return Builder.CreateCall(F, Ops, "");

845}

846

847static LLVM_ATTRIBUTE_NOINLINE Value *

851 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {

852 auto &Builder = CGF->Builder;

853 auto &CGM = CGF->CGM;

854

855 if (ResultType->isIntOrIntVectorTy(1) ||

856 Ops[0]->getType()->isIntOrIntVectorTy(1)) {

859

860 LLVMContext &Context = CGM.getLLVMContext();

861 ScalableVectorType *Boolean64Ty =

862 ScalableVectorType::get(llvm::Type::getInt1Ty(Context), 64);

863

864 if (ResultType->isIntOrIntVectorTy(1)) {

865

866

867

868

869 llvm::Value *BitCast = Builder.CreateBitCast(Ops[0], Boolean64Ty);

870 return Builder.CreateExtractVector(ResultType, BitCast,

871 ConstantInt::get(CGF->Int64Ty, 0));

872 } else {

873

874

875

876

877 llvm::Value *Boolean64Val = Builder.CreateInsertVector(

878 Boolean64Ty, llvm::PoisonValue::get(Boolean64Ty), Ops[0],

879 ConstantInt::get(CGF->Int64Ty, 0));

880 return Builder.CreateBitCast(Boolean64Val, ResultType);

881 }

882 }

883 return Builder.CreateBitCast(Ops[0], ResultType);

884}

885

886static LLVM_ATTRIBUTE_NOINLINE Value *

890 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {

891 auto &Builder = CGF->Builder;

893 if (auto *OpVecTy = dyn_cast(Ops[0]->getType())) {

894 unsigned MaxIndex =

895 OpVecTy->getMinNumElements() / VecTy->getMinNumElements();

896 assert(isPowerOf2_32(MaxIndex));

897

898 Ops[1] = Builder.CreateZExt(Ops[1], Builder.getInt64Ty());

899 Ops[1] = Builder.CreateAnd(Ops[1], MaxIndex - 1);

900 Ops[1] =

901 Builder.CreateMul(Ops[1], ConstantInt::get(Ops[1]->getType(),

902 VecTy->getMinNumElements()));

903 return Builder.CreateExtractVector(ResultType, Ops[0], Ops[1]);

904 }

905

906 return Builder.CreateIntrinsic(

907 Intrinsic::riscv_tuple_extract, {ResultType, Ops[0]->getType()},

908 {Ops[0], Builder.CreateTrunc(Ops[1], Builder.getInt32Ty())});

909}

910

911static LLVM_ATTRIBUTE_NOINLINE Value *

915 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {

916 auto &Builder = CGF->Builder;

917 if (auto *ResVecTy = dyn_cast(ResultType)) {

919 unsigned MaxIndex =

920 ResVecTy->getMinNumElements() / VecTy->getMinNumElements();

921 assert(isPowerOf2_32(MaxIndex));

922

923 Ops[1] = Builder.CreateZExt(Ops[1], Builder.getInt64Ty());

924 Ops[1] = Builder.CreateAnd(Ops[1], MaxIndex - 1);

925 Ops[1] =

926 Builder.CreateMul(Ops[1], ConstantInt::get(Ops[1]->getType(),

927 VecTy->getMinNumElements()));

928 return Builder.CreateInsertVector(ResultType, Ops[0], Ops[2], Ops[1]);

929 }

930

931 return Builder.CreateIntrinsic(

932 Intrinsic::riscv_tuple_insert, {ResultType, Ops[2]->getType()},

933 {Ops[0], Ops[2], Builder.CreateTrunc(Ops[1], Builder.getInt32Ty())});

934}

935

936static LLVM_ATTRIBUTE_NOINLINE Value *

940 int PolicyAttrs, bool IsMasked, unsigned SegInstSEW) {

941 auto &Builder = CGF->Builder;

942 llvm::Value *ReturnVector = llvm::PoisonValue::get(ResultType);

944 for (unsigned I = 0, N = Ops.size(); I < N; ++I) {

946 llvm::Value *Idx = ConstantInt::get(Builder.getInt64Ty(),

947 VecTy->getMinNumElements() * I);

948 ReturnVector =

949 Builder.CreateInsertVector(ResultType, ReturnVector, Ops[I], Idx);

950 } else {

951 llvm::Value *Idx = ConstantInt::get(Builder.getInt32Ty(), I);

952 ReturnVector = Builder.CreateIntrinsic(Intrinsic::riscv_tuple_insert,

953 {ResultType, Ops[I]->getType()},

954 {ReturnVector, Ops[I], Idx});

955 }

956 }

957 return ReturnVector;

958}

959

961 llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, {VoidPtrTy}, false);

962 llvm::FunctionCallee Func =

963 CGM.CreateRuntimeFunction(FTy, "__init_riscv_feature_bits");

965 CalleeGV->setDSOLocal(true);

966 CalleeGV->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);

967 return Builder.CreateCall(Func, {llvm::ConstantPointerNull::get(VoidPtrTy)});

968}

969

971

974 if (getContext().getTargetInfo().validateCpuSupports(FeatureStr))

975 return Builder.getFalse();

976

978}

979

982 llvm::Type *Int32Ty = Builder.getInt32Ty();

983 llvm::Type *Int64Ty = Builder.getInt64Ty();

984 llvm::ArrayType *ArrayOfInt64Ty =

985 llvm::ArrayType::get(Int64Ty, llvm::RISCVISAInfo::FeatureBitSize);

986 llvm::Type *StructTy = llvm::StructType::get(Int32Ty, ArrayOfInt64Ty);

987 llvm::Constant *RISCVFeaturesBits =

990 Value *IndexVal = llvm::ConstantInt::get(Int32Ty, Index);

991 llvm::Value *GEPIndices[] = {Builder.getInt32(0), Builder.getInt32(1),

992 IndexVal};

994 Builder.CreateInBoundsGEP(StructTy, RISCVFeaturesBits, GEPIndices);

995 Value *FeaturesBit =

997 return FeaturesBit;

998}

999

1001 const unsigned RISCVFeatureLength = llvm::RISCVISAInfo::FeatureBitSize;

1002 uint64_t RequireBitMasks[RISCVFeatureLength] = {0};

1003

1004 for (auto Feat : FeaturesStrs) {

1005 auto [GroupID, BitPos] = RISCVISAInfo::getRISCVFeaturesBitsInfo(Feat);

1006

1007

1008

1009 if (BitPos == -1)

1010 return Builder.getFalse();

1011

1012 RequireBitMasks[GroupID] |= (1ULL << BitPos);

1013 }

1014

1016 for (unsigned Idx = 0; Idx < RISCVFeatureLength; Idx++) {

1017 if (RequireBitMasks[Idx] == 0)

1018 continue;

1019

1020 Value *Mask = Builder.getInt64(RequireBitMasks[Idx]);

1023 Value *CmpV = Builder.CreateICmpEQ(Bitset, Mask);

1025 }

1026

1027 assert(Result && "Should have value here.");

1028

1030}

1031

1037

1042 llvm::Constant *RISCVCPUModel =

1043 CGM.CreateRuntimeVariable(StructTy, "__riscv_cpu_model");

1045

1046 auto loadRISCVCPUID = [&](unsigned Index) {

1047 Value *Ptr = Builder.CreateStructGEP(StructTy, RISCVCPUModel, Index);

1048 Value *CPUID = Builder.CreateAlignedLoad(StructTy->getTypeAtIndex(Index),

1049 Ptr, llvm::MaybeAlign());

1050 return CPUID;

1051 };

1052

1053 const llvm::RISCV::CPUModel Model = llvm::RISCV::getCPUModel(CPUStr);

1054

1055

1056 Value *VendorID = loadRISCVCPUID(0);

1058 Builder.CreateICmpEQ(VendorID, Builder.getInt32(Model.MVendorID));

1059

1060

1061 Value *ArchID = loadRISCVCPUID(1);

1064

1065

1066 Value *ImpID = loadRISCVCPUID(2);

1069

1071}

1072

1076

1077 if (BuiltinID == Builtin::BI__builtin_cpu_supports)

1079 if (BuiltinID == Builtin::BI__builtin_cpu_init)

1081 if (BuiltinID == Builtin::BI__builtin_cpu_is)

1083

1086

1087

1088 unsigned ICEArguments = 0;

1092

1095 ICEArguments = 0;

1096 if (BuiltinID == RISCVVector::BI__builtin_rvv_vget_v ||

1097 BuiltinID == RISCVVector::BI__builtin_rvv_vset_v)

1098 ICEArguments = 1 << 1;

1099 } else {

1101 }

1102

1103 if (BuiltinID == RISCV::BI__builtin_riscv_ntl_load)

1104 ICEArguments |= (1 << 1);

1105 if (BuiltinID == RISCV::BI__builtin_riscv_ntl_store)

1106 ICEArguments |= (1 << 2);

1107

1108 for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) {

1109

1113 Ops.push_back(AggValue);

1114 continue;

1115 }

1117 }

1118

1119 Intrinsic::ID ID = Intrinsic::not_intrinsic;

1120 int PolicyAttrs = 0;

1121 bool IsMasked = false;

1122

1123 unsigned SegInstSEW = 8;

1124

1125 unsigned TWiden = 0;

1126

1127

1129 switch (BuiltinID) {

1130 default: llvm_unreachable("unexpected builtin ID");

1131 case RISCV::BI__builtin_riscv_orc_b_32:

1132 case RISCV::BI__builtin_riscv_orc_b_64:

1133 case RISCV::BI__builtin_riscv_clmul_32:

1134 case RISCV::BI__builtin_riscv_clmul_64:

1135 case RISCV::BI__builtin_riscv_clmulh_32:

1136 case RISCV::BI__builtin_riscv_clmulh_64:

1137 case RISCV::BI__builtin_riscv_clmulr_32:

1138 case RISCV::BI__builtin_riscv_clmulr_64:

1139 case RISCV::BI__builtin_riscv_xperm4_32:

1140 case RISCV::BI__builtin_riscv_xperm4_64:

1141 case RISCV::BI__builtin_riscv_xperm8_32:

1142 case RISCV::BI__builtin_riscv_xperm8_64:

1143 case RISCV::BI__builtin_riscv_brev8_32:

1144 case RISCV::BI__builtin_riscv_brev8_64:

1145 case RISCV::BI__builtin_riscv_zip_32:

1146 case RISCV::BI__builtin_riscv_unzip_32: {

1147 switch (BuiltinID) {

1148 default: llvm_unreachable("unexpected builtin ID");

1149

1150 case RISCV::BI__builtin_riscv_orc_b_32:

1151 case RISCV::BI__builtin_riscv_orc_b_64:

1152 ID = Intrinsic::riscv_orc_b;

1153 break;

1154

1155

1156 case RISCV::BI__builtin_riscv_clmul_32:

1157 case RISCV::BI__builtin_riscv_clmul_64:

1158 ID = Intrinsic::riscv_clmul;

1159 break;

1160 case RISCV::BI__builtin_riscv_clmulh_32:

1161 case RISCV::BI__builtin_riscv_clmulh_64:

1162 ID = Intrinsic::riscv_clmulh;

1163 break;

1164 case RISCV::BI__builtin_riscv_clmulr_32:

1165 case RISCV::BI__builtin_riscv_clmulr_64:

1166 ID = Intrinsic::riscv_clmulr;

1167 break;

1168

1169

1170 case RISCV::BI__builtin_riscv_xperm8_32:

1171 case RISCV::BI__builtin_riscv_xperm8_64:

1172 ID = Intrinsic::riscv_xperm8;

1173 break;

1174 case RISCV::BI__builtin_riscv_xperm4_32:

1175 case RISCV::BI__builtin_riscv_xperm4_64:

1176 ID = Intrinsic::riscv_xperm4;

1177 break;

1178

1179

1180 case RISCV::BI__builtin_riscv_brev8_32:

1181 case RISCV::BI__builtin_riscv_brev8_64:

1182 ID = Intrinsic::riscv_brev8;

1183 break;

1184 case RISCV::BI__builtin_riscv_zip_32:

1185 ID = Intrinsic::riscv_zip;

1186 break;

1187 case RISCV::BI__builtin_riscv_unzip_32:

1188 ID = Intrinsic::riscv_unzip;

1189 break;

1190 }

1191

1192 IntrinsicTypes = {ResultType};

1193 break;

1194 }

1195

1196

1197

1198

1199 case RISCV::BI__builtin_riscv_sha256sig0:

1200 ID = Intrinsic::riscv_sha256sig0;

1201 break;

1202 case RISCV::BI__builtin_riscv_sha256sig1:

1203 ID = Intrinsic::riscv_sha256sig1;

1204 break;

1205 case RISCV::BI__builtin_riscv_sha256sum0:

1206 ID = Intrinsic::riscv_sha256sum0;

1207 break;

1208 case RISCV::BI__builtin_riscv_sha256sum1:

1209 ID = Intrinsic::riscv_sha256sum1;

1210 break;

1211

1212

1213 case RISCV::BI__builtin_riscv_sm4ks:

1214 ID = Intrinsic::riscv_sm4ks;

1215 break;

1216 case RISCV::BI__builtin_riscv_sm4ed:

1217 ID = Intrinsic::riscv_sm4ed;

1218 break;

1219

1220

1221 case RISCV::BI__builtin_riscv_sm3p0:

1222 ID = Intrinsic::riscv_sm3p0;

1223 break;

1224 case RISCV::BI__builtin_riscv_sm3p1:

1225 ID = Intrinsic::riscv_sm3p1;

1226 break;

1227

1228 case RISCV::BI__builtin_riscv_clz_32:

1229 case RISCV::BI__builtin_riscv_clz_64: {

1232 if (Result->getType() != ResultType)

1234 Builder.CreateIntCast(Result, ResultType, false, "cast");

1236 }

1237 case RISCV::BI__builtin_riscv_ctz_32:

1238 case RISCV::BI__builtin_riscv_ctz_64: {

1241 if (Result->getType() != ResultType)

1243 Builder.CreateIntCast(Result, ResultType, false, "cast");

1245 }

1246

1247

1248 case RISCV::BI__builtin_riscv_ntl_load: {

1250 unsigned DomainVal = 5;

1251 if (Ops.size() == 2)

1253

1254 llvm::MDNode *RISCVDomainNode = llvm::MDNode::get(

1256 llvm::ConstantAsMetadata::get(Builder.getInt32(DomainVal)));

1257 llvm::MDNode *NontemporalNode = llvm::MDNode::get(

1259

1260 int Width;

1261 if(ResTy->isScalableTy()) {

1263 llvm::Type *ScalarTy = ResTy->getScalarType();

1264 Width = ScalarTy->getPrimitiveSizeInBits() *

1265 SVTy->getElementCount().getKnownMinValue();

1266 } else

1267 Width = ResTy->getPrimitiveSizeInBits();

1268 LoadInst *Load = Builder.CreateLoad(

1270

1271 Load->setMetadata(llvm::LLVMContext::MD_nontemporal, NontemporalNode);

1272 Load->setMetadata(CGM.getModule().getMDKindID("riscv-nontemporal-domain"),

1273 RISCVDomainNode);

1274

1275 return Load;

1276 }

1277 case RISCV::BI__builtin_riscv_ntl_store: {

1278 unsigned DomainVal = 5;

1279 if (Ops.size() == 3)

1281

1282 llvm::MDNode *RISCVDomainNode = llvm::MDNode::get(

1284 llvm::ConstantAsMetadata::get(Builder.getInt32(DomainVal)));

1285 llvm::MDNode *NontemporalNode = llvm::MDNode::get(

1287

1288 StoreInst *Store = Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);

1289 Store->setMetadata(llvm::LLVMContext::MD_nontemporal, NontemporalNode);

1290 Store->setMetadata(CGM.getModule().getMDKindID("riscv-nontemporal-domain"),

1291 RISCVDomainNode);

1292

1293 return Store;

1294 }

1295

1296 case RISCV::BI__builtin_riscv_pause: {

1297 llvm::Function *Fn = CGM.getIntrinsic(llvm::Intrinsic::riscv_pause);

1298 return Builder.CreateCall(Fn, {});

1299 }

1300

1301

1302 case RISCV::BI__builtin_riscv_cv_alu_addN:

1303 ID = Intrinsic::riscv_cv_alu_addN;

1304 break;

1305 case RISCV::BI__builtin_riscv_cv_alu_addRN:

1306 ID = Intrinsic::riscv_cv_alu_addRN;

1307 break;

1308 case RISCV::BI__builtin_riscv_cv_alu_adduN:

1309 ID = Intrinsic::riscv_cv_alu_adduN;

1310 break;

1311 case RISCV::BI__builtin_riscv_cv_alu_adduRN:

1312 ID = Intrinsic::riscv_cv_alu_adduRN;

1313 break;

1314 case RISCV::BI__builtin_riscv_cv_alu_clip:

1315 ID = Intrinsic::riscv_cv_alu_clip;

1316 break;

1317 case RISCV::BI__builtin_riscv_cv_alu_clipu:

1318 ID = Intrinsic::riscv_cv_alu_clipu;

1319 break;

1320 case RISCV::BI__builtin_riscv_cv_alu_extbs:

1322 "extbs");

1323 case RISCV::BI__builtin_riscv_cv_alu_extbz:

1325 "extbz");

1326 case RISCV::BI__builtin_riscv_cv_alu_exths:

1328 "exths");

1329 case RISCV::BI__builtin_riscv_cv_alu_exthz:

1331 "exthz");

1332 case RISCV::BI__builtin_riscv_cv_alu_sle:

1334 "sle");

1335 case RISCV::BI__builtin_riscv_cv_alu_sleu:

1337 "sleu");

1338 case RISCV::BI__builtin_riscv_cv_alu_subN:

1339 ID = Intrinsic::riscv_cv_alu_subN;

1340 break;

1341 case RISCV::BI__builtin_riscv_cv_alu_subRN:

1342 ID = Intrinsic::riscv_cv_alu_subRN;

1343 break;

1344 case RISCV::BI__builtin_riscv_cv_alu_subuN:

1345 ID = Intrinsic::riscv_cv_alu_subuN;

1346 break;

1347 case RISCV::BI__builtin_riscv_cv_alu_subuRN:

1348 ID = Intrinsic::riscv_cv_alu_subuRN;

1349 break;

1350

1351

1352 case RISCV::BI__builtin_riscv_nds_fcvt_s_bf16:

1354 case RISCV::BI__builtin_riscv_nds_fcvt_bf16_s:

1356

1357

1358#include "clang/Basic/riscv_vector_builtin_cg.inc"

1359

1360

1361#include "clang/Basic/riscv_sifive_vector_builtin_cg.inc"

1362

1363

1364#include "clang/Basic/riscv_andes_vector_builtin_cg.inc"

1365 }

1366

1367 assert(ID != Intrinsic::not_intrinsic);

1368

1369 llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);

1370 return Builder.CreateCall(F, Ops, "");

1371}

static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVGetBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)

Definition RISCV.cpp:887

static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVStridedSegLoadTupleBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)

Definition RISCV.cpp:432

static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVFMABuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)

Definition RISCV.cpp:688

static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVPseudoVWCVTBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)

Definition RISCV.cpp:220

static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVPseudoVNCVTBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)

Definition RISCV.cpp:250

static constexpr unsigned RVV_VMA

Definition RISCV.cpp:26

static Value * loadRISCVFeatureBits(unsigned Index, CGBuilderTy &Builder, CodeGenModule &CGM)

Definition RISCV.cpp:980

static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVFloatingPointBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)

Definition RISCV.cpp:550

static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVVlenbBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)

Definition RISCV.cpp:282

static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVFloatingConvBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)

Definition RISCV.cpp:781

static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVStridedSegStoreTupleBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)

Definition RISCV.cpp:463

static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVIndexedSegLoadTupleBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)

Definition RISCV.cpp:621

static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVReinterpretBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)

Definition RISCV.cpp:848

static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVVSEMaskBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)

Definition RISCV.cpp:310

static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVAveragingBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)

Definition RISCV.cpp:491

static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVWideningFMABuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)

Definition RISCV.cpp:717

static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVUnitStridedSegLoadFFTupleBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)

Definition RISCV.cpp:392

static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVUnitStridedSegStoreTupleBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)

Definition RISCV.cpp:365

static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVVLEFFBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)

Definition RISCV.cpp:32

static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVIndexedStoreBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)

Definition RISCV.cpp:92

static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVPseudoMaskBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)

Definition RISCV.cpp:179

static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVFloatingReductionBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)

Definition RISCV.cpp:815

static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVIndexedSegStoreTupleBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)

Definition RISCV.cpp:656

static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVPseudoUnaryBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)

Definition RISCV.cpp:119

static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVFloatingUnaryBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)

Definition RISCV.cpp:745

static constexpr unsigned RVV_VTA

Definition RISCV.cpp:25

static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVWideningFloatingPointBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)

Definition RISCV.cpp:585

static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVPseudoVFUnaryBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)

Definition RISCV.cpp:193

static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVVSSEBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)

Definition RISCV.cpp:69

static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVVsetvliBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)

Definition RISCV.cpp:299

static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVSetBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)

Definition RISCV.cpp:912

static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVNarrowingClipBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)

Definition RISCV.cpp:520

static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVPseudoVNotBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)

Definition RISCV.cpp:149

static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVCreateBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)

Definition RISCV.cpp:937

static LLVM_ATTRIBUTE_NOINLINE Value * emitRVVUnitStridedSegLoadTupleBuiltin(CodeGenFunction *CGF, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Type *ResultType, Intrinsic::ID ID, SmallVectorImpl< Value * > &Ops, int PolicyAttrs, bool IsMasked, unsigned SegInstSEW)

Definition RISCV.cpp:334

TokenType getType() const

Returns the token's type, e.g.

Enumerates target-specific builtins in their own namespaces within namespace clang.

QualType GetBuiltinType(unsigned ID, GetBuiltinTypeError &Error, unsigned *IntegerConstantArgs=nullptr) const

Return the type for the specified builtin.

@ GE_Missing_type

Missing a type.

CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).

Expr * getArg(unsigned Arg)

getArg - Return the specified argument.

unsigned getNumArgs() const

getNumArgs - Return the number of actual arguments to this call.

CharUnits - This is an opaque type for sizes expressed in character units.

static CharUnits fromQuantity(QuantityType Quantity)

fromQuantity - Construct a CharUnits quantity from a raw integer type.

Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...

CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...

llvm::Value * EmitScalarOrConstFoldImmArg(unsigned ICEArguments, unsigned Idx, const CallExpr *E)

llvm::Value * EmitRISCVCpuSupports(const CallExpr *E)

Definition RISCV.cpp:970

llvm::Value * EmitRISCVCpuInit()

Definition RISCV.cpp:960

llvm::Type * ConvertType(QualType T)

llvm::Value * EmitRISCVBuiltinExpr(unsigned BuiltinID, const CallExpr *E, ReturnValueSlot ReturnValue)

Definition RISCV.cpp:1073

llvm::Value * EmitRISCVCpuIs(const CallExpr *E)

Definition RISCV.cpp:1032

LValue EmitAggExprToLValue(const Expr *E)

EmitAggExprToLValue - Emit the computation of the specified expression of aggregate type into a tempo...

ASTContext & getContext() const

static bool hasAggregateEvaluationKind(QualType T)

Address ReturnValue

ReturnValue - The temporary alloca to hold the return value.

llvm::LLVMContext & getLLVMContext()

This class organizes the cross-function state that is used while generating LLVM code.

llvm::Constant * CreateRuntimeVariable(llvm::Type *Ty, StringRef Name)

Create a new runtime global variable with the specified type and name.

llvm::LLVMContext & getLLVMContext()

llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys={})

LValue - This represents an lvalue references.

Address getAddress() const

ReturnValueSlot - Contains the address where the return value of a function can be stored,...

This represents one expression.

Expr * IgnoreParenCasts() LLVM_READONLY

Skip past any parentheses and casts which might surround this expression until reaching a fixed point...

The JSON file list parser is used to communicate input to InstallAPI.

bool isa(CodeGen::Address addr)

@ Result

The result type of a method or function.

U cast(CodeGen::Address addr)

Diagnostic wrappers for TextAPI types for error reporting.

llvm::PointerType * VoidPtrTy

llvm::IntegerType * Int64Ty

llvm::IntegerType * Int8Ty

i8, i16, i32, and i64

llvm::IntegerType * SizeTy

llvm::IntegerType * Int32Ty

llvm::IntegerType * Int16Ty