LLVM: lib/IR/AutoUpgrade.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

34#include "llvm/IR/IntrinsicsAArch64.h"

35#include "llvm/IR/IntrinsicsARM.h"

36#include "llvm/IR/IntrinsicsNVPTX.h"

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

38#include "llvm/IR/IntrinsicsWebAssembly.h"

39#include "llvm/IR/IntrinsicsX86.h"

53#include

54#include

55#include

56

57using namespace llvm;

58

61 cl::desc("Disable autoupgrade of debug info"));

62

64

65

66

69

70

71 Type *Arg0Type = F->getFunctionType()->getParamType(0);

73 return false;

74

75

78 return true;

79}

80

81

82

85

86 Type *LastArgType = F->getFunctionType()->getParamType(

87 F->getFunctionType()->getNumParams() - 1);

89 return false;

90

91

94 return true;

95}

96

97

98

101

102 if (F->getReturnType()->isVectorTy())

103 return false;

104

107 return true;

108}

109

110

111

114

115 Type *Arg1Type = F->getFunctionType()->getParamType(1);

116 Type *Arg2Type = F->getFunctionType()->getParamType(2);

118 cast(Arg1Type)->getElementType()->isIntegerTy(8) &&

120 cast(Arg2Type)->getElementType()->isIntegerTy(8))

121 return false;

122

125 return true;

126}

127

130 if (F->getReturnType()->getScalarType()->isBFloatTy())

131 return false;

132

135 return true;

136}

137

140 if (F->getFunctionType()->getParamType(1)->getScalarType()->isBFloatTy())

141 return false;

142

145 return true;

146}

147

149

150

151

152

153

154 if (Name.consume_front("avx."))

155 return (Name.starts_with("blend.p") ||

156 Name == "cvt.ps2.pd.256" ||

157 Name == "cvtdq2.pd.256" ||

158 Name == "cvtdq2.ps.256" ||

159 Name.starts_with("movnt.") ||

160 Name.starts_with("sqrt.p") ||

161 Name.starts_with("storeu.") ||

162 Name.starts_with("vbroadcast.s") ||

163 Name.starts_with("vbroadcastf128") ||

164 Name.starts_with("vextractf128.") ||

165 Name.starts_with("vinsertf128.") ||

166 Name.starts_with("vperm2f128.") ||

167 Name.starts_with("vpermil."));

168

169 if (Name.consume_front("avx2."))

170 return (Name == "movntdqa" ||

171 Name.starts_with("pabs.") ||

172 Name.starts_with("padds.") ||

173 Name.starts_with("paddus.") ||

174 Name.starts_with("pblendd.") ||

175 Name == "pblendw" ||

176 Name.starts_with("pbroadcast") ||

177 Name.starts_with("pcmpeq.") ||

178 Name.starts_with("pcmpgt.") ||

179 Name.starts_with("pmax") ||

180 Name.starts_with("pmin") ||

181 Name.starts_with("pmovsx") ||

182 Name.starts_with("pmovzx") ||

183 Name == "pmul.dq" ||

184 Name == "pmulu.dq" ||

185 Name.starts_with("psll.dq") ||

186 Name.starts_with("psrl.dq") ||

187 Name.starts_with("psubs.") ||

188 Name.starts_with("psubus.") ||

189 Name.starts_with("vbroadcast") ||

190 Name == "vbroadcasti128" ||

191 Name == "vextracti128" ||

192 Name == "vinserti128" ||

193 Name == "vperm2i128");

194

195 if (Name.consume_front("avx512.")) {

196 if (Name.consume_front("mask."))

197

198 return (Name.starts_with("add.p") ||

199 Name.starts_with("and.") ||

200 Name.starts_with("andn.") ||

201 Name.starts_with("broadcast.s") ||

202 Name.starts_with("broadcastf32x4.") ||

203 Name.starts_with("broadcastf32x8.") ||

204 Name.starts_with("broadcastf64x2.") ||

205 Name.starts_with("broadcastf64x4.") ||

206 Name.starts_with("broadcasti32x4.") ||

207 Name.starts_with("broadcasti32x8.") ||

208 Name.starts_with("broadcasti64x2.") ||

209 Name.starts_with("broadcasti64x4.") ||

210 Name.starts_with("cmp.b") ||

211 Name.starts_with("cmp.d") ||

212 Name.starts_with("cmp.q") ||

213 Name.starts_with("cmp.w") ||

214 Name.starts_with("compress.b") ||

215 Name.starts_with("compress.d") ||

216 Name.starts_with("compress.p") ||

217 Name.starts_with("compress.q") ||

218 Name.starts_with("compress.store.") ||

219 Name.starts_with("compress.w") ||

220 Name.starts_with("conflict.") ||

221 Name.starts_with("cvtdq2pd.") ||

222 Name.starts_with("cvtdq2ps.") ||

223 Name == "cvtpd2dq.256" ||

224 Name == "cvtpd2ps.256" ||

225 Name == "cvtps2pd.128" ||

226 Name == "cvtps2pd.256" ||

227 Name.starts_with("cvtqq2pd.") ||

228 Name == "cvtqq2ps.256" ||

229 Name == "cvtqq2ps.512" ||

230 Name == "cvttpd2dq.256" ||

231 Name == "cvttps2dq.128" ||

232 Name == "cvttps2dq.256" ||

233 Name.starts_with("cvtudq2pd.") ||

234 Name.starts_with("cvtudq2ps.") ||

235 Name.starts_with("cvtuqq2pd.") ||

236 Name == "cvtuqq2ps.256" ||

237 Name == "cvtuqq2ps.512" ||

238 Name.starts_with("dbpsadbw.") ||

239 Name.starts_with("div.p") ||

240 Name.starts_with("expand.b") ||

241 Name.starts_with("expand.d") ||

242 Name.starts_with("expand.load.") ||

243 Name.starts_with("expand.p") ||

244 Name.starts_with("expand.q") ||

245 Name.starts_with("expand.w") ||

246 Name.starts_with("fpclass.p") ||

247 Name.starts_with("insert") ||

248 Name.starts_with("load.") ||

249 Name.starts_with("loadu.") ||

250 Name.starts_with("lzcnt.") ||

251 Name.starts_with("max.p") ||

252 Name.starts_with("min.p") ||

253 Name.starts_with("movddup") ||

254 Name.starts_with("move.s") ||

255 Name.starts_with("movshdup") ||

256 Name.starts_with("movsldup") ||

257 Name.starts_with("mul.p") ||

258 Name.starts_with("or.") ||

259 Name.starts_with("pabs.") ||

260 Name.starts_with("packssdw.") ||

261 Name.starts_with("packsswb.") ||

262 Name.starts_with("packusdw.") ||

263 Name.starts_with("packuswb.") ||

264 Name.starts_with("padd.") ||

265 Name.starts_with("padds.") ||

266 Name.starts_with("paddus.") ||

267 Name.starts_with("palignr.") ||

268 Name.starts_with("pand.") ||

269 Name.starts_with("pandn.") ||

270 Name.starts_with("pavg") ||

271 Name.starts_with("pbroadcast") ||

272 Name.starts_with("pcmpeq.") ||

273 Name.starts_with("pcmpgt.") ||

274 Name.starts_with("perm.df.") ||

275 Name.starts_with("perm.di.") ||

276 Name.starts_with("permvar.") ||

277 Name.starts_with("pmaddubs.w.") ||

278 Name.starts_with("pmaddw.d.") ||

279 Name.starts_with("pmax") ||

280 Name.starts_with("pmin") ||

281 Name == "pmov.qd.256" ||

282 Name == "pmov.qd.512" ||

283 Name == "pmov.wb.256" ||

284 Name == "pmov.wb.512" ||

285 Name.starts_with("pmovsx") ||

286 Name.starts_with("pmovzx") ||

287 Name.starts_with("pmul.dq.") ||

288 Name.starts_with("pmul.hr.sw.") ||

289 Name.starts_with("pmulh.w.") ||

290 Name.starts_with("pmulhu.w.") ||

291 Name.starts_with("pmull.") ||

292 Name.starts_with("pmultishift.qb.") ||

293 Name.starts_with("pmulu.dq.") ||

294 Name.starts_with("por.") ||

295 Name.starts_with("prol.") ||

296 Name.starts_with("prolv.") ||

297 Name.starts_with("pror.") ||

298 Name.starts_with("prorv.") ||

299 Name.starts_with("pshuf.b.") ||

300 Name.starts_with("pshuf.d.") ||

301 Name.starts_with("pshufh.w.") ||

302 Name.starts_with("pshufl.w.") ||

303 Name.starts_with("psll.d") ||

304 Name.starts_with("psll.q") ||

305 Name.starts_with("psll.w") ||

306 Name.starts_with("pslli") ||

307 Name.starts_with("psllv") ||

308 Name.starts_with("psra.d") ||

309 Name.starts_with("psra.q") ||

310 Name.starts_with("psra.w") ||

311 Name.starts_with("psrai") ||

312 Name.starts_with("psrav") ||

313 Name.starts_with("psrl.d") ||

314 Name.starts_with("psrl.q") ||

315 Name.starts_with("psrl.w") ||

316 Name.starts_with("psrli") ||

317 Name.starts_with("psrlv") ||

318 Name.starts_with("psub.") ||

319 Name.starts_with("psubs.") ||

320 Name.starts_with("psubus.") ||

321 Name.starts_with("pternlog.") ||

322 Name.starts_with("punpckh") ||

323 Name.starts_with("punpckl") ||

324 Name.starts_with("pxor.") ||

325 Name.starts_with("shuf.f") ||

326 Name.starts_with("shuf.i") ||

327 Name.starts_with("shuf.p") ||

328 Name.starts_with("sqrt.p") ||

329 Name.starts_with("store.b.") ||

330 Name.starts_with("store.d.") ||

331 Name.starts_with("store.p") ||

332 Name.starts_with("store.q.") ||

333 Name.starts_with("store.w.") ||

334 Name == "store.ss" ||

335 Name.starts_with("storeu.") ||

336 Name.starts_with("sub.p") ||

337 Name.starts_with("ucmp.") ||

338 Name.starts_with("unpckh.") ||

339 Name.starts_with("unpckl.") ||

340 Name.starts_with("valign.") ||

341 Name == "vcvtph2ps.128" ||

342 Name == "vcvtph2ps.256" ||

343 Name.starts_with("vextract") ||

344 Name.starts_with("vfmadd.") ||

345 Name.starts_with("vfmaddsub.") ||

346 Name.starts_with("vfnmadd.") ||

347 Name.starts_with("vfnmsub.") ||

348 Name.starts_with("vpdpbusd.") ||

349 Name.starts_with("vpdpbusds.") ||

350 Name.starts_with("vpdpwssd.") ||

351 Name.starts_with("vpdpwssds.") ||

352 Name.starts_with("vpermi2var.") ||

353 Name.starts_with("vpermil.p") ||

354 Name.starts_with("vpermilvar.") ||

355 Name.starts_with("vpermt2var.") ||

356 Name.starts_with("vpmadd52") ||

357 Name.starts_with("vpshld.") ||

358 Name.starts_with("vpshldv.") ||

359 Name.starts_with("vpshrd.") ||

360 Name.starts_with("vpshrdv.") ||

361 Name.starts_with("vpshufbitqmb.") ||

362 Name.starts_with("xor."));

363

364 if (Name.consume_front("mask3."))

365

366 return (Name.starts_with("vfmadd.") ||

367 Name.starts_with("vfmaddsub.") ||

368 Name.starts_with("vfmsub.") ||

369 Name.starts_with("vfmsubadd.") ||

370 Name.starts_with("vfnmsub."));

371

372 if (Name.consume_front("maskz."))

373

374 return (Name.starts_with("pternlog.") ||

375 Name.starts_with("vfmadd.") ||

376 Name.starts_with("vfmaddsub.") ||

377 Name.starts_with("vpdpbusd.") ||

378 Name.starts_with("vpdpbusds.") ||

379 Name.starts_with("vpdpwssd.") ||

380 Name.starts_with("vpdpwssds.") ||

381 Name.starts_with("vpermt2var.") ||

382 Name.starts_with("vpmadd52") ||

383 Name.starts_with("vpshldv.") ||

384 Name.starts_with("vpshrdv."));

385

386

387 return (Name == "movntdqa" ||

388 Name == "pmul.dq.512" ||

389 Name == "pmulu.dq.512" ||

390 Name.starts_with("broadcastm") ||

391 Name.starts_with("cmp.p") ||

392 Name.starts_with("cvtb2mask.") ||

393 Name.starts_with("cvtd2mask.") ||

394 Name.starts_with("cvtmask2") ||

395 Name.starts_with("cvtq2mask.") ||

396 Name == "cvtusi2sd" ||

397 Name.starts_with("cvtw2mask.") ||

398 Name == "kand.w" ||

399 Name == "kandn.w" ||

400 Name == "knot.w" ||

401 Name == "kor.w" ||

402 Name == "kortestc.w" ||

403 Name == "kortestz.w" ||

404 Name.starts_with("kunpck") ||

405 Name == "kxnor.w" ||

406 Name == "kxor.w" ||

407 Name.starts_with("padds.") ||

408 Name.starts_with("pbroadcast") ||

409 Name.starts_with("prol") ||

410 Name.starts_with("pror") ||

411 Name.starts_with("psll.dq") ||

412 Name.starts_with("psrl.dq") ||

413 Name.starts_with("psubs.") ||

414 Name.starts_with("ptestm") ||

415 Name.starts_with("ptestnm") ||

416 Name.starts_with("storent.") ||

417 Name.starts_with("vbroadcast.s") ||

418 Name.starts_with("vpshld.") ||

419 Name.starts_with("vpshrd."));

420 }

421

422 if (Name.consume_front("fma."))

423 return (Name.starts_with("vfmadd.") ||

424 Name.starts_with("vfmsub.") ||

425 Name.starts_with("vfmsubadd.") ||

426 Name.starts_with("vfnmadd.") ||

427 Name.starts_with("vfnmsub."));

428

429 if (Name.consume_front("fma4."))

430 return Name.starts_with("vfmadd.s");

431

432 if (Name.consume_front("sse."))

433 return (Name == "add.ss" ||

434 Name == "cvtsi2ss" ||

435 Name == "cvtsi642ss" ||

436 Name == "div.ss" ||

437 Name == "mul.ss" ||

438 Name.starts_with("sqrt.p") ||

439 Name == "sqrt.ss" ||

440 Name.starts_with("storeu.") ||

441 Name == "sub.ss");

442

443 if (Name.consume_front("sse2."))

444 return (Name == "add.sd" ||

445 Name == "cvtdq2pd" ||

446 Name == "cvtdq2ps" ||

447 Name == "cvtps2pd" ||

448 Name == "cvtsi2sd" ||

449 Name == "cvtsi642sd" ||

450 Name == "cvtss2sd" ||

451 Name == "div.sd" ||

452 Name == "mul.sd" ||

453 Name.starts_with("padds.") ||

454 Name.starts_with("paddus.") ||

455 Name.starts_with("pcmpeq.") ||

456 Name.starts_with("pcmpgt.") ||

457 Name == "pmaxs.w" ||

458 Name == "pmaxu.b" ||

459 Name == "pmins.w" ||

460 Name == "pminu.b" ||

461 Name == "pmulu.dq" ||

462 Name.starts_with("pshuf") ||

463 Name.starts_with("psll.dq") ||

464 Name.starts_with("psrl.dq") ||

465 Name.starts_with("psubs.") ||

466 Name.starts_with("psubus.") ||

467 Name.starts_with("sqrt.p") ||

468 Name == "sqrt.sd" ||

469 Name == "storel.dq" ||

470 Name.starts_with("storeu.") ||

471 Name == "sub.sd");

472

473 if (Name.consume_front("sse41."))

474 return (Name.starts_with("blendp") ||

475 Name == "movntdqa" ||

476 Name == "pblendw" ||

477 Name == "pmaxsb" ||

478 Name == "pmaxsd" ||

479 Name == "pmaxud" ||

480 Name == "pmaxuw" ||

481 Name == "pminsb" ||

482 Name == "pminsd" ||

483 Name == "pminud" ||

484 Name == "pminuw" ||

485 Name.starts_with("pmovsx") ||

486 Name.starts_with("pmovzx") ||

487 Name == "pmuldq");

488

489 if (Name.consume_front("sse42."))

490 return Name == "crc32.64.8";

491

492 if (Name.consume_front("sse4a."))

493 return Name.starts_with("movnt.");

494

495 if (Name.consume_front("ssse3."))

496 return (Name == "pabs.b.128" ||

497 Name == "pabs.d.128" ||

498 Name == "pabs.w.128");

499

500 if (Name.consume_front("xop."))

501 return (Name == "vpcmov" ||

502 Name == "vpcmov.256" ||

503 Name.starts_with("vpcom") ||

504 Name.starts_with("vprot"));

505

506 return (Name == "addcarry.u32" ||

507 Name == "addcarry.u64" ||

508 Name == "addcarryx.u32" ||

509 Name == "addcarryx.u64" ||

510 Name == "subborrow.u32" ||

511 Name == "subborrow.u64" ||

512 Name.starts_with("vcvtph2ps."));

513}

514

517

518 if (!Name.consume_front("x86."))

519 return false;

520

522 NewFn = nullptr;

523 return true;

524 }

525

526 if (Name == "rdtscp") {

527

528 if (F->getFunctionType()->getNumParams() == 0)

529 return false;

530

533 Intrinsic::x86_rdtscp);

534 return true;

535 }

536

538

539

540 if (Name.consume_front("sse41.ptest")) {

542 .Case("c", Intrinsic::x86_sse41_ptestc)

543 .Case("z", Intrinsic::x86_sse41_ptestz)

544 .Case("nzc", Intrinsic::x86_sse41_ptestnzc)

548

549 return false;

550 }

551

552

553

554

555

557 .Case("sse41.insertps", Intrinsic::x86_sse41_insertps)

558 .Case("sse41.dppd", Intrinsic::x86_sse41_dppd)

559 .Case("sse41.dpps", Intrinsic::x86_sse41_dpps)

560 .Case("sse41.mpsadbw", Intrinsic::x86_sse41_mpsadbw)

561 .Case("avx.dp.ps.256", Intrinsic::x86_avx_dp_ps_256)

562 .Case("avx2.mpsadbw", Intrinsic::x86_avx2_mpsadbw)

566

567 if (Name.consume_front("avx512.")) {

568 if (Name.consume_front("mask.cmp.")) {

569

571 .Case("pd.128", Intrinsic::x86_avx512_mask_cmp_pd_128)

572 .Case("pd.256", Intrinsic::x86_avx512_mask_cmp_pd_256)

573 .Case("pd.512", Intrinsic::x86_avx512_mask_cmp_pd_512)

574 .Case("ps.128", Intrinsic::x86_avx512_mask_cmp_ps_128)

575 .Case("ps.256", Intrinsic::x86_avx512_mask_cmp_ps_256)

576 .Case("ps.512", Intrinsic::x86_avx512_mask_cmp_ps_512)

580 } else if (Name.starts_with("vpdpbusd.") ||

581 Name.starts_with("vpdpbusds.")) {

582

584 .Case("vpdpbusd.128", Intrinsic::x86_avx512_vpdpbusd_128)

585 .Case("vpdpbusd.256", Intrinsic::x86_avx512_vpdpbusd_256)

586 .Case("vpdpbusd.512", Intrinsic::x86_avx512_vpdpbusd_512)

587 .Case("vpdpbusds.128", Intrinsic::x86_avx512_vpdpbusds_128)

588 .Case("vpdpbusds.256", Intrinsic::x86_avx512_vpdpbusds_256)

589 .Case("vpdpbusds.512", Intrinsic::x86_avx512_vpdpbusds_512)

593 }

594 return false;

595 }

596

597 if (Name.consume_front("avx2.vpdpb")) {

598

600 .Case("ssd.128", Intrinsic::x86_avx2_vpdpbssd_128)

601 .Case("ssd.256", Intrinsic::x86_avx2_vpdpbssd_256)

602 .Case("ssds.128", Intrinsic::x86_avx2_vpdpbssds_128)

603 .Case("ssds.256", Intrinsic::x86_avx2_vpdpbssds_256)

604 .Case("sud.128", Intrinsic::x86_avx2_vpdpbsud_128)

605 .Case("sud.256", Intrinsic::x86_avx2_vpdpbsud_256)

606 .Case("suds.128", Intrinsic::x86_avx2_vpdpbsuds_128)

607 .Case("suds.256", Intrinsic::x86_avx2_vpdpbsuds_256)

608 .Case("uud.128", Intrinsic::x86_avx2_vpdpbuud_128)

609 .Case("uud.256", Intrinsic::x86_avx2_vpdpbuud_256)

610 .Case("uuds.128", Intrinsic::x86_avx2_vpdpbuuds_128)

611 .Case("uuds.256", Intrinsic::x86_avx2_vpdpbuuds_256)

615 return false;

616 }

617

618 if (Name.consume_front("avx10.vpdpb")) {

619

621 .Case("ssd.512", Intrinsic::x86_avx10_vpdpbssd_512)

622 .Case("ssds.512", Intrinsic::x86_avx10_vpdpbssds_512)

623 .Case("sud.512", Intrinsic::x86_avx10_vpdpbsud_512)

624 .Case("suds.512", Intrinsic::x86_avx10_vpdpbsuds_512)

625 .Case("uud.512", Intrinsic::x86_avx10_vpdpbuud_512)

626 .Case("uuds.512", Intrinsic::x86_avx10_vpdpbuuds_512)

630 return false;

631 }

632

633 if (Name.consume_front("avx512bf16.")) {

634

636 .Case("cvtne2ps2bf16.128",

637 Intrinsic::x86_avx512bf16_cvtne2ps2bf16_128)

638 .Case("cvtne2ps2bf16.256",

639 Intrinsic::x86_avx512bf16_cvtne2ps2bf16_256)

640 .Case("cvtne2ps2bf16.512",

641 Intrinsic::x86_avx512bf16_cvtne2ps2bf16_512)

642 .Case("mask.cvtneps2bf16.128",

643 Intrinsic::x86_avx512bf16_mask_cvtneps2bf16_128)

644 .Case("cvtneps2bf16.256",

645 Intrinsic::x86_avx512bf16_cvtneps2bf16_256)

646 .Case("cvtneps2bf16.512",

647 Intrinsic::x86_avx512bf16_cvtneps2bf16_512)

651

652

654 .Case("dpbf16ps.128", Intrinsic::x86_avx512bf16_dpbf16ps_128)

655 .Case("dpbf16ps.256", Intrinsic::x86_avx512bf16_dpbf16ps_256)

656 .Case("dpbf16ps.512", Intrinsic::x86_avx512bf16_dpbf16ps_512)

660 return false;

661 }

662

663 if (Name.consume_front("xop.")) {

665 if (Name.starts_with("vpermil2")) {

666

667

668 auto Idx = F->getFunctionType()->getParamType(2);

669 if (Idx->isFPOrFPVectorTy()) {

670 unsigned IdxSize = Idx->getPrimitiveSizeInBits();

671 unsigned EltSize = Idx->getScalarSizeInBits();

672 if (EltSize == 64 && IdxSize == 128)

673 ID = Intrinsic::x86_xop_vpermil2pd;

674 else if (EltSize == 32 && IdxSize == 128)

675 ID = Intrinsic::x86_xop_vpermil2ps;

676 else if (EltSize == 64 && IdxSize == 256)

677 ID = Intrinsic::x86_xop_vpermil2pd_256;

678 else

679 ID = Intrinsic::x86_xop_vpermil2ps_256;

680 }

681 } else if (F->arg_size() == 2)

682

684 .Case("vfrcz.ss", Intrinsic::x86_xop_vfrcz_ss)

685 .Case("vfrcz.sd", Intrinsic::x86_xop_vfrcz_sd)

687

691 return true;

692 }

693 return false;

694 }

695

696 if (Name == "seh.recoverfp") {

698 Intrinsic::eh_recoverfp);

699 return true;

700 }

701

702 return false;

703}

704

705

706

710 if (Name.starts_with("rbit")) {

711

713 F->getParent(), Intrinsic::bitreverse, F->arg_begin()->getType());

714 return true;

715 }

716

717 if (Name == "thread.pointer") {

718

720 F->getParent(), Intrinsic::thread_pointer, F->getReturnType());

721 return true;

722 }

723

724 bool Neon = Name.consume_front("neon.");

725 if (Neon) {

726

727

728

729 if (Name.consume_front("bfdot.")) {

730

733 .Cases({"v2f32.v8i8", "v4f32.v16i8"},

738 size_t OperandWidth = F->getReturnType()->getPrimitiveSizeInBits();

739 assert((OperandWidth == 64 || OperandWidth == 128) &&

740 "Unexpected operand width");

741 LLVMContext &Ctx = F->getParent()->getContext();

742 std::array<Type *, 2> Tys{

743 {F->getReturnType(),

746 return true;

747 }

748 return false;

749 }

750

751

752

753 if (Name.consume_front("bfm")) {

754

755 if (Name.consume_back(".v4f32.v16i8")) {

756

760 IsArm ? (Intrinsic::ID)Intrinsic::arm_neon_bfmmla

762 .Case("lalb",

763 IsArm ? (Intrinsic::ID)Intrinsic::arm_neon_bfmlalb

764 : (Intrinsic::ID)Intrinsic::aarch64_neon_bfmlalb)

765 .Case("lalt",

766 IsArm ? (Intrinsic::ID)Intrinsic::arm_neon_bfmlalt

767 : (Intrinsic::ID)Intrinsic::aarch64_neon_bfmlalt)

771 return true;

772 }

773 return false;

774 }

775 return false;

776 }

777

778 }

779

780

781 if (IsArm) {

782

783 if (Neon) {

784

786 .StartsWith("vclz.", Intrinsic::ctlz)

787 .StartsWith("vcnt.", Intrinsic::ctpop)

788 .StartsWith("vqadds.", Intrinsic::sadd_sat)

789 .StartsWith("vqaddu.", Intrinsic::uadd_sat)

790 .StartsWith("vqsubs.", Intrinsic::ssub_sat)

791 .StartsWith("vqsubu.", Intrinsic::usub_sat)

792 .StartsWith("vrinta.", Intrinsic::round)

793 .StartsWith("vrintn.", Intrinsic::roundeven)

794 .StartsWith("vrintm.", Intrinsic::floor)

795 .StartsWith("vrintp.", Intrinsic::ceil)

796 .StartsWith("vrintx.", Intrinsic::rint)

797 .StartsWith("vrintz.", Intrinsic::trunc)

801 F->arg_begin()->getType());

802 return true;

803 }

804

805 if (Name.consume_front("vst")) {

806

807 static const Regex vstRegex("^([1234]|[234]lane)\\.v[a-z0-9]*$");

811 Intrinsic::arm_neon_vst1, Intrinsic::arm_neon_vst2,

812 Intrinsic::arm_neon_vst3, Intrinsic::arm_neon_vst4};

813

815 Intrinsic::arm_neon_vst2lane, Intrinsic::arm_neon_vst3lane,

816 Intrinsic::arm_neon_vst4lane};

817

818 auto fArgs = F->getFunctionType()->params();

819 Type *Tys[] = {fArgs[0], fArgs[1]};

822 F->getParent(), StoreInts[fArgs.size() - 3], Tys);

823 else

825 F->getParent(), StoreLaneInts[fArgs.size() - 5], Tys);

826 return true;

827 }

828 return false;

829 }

830

831 return false;

832 }

833

834 if (Name.consume_front("mve.")) {

835

836 if (Name == "vctp64") {

838

839

841 return true;

842 }

843 return false;

844 }

845

846 if (Name.starts_with("vrintn.v")) {

848 F->getParent(), Intrinsic::roundeven, F->arg_begin()->getType());

849 return true;

850 }

851

852

853 if (Name.consume_back(".v4i1")) {

854

855 if (Name.consume_back(".predicated.v2i64.v4i32"))

856

857 return Name == "mull.int" || Name == "vqdmull";

858

859 if (Name.consume_back(".v2i64")) {

860

861 bool IsGather = Name.consume_front("vldr.gather.");

862 if (IsGather || Name.consume_front("vstr.scatter.")) {

863 if (Name.consume_front("base.")) {

864

865 Name.consume_front("wb.");

866

867

868 return Name == "predicated.v2i64";

869 }

870

871 if (Name.consume_front("offset.predicated."))

872 return Name == (IsGather ? "v2i64.p0i64" : "p0i64.v2i64") ||

873 Name == (IsGather ? "v2i64.p0" : "p0.v2i64");

874

875

876 return false;

877 }

878

879 return false;

880 }

881 return false;

882 }

883 return false;

884 }

885

886 if (Name.consume_front("cde.vcx")) {

887

888 if (Name.consume_back(".predicated.v2i64.v4i1"))

889

890 return Name == "1q" || Name == "1qa" || Name == "2q" || Name == "2qa" ||

891 Name == "3q" || Name == "3qa";

892

893 return false;

894 }

895 } else {

896

897 if (Neon) {

898

900 .StartsWith("frintn", Intrinsic::roundeven)

901 .StartsWith("rbit", Intrinsic::bitreverse)

905 F->arg_begin()->getType());

906 return true;

907 }

908

909 if (Name.starts_with("addp")) {

910

911 if (F->arg_size() != 2)

912 return false;

914 if (Ty && Ty->getElementType()->isFloatingPointTy()) {

916 F->getParent(), Intrinsic::aarch64_neon_faddp, Ty);

917 return true;

918 }

919 }

920

921

922 if (Name.starts_with("bfcvt")) {

923 NewFn = nullptr;

924 return true;

925 }

926

927 return false;

928 }

929 if (Name.consume_front("sve.")) {

930

931 if (Name.consume_front("bf")) {

932 if (Name.consume_back(".lane")) {

933

936 .Case("dot", Intrinsic::aarch64_sve_bfdot_lane_v2)

937 .Case("mlalb", Intrinsic::aarch64_sve_bfmlalb_lane_v2)

938 .Case("mlalt", Intrinsic::aarch64_sve_bfmlalt_lane_v2)

942 return true;

943 }

944 return false;

945 }

946 return false;

947 }

948

949

950 if (Name == "fcvt.bf16f32" || Name == "fcvtnt.bf16f32") {

951 NewFn = nullptr;

952 return true;

953 }

954

955 if (Name.consume_front("addqv")) {

956

957 if (F->getReturnType()->isFPOrFPVectorTy())

958 return false;

959

960 auto Args = F->getFunctionType()->params();

961 Type *Tys[] = {F->getReturnType(), Args[1]};

963 F->getParent(), Intrinsic::aarch64_sve_faddqv, Tys);

964 return true;

965 }

966

967 if (Name.consume_front("ld")) {

968

969 static const Regex LdRegex("^[234](.nxv[a-z0-9]+|$)");

970 if (LdRegex.match(Name)) {

971 Type *ScalarTy =

977 Intrinsic::aarch64_sve_ld2_sret,

978 Intrinsic::aarch64_sve_ld3_sret,

979 Intrinsic::aarch64_sve_ld4_sret,

980 };

982 LoadIDs[Name[0] - '2'], Ty);

983 return true;

984 }

985 return false;

986 }

987

988 if (Name.consume_front("tuple.")) {

989

990 if (Name.starts_with("get")) {

991

992 Type *Tys[] = {F->getReturnType(), F->arg_begin()->getType()};

994 F->getParent(), Intrinsic::vector_extract, Tys);

995 return true;

996 }

997

998 if (Name.starts_with("set")) {

999

1000 auto Args = F->getFunctionType()->params();

1001 Type *Tys[] = {Args[0], Args[2], Args[1]};

1003 F->getParent(), Intrinsic::vector_insert, Tys);

1004 return true;

1005 }

1006

1007 static const Regex CreateTupleRegex("^create[234](.nxv[a-z0-9]+|$)");

1008 if (CreateTupleRegex.match(Name)) {

1009

1010 auto Args = F->getFunctionType()->params();

1011 Type *Tys[] = {F->getReturnType(), Args[1]};

1013 F->getParent(), Intrinsic::vector_insert, Tys);

1014 return true;

1015 }

1016 return false;

1017 }

1018

1019 if (Name.starts_with("rev.nxv")) {

1020

1022 F->getParent(), Intrinsic::vector_reverse, F->getReturnType());

1023 return true;

1024 }

1025

1026 return false;

1027 }

1028 }

1029 return false;

1030}

1031

1034 if (Name.consume_front("cp.async.bulk.tensor.g2s.")) {

1037 .Case("im2col.3d",

1038 Intrinsic::nvvm_cp_async_bulk_tensor_g2s_im2col_3d)

1039 .Case("im2col.4d",

1040 Intrinsic::nvvm_cp_async_bulk_tensor_g2s_im2col_4d)

1041 .Case("im2col.5d",

1042 Intrinsic::nvvm_cp_async_bulk_tensor_g2s_im2col_5d)

1043 .Case("tile.1d", Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_1d)

1044 .Case("tile.2d", Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_2d)

1045 .Case("tile.3d", Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_3d)

1046 .Case("tile.4d", Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_4d)

1047 .Case("tile.5d", Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_5d)

1049

1051 return ID;

1052

1053

1054

1055

1056 if (F->getArg(0)->getType()->getPointerAddressSpace() ==

1058 return ID;

1059

1060

1061

1062

1063

1064

1065

1066

1067

1068

1069

1070 size_t FlagStartIndex = F->getFunctionType()->getNumParams() - 3;

1071 Type *ArgType = F->getFunctionType()->getParamType(FlagStartIndex);

1073 return ID;

1074 }

1075

1077}

1078

1081 if (Name.consume_front("mapa.shared.cluster"))

1082 if (F->getReturnType()->getPointerAddressSpace() ==

1084 return Intrinsic::nvvm_mapa_shared_cluster;

1085

1086 if (Name.consume_front("cp.async.bulk.")) {

1089 .Case("global.to.shared.cluster",

1090 Intrinsic::nvvm_cp_async_bulk_global_to_shared_cluster)

1091 .Case("shared.cta.to.cluster",

1092 Intrinsic::nvvm_cp_async_bulk_shared_cta_to_cluster)

1094

1096 if (F->getArg(0)->getType()->getPointerAddressSpace() ==

1098 return ID;

1099 }

1100

1102}

1103

1105 if (Name.consume_front("fma.rn."))

1107 .Case("bf16", Intrinsic::nvvm_fma_rn_bf16)

1108 .Case("bf16x2", Intrinsic::nvvm_fma_rn_bf16x2)

1109 .Case("ftz.bf16", Intrinsic::nvvm_fma_rn_ftz_bf16)

1110 .Case("ftz.bf16x2", Intrinsic::nvvm_fma_rn_ftz_bf16x2)

1111 .Case("ftz.relu.bf16", Intrinsic::nvvm_fma_rn_ftz_relu_bf16)

1112 .Case("ftz.relu.bf16x2", Intrinsic::nvvm_fma_rn_ftz_relu_bf16x2)

1113 .Case("ftz.sat.bf16", Intrinsic::nvvm_fma_rn_ftz_sat_bf16)

1114 .Case("ftz.sat.bf16x2", Intrinsic::nvvm_fma_rn_ftz_sat_bf16x2)

1115 .Case("relu.bf16", Intrinsic::nvvm_fma_rn_relu_bf16)

1116 .Case("relu.bf16x2", Intrinsic::nvvm_fma_rn_relu_bf16x2)

1117 .Case("sat.bf16", Intrinsic::nvvm_fma_rn_sat_bf16)

1118 .Case("sat.bf16x2", Intrinsic::nvvm_fma_rn_sat_bf16x2)

1120

1121 if (Name.consume_front("fmax."))

1123 .Case("bf16", Intrinsic::nvvm_fmax_bf16)

1124 .Case("bf16x2", Intrinsic::nvvm_fmax_bf16x2)

1125 .Case("ftz.bf16", Intrinsic::nvvm_fmax_ftz_bf16)

1126 .Case("ftz.bf16x2", Intrinsic::nvvm_fmax_ftz_bf16x2)

1127 .Case("ftz.nan.bf16", Intrinsic::nvvm_fmax_ftz_nan_bf16)

1128 .Case("ftz.nan.bf16x2", Intrinsic::nvvm_fmax_ftz_nan_bf16x2)

1129 .Case("ftz.nan.xorsign.abs.bf16",

1130 Intrinsic::nvvm_fmax_ftz_nan_xorsign_abs_bf16)

1131 .Case("ftz.nan.xorsign.abs.bf16x2",

1132 Intrinsic::nvvm_fmax_ftz_nan_xorsign_abs_bf16x2)

1133 .Case("ftz.xorsign.abs.bf16", Intrinsic::nvvm_fmax_ftz_xorsign_abs_bf16)

1134 .Case("ftz.xorsign.abs.bf16x2",

1135 Intrinsic::nvvm_fmax_ftz_xorsign_abs_bf16x2)

1136 .Case("nan.bf16", Intrinsic::nvvm_fmax_nan_bf16)

1137 .Case("nan.bf16x2", Intrinsic::nvvm_fmax_nan_bf16x2)

1138 .Case("nan.xorsign.abs.bf16", Intrinsic::nvvm_fmax_nan_xorsign_abs_bf16)

1139 .Case("nan.xorsign.abs.bf16x2",

1140 Intrinsic::nvvm_fmax_nan_xorsign_abs_bf16x2)

1141 .Case("xorsign.abs.bf16", Intrinsic::nvvm_fmax_xorsign_abs_bf16)

1142 .Case("xorsign.abs.bf16x2", Intrinsic::nvvm_fmax_xorsign_abs_bf16x2)

1144

1145 if (Name.consume_front("fmin."))

1147 .Case("bf16", Intrinsic::nvvm_fmin_bf16)

1148 .Case("bf16x2", Intrinsic::nvvm_fmin_bf16x2)

1149 .Case("ftz.bf16", Intrinsic::nvvm_fmin_ftz_bf16)

1150 .Case("ftz.bf16x2", Intrinsic::nvvm_fmin_ftz_bf16x2)

1151 .Case("ftz.nan.bf16", Intrinsic::nvvm_fmin_ftz_nan_bf16)

1152 .Case("ftz.nan.bf16x2", Intrinsic::nvvm_fmin_ftz_nan_bf16x2)

1153 .Case("ftz.nan.xorsign.abs.bf16",

1154 Intrinsic::nvvm_fmin_ftz_nan_xorsign_abs_bf16)

1155 .Case("ftz.nan.xorsign.abs.bf16x2",

1156 Intrinsic::nvvm_fmin_ftz_nan_xorsign_abs_bf16x2)

1157 .Case("ftz.xorsign.abs.bf16", Intrinsic::nvvm_fmin_ftz_xorsign_abs_bf16)

1158 .Case("ftz.xorsign.abs.bf16x2",

1159 Intrinsic::nvvm_fmin_ftz_xorsign_abs_bf16x2)

1160 .Case("nan.bf16", Intrinsic::nvvm_fmin_nan_bf16)

1161 .Case("nan.bf16x2", Intrinsic::nvvm_fmin_nan_bf16x2)

1162 .Case("nan.xorsign.abs.bf16", Intrinsic::nvvm_fmin_nan_xorsign_abs_bf16)

1163 .Case("nan.xorsign.abs.bf16x2",

1164 Intrinsic::nvvm_fmin_nan_xorsign_abs_bf16x2)

1165 .Case("xorsign.abs.bf16", Intrinsic::nvvm_fmin_xorsign_abs_bf16)

1166 .Case("xorsign.abs.bf16x2", Intrinsic::nvvm_fmin_xorsign_abs_bf16x2)

1168

1169 if (Name.consume_front("neg."))

1171 .Case("bf16", Intrinsic::nvvm_neg_bf16)

1172 .Case("bf16x2", Intrinsic::nvvm_neg_bf16x2)

1174

1176}

1177

1179 return Name.consume_front("local") || Name.consume_front("shared") ||

1180 Name.consume_front("global") || Name.consume_front("constant") ||

1181 Name.consume_front("param");

1182}

1183

1185 bool CanUpgradeDebugIntrinsicsToRecords) {

1186 assert(F && "Illegal to upgrade a non-existent Function.");

1187

1189

1190

1191 if (!Name.consume_front("llvm.") || Name.empty())

1192 return false;

1193

1194 switch (Name[0]) {

1195 default: break;

1196 case 'a': {

1197 bool IsArm = Name.consume_front("arm.");

1198 if (IsArm || Name.consume_front("aarch64.")) {

1200 return true;

1201 break;

1202 }

1203

1204 if (Name.consume_front("amdgcn.")) {

1205 if (Name == "alignbit") {

1206

1208 F->getParent(), Intrinsic::fshr, {F->getReturnType()});

1209 return true;

1210 }

1211

1212 if (Name.consume_front("atomic.")) {

1213 if (Name.starts_with("inc") || Name.starts_with("dec")) {

1214

1215

1216 NewFn = nullptr;

1217 return true;

1218 }

1219 break;

1220 }

1221

1222 if (Name.consume_front("ds.") || Name.consume_front("global.atomic.") ||

1223 Name.consume_front("flat.atomic.")) {

1224 if (Name.starts_with("fadd") ||

1225

1226 (Name.starts_with("fmin") && !Name.starts_with("fmin.num")) ||

1227 (Name.starts_with("fmax") && !Name.starts_with("fmax.num"))) {

1228

1229

1230 NewFn = nullptr;

1231 return true;

1232 }

1233 }

1234

1235 if (Name.starts_with("ldexp.")) {

1236

1238 F->getParent(), Intrinsic::ldexp,

1239 {F->getReturnType(), F->getArg(1)->getType()});

1240 return true;

1241 }

1242 break;

1243 }

1244

1245 break;

1246 }

1247 case 'c': {

1248 if (F->arg_size() == 1) {

1250 .StartsWith("ctlz.", Intrinsic::ctlz)

1251 .StartsWith("cttz.", Intrinsic::cttz)

1256 F->arg_begin()->getType());

1257 return true;

1258 }

1259 }

1260

1261 if (F->arg_size() == 2 && Name == "coro.end") {

1264 Intrinsic::coro_end);

1265 return true;

1266 }

1267

1268 break;

1269 }

1270 case 'd':

1271 if (Name.consume_front("dbg.")) {

1272

1273 if (CanUpgradeDebugIntrinsicsToRecords) {

1274 if (Name == "addr" || Name == "value" || Name == "assign" ||

1275 Name == "declare" || Name == "label") {

1276

1277 NewFn = nullptr;

1278

1279 return true;

1280 }

1281 }

1282

1283

1284 if (Name == "addr" || (Name == "value" && F->arg_size() == 4)) {

1287 Intrinsic::dbg_value);

1288 return true;

1289 }

1290 break;

1291 }

1292 break;

1293 case 'e':

1294 if (Name.consume_front("experimental.vector.")) {

1297

1298

1300 .StartsWith("extract.", Intrinsic::vector_extract)

1301 .StartsWith("insert.", Intrinsic::vector_insert)

1302 .StartsWith("splice.", Intrinsic::vector_splice)

1303 .StartsWith("reverse.", Intrinsic::vector_reverse)

1304 .StartsWith("interleave2.", Intrinsic::vector_interleave2)

1305 .StartsWith("deinterleave2.", Intrinsic::vector_deinterleave2)

1307 Intrinsic::vector_partial_reduce_add)

1310 const auto *FT = F->getFunctionType();

1312 if (ID == Intrinsic::vector_extract ||

1313 ID == Intrinsic::vector_interleave2)

1314

1315 Tys.push_back(FT->getReturnType());

1316 if (ID != Intrinsic::vector_interleave2)

1317 Tys.push_back(FT->getParamType(0));

1318 if (ID == Intrinsic::vector_insert ||

1319 ID == Intrinsic::vector_partial_reduce_add)

1320

1321 Tys.push_back(FT->getParamType(1));

1324 return true;

1325 }

1326

1327 if (Name.consume_front("reduce.")) {

1329 static const Regex R("^([a-z]+)\\.[a-z][0-9]+");

1330 if (R.match(Name, &Groups))

1332 .Case("add", Intrinsic::vector_reduce_add)

1333 .Case("mul", Intrinsic::vector_reduce_mul)

1334 .Case("and", Intrinsic::vector_reduce_and)

1335 .Case("or", Intrinsic::vector_reduce_or)

1336 .Case("xor", Intrinsic::vector_reduce_xor)

1337 .Case("smax", Intrinsic::vector_reduce_smax)

1338 .Case("smin", Intrinsic::vector_reduce_smin)

1339 .Case("umax", Intrinsic::vector_reduce_umax)

1340 .Case("umin", Intrinsic::vector_reduce_umin)

1341 .Case("fmax", Intrinsic::vector_reduce_fmax)

1342 .Case("fmin", Intrinsic::vector_reduce_fmin)

1344

1345 bool V2 = false;

1347 static const Regex R2("^v2\\.([a-z]+)\\.[fi][0-9]+");

1349 V2 = true;

1350 if (R2.match(Name, &Groups))

1352 .Case("fadd", Intrinsic::vector_reduce_fadd)

1353 .Case("fmul", Intrinsic::vector_reduce_fmul)

1355 }

1358 auto Args = F->getFunctionType()->params();

1360 {Args[V2 ? 1 : 0]});

1361 return true;

1362 }

1363 break;

1364 }

1365 break;

1366 }

1367 if (Name.consume_front("experimental.stepvector.")) {

1371 F->getParent(), ID, F->getFunctionType()->getReturnType());

1372 return true;

1373 }

1374 break;

1375 case 'f':

1376 if (Name.starts_with("flt.rounds")) {

1379 Intrinsic::get_rounding);

1380 return true;

1381 }

1382 break;

1383 case 'i':

1384 if (Name.starts_with("invariant.group.barrier")) {

1385

1386 auto Args = F->getFunctionType()->params();

1387 Type* ObjectPtr[1] = {Args[0]};

1390 F->getParent(), Intrinsic::launder_invariant_group, ObjectPtr);

1391 return true;

1392 }

1393 break;

1394 case 'l':

1395 if ((Name.starts_with("lifetime.start") ||

1396 Name.starts_with("lifetime.end")) &&

1397 F->arg_size() == 2) {

1398 Intrinsic::ID IID = Name.starts_with("lifetime.start")

1399 ? Intrinsic::lifetime_start

1400 : Intrinsic::lifetime_end;

1403 F->getArg(0)->getType());

1404 return true;

1405 }

1406 break;

1407 case 'm': {

1408

1409

1410

1412 .StartsWith("memcpy.", Intrinsic::memcpy)

1413 .StartsWith("memmove.", Intrinsic::memmove)

1415 if (F->arg_size() == 5) {

1417

1419 F->getFunctionType()->params().slice(0, 3);

1420 NewFn =

1422 return true;

1423 }

1424 }

1425 if (Name.starts_with("memset.") && F->arg_size() == 5) {

1427

1428 const auto *FT = F->getFunctionType();

1429 Type *ParamTypes[2] = {

1430 FT->getParamType(0),

1431 FT->getParamType(2)

1432 };

1434 Intrinsic::memset, ParamTypes);

1435 return true;

1436 }

1437

1438 unsigned MaskedID =

1440 .StartsWith("masked.load", Intrinsic::masked_load)

1441 .StartsWith("masked.gather", Intrinsic::masked_gather)

1442 .StartsWith("masked.store", Intrinsic::masked_store)

1443 .StartsWith("masked.scatter", Intrinsic::masked_scatter)

1445 if (MaskedID && F->arg_size() == 4) {

1447 if (MaskedID == Intrinsic::masked_load ||

1448 MaskedID == Intrinsic::masked_gather) {

1450 F->getParent(), MaskedID,

1451 {F->getReturnType(), F->getArg(0)->getType()});

1452 return true;

1453 }

1455 F->getParent(), MaskedID,

1456 {F->getArg(0)->getType(), F->getArg(1)->getType()});

1457 return true;

1458 }

1459 break;

1460 }

1461 case 'n': {

1462 if (Name.consume_front("nvvm.")) {

1463

1464 if (F->arg_size() == 1) {

1467 .Cases({"brev32", "brev64"}, Intrinsic::bitreverse)

1468 .Case("clz.i", Intrinsic::ctlz)

1469 .Case("popc.i", Intrinsic::ctpop)

1473 {F->getReturnType()});

1474 return true;

1475 }

1476 }

1477

1478

1479 if (F->getReturnType()->getScalarType()->isBFloatTy()) {

1482 NewFn = nullptr;

1483 return true;

1484 }

1485 }

1486

1487

1492 return true;

1493 }

1494

1495

1500 return true;

1501 }

1502

1503

1504

1505

1506

1507 bool Expand = false;

1508 if (Name.consume_front("abs."))

1509

1510 Expand =

1511 Name == "i" || Name == "ll" || Name == "bf16" || Name == "bf16x2";

1512 else if (Name.consume_front("fabs."))

1513

1514 Expand = Name == "f" || Name == "ftz.f" || Name == "d";

1515 else if (Name.consume_front("ex2.approx."))

1516

1517 Expand =

1518 Name == "f" || Name == "ftz.f" || Name == "d" || Name == "f16x2";

1519 else if (Name.consume_front("max.") || Name.consume_front("min."))

1520

1521 Expand = Name == "s" || Name == "i" || Name == "ll" || Name == "us" ||

1522 Name == "ui" || Name == "ull";

1523 else if (Name.consume_front("atomic.load."))

1524

1525

1532 else if (Name.consume_front("bitcast."))

1533

1534 Expand =

1535 Name == "f2i" || Name == "i2f" || Name == "ll2d" || Name == "d2ll";

1536 else if (Name.consume_front("rotate."))

1537

1538 Expand = Name == "b32" || Name == "b64" || Name == "right.b64";

1539 else if (Name.consume_front("ptr.gen.to."))

1540

1542 else if (Name.consume_front("ptr."))

1543

1545 else if (Name.consume_front("ldg.global."))

1546

1547 Expand = (Name.starts_with("i.") || Name.starts_with("f.") ||

1548 Name.starts_with("p."));

1549 else

1551 .Case("barrier0", true)

1552 .Case("barrier.n", true)

1553 .Case("barrier.sync.cnt", true)

1554 .Case("barrier.sync", true)

1555 .Case("barrier", true)

1556 .Case("bar.sync", true)

1557 .Case("clz.ll", true)

1558 .Case("popc.ll", true)

1559 .Case("h2f", true)

1560 .Case("swap.lo.hi.b64", true)

1561 .Case("tanh.approx.f32", true)

1563

1564 if (Expand) {

1565 NewFn = nullptr;

1566 return true;

1567 }

1568 break;

1569 }

1570 break;

1571 }

1572 case 'o':

1573 if (Name.starts_with("objectsize.")) {

1574 Type *Tys[2] = { F->getReturnType(), F->arg_begin()->getType() };

1575 if (F->arg_size() == 2 || F->arg_size() == 3) {

1578 Intrinsic::objectsize, Tys);

1579 return true;

1580 }

1581 }

1582 break;

1583

1584 case 'p':

1585 if (Name.starts_with("ptr.annotation.") && F->arg_size() == 4) {

1588 F->getParent(), Intrinsic::ptr_annotation,

1589 {F->arg_begin()->getType(), F->getArg(1)->getType()});

1590 return true;

1591 }

1592 break;

1593

1594 case 'r': {

1595 if (Name.consume_front("riscv.")) {

1598 .Case("aes32dsi", Intrinsic::riscv_aes32dsi)

1599 .Case("aes32dsmi", Intrinsic::riscv_aes32dsmi)

1600 .Case("aes32esi", Intrinsic::riscv_aes32esi)

1601 .Case("aes32esmi", Intrinsic::riscv_aes32esmi)

1604 if (F->getFunctionType()->getParamType(2)->isIntegerTy(32)) {

1607 return true;

1608 }

1609 break;

1610 }

1611

1613 .StartsWith("sm4ks", Intrinsic::riscv_sm4ks)

1614 .StartsWith("sm4ed", Intrinsic::riscv_sm4ed)

1617 if (F->getFunctionType()->getParamType(2)->isIntegerTy(32) ||

1618 F->getFunctionType()->getReturnType()->isIntegerTy(64)) {

1621 return true;

1622 }

1623 break;

1624 }

1625

1627 .StartsWith("sha256sig0", Intrinsic::riscv_sha256sig0)

1628 .StartsWith("sha256sig1", Intrinsic::riscv_sha256sig1)

1629 .StartsWith("sha256sum0", Intrinsic::riscv_sha256sum0)

1630 .StartsWith("sha256sum1", Intrinsic::riscv_sha256sum1)

1631 .StartsWith("sm3p0", Intrinsic::riscv_sm3p0)

1632 .StartsWith("sm3p1", Intrinsic::riscv_sm3p1)

1635 if (F->getFunctionType()->getReturnType()->isIntegerTy(64)) {

1638 return true;

1639 }

1640 break;

1641 }

1642 break;

1643 }

1644 } break;

1645

1646 case 's':

1647 if (Name == "stackprotectorcheck") {

1648 NewFn = nullptr;

1649 return true;

1650 }

1651 break;

1652

1653 case 't':

1654 if (Name == "thread.pointer") {

1656 F->getParent(), Intrinsic::thread_pointer, F->getReturnType());

1657 return true;

1658 }

1659 break;

1660

1661 case 'v': {

1662 if (Name == "var.annotation" && F->arg_size() == 4) {

1665 F->getParent(), Intrinsic::var_annotation,

1666 {{F->arg_begin()->getType(), F->getArg(1)->getType()}});

1667 return true;

1668 }

1669 break;

1670 }

1671

1672 case 'w':

1673 if (Name.consume_front("wasm.")) {

1676 .StartsWith("fma.", Intrinsic::wasm_relaxed_madd)

1677 .StartsWith("fms.", Intrinsic::wasm_relaxed_nmadd)

1678 .StartsWith("laneselect.", Intrinsic::wasm_relaxed_laneselect)

1683 F->getReturnType());

1684 return true;

1685 }

1686

1687 if (Name.consume_front("dot.i8x16.i7x16.")) {

1689 .Case("signed", Intrinsic::wasm_relaxed_dot_i8x16_i7x16_signed)

1690 .Case("add.signed",

1691 Intrinsic::wasm_relaxed_dot_i8x16_i7x16_add_signed)

1696 return true;

1697 }

1698 break;

1699 }

1700 break;

1701 }

1702 break;

1703

1704 case 'x':

1706 return true;

1707 }

1708

1710 if (ST && (ST->isLiteral() || ST->isPacked()) &&

1712

1713

1714

1715

1719 auto *FT = F->getFunctionType();

1721 auto *NewFT = FunctionType::get(NewST, FT->params(), FT->isVarArg());

1722 std::string Name = F->getName().str();

1724 NewFn = Function::Create(NewFT, F->getLinkage(), F->getAddressSpace(),

1725 Name, F->getParent());

1726

1727

1730 return true;

1731 }

1732 }

1733

1734

1736 if (Result != std::nullopt) {

1738 return true;

1739 }

1740

1741

1742

1743

1744

1745 return false;

1746}

1747

1749 bool CanUpgradeDebugIntrinsicsToRecords) {

1750 NewFn = nullptr;

1751 bool Upgraded =

1753

1754

1755 if (NewFn)

1756 F = NewFn;

1758

1761 F->setAttributes(

1763 }

1764 return Upgraded;

1765}

1766

1768 if (!(GV->hasName() && (GV->getName() == "llvm.global_ctors" ||

1769 GV->getName() == "llvm.global_dtors")) ||

1771 return nullptr;

1773 if (!ATy)

1774 return nullptr;

1777 return nullptr;

1778

1784 unsigned N = Init->getNumOperands();

1785 std::vector<Constant *> NewCtors(N);

1786 for (unsigned i = 0; i != N; ++i) {

1789 Ctor->getAggregateElement(1),

1791 }

1793

1795 NewInit, GV->getName());

1796}

1797

1798

1799

1801 unsigned Shift) {

1803 unsigned NumElts = ResultTy->getNumElements() * 8;

1804

1805

1807 Op = Builder.CreateBitCast(Op, VecTy, "cast");

1808

1809

1811

1812

1813

1814 if (Shift < 16) {

1815 int Idxs[64];

1816

1817 for (unsigned l = 0; l != NumElts; l += 16)

1818 for (unsigned i = 0; i != 16; ++i) {

1819 unsigned Idx = NumElts + i - Shift;

1820 if (Idx < NumElts)

1821 Idx -= NumElts - 16;

1822 Idxs[l + i] = Idx + l;

1823 }

1824

1825 Res = Builder.CreateShuffleVector(Res, Op, ArrayRef(Idxs, NumElts));

1826 }

1827

1828

1829 return Builder.CreateBitCast(Res, ResultTy, "cast");

1830}

1831

1832

1833

1835 unsigned Shift) {

1837 unsigned NumElts = ResultTy->getNumElements() * 8;

1838

1839

1841 Op = Builder.CreateBitCast(Op, VecTy, "cast");

1842

1843

1845

1846

1847

1848 if (Shift < 16) {

1849 int Idxs[64];

1850

1851 for (unsigned l = 0; l != NumElts; l += 16)

1852 for (unsigned i = 0; i != 16; ++i) {

1853 unsigned Idx = i + Shift;

1854 if (Idx >= 16)

1855 Idx += NumElts - 16;

1856 Idxs[l + i] = Idx + l;

1857 }

1858

1859 Res = Builder.CreateShuffleVector(Op, Res, ArrayRef(Idxs, NumElts));

1860 }

1861

1862

1863 return Builder.CreateBitCast(Res, ResultTy, "cast");

1864}

1865

1867 unsigned NumElts) {

1870 Builder.getInt1Ty(), cast(Mask->getType())->getBitWidth());

1871 Mask = Builder.CreateBitCast(Mask, MaskTy);

1872

1873

1874

1875 if (NumElts <= 4) {

1876 int Indices[4];

1877 for (unsigned i = 0; i != NumElts; ++i)

1878 Indices[i] = i;

1879 Mask = Builder.CreateShuffleVector(Mask, Mask, ArrayRef(Indices, NumElts),

1880 "extract");

1881 }

1882

1883 return Mask;

1884}

1885

1888

1890 if (C->isAllOnesValue())

1891 return Op0;

1892

1895 return Builder.CreateSelect(Mask, Op0, Op1);

1896}

1897

1900

1902 if (C->isAllOnesValue())

1903 return Op0;

1904

1906 Mask->getType()->getIntegerBitWidth());

1907 Mask = Builder.CreateBitCast(Mask, MaskTy);

1908 Mask = Builder.CreateExtractElement(Mask, (uint64_t)0);

1909 return Builder.CreateSelect(Mask, Op0, Op1);

1910}

1911

1912

1913

1914

1918 bool IsVALIGN) {

1920

1922 assert((IsVALIGN || NumElts % 16 == 0) && "Illegal NumElts for PALIGNR!");

1923 assert((!IsVALIGN || NumElts <= 16) && "NumElts too large for VALIGN!");

1925

1926

1927 if (IsVALIGN)

1928 ShiftVal &= (NumElts - 1);

1929

1930

1931

1932 if (ShiftVal >= 32)

1934

1935

1936

1937 if (ShiftVal > 16) {

1938 ShiftVal -= 16;

1939 Op1 = Op0;

1941 }

1942

1943 int Indices[64];

1944

1945 for (unsigned l = 0; l < NumElts; l += 16) {

1946 for (unsigned i = 0; i != 16; ++i) {

1947 unsigned Idx = ShiftVal + i;

1948 if (!IsVALIGN && Idx >= 16)

1949 Idx += NumElts - 16;

1950 Indices[l + i] = Idx + l;

1951 }

1952 }

1953

1954 Value *Align = Builder.CreateShuffleVector(

1955 Op1, Op0, ArrayRef(Indices, NumElts), "palignr");

1956

1958}

1959

1961 bool ZeroMask, bool IndexForm) {

1964 unsigned EltWidth = Ty->getScalarSizeInBits();

1965 bool IsFloat = Ty->isFPOrFPVectorTy();

1967 if (VecWidth == 128 && EltWidth == 32 && IsFloat)

1968 IID = Intrinsic::x86_avx512_vpermi2var_ps_128;

1969 else if (VecWidth == 128 && EltWidth == 32 && !IsFloat)

1970 IID = Intrinsic::x86_avx512_vpermi2var_d_128;

1971 else if (VecWidth == 128 && EltWidth == 64 && IsFloat)

1972 IID = Intrinsic::x86_avx512_vpermi2var_pd_128;

1973 else if (VecWidth == 128 && EltWidth == 64 && !IsFloat)

1974 IID = Intrinsic::x86_avx512_vpermi2var_q_128;

1975 else if (VecWidth == 256 && EltWidth == 32 && IsFloat)

1976 IID = Intrinsic::x86_avx512_vpermi2var_ps_256;

1977 else if (VecWidth == 256 && EltWidth == 32 && !IsFloat)

1978 IID = Intrinsic::x86_avx512_vpermi2var_d_256;

1979 else if (VecWidth == 256 && EltWidth == 64 && IsFloat)

1980 IID = Intrinsic::x86_avx512_vpermi2var_pd_256;

1981 else if (VecWidth == 256 && EltWidth == 64 && !IsFloat)

1982 IID = Intrinsic::x86_avx512_vpermi2var_q_256;

1983 else if (VecWidth == 512 && EltWidth == 32 && IsFloat)

1984 IID = Intrinsic::x86_avx512_vpermi2var_ps_512;

1985 else if (VecWidth == 512 && EltWidth == 32 && !IsFloat)

1986 IID = Intrinsic::x86_avx512_vpermi2var_d_512;

1987 else if (VecWidth == 512 && EltWidth == 64 && IsFloat)

1988 IID = Intrinsic::x86_avx512_vpermi2var_pd_512;

1989 else if (VecWidth == 512 && EltWidth == 64 && !IsFloat)

1990 IID = Intrinsic::x86_avx512_vpermi2var_q_512;

1991 else if (VecWidth == 128 && EltWidth == 16)

1992 IID = Intrinsic::x86_avx512_vpermi2var_hi_128;

1993 else if (VecWidth == 256 && EltWidth == 16)

1994 IID = Intrinsic::x86_avx512_vpermi2var_hi_256;

1995 else if (VecWidth == 512 && EltWidth == 16)

1996 IID = Intrinsic::x86_avx512_vpermi2var_hi_512;

1997 else if (VecWidth == 128 && EltWidth == 8)

1998 IID = Intrinsic::x86_avx512_vpermi2var_qi_128;

1999 else if (VecWidth == 256 && EltWidth == 8)

2000 IID = Intrinsic::x86_avx512_vpermi2var_qi_256;

2001 else if (VecWidth == 512 && EltWidth == 8)

2002 IID = Intrinsic::x86_avx512_vpermi2var_qi_512;

2003 else

2005

2008

2009

2010 if (!IndexForm)

2012

2013 Value *V = Builder.CreateIntrinsic(IID, Args);

2016 Ty);

2018}

2019

2025 Value *Res = Builder.CreateIntrinsic(IID, Ty, {Op0, Op1});

2026

2027 if (CI.arg_size() == 4) {

2030 Res = emitX86Select(Builder, Mask, Res, VecSrc);

2031 }

2032 return Res;

2033}

2034

2036 bool IsRotateRight) {

2040

2041

2042

2043

2044 if (Amt->getType() != Ty) {

2046 Amt = Builder.CreateIntCast(Amt, Ty->getScalarType(), false);

2047 Amt = Builder.CreateVectorSplat(NumElts, Amt);

2048 }

2049

2050 Intrinsic::ID IID = IsRotateRight ? Intrinsic::fshr : Intrinsic::fshl;

2051 Value *Res = Builder.CreateIntrinsic(IID, Ty, {Src, Src, Amt});

2052

2053 if (CI.arg_size() == 4) {

2056 Res = emitX86Select(Builder, Mask, Res, VecSrc);

2057 }

2058 return Res;

2059}

2060

2062 bool IsSigned) {

2066

2068 switch (Imm) {

2069 case 0x0:

2071 break;

2072 case 0x1:

2074 break;

2075 case 0x2:

2077 break;

2078 case 0x3:

2080 break;

2081 case 0x4:

2083 break;

2084 case 0x5:

2086 break;

2087 case 0x6:

2089 case 0x7:

2091 default:

2093 }

2094

2095 Value *Cmp = Builder.CreateICmp(Pred, LHS, RHS);

2096 Value *Ext = Builder.CreateSExt(Cmp, Ty);

2097 return Ext;

2098}

2099

2101 bool IsShiftRight, bool ZeroMask) {

2106

2107 if (IsShiftRight)

2109

2110

2111

2112

2113 if (Amt->getType() != Ty) {

2115 Amt = Builder.CreateIntCast(Amt, Ty->getScalarType(), false);

2116 Amt = Builder.CreateVectorSplat(NumElts, Amt);

2117 }

2118

2119 Intrinsic::ID IID = IsShiftRight ? Intrinsic::fshr : Intrinsic::fshl;

2120 Value *Res = Builder.CreateIntrinsic(IID, Ty, {Op0, Op1, Amt});

2121

2122 unsigned NumArgs = CI.arg_size();

2123 if (NumArgs >= 4) {

2128 Res = emitX86Select(Builder, Mask, Res, VecSrc);

2129 }

2130 return Res;

2131}

2132

2135 const Align Alignment =

2137 ? Align(Data->getType()->getPrimitiveSizeInBits().getFixedValue() / 8)

2139

2140

2142 if (C->isAllOnesValue())

2143 return Builder.CreateAlignedStore(Data, Ptr, Alignment);

2144

2145

2148 return Builder.CreateMaskedStore(Data, Ptr, Alignment, Mask);

2149}

2150

2154 const Align Alignment =

2158 8)

2160

2161

2163 if (C->isAllOnesValue())

2164 return Builder.CreateAlignedLoad(ValTy, Ptr, Alignment);

2165

2166

2169 return Builder.CreateMaskedLoad(ValTy, Ptr, Alignment, Mask, Passthru);

2170}

2171

2175 Value *Res = Builder.CreateIntrinsic(Intrinsic::abs, Ty,

2176 {Op0, Builder.getInt1(false)});

2179 return Res;

2180}

2181

2184

2185

2188

2189 if (IsSigned) {

2190

2191 Constant *ShiftAmt = ConstantInt::get(Ty, 32);

2192 LHS = Builder.CreateShl(LHS, ShiftAmt);

2193 LHS = Builder.CreateAShr(LHS, ShiftAmt);

2194 RHS = Builder.CreateShl(RHS, ShiftAmt);

2195 RHS = Builder.CreateAShr(RHS, ShiftAmt);

2196 } else {

2197

2198 Constant *Mask = ConstantInt::get(Ty, 0xffffffff);

2199 LHS = Builder.CreateAnd(LHS, Mask);

2200 RHS = Builder.CreateAnd(RHS, Mask);

2201 }

2202

2203 Value *Res = Builder.CreateMul(LHS, RHS);

2204

2207

2208 return Res;

2209}

2210

2211

2215 if (Mask) {

2217 if (C || C->isAllOnesValue())

2218 Vec = Builder.CreateAnd(Vec, getX86MaskVec(Builder, Mask, NumElts));

2219 }

2220

2221 if (NumElts < 8) {

2222 int Indices[8];

2223 for (unsigned i = 0; i != NumElts; ++i)

2224 Indices[i] = i;

2225 for (unsigned i = NumElts; i != 8; ++i)

2226 Indices[i] = NumElts + i % NumElts;

2227 Vec = Builder.CreateShuffleVector(Vec,

2229 Indices);

2230 }

2231 return Builder.CreateBitCast(Vec, Builder.getIntNTy(std::max(NumElts, 8U)));

2232}

2233

2235 unsigned CC, bool Signed) {

2238

2240 if (CC == 3) {

2243 } else if (CC == 7) {

2246 } else {

2248 switch (CC) {

2256 }

2257 Cmp = Builder.CreateICmp(Pred, Op0, CI.getArgOperand(1));

2258 }

2259

2261

2263}

2264

2265

2272

2278

2279 Value* AndNode = Builder.CreateAnd(Mask, APInt(8, 1));

2280 Value* Cmp = Builder.CreateIsNotNull(AndNode);

2281 Value* Extract1 = Builder.CreateExtractElement(B, (uint64_t)0);

2282 Value* Extract2 = Builder.CreateExtractElement(Src, (uint64_t)0);

2283 Value* Select = Builder.CreateSelect(Cmp, Extract1, Extract2);

2284 return Builder.CreateInsertElement(A, Select, (uint64_t)0);

2285}

2286

2292 return Builder.CreateSExt(Mask, ReturnOp, "vpmovm2");

2293}

2294

2295

2298 Name = Name.substr(12);

2299

2303 if (Name.starts_with("max.p")) {

2304 if (VecWidth == 128 && EltWidth == 32)

2305 IID = Intrinsic::x86_sse_max_ps;

2306 else if (VecWidth == 128 && EltWidth == 64)

2307 IID = Intrinsic::x86_sse2_max_pd;

2308 else if (VecWidth == 256 && EltWidth == 32)

2309 IID = Intrinsic::x86_avx_max_ps_256;

2310 else if (VecWidth == 256 && EltWidth == 64)

2311 IID = Intrinsic::x86_avx_max_pd_256;

2312 else

2314 } else if (Name.starts_with("min.p")) {

2315 if (VecWidth == 128 && EltWidth == 32)

2316 IID = Intrinsic::x86_sse_min_ps;

2317 else if (VecWidth == 128 && EltWidth == 64)

2318 IID = Intrinsic::x86_sse2_min_pd;

2319 else if (VecWidth == 256 && EltWidth == 32)

2320 IID = Intrinsic::x86_avx_min_ps_256;

2321 else if (VecWidth == 256 && EltWidth == 64)

2322 IID = Intrinsic::x86_avx_min_pd_256;

2323 else

2325 } else if (Name.starts_with("pshuf.b.")) {

2326 if (VecWidth == 128)

2327 IID = Intrinsic::x86_ssse3_pshuf_b_128;

2328 else if (VecWidth == 256)

2329 IID = Intrinsic::x86_avx2_pshuf_b;

2330 else if (VecWidth == 512)

2331 IID = Intrinsic::x86_avx512_pshuf_b_512;

2332 else

2334 } else if (Name.starts_with("pmul.hr.sw.")) {

2335 if (VecWidth == 128)

2336 IID = Intrinsic::x86_ssse3_pmul_hr_sw_128;

2337 else if (VecWidth == 256)

2338 IID = Intrinsic::x86_avx2_pmul_hr_sw;

2339 else if (VecWidth == 512)

2340 IID = Intrinsic::x86_avx512_pmul_hr_sw_512;

2341 else

2343 } else if (Name.starts_with("pmulh.w.")) {

2344 if (VecWidth == 128)

2345 IID = Intrinsic::x86_sse2_pmulh_w;

2346 else if (VecWidth == 256)

2347 IID = Intrinsic::x86_avx2_pmulh_w;

2348 else if (VecWidth == 512)

2349 IID = Intrinsic::x86_avx512_pmulh_w_512;

2350 else

2352 } else if (Name.starts_with("pmulhu.w.")) {

2353 if (VecWidth == 128)

2354 IID = Intrinsic::x86_sse2_pmulhu_w;

2355 else if (VecWidth == 256)

2356 IID = Intrinsic::x86_avx2_pmulhu_w;

2357 else if (VecWidth == 512)

2358 IID = Intrinsic::x86_avx512_pmulhu_w_512;

2359 else

2361 } else if (Name.starts_with("pmaddw.d.")) {

2362 if (VecWidth == 128)

2363 IID = Intrinsic::x86_sse2_pmadd_wd;

2364 else if (VecWidth == 256)

2365 IID = Intrinsic::x86_avx2_pmadd_wd;

2366 else if (VecWidth == 512)

2367 IID = Intrinsic::x86_avx512_pmaddw_d_512;

2368 else

2370 } else if (Name.starts_with("pmaddubs.w.")) {

2371 if (VecWidth == 128)

2372 IID = Intrinsic::x86_ssse3_pmadd_ub_sw_128;

2373 else if (VecWidth == 256)

2374 IID = Intrinsic::x86_avx2_pmadd_ub_sw;

2375 else if (VecWidth == 512)

2376 IID = Intrinsic::x86_avx512_pmaddubs_w_512;

2377 else

2379 } else if (Name.starts_with("packsswb.")) {

2380 if (VecWidth == 128)

2381 IID = Intrinsic::x86_sse2_packsswb_128;

2382 else if (VecWidth == 256)

2383 IID = Intrinsic::x86_avx2_packsswb;

2384 else if (VecWidth == 512)

2385 IID = Intrinsic::x86_avx512_packsswb_512;

2386 else

2388 } else if (Name.starts_with("packssdw.")) {

2389 if (VecWidth == 128)

2390 IID = Intrinsic::x86_sse2_packssdw_128;

2391 else if (VecWidth == 256)

2392 IID = Intrinsic::x86_avx2_packssdw;

2393 else if (VecWidth == 512)

2394 IID = Intrinsic::x86_avx512_packssdw_512;

2395 else

2397 } else if (Name.starts_with("packuswb.")) {

2398 if (VecWidth == 128)

2399 IID = Intrinsic::x86_sse2_packuswb_128;

2400 else if (VecWidth == 256)

2401 IID = Intrinsic::x86_avx2_packuswb;

2402 else if (VecWidth == 512)

2403 IID = Intrinsic::x86_avx512_packuswb_512;

2404 else

2406 } else if (Name.starts_with("packusdw.")) {

2407 if (VecWidth == 128)

2408 IID = Intrinsic::x86_sse41_packusdw;

2409 else if (VecWidth == 256)

2410 IID = Intrinsic::x86_avx2_packusdw;

2411 else if (VecWidth == 512)

2412 IID = Intrinsic::x86_avx512_packusdw_512;

2413 else

2415 } else if (Name.starts_with("vpermilvar.")) {

2416 if (VecWidth == 128 && EltWidth == 32)

2417 IID = Intrinsic::x86_avx_vpermilvar_ps;

2418 else if (VecWidth == 128 && EltWidth == 64)

2419 IID = Intrinsic::x86_avx_vpermilvar_pd;

2420 else if (VecWidth == 256 && EltWidth == 32)

2421 IID = Intrinsic::x86_avx_vpermilvar_ps_256;

2422 else if (VecWidth == 256 && EltWidth == 64)

2423 IID = Intrinsic::x86_avx_vpermilvar_pd_256;

2424 else if (VecWidth == 512 && EltWidth == 32)

2425 IID = Intrinsic::x86_avx512_vpermilvar_ps_512;

2426 else if (VecWidth == 512 && EltWidth == 64)

2427 IID = Intrinsic::x86_avx512_vpermilvar_pd_512;

2428 else

2430 } else if (Name == "cvtpd2dq.256") {

2431 IID = Intrinsic::x86_avx_cvt_pd2dq_256;

2432 } else if (Name == "cvtpd2ps.256") {

2433 IID = Intrinsic::x86_avx_cvt_pd2_ps_256;

2434 } else if (Name == "cvttpd2dq.256") {

2435 IID = Intrinsic::x86_avx_cvtt_pd2dq_256;

2436 } else if (Name == "cvttps2dq.128") {

2437 IID = Intrinsic::x86_sse2_cvttps2dq;

2438 } else if (Name == "cvttps2dq.256") {

2439 IID = Intrinsic::x86_avx_cvtt_ps2dq_256;

2440 } else if (Name.starts_with("permvar.")) {

2442 if (VecWidth == 256 && EltWidth == 32 && IsFloat)

2443 IID = Intrinsic::x86_avx2_permps;

2444 else if (VecWidth == 256 && EltWidth == 32 && !IsFloat)

2445 IID = Intrinsic::x86_avx2_permd;

2446 else if (VecWidth == 256 && EltWidth == 64 && IsFloat)

2447 IID = Intrinsic::x86_avx512_permvar_df_256;

2448 else if (VecWidth == 256 && EltWidth == 64 && !IsFloat)

2449 IID = Intrinsic::x86_avx512_permvar_di_256;

2450 else if (VecWidth == 512 && EltWidth == 32 && IsFloat)

2451 IID = Intrinsic::x86_avx512_permvar_sf_512;

2452 else if (VecWidth == 512 && EltWidth == 32 && !IsFloat)

2453 IID = Intrinsic::x86_avx512_permvar_si_512;

2454 else if (VecWidth == 512 && EltWidth == 64 && IsFloat)

2455 IID = Intrinsic::x86_avx512_permvar_df_512;

2456 else if (VecWidth == 512 && EltWidth == 64 && !IsFloat)

2457 IID = Intrinsic::x86_avx512_permvar_di_512;

2458 else if (VecWidth == 128 && EltWidth == 16)

2459 IID = Intrinsic::x86_avx512_permvar_hi_128;

2460 else if (VecWidth == 256 && EltWidth == 16)

2461 IID = Intrinsic::x86_avx512_permvar_hi_256;

2462 else if (VecWidth == 512 && EltWidth == 16)

2463 IID = Intrinsic::x86_avx512_permvar_hi_512;

2464 else if (VecWidth == 128 && EltWidth == 8)

2465 IID = Intrinsic::x86_avx512_permvar_qi_128;

2466 else if (VecWidth == 256 && EltWidth == 8)

2467 IID = Intrinsic::x86_avx512_permvar_qi_256;

2468 else if (VecWidth == 512 && EltWidth == 8)

2469 IID = Intrinsic::x86_avx512_permvar_qi_512;

2470 else

2472 } else if (Name.starts_with("dbpsadbw.")) {

2473 if (VecWidth == 128)

2474 IID = Intrinsic::x86_avx512_dbpsadbw_128;

2475 else if (VecWidth == 256)

2476 IID = Intrinsic::x86_avx512_dbpsadbw_256;

2477 else if (VecWidth == 512)

2478 IID = Intrinsic::x86_avx512_dbpsadbw_512;

2479 else

2481 } else if (Name.starts_with("pmultishift.qb.")) {

2482 if (VecWidth == 128)

2483 IID = Intrinsic::x86_avx512_pmultishift_qb_128;

2484 else if (VecWidth == 256)

2485 IID = Intrinsic::x86_avx512_pmultishift_qb_256;

2486 else if (VecWidth == 512)

2487 IID = Intrinsic::x86_avx512_pmultishift_qb_512;

2488 else

2490 } else if (Name.starts_with("conflict.")) {

2491 if (Name[9] == 'd' && VecWidth == 128)

2492 IID = Intrinsic::x86_avx512_conflict_d_128;

2493 else if (Name[9] == 'd' && VecWidth == 256)

2494 IID = Intrinsic::x86_avx512_conflict_d_256;

2495 else if (Name[9] == 'd' && VecWidth == 512)

2496 IID = Intrinsic::x86_avx512_conflict_d_512;

2497 else if (Name[9] == 'q' && VecWidth == 128)

2498 IID = Intrinsic::x86_avx512_conflict_q_128;

2499 else if (Name[9] == 'q' && VecWidth == 256)

2500 IID = Intrinsic::x86_avx512_conflict_q_256;

2501 else if (Name[9] == 'q' && VecWidth == 512)

2502 IID = Intrinsic::x86_avx512_conflict_q_512;

2503 else

2505 } else if (Name.starts_with("pavg.")) {

2506 if (Name[5] == 'b' && VecWidth == 128)

2507 IID = Intrinsic::x86_sse2_pavg_b;

2508 else if (Name[5] == 'b' && VecWidth == 256)

2509 IID = Intrinsic::x86_avx2_pavg_b;

2510 else if (Name[5] == 'b' && VecWidth == 512)

2511 IID = Intrinsic::x86_avx512_pavg_b_512;

2512 else if (Name[5] == 'w' && VecWidth == 128)

2513 IID = Intrinsic::x86_sse2_pavg_w;

2514 else if (Name[5] == 'w' && VecWidth == 256)

2515 IID = Intrinsic::x86_avx2_pavg_w;

2516 else if (Name[5] == 'w' && VecWidth == 512)

2517 IID = Intrinsic::x86_avx512_pavg_w_512;

2518 else

2520 } else

2521 return false;

2522

2524 Args.pop_back();

2525 Args.pop_back();

2526 Rep = Builder.CreateIntrinsic(IID, Args);

2527 unsigned NumArgs = CI.arg_size();

2530 return true;

2531}

2532

2533

2534

2536 size_t Pos;

2537 if (AsmStr->find("mov\tfp") == 0 &&

2538 AsmStr->find("objc_retainAutoreleaseReturnValue") != std:🧵:npos &&

2539 (Pos = AsmStr->find("# marker")) != std:🧵:npos) {

2540 AsmStr->replace(Pos, 1, ";");

2541 }

2542}

2543

2546 Value *Rep = nullptr;

2547

2548 if (Name == "abs.i" || Name == "abs.ll") {

2550 Value *Neg = Builder.CreateNeg(Arg, "neg");

2551 Value *Cmp = Builder.CreateICmpSGE(

2553 Rep = Builder.CreateSelect(Cmp, Arg, Neg, "abs");

2554 } else if (Name == "abs.bf16" || Name == "abs.bf16x2") {

2555 Type *Ty = (Name == "abs.bf16")

2559 Value *Abs = Builder.CreateUnaryIntrinsic(Intrinsic::nvvm_fabs, Arg);

2560 Rep = Builder.CreateBitCast(Abs, CI->getType());

2561 } else if (Name == "fabs.f" || Name == "fabs.ftz.f" || Name == "fabs.d") {

2562 Intrinsic::ID IID = (Name == "fabs.ftz.f") ? Intrinsic::nvvm_fabs_ftz

2563 : Intrinsic::nvvm_fabs;

2564 Rep = Builder.CreateUnaryIntrinsic(IID, CI->getArgOperand(0));

2565 } else if (Name.consume_front("ex2.approx.")) {

2566

2567 Intrinsic::ID IID = Name.starts_with("ftz") ? Intrinsic::nvvm_ex2_approx_ftz

2568 : Intrinsic::nvvm_ex2_approx;

2569 Rep = Builder.CreateUnaryIntrinsic(IID, CI->getArgOperand(0));

2570 } else if (Name.starts_with("atomic.load.add.f32.p") ||

2571 Name.starts_with("atomic.load.add.f64.p")) {

2576 } else if (Name.starts_with("atomic.load.inc.32.p") ||

2577 Name.starts_with("atomic.load.dec.32.p")) {

2582 Rep = Builder.CreateAtomicRMW(Op, Ptr, Val, MaybeAlign(),

2584 } else if (Name.consume_front("max.") &&

2585 (Name == "s" || Name == "i" || Name == "ll" || Name == "us" ||

2586 Name == "ui" || Name == "ull")) {

2589 Value *Cmp = Name.starts_with("u")

2590 ? Builder.CreateICmpUGE(Arg0, Arg1, "max.cond")

2591 : Builder.CreateICmpSGE(Arg0, Arg1, "max.cond");

2592 Rep = Builder.CreateSelect(Cmp, Arg0, Arg1, "max");

2593 } else if (Name.consume_front("min.") &&

2594 (Name == "s" || Name == "i" || Name == "ll" || Name == "us" ||

2595 Name == "ui" || Name == "ull")) {

2598 Value *Cmp = Name.starts_with("u")

2599 ? Builder.CreateICmpULE(Arg0, Arg1, "min.cond")

2600 : Builder.CreateICmpSLE(Arg0, Arg1, "min.cond");

2601 Rep = Builder.CreateSelect(Cmp, Arg0, Arg1, "min");

2602 } else if (Name == "clz.ll") {

2603

2605 Value *Ctlz = Builder.CreateIntrinsic(Intrinsic::ctlz, {Arg->getType()},

2606 {Arg, Builder.getFalse()},

2607 nullptr, "ctlz");

2608 Rep = Builder.CreateTrunc(Ctlz, Builder.getInt32Ty(), "ctlz.trunc");

2609 } else if (Name == "popc.ll") {

2610

2611

2613 Value *Popc = Builder.CreateIntrinsic(Intrinsic::ctpop, {Arg->getType()},

2614 Arg, nullptr, "ctpop");

2615 Rep = Builder.CreateTrunc(Popc, Builder.getInt32Ty(), "ctpop.trunc");

2616 } else if (Name == "h2f") {

2617 Rep = Builder.CreateIntrinsic(Intrinsic::convert_from_fp16,

2619 nullptr, "h2f");

2620 } else if (Name.consume_front("bitcast.") &&

2621 (Name == "f2i" || Name == "i2f" || Name == "ll2d" ||

2622 Name == "d2ll")) {

2624 } else if (Name == "rotate.b32") {

2627 Rep = Builder.CreateIntrinsic(Builder.getInt32Ty(), Intrinsic::fshl,

2628 {Arg, Arg, ShiftAmt});

2629 } else if (Name == "rotate.b64") {

2632 Value *ZExtShiftAmt = Builder.CreateZExt(CI->getOperand(1), Int64Ty);

2633 Rep = Builder.CreateIntrinsic(Int64Ty, Intrinsic::fshl,

2634 {Arg, Arg, ZExtShiftAmt});

2635 } else if (Name == "rotate.right.b64") {

2638 Value *ZExtShiftAmt = Builder.CreateZExt(CI->getOperand(1), Int64Ty);

2639 Rep = Builder.CreateIntrinsic(Int64Ty, Intrinsic::fshr,

2640 {Arg, Arg, ZExtShiftAmt});

2641 } else if (Name == "swap.lo.hi.b64") {

2644 Rep = Builder.CreateIntrinsic(Int64Ty, Intrinsic::fshl,

2645 {Arg, Arg, Builder.getInt64(32)});

2646 } else if ((Name.consume_front("ptr.gen.to.") &&

2649 Name.starts_with(".to.gen"))) {

2651 } else if (Name.consume_front("ldg.global")) {

2654

2655 Value *ASC = Builder.CreateAddrSpaceCast(Ptr, Builder.getPtrTy(1));

2656 Instruction *LD = Builder.CreateAlignedLoad(CI->getType(), ASC, PtrAlign);

2658 LD->setMetadata(LLVMContext::MD_invariant_load, MD);

2659 return LD;

2660 } else if (Name == "tanh.approx.f32") {

2661

2664 Rep = Builder.CreateUnaryIntrinsic(Intrinsic::tanh, CI->getArgOperand(0),

2665 FMF);

2666 } else if (Name == "barrier0" || Name == "barrier.n" || Name == "bar.sync") {

2668 Name.ends_with('0') ? Builder.getInt32(0) : CI->getArgOperand(0);

2669 Rep = Builder.CreateIntrinsic(Intrinsic::nvvm_barrier_cta_sync_aligned_all,

2670 {}, {Arg});

2671 } else if (Name == "barrier") {

2672 Rep = Builder.CreateIntrinsic(

2673 Intrinsic::nvvm_barrier_cta_sync_aligned_count, {},

2675 } else if (Name == "barrier.sync") {

2676 Rep = Builder.CreateIntrinsic(Intrinsic::nvvm_barrier_cta_sync_all, {},

2678 } else if (Name == "barrier.sync.cnt") {

2679 Rep = Builder.CreateIntrinsic(Intrinsic::nvvm_barrier_cta_sync_count, {},

2681 } else {

2684 F->getReturnType()->getScalarType()->isBFloatTy()) {

2688 for (size_t I = 0; I < NewFn->arg_size(); ++I) {

2692 Args.push_back(

2694 ? Builder.CreateBitCast(Arg, NewType)

2695 : Arg);

2696 }

2697 Rep = Builder.CreateCall(NewFn, Args);

2698 if (F->getReturnType()->isIntegerTy())

2699 Rep = Builder.CreateBitCast(Rep, F->getReturnType());

2700 }

2701 }

2702

2703 return Rep;

2704}

2705

2709 Value *Rep = nullptr;

2710

2711 if (Name.starts_with("sse4a.movnt.")) {

2716

2719

2720

2721

2722 Value *Extract =

2723 Builder.CreateExtractElement(Arg1, (uint64_t)0, "extractelement");

2724

2725 StoreInst *SI = Builder.CreateAlignedStore(Extract, Arg0, Align(1));

2726 SI->setMetadata(LLVMContext::MD_nontemporal, Node);

2727 } else if (Name.starts_with("avx.movnt.") ||

2728 Name.starts_with("avx512.storent.")) {

2733

2736

2737 StoreInst *SI = Builder.CreateAlignedStore(

2738 Arg1, Arg0,

2740 SI->setMetadata(LLVMContext::MD_nontemporal, Node);

2741 } else if (Name == "sse2.storel.dq") {

2744

2746 Value *BC0 = Builder.CreateBitCast(Arg1, NewVecTy, "cast");

2747 Value *Elt = Builder.CreateExtractElement(BC0, (uint64_t)0);

2748 Builder.CreateAlignedStore(Elt, Arg0, Align(1));

2749 } else if (Name.starts_with("sse.storeu.") ||

2750 Name.starts_with("sse2.storeu.") ||

2751 Name.starts_with("avx.storeu.")) {

2754 Builder.CreateAlignedStore(Arg1, Arg0, Align(1));

2755 } else if (Name == "avx512.mask.store.ss") {

2756 Value *Mask = Builder.CreateAnd(CI->getArgOperand(2), Builder.getInt8(1));

2758 Mask, false);

2759 } else if (Name.starts_with("avx512.mask.store")) {

2760

2761 bool Aligned = Name[17] != 'u';

2764 } else if (Name.starts_with("sse2.pcmp") || Name.starts_with("avx2.pcmp")) {

2765

2766

2767 bool CmpEq = Name[9] == 'e';

2770 Rep = Builder.CreateSExt(Rep, CI->getType(), "");

2771 } else if (Name.starts_with("avx512.broadcastm")) {

2777 Rep = Builder.CreateZExt(CI->getArgOperand(0), ExtTy);

2778 Rep = Builder.CreateVectorSplat(NumElts, Rep);

2779 } else if (Name == "sse.sqrt.ss" || Name == "sse2.sqrt.sd") {

2781 Value *Elt0 = Builder.CreateExtractElement(Vec, (uint64_t)0);

2782 Elt0 = Builder.CreateIntrinsic(Intrinsic::sqrt, Elt0->getType(), Elt0);

2783 Rep = Builder.CreateInsertElement(Vec, Elt0, (uint64_t)0);

2784 } else if (Name.starts_with("avx.sqrt.p") ||

2785 Name.starts_with("sse2.sqrt.p") ||

2786 Name.starts_with("sse.sqrt.p")) {

2787 Rep = Builder.CreateIntrinsic(Intrinsic::sqrt, CI->getType(),

2788 {CI->getArgOperand(0)});

2789 } else if (Name.starts_with("avx512.mask.sqrt.p")) {

2793 Intrinsic::ID IID = Name[18] == 's' ? Intrinsic::x86_avx512_sqrt_ps_512

2794 : Intrinsic::x86_avx512_sqrt_pd_512;

2795

2797 Rep = Builder.CreateIntrinsic(IID, Args);

2798 } else {

2799 Rep = Builder.CreateIntrinsic(Intrinsic::sqrt, CI->getType(),

2800 {CI->getArgOperand(0)});

2801 }

2802 Rep =

2804 } else if (Name.starts_with("avx512.ptestm") ||

2805 Name.starts_with("avx512.ptestnm")) {

2809 Rep = Builder.CreateAnd(Op0, Op1);

2815 Rep = Builder.CreateICmp(Pred, Rep, Zero);

2817 } else if (Name.starts_with("avx512.mask.pbroadcast")) {

2819 ->getNumElements();

2820 Rep = Builder.CreateVectorSplat(NumElts, CI->getArgOperand(0));

2821 Rep =

2823 } else if (Name.starts_with("avx512.kunpck")) {

2827 int Indices[64];

2828 for (unsigned i = 0; i != NumElts; ++i)

2829 Indices[i] = i;

2830

2831

2832

2833 LHS = Builder.CreateShuffleVector(LHS, LHS, ArrayRef(Indices, NumElts / 2));

2834 RHS = Builder.CreateShuffleVector(RHS, RHS, ArrayRef(Indices, NumElts / 2));

2835

2836

2837 Rep = Builder.CreateShuffleVector(RHS, LHS, ArrayRef(Indices, NumElts));

2838 Rep = Builder.CreateBitCast(Rep, CI->getType());

2839 } else if (Name == "avx512.kand.w") {

2842 Rep = Builder.CreateAnd(LHS, RHS);

2843 Rep = Builder.CreateBitCast(Rep, CI->getType());

2844 } else if (Name == "avx512.kandn.w") {

2847 LHS = Builder.CreateNot(LHS);

2848 Rep = Builder.CreateAnd(LHS, RHS);

2849 Rep = Builder.CreateBitCast(Rep, CI->getType());

2850 } else if (Name == "avx512.kor.w") {

2853 Rep = Builder.CreateOr(LHS, RHS);

2854 Rep = Builder.CreateBitCast(Rep, CI->getType());

2855 } else if (Name == "avx512.kxor.w") {

2858 Rep = Builder.CreateXor(LHS, RHS);

2859 Rep = Builder.CreateBitCast(Rep, CI->getType());

2860 } else if (Name == "avx512.kxnor.w") {

2863 LHS = Builder.CreateNot(LHS);

2864 Rep = Builder.CreateXor(LHS, RHS);

2865 Rep = Builder.CreateBitCast(Rep, CI->getType());

2866 } else if (Name == "avx512.knot.w") {

2868 Rep = Builder.CreateNot(Rep);

2869 Rep = Builder.CreateBitCast(Rep, CI->getType());

2870 } else if (Name == "avx512.kortestz.w" || Name == "avx512.kortestc.w") {

2873 Rep = Builder.CreateOr(LHS, RHS);

2874 Rep = Builder.CreateBitCast(Rep, Builder.getInt16Ty());

2876 if (Name[14] == 'c')

2878 else

2880 Rep = Builder.CreateICmpEQ(Rep, C);

2881 Rep = Builder.CreateZExt(Rep, Builder.getInt32Ty());

2882 } else if (Name == "sse.add.ss" || Name == "sse2.add.sd" ||

2883 Name == "sse.sub.ss" || Name == "sse2.sub.sd" ||

2884 Name == "sse.mul.ss" || Name == "sse2.mul.sd" ||

2885 Name == "sse.div.ss" || Name == "sse2.div.sd") {

2888 ConstantInt::get(I32Ty, 0));

2890 ConstantInt::get(I32Ty, 0));

2892 if (Name.contains(".add."))

2893 EltOp = Builder.CreateFAdd(Elt0, Elt1);

2894 else if (Name.contains(".sub."))

2895 EltOp = Builder.CreateFSub(Elt0, Elt1);

2896 else if (Name.contains(".mul."))

2897 EltOp = Builder.CreateFMul(Elt0, Elt1);

2898 else

2899 EltOp = Builder.CreateFDiv(Elt0, Elt1);

2900 Rep = Builder.CreateInsertElement(CI->getArgOperand(0), EltOp,

2901 ConstantInt::get(I32Ty, 0));

2902 } else if (Name.starts_with("avx512.mask.pcmp")) {

2903

2904 bool CmpEq = Name[16] == 'e';

2906 } else if (Name.starts_with("avx512.mask.vpshufbitqmb.")) {

2910 switch (VecWidth) {

2911 default:

2913 case 128:

2914 IID = Intrinsic::x86_avx512_vpshufbitqmb_128;

2915 break;

2916 case 256:

2917 IID = Intrinsic::x86_avx512_vpshufbitqmb_256;

2918 break;

2919 case 512:

2920 IID = Intrinsic::x86_avx512_vpshufbitqmb_512;

2921 break;

2922 }

2923

2924 Rep =

2927 } else if (Name.starts_with("avx512.mask.fpclass.p")) {

2932 if (VecWidth == 128 && EltWidth == 32)

2933 IID = Intrinsic::x86_avx512_fpclass_ps_128;

2934 else if (VecWidth == 256 && EltWidth == 32)

2935 IID = Intrinsic::x86_avx512_fpclass_ps_256;

2936 else if (VecWidth == 512 && EltWidth == 32)

2937 IID = Intrinsic::x86_avx512_fpclass_ps_512;

2938 else if (VecWidth == 128 && EltWidth == 64)

2939 IID = Intrinsic::x86_avx512_fpclass_pd_128;

2940 else if (VecWidth == 256 && EltWidth == 64)

2941 IID = Intrinsic::x86_avx512_fpclass_pd_256;

2942 else if (VecWidth == 512 && EltWidth == 64)

2943 IID = Intrinsic::x86_avx512_fpclass_pd_512;

2944 else

2946

2947 Rep =

2950 } else if (Name.starts_with("avx512.cmp.p")) {

2952 Type *OpTy = Args[0]->getType();

2956 if (VecWidth == 128 && EltWidth == 32)

2957 IID = Intrinsic::x86_avx512_mask_cmp_ps_128;

2958 else if (VecWidth == 256 && EltWidth == 32)

2959 IID = Intrinsic::x86_avx512_mask_cmp_ps_256;

2960 else if (VecWidth == 512 && EltWidth == 32)

2961 IID = Intrinsic::x86_avx512_mask_cmp_ps_512;

2962 else if (VecWidth == 128 && EltWidth == 64)

2963 IID = Intrinsic::x86_avx512_mask_cmp_pd_128;

2964 else if (VecWidth == 256 && EltWidth == 64)

2965 IID = Intrinsic::x86_avx512_mask_cmp_pd_256;

2966 else if (VecWidth == 512 && EltWidth == 64)

2967 IID = Intrinsic::x86_avx512_mask_cmp_pd_512;

2968 else

2970

2972 if (VecWidth == 512)

2974 Args.push_back(Mask);

2975

2976 Rep = Builder.CreateIntrinsic(IID, Args);

2977 } else if (Name.starts_with("avx512.mask.cmp.")) {

2978

2981 } else if (Name.starts_with("avx512.mask.ucmp.")) {

2984 } else if (Name.starts_with("avx512.cvtb2mask.") ||

2985 Name.starts_with("avx512.cvtw2mask.") ||

2986 Name.starts_with("avx512.cvtd2mask.") ||

2987 Name.starts_with("avx512.cvtq2mask.")) {

2992 } else if (Name == "ssse3.pabs.b.128" || Name == "ssse3.pabs.w.128" ||

2993 Name == "ssse3.pabs.d.128" || Name.starts_with("avx2.pabs") ||

2994 Name.starts_with("avx512.mask.pabs")) {

2996 } else if (Name == "sse41.pmaxsb" || Name == "sse2.pmaxs.w" ||

2997 Name == "sse41.pmaxsd" || Name.starts_with("avx2.pmaxs") ||

2998 Name.starts_with("avx512.mask.pmaxs")) {

3000 } else if (Name == "sse2.pmaxu.b" || Name == "sse41.pmaxuw" ||

3001 Name == "sse41.pmaxud" || Name.starts_with("avx2.pmaxu") ||

3002 Name.starts_with("avx512.mask.pmaxu")) {

3004 } else if (Name == "sse41.pminsb" || Name == "sse2.pmins.w" ||

3005 Name == "sse41.pminsd" || Name.starts_with("avx2.pmins") ||

3006 Name.starts_with("avx512.mask.pmins")) {

3008 } else if (Name == "sse2.pminu.b" || Name == "sse41.pminuw" ||

3009 Name == "sse41.pminud" || Name.starts_with("avx2.pminu") ||

3010 Name.starts_with("avx512.mask.pminu")) {

3012 } else if (Name == "sse2.pmulu.dq" || Name == "avx2.pmulu.dq" ||

3013 Name == "avx512.pmulu.dq.512" ||

3014 Name.starts_with("avx512.mask.pmulu.dq.")) {

3015 Rep = upgradePMULDQ(Builder, *CI, false);

3016 } else if (Name == "sse41.pmuldq" || Name == "avx2.pmul.dq" ||

3017 Name == "avx512.pmul.dq.512" ||

3018 Name.starts_with("avx512.mask.pmul.dq.")) {

3019 Rep = upgradePMULDQ(Builder, *CI, true);

3020 } else if (Name == "sse.cvtsi2ss" || Name == "sse2.cvtsi2sd" ||

3021 Name == "sse.cvtsi642ss" || Name == "sse2.cvtsi642sd") {

3022 Rep =

3026 } else if (Name == "avx512.cvtusi2sd") {

3027 Rep =

3031 } else if (Name == "sse2.cvtss2sd") {

3033 Rep = Builder.CreateFPExt(

3036 } else if (Name == "sse2.cvtdq2pd" || Name == "sse2.cvtdq2ps" ||

3037 Name == "avx.cvtdq2.pd.256" || Name == "avx.cvtdq2.ps.256" ||

3038 Name.starts_with("avx512.mask.cvtdq2pd.") ||

3039 Name.starts_with("avx512.mask.cvtudq2pd.") ||

3040 Name.starts_with("avx512.mask.cvtdq2ps.") ||

3041 Name.starts_with("avx512.mask.cvtudq2ps.") ||

3042 Name.starts_with("avx512.mask.cvtqq2pd.") ||

3043 Name.starts_with("avx512.mask.cvtuqq2pd.") ||

3044 Name == "avx512.mask.cvtqq2ps.256" ||

3045 Name == "avx512.mask.cvtqq2ps.512" ||

3046 Name == "avx512.mask.cvtuqq2ps.256" ||

3047 Name == "avx512.mask.cvtuqq2ps.512" || Name == "sse2.cvtps2pd" ||

3048 Name == "avx.cvt.ps2.pd.256" ||

3049 Name == "avx512.mask.cvtps2pd.128" ||

3050 Name == "avx512.mask.cvtps2pd.256") {

3054

3055 unsigned NumDstElts = DstTy->getNumElements();

3057 assert(NumDstElts == 2 && "Unexpected vector size");

3058 Rep = Builder.CreateShuffleVector(Rep, Rep, ArrayRef{0, 1});

3059 }

3060

3061 bool IsPS2PD = SrcTy->getElementType()->isFloatTy();

3062 bool IsUnsigned = Name.contains("cvtu");

3063 if (IsPS2PD)

3064 Rep = Builder.CreateFPExt(Rep, DstTy, "cvtps2pd");

3065 else if (CI->arg_size() == 4 &&

3068 Intrinsic::ID IID = IsUnsigned ? Intrinsic::x86_avx512_uitofp_round

3069 : Intrinsic::x86_avx512_sitofp_round;

3070 Rep = Builder.CreateIntrinsic(IID, {DstTy, SrcTy},

3072 } else {

3073 Rep = IsUnsigned ? Builder.CreateUIToFP(Rep, DstTy, "cvt")

3074 : Builder.CreateSIToFP(Rep, DstTy, "cvt");

3075 }

3076

3080 } else if (Name.starts_with("avx512.mask.vcvtph2ps.") ||

3081 Name.starts_with("vcvtph2ps.")) {

3085 unsigned NumDstElts = DstTy->getNumElements();

3086 if (NumDstElts != SrcTy->getNumElements()) {

3087 assert(NumDstElts == 4 && "Unexpected vector size");

3088 Rep = Builder.CreateShuffleVector(Rep, Rep, ArrayRef{0, 1, 2, 3});

3089 }

3090 Rep = Builder.CreateBitCast(

3092 Rep = Builder.CreateFPExt(Rep, DstTy, "cvtph2ps");

3096 } else if (Name.starts_with("avx512.mask.load")) {

3097

3098 bool Aligned = Name[16] != 'u';

3101 } else if (Name.starts_with("avx512.mask.expand.load.")) {

3104 ResultTy->getNumElements());

3105

3106 Rep = Builder.CreateIntrinsic(

3107 Intrinsic::masked_expandload, ResultTy,

3109 } else if (Name.starts_with("avx512.mask.compress.store.")) {

3111 Value *MaskVec =

3114

3115 Rep = Builder.CreateIntrinsic(

3116 Intrinsic::masked_compressstore, ResultTy,

3118 } else if (Name.starts_with("avx512.mask.compress.") ||

3119 Name.starts_with("avx512.mask.expand.")) {

3121

3123 ResultTy->getNumElements());

3124

3125 bool IsCompress = Name[12] == 'c';

3126 Intrinsic::ID IID = IsCompress ? Intrinsic::x86_avx512_mask_compress

3127 : Intrinsic::x86_avx512_mask_expand;

3128 Rep = Builder.CreateIntrinsic(

3130 } else if (Name.starts_with("xop.vpcom")) {

3131 bool IsSigned;

3132 if (Name.ends_with("ub") || Name.ends_with("uw") || Name.ends_with("ud") ||

3133 Name.ends_with("uq"))

3134 IsSigned = false;

3135 else if (Name.ends_with("b") || Name.ends_with("w") ||

3136 Name.ends_with("d") || Name.ends_with("q"))

3137 IsSigned = true;

3138 else

3140

3141 unsigned Imm;

3144 } else {

3145 Name = Name.substr(9);

3146 if (Name.starts_with("lt"))

3147 Imm = 0;

3148 else if (Name.starts_with("le"))

3149 Imm = 1;

3150 else if (Name.starts_with("gt"))

3151 Imm = 2;

3152 else if (Name.starts_with("ge"))

3153 Imm = 3;

3154 else if (Name.starts_with("eq"))

3155 Imm = 4;

3156 else if (Name.starts_with("ne"))

3157 Imm = 5;

3158 else if (Name.starts_with("false"))

3159 Imm = 6;

3160 else if (Name.starts_with("true"))

3161 Imm = 7;

3162 else

3164 }

3165

3167 } else if (Name.starts_with("xop.vpcmov")) {

3169 Value *NotSel = Builder.CreateNot(Sel);

3172 Rep = Builder.CreateOr(Sel0, Sel1);

3173 } else if (Name.starts_with("xop.vprot") || Name.starts_with("avx512.prol") ||

3174 Name.starts_with("avx512.mask.prol")) {

3176 } else if (Name.starts_with("avx512.pror") ||

3177 Name.starts_with("avx512.mask.pror")) {

3179 } else if (Name.starts_with("avx512.vpshld.") ||

3180 Name.starts_with("avx512.mask.vpshld") ||

3181 Name.starts_with("avx512.maskz.vpshld")) {

3182 bool ZeroMask = Name[11] == 'z';

3184 } else if (Name.starts_with("avx512.vpshrd.") ||

3185 Name.starts_with("avx512.mask.vpshrd") ||

3186 Name.starts_with("avx512.maskz.vpshrd")) {

3187 bool ZeroMask = Name[11] == 'z';

3189 } else if (Name == "sse42.crc32.64.8") {

3192 Rep = Builder.CreateIntrinsic(Intrinsic::x86_sse42_crc32_32_8,

3194 Rep = Builder.CreateZExt(Rep, CI->getType(), "");

3195 } else if (Name.starts_with("avx.vbroadcast.s") ||

3196 Name.starts_with("avx512.vbroadcast.s")) {

3197

3199 Type *EltTy = VecTy->getElementType();

3200 unsigned EltNum = VecTy->getNumElements();

3204 for (unsigned I = 0; I < EltNum; ++I)

3205 Rep = Builder.CreateInsertElement(Rep, Load, ConstantInt::get(I32Ty, I));

3206 } else if (Name.starts_with("sse41.pmovsx") ||

3207 Name.starts_with("sse41.pmovzx") ||

3208 Name.starts_with("avx2.pmovsx") ||

3209 Name.starts_with("avx2.pmovzx") ||

3210 Name.starts_with("avx512.mask.pmovsx") ||

3211 Name.starts_with("avx512.mask.pmovzx")) {

3213 unsigned NumDstElts = DstTy->getNumElements();

3214

3215

3217 for (unsigned i = 0; i != NumDstElts; ++i)

3218 ShuffleMask[i] = i;

3219

3220 Value *SV = Builder.CreateShuffleVector(CI->getArgOperand(0), ShuffleMask);

3221

3222 bool DoSext = Name.contains("pmovsx");

3223 Rep =

3224 DoSext ? Builder.CreateSExt(SV, DstTy) : Builder.CreateZExt(SV, DstTy);

3225

3229 } else if (Name == "avx512.mask.pmov.qd.256" ||

3230 Name == "avx512.mask.pmov.qd.512" ||

3231 Name == "avx512.mask.pmov.wb.256" ||

3232 Name == "avx512.mask.pmov.wb.512") {

3234 Rep = Builder.CreateTrunc(CI->getArgOperand(0), Ty);

3235 Rep =

3237 } else if (Name.starts_with("avx.vbroadcastf128") ||

3238 Name == "avx2.vbroadcasti128") {

3239

3244 if (NumSrcElts == 2)

3245 Rep = Builder.CreateShuffleVector(Load, ArrayRef{0, 1, 0, 1});

3246 else

3247 Rep = Builder.CreateShuffleVector(Load,

3249 } else if (Name.starts_with("avx512.mask.shuf.i") ||

3250 Name.starts_with("avx512.mask.shuf.f")) {

3255 unsigned ControlBitsMask = NumLanes - 1;

3256 unsigned NumControlBits = NumLanes / 2;

3258

3259 for (unsigned l = 0; l != NumLanes; ++l) {

3260 unsigned LaneMask = (Imm >> (l * NumControlBits)) & ControlBitsMask;

3261

3262 if (l >= NumLanes / 2)

3263 LaneMask += NumLanes;

3264 for (unsigned i = 0; i != NumElementsInLane; ++i)

3265 ShuffleMask.push_back(LaneMask * NumElementsInLane + i);

3266 }

3267 Rep = Builder.CreateShuffleVector(CI->getArgOperand(0),

3269 Rep =

3271 } else if (Name.starts_with("avx512.mask.broadcastf") ||

3272 Name.starts_with("avx512.mask.broadcasti")) {

3274 ->getNumElements();

3275 unsigned NumDstElts =

3277

3279 for (unsigned i = 0; i != NumDstElts; ++i)

3280 ShuffleMask[i] = i % NumSrcElts;

3281

3282 Rep = Builder.CreateShuffleVector(CI->getArgOperand(0),

3284 Rep =

3286 } else if (Name.starts_with("avx2.pbroadcast") ||

3287 Name.starts_with("avx2.vbroadcast") ||

3288 Name.starts_with("avx512.pbroadcast") ||

3289 Name.starts_with("avx512.mask.broadcast.s")) {

3290

3296 Rep = Builder.CreateShuffleVector(Op, M);

3297

3301 } else if (Name.starts_with("sse2.padds.") ||

3302 Name.starts_with("avx2.padds.") ||

3303 Name.starts_with("avx512.padds.") ||

3304 Name.starts_with("avx512.mask.padds.")) {

3306 } else if (Name.starts_with("sse2.psubs.") ||

3307 Name.starts_with("avx2.psubs.") ||

3308 Name.starts_with("avx512.psubs.") ||

3309 Name.starts_with("avx512.mask.psubs.")) {

3311 } else if (Name.starts_with("sse2.paddus.") ||

3312 Name.starts_with("avx2.paddus.") ||

3313 Name.starts_with("avx512.mask.paddus.")) {

3315 } else if (Name.starts_with("sse2.psubus.") ||

3316 Name.starts_with("avx2.psubus.") ||

3317 Name.starts_with("avx512.mask.psubus.")) {

3319 } else if (Name.starts_with("avx512.mask.palignr.")) {

3323 false);

3324 } else if (Name.starts_with("avx512.mask.valign.")) {

3328 } else if (Name == "sse2.psll.dq" || Name == "avx2.psll.dq") {

3329

3332 Shift / 8);

3333 } else if (Name == "sse2.psrl.dq" || Name == "avx2.psrl.dq") {

3334

3337 Shift / 8);

3338 } else if (Name == "sse2.psll.dq.bs" || Name == "avx2.psll.dq.bs" ||

3339 Name == "avx512.psll.dq.512") {

3340

3343 } else if (Name == "sse2.psrl.dq.bs" || Name == "avx2.psrl.dq.bs" ||

3344 Name == "avx512.psrl.dq.512") {

3345

3348 } else if (Name == "sse41.pblendw" || Name.starts_with("sse41.blendp") ||

3349 Name.starts_with("avx.blend.p") || Name == "avx2.pblendw" ||

3350 Name.starts_with("avx2.pblendd.")) {

3355 unsigned NumElts = VecTy->getNumElements();

3356

3358 for (unsigned i = 0; i != NumElts; ++i)

3359 Idxs[i] = ((Imm >> (i % 8)) & 1) ? i + NumElts : i;

3360

3361 Rep = Builder.CreateShuffleVector(Op0, Op1, Idxs);

3362 } else if (Name.starts_with("avx.vinsertf128.") ||

3363 Name == "avx2.vinserti128" ||

3364 Name.starts_with("avx512.mask.insert")) {

3368 unsigned DstNumElts =

3370 unsigned SrcNumElts =

3372 unsigned Scale = DstNumElts / SrcNumElts;

3373

3374

3375 Imm = Imm % Scale;

3376

3377

3379 for (unsigned i = 0; i != SrcNumElts; ++i)

3380 Idxs[i] = i;

3381 for (unsigned i = SrcNumElts; i != DstNumElts; ++i)

3382 Idxs[i] = SrcNumElts;

3383 Rep = Builder.CreateShuffleVector(Op1, Idxs);

3384

3385

3386

3387

3388

3389

3390

3391

3392

3393

3394

3395

3396

3397 for (unsigned i = 0; i != DstNumElts; ++i)

3398 Idxs[i] = i;

3399

3400 for (unsigned i = 0; i != SrcNumElts; ++i)

3401 Idxs[i + Imm * SrcNumElts] = i + DstNumElts;

3402 Rep = Builder.CreateShuffleVector(Op0, Rep, Idxs);

3403

3404

3408 } else if (Name.starts_with("avx.vextractf128.") ||

3409 Name == "avx2.vextracti128" ||

3410 Name.starts_with("avx512.mask.vextract")) {

3413 unsigned DstNumElts =

3415 unsigned SrcNumElts =

3417 unsigned Scale = SrcNumElts / DstNumElts;

3418

3419

3420 Imm = Imm % Scale;

3421

3422

3424 for (unsigned i = 0; i != DstNumElts; ++i) {

3425 Idxs[i] = i + (Imm * DstNumElts);

3426 }

3427 Rep = Builder.CreateShuffleVector(Op0, Op0, Idxs);

3428

3429

3433 } else if (Name.starts_with("avx512.mask.perm.df.") ||

3434 Name.starts_with("avx512.mask.perm.di.")) {

3438 unsigned NumElts = VecTy->getNumElements();

3439

3441 for (unsigned i = 0; i != NumElts; ++i)

3442 Idxs[i] = (i & ~0x3) + ((Imm >> (2 * (i & 0x3))) & 3);

3443

3444 Rep = Builder.CreateShuffleVector(Op0, Op0, Idxs);

3445

3449 } else if (Name.starts_with("avx.vperm2f128.") || Name == "avx2.vperm2i128") {

3450

3451

3452

3453

3454

3455

3456

3457

3459

3461 unsigned HalfSize = NumElts / 2;

3463

3464

3467

3468

3471

3472

3473 unsigned StartIndex = (Imm & 0x01) ? HalfSize : 0;

3474 for (unsigned i = 0; i < HalfSize; ++i)

3475 ShuffleMask[i] = StartIndex + i;

3476

3477

3478 StartIndex = (Imm & 0x10) ? HalfSize : 0;

3479 for (unsigned i = 0; i < HalfSize; ++i)

3480 ShuffleMask[i + HalfSize] = NumElts + StartIndex + i;

3481

3482 Rep = Builder.CreateShuffleVector(V0, V1, ShuffleMask);

3483

3484 } else if (Name.starts_with("avx.vpermil.") || Name == "sse2.pshuf.d" ||

3485 Name.starts_with("avx512.mask.vpermil.p") ||

3486 Name.starts_with("avx512.mask.pshuf.d.")) {

3490 unsigned NumElts = VecTy->getNumElements();

3491

3492 unsigned IdxSize = 64 / VecTy->getScalarSizeInBits();

3493 unsigned IdxMask = ((1 << IdxSize) - 1);

3494

3496

3497

3498

3499 for (unsigned i = 0; i != NumElts; ++i)

3500 Idxs[i] = ((Imm >> ((i * IdxSize) % 8)) & IdxMask) | (i & ~IdxMask);

3501

3502 Rep = Builder.CreateShuffleVector(Op0, Op0, Idxs);

3503

3507 } else if (Name == "sse2.pshufl.w" ||

3508 Name.starts_with("avx512.mask.pshufl.w.")) {

3512

3514 for (unsigned l = 0; l != NumElts; l += 8) {

3515 for (unsigned i = 0; i != 4; ++i)

3516 Idxs[i + l] = ((Imm >> (2 * i)) & 0x3) + l;

3517 for (unsigned i = 4; i != 8; ++i)

3518 Idxs[i + l] = i + l;

3519 }

3520

3521 Rep = Builder.CreateShuffleVector(Op0, Op0, Idxs);

3522

3526 } else if (Name == "sse2.pshufh.w" ||

3527 Name.starts_with("avx512.mask.pshufh.w.")) {

3531

3533 for (unsigned l = 0; l != NumElts; l += 8) {

3534 for (unsigned i = 0; i != 4; ++i)

3535 Idxs[i + l] = i + l;

3536 for (unsigned i = 0; i != 4; ++i)

3537 Idxs[i + l + 4] = ((Imm >> (2 * i)) & 0x3) + 4 + l;

3538 }

3539

3540 Rep = Builder.CreateShuffleVector(Op0, Op0, Idxs);

3541

3545 } else if (Name.starts_with("avx512.mask.shuf.p")) {

3550

3552 unsigned HalfLaneElts = NumLaneElts / 2;

3553

3555 for (unsigned i = 0; i != NumElts; ++i) {

3556

3557 Idxs[i] = i - (i % NumLaneElts);

3558

3559 if ((i % NumLaneElts) >= HalfLaneElts)

3560 Idxs[i] += NumElts;

3561

3562

3563 Idxs[i] += (Imm >> ((i * HalfLaneElts) % 8)) & ((1 << HalfLaneElts) - 1);

3564 }

3565

3566 Rep = Builder.CreateShuffleVector(Op0, Op1, Idxs);

3567

3568 Rep =

3570 } else if (Name.starts_with("avx512.mask.movddup") ||

3571 Name.starts_with("avx512.mask.movshdup") ||

3572 Name.starts_with("avx512.mask.movsldup")) {

3576

3577 unsigned Offset = 0;

3578 if (Name.starts_with("avx512.mask.movshdup."))

3580

3582 for (unsigned l = 0; l != NumElts; l += NumLaneElts)

3583 for (unsigned i = 0; i != NumLaneElts; i += 2) {

3584 Idxs[i + l + 0] = i + l + Offset;

3585 Idxs[i + l + 1] = i + l + Offset;

3586 }

3587

3588 Rep = Builder.CreateShuffleVector(Op0, Op0, Idxs);

3589

3590 Rep =

3592 } else if (Name.starts_with("avx512.mask.punpckl") ||

3593 Name.starts_with("avx512.mask.unpckl.")) {

3598

3600 for (int l = 0; l != NumElts; l += NumLaneElts)

3601 for (int i = 0; i != NumLaneElts; ++i)

3602 Idxs[i + l] = l + (i / 2) + NumElts * (i % 2);

3603

3604 Rep = Builder.CreateShuffleVector(Op0, Op1, Idxs);

3605

3606 Rep =

3608 } else if (Name.starts_with("avx512.mask.punpckh") ||

3609 Name.starts_with("avx512.mask.unpckh.")) {

3614

3616 for (int l = 0; l != NumElts; l += NumLaneElts)

3617 for (int i = 0; i != NumLaneElts; ++i)

3618 Idxs[i + l] = (NumLaneElts / 2) + l + (i / 2) + NumElts * (i % 2);

3619

3620 Rep = Builder.CreateShuffleVector(Op0, Op1, Idxs);

3621

3622 Rep =

3624 } else if (Name.starts_with("avx512.mask.and.") ||

3625 Name.starts_with("avx512.mask.pand.")) {

3628 Rep = Builder.CreateAnd(Builder.CreateBitCast(CI->getArgOperand(0), ITy),

3629 Builder.CreateBitCast(CI->getArgOperand(1), ITy));

3630 Rep = Builder.CreateBitCast(Rep, FTy);

3631 Rep =

3633 } else if (Name.starts_with("avx512.mask.andn.") ||

3634 Name.starts_with("avx512.mask.pandn.")) {

3637 Rep = Builder.CreateNot(Builder.CreateBitCast(CI->getArgOperand(0), ITy));

3638 Rep = Builder.CreateAnd(Rep,

3639 Builder.CreateBitCast(CI->getArgOperand(1), ITy));

3640 Rep = Builder.CreateBitCast(Rep, FTy);

3641 Rep =

3643 } else if (Name.starts_with("avx512.mask.or.") ||

3644 Name.starts_with("avx512.mask.por.")) {

3647 Rep = Builder.CreateOr(Builder.CreateBitCast(CI->getArgOperand(0), ITy),

3648 Builder.CreateBitCast(CI->getArgOperand(1), ITy));

3649 Rep = Builder.CreateBitCast(Rep, FTy);

3650 Rep =

3652 } else if (Name.starts_with("avx512.mask.xor.") ||

3653 Name.starts_with("avx512.mask.pxor.")) {

3656 Rep = Builder.CreateXor(Builder.CreateBitCast(CI->getArgOperand(0), ITy),

3657 Builder.CreateBitCast(CI->getArgOperand(1), ITy));

3658 Rep = Builder.CreateBitCast(Rep, FTy);

3659 Rep =

3661 } else if (Name.starts_with("avx512.mask.padd.")) {

3663 Rep =

3665 } else if (Name.starts_with("avx512.mask.psub.")) {

3667 Rep =

3669 } else if (Name.starts_with("avx512.mask.pmull.")) {

3671 Rep =

3673 } else if (Name.starts_with("avx512.mask.add.p")) {

3674 if (Name.ends_with(".512")) {

3676 if (Name[17] == 's')

3677 IID = Intrinsic::x86_avx512_add_ps_512;

3678 else

3679 IID = Intrinsic::x86_avx512_add_pd_512;

3680

3681 Rep = Builder.CreateIntrinsic(

3682 IID,

3684 } else {

3686 }

3687 Rep =

3689 } else if (Name.starts_with("avx512.mask.div.p")) {

3690 if (Name.ends_with(".512")) {

3692 if (Name[17] == 's')

3693 IID = Intrinsic::x86_avx512_div_ps_512;

3694 else

3695 IID = Intrinsic::x86_avx512_div_pd_512;

3696

3697 Rep = Builder.CreateIntrinsic(

3698 IID,

3700 } else {

3702 }

3703 Rep =

3705 } else if (Name.starts_with("avx512.mask.mul.p")) {

3706 if (Name.ends_with(".512")) {

3708 if (Name[17] == 's')

3709 IID = Intrinsic::x86_avx512_mul_ps_512;

3710 else

3711 IID = Intrinsic::x86_avx512_mul_pd_512;

3712

3713 Rep = Builder.CreateIntrinsic(

3714 IID,

3716 } else {

3718 }

3719 Rep =

3721 } else if (Name.starts_with("avx512.mask.sub.p")) {

3722 if (Name.ends_with(".512")) {

3724 if (Name[17] == 's')

3725 IID = Intrinsic::x86_avx512_sub_ps_512;

3726 else

3727 IID = Intrinsic::x86_avx512_sub_pd_512;

3728

3729 Rep = Builder.CreateIntrinsic(

3730 IID,

3732 } else {

3734 }

3735 Rep =

3737 } else if ((Name.starts_with("avx512.mask.max.p") ||

3738 Name.starts_with("avx512.mask.min.p")) &&

3739 Name.drop_front(18) == ".512") {

3740 bool IsDouble = Name[17] == 'd';

3741 bool IsMin = Name[13] == 'i';

3743 {Intrinsic::x86_avx512_max_ps_512, Intrinsic::x86_avx512_max_pd_512},

3744 {Intrinsic::x86_avx512_min_ps_512, Intrinsic::x86_avx512_min_pd_512}};

3746

3747 Rep = Builder.CreateIntrinsic(

3748 IID,

3750 Rep =

3752 } else if (Name.starts_with("avx512.mask.lzcnt.")) {

3753 Rep =

3754 Builder.CreateIntrinsic(Intrinsic::ctlz, CI->getType(),

3755 {CI->getArgOperand(0), Builder.getInt1(false)});

3756 Rep =

3758 } else if (Name.starts_with("avx512.mask.psll")) {

3759 bool IsImmediate = Name[16] == 'i' || (Name.size() > 18 && Name[18] == 'i');

3760 bool IsVariable = Name[16] == 'v';

3761 char Size = Name[16] == '.' ? Name[17]

3762 : Name[17] == '.' ? Name[18]

3763 : Name[18] == '.' ? Name[19]

3764 : Name[20];

3765

3767 if (IsVariable && Name[17] != '.') {

3768 if (Size == 'd' && Name[17] == '2')

3769 IID = Intrinsic::x86_avx2_psllv_q;

3770 else if (Size == 'd' && Name[17] == '4')

3771 IID = Intrinsic::x86_avx2_psllv_q_256;

3772 else if (Size == 's' && Name[17] == '4')

3773 IID = Intrinsic::x86_avx2_psllv_d;

3774 else if (Size == 's' && Name[17] == '8')

3775 IID = Intrinsic::x86_avx2_psllv_d_256;

3776 else if (Size == 'h' && Name[17] == '8')

3777 IID = Intrinsic::x86_avx512_psllv_w_128;

3778 else if (Size == 'h' && Name[17] == '1')

3779 IID = Intrinsic::x86_avx512_psllv_w_256;

3780 else if (Name[17] == '3' && Name[18] == '2')

3781 IID = Intrinsic::x86_avx512_psllv_w_512;

3782 else

3784 } else if (Name.ends_with(".128")) {

3785 if (Size == 'd')

3786 IID = IsImmediate ? Intrinsic::x86_sse2_pslli_d

3787 : Intrinsic::x86_sse2_psll_d;

3788 else if (Size == 'q')

3789 IID = IsImmediate ? Intrinsic::x86_sse2_pslli_q

3790 : Intrinsic::x86_sse2_psll_q;

3791 else if (Size == 'w')

3792 IID = IsImmediate ? Intrinsic::x86_sse2_pslli_w

3793 : Intrinsic::x86_sse2_psll_w;

3794 else

3796 } else if (Name.ends_with(".256")) {

3797 if (Size == 'd')

3798 IID = IsImmediate ? Intrinsic::x86_avx2_pslli_d

3799 : Intrinsic::x86_avx2_psll_d;

3800 else if (Size == 'q')

3801 IID = IsImmediate ? Intrinsic::x86_avx2_pslli_q

3802 : Intrinsic::x86_avx2_psll_q;

3803 else if (Size == 'w')

3804 IID = IsImmediate ? Intrinsic::x86_avx2_pslli_w

3805 : Intrinsic::x86_avx2_psll_w;

3806 else

3808 } else {

3809 if (Size == 'd')

3810 IID = IsImmediate ? Intrinsic::x86_avx512_pslli_d_512

3811 : IsVariable ? Intrinsic::x86_avx512_psllv_d_512

3812 : Intrinsic::x86_avx512_psll_d_512;

3813 else if (Size == 'q')

3814 IID = IsImmediate ? Intrinsic::x86_avx512_pslli_q_512

3815 : IsVariable ? Intrinsic::x86_avx512_psllv_q_512

3816 : Intrinsic::x86_avx512_psll_q_512;

3817 else if (Size == 'w')

3818 IID = IsImmediate ? Intrinsic::x86_avx512_pslli_w_512

3819 : Intrinsic::x86_avx512_psll_w_512;

3820 else

3822 }

3823

3825 } else if (Name.starts_with("avx512.mask.psrl")) {

3826 bool IsImmediate = Name[16] == 'i' || (Name.size() > 18 && Name[18] == 'i');

3827 bool IsVariable = Name[16] == 'v';

3828 char Size = Name[16] == '.' ? Name[17]

3829 : Name[17] == '.' ? Name[18]

3830 : Name[18] == '.' ? Name[19]

3831 : Name[20];

3832

3834 if (IsVariable && Name[17] != '.') {

3835 if (Size == 'd' && Name[17] == '2')

3836 IID = Intrinsic::x86_avx2_psrlv_q;

3837 else if (Size == 'd' && Name[17] == '4')

3838 IID = Intrinsic::x86_avx2_psrlv_q_256;

3839 else if (Size == 's' && Name[17] == '4')

3840 IID = Intrinsic::x86_avx2_psrlv_d;

3841 else if (Size == 's' && Name[17] == '8')

3842 IID = Intrinsic::x86_avx2_psrlv_d_256;

3843 else if (Size == 'h' && Name[17] == '8')

3844 IID = Intrinsic::x86_avx512_psrlv_w_128;

3845 else if (Size == 'h' && Name[17] == '1')

3846 IID = Intrinsic::x86_avx512_psrlv_w_256;

3847 else if (Name[17] == '3' && Name[18] == '2')

3848 IID = Intrinsic::x86_avx512_psrlv_w_512;

3849 else

3851 } else if (Name.ends_with(".128")) {

3852 if (Size == 'd')

3853 IID = IsImmediate ? Intrinsic::x86_sse2_psrli_d

3854 : Intrinsic::x86_sse2_psrl_d;

3855 else if (Size == 'q')

3856 IID = IsImmediate ? Intrinsic::x86_sse2_psrli_q

3857 : Intrinsic::x86_sse2_psrl_q;

3858 else if (Size == 'w')

3859 IID = IsImmediate ? Intrinsic::x86_sse2_psrli_w

3860 : Intrinsic::x86_sse2_psrl_w;

3861 else

3863 } else if (Name.ends_with(".256")) {

3864 if (Size == 'd')

3865 IID = IsImmediate ? Intrinsic::x86_avx2_psrli_d

3866 : Intrinsic::x86_avx2_psrl_d;

3867 else if (Size == 'q')

3868 IID = IsImmediate ? Intrinsic::x86_avx2_psrli_q

3869 : Intrinsic::x86_avx2_psrl_q;

3870 else if (Size == 'w')

3871 IID = IsImmediate ? Intrinsic::x86_avx2_psrli_w

3872 : Intrinsic::x86_avx2_psrl_w;

3873 else

3875 } else {

3876 if (Size == 'd')

3877 IID = IsImmediate ? Intrinsic::x86_avx512_psrli_d_512

3878 : IsVariable ? Intrinsic::x86_avx512_psrlv_d_512

3879 : Intrinsic::x86_avx512_psrl_d_512;

3880 else if (Size == 'q')

3881 IID = IsImmediate ? Intrinsic::x86_avx512_psrli_q_512

3882 : IsVariable ? Intrinsic::x86_avx512_psrlv_q_512

3883 : Intrinsic::x86_avx512_psrl_q_512;

3884 else if (Size == 'w')

3885 IID = IsImmediate ? Intrinsic::x86_avx512_psrli_w_512

3886 : Intrinsic::x86_avx512_psrl_w_512;

3887 else

3889 }

3890

3892 } else if (Name.starts_with("avx512.mask.psra")) {

3893 bool IsImmediate = Name[16] == 'i' || (Name.size() > 18 && Name[18] == 'i');

3894 bool IsVariable = Name[16] == 'v';

3895 char Size = Name[16] == '.' ? Name[17]

3896 : Name[17] == '.' ? Name[18]

3897 : Name[18] == '.' ? Name[19]

3898 : Name[20];

3899

3901 if (IsVariable && Name[17] != '.') {

3902 if (Size == 's' && Name[17] == '4')

3903 IID = Intrinsic::x86_avx2_psrav_d;

3904 else if (Size == 's' && Name[17] == '8')

3905 IID = Intrinsic::x86_avx2_psrav_d_256;

3906 else if (Size == 'h' && Name[17] == '8')

3907 IID = Intrinsic::x86_avx512_psrav_w_128;

3908 else if (Size == 'h' && Name[17] == '1')

3909 IID = Intrinsic::x86_avx512_psrav_w_256;

3910 else if (Name[17] == '3' && Name[18] == '2')

3911 IID = Intrinsic::x86_avx512_psrav_w_512;

3912 else

3914 } else if (Name.ends_with(".128")) {

3915 if (Size == 'd')

3916 IID = IsImmediate ? Intrinsic::x86_sse2_psrai_d

3917 : Intrinsic::x86_sse2_psra_d;

3918 else if (Size == 'q')

3919 IID = IsImmediate ? Intrinsic::x86_avx512_psrai_q_128

3920 : IsVariable ? Intrinsic::x86_avx512_psrav_q_128

3921 : Intrinsic::x86_avx512_psra_q_128;

3922 else if (Size == 'w')

3923 IID = IsImmediate ? Intrinsic::x86_sse2_psrai_w

3924 : Intrinsic::x86_sse2_psra_w;

3925 else

3927 } else if (Name.ends_with(".256")) {

3928 if (Size == 'd')

3929 IID = IsImmediate ? Intrinsic::x86_avx2_psrai_d

3930 : Intrinsic::x86_avx2_psra_d;

3931 else if (Size == 'q')

3932 IID = IsImmediate ? Intrinsic::x86_avx512_psrai_q_256

3933 : IsVariable ? Intrinsic::x86_avx512_psrav_q_256

3934 : Intrinsic::x86_avx512_psra_q_256;

3935 else if (Size == 'w')

3936 IID = IsImmediate ? Intrinsic::x86_avx2_psrai_w

3937 : Intrinsic::x86_avx2_psra_w;

3938 else

3940 } else {

3941 if (Size == 'd')

3942 IID = IsImmediate ? Intrinsic::x86_avx512_psrai_d_512

3943 : IsVariable ? Intrinsic::x86_avx512_psrav_d_512

3944 : Intrinsic::x86_avx512_psra_d_512;

3945 else if (Size == 'q')

3946 IID = IsImmediate ? Intrinsic::x86_avx512_psrai_q_512

3947 : IsVariable ? Intrinsic::x86_avx512_psrav_q_512

3948 : Intrinsic::x86_avx512_psra_q_512;

3949 else if (Size == 'w')

3950 IID = IsImmediate ? Intrinsic::x86_avx512_psrai_w_512

3951 : Intrinsic::x86_avx512_psra_w_512;

3952 else

3954 }

3955

3957 } else if (Name.starts_with("avx512.mask.move.s")) {

3959 } else if (Name.starts_with("avx512.cvtmask2")) {

3961 } else if (Name.ends_with(".movntdqa")) {

3964

3965 LoadInst *LI = Builder.CreateAlignedLoad(

3969 Rep = LI;

3970 } else if (Name.starts_with("fma.vfmadd.") ||

3971 Name.starts_with("fma.vfmsub.") ||

3972 Name.starts_with("fma.vfnmadd.") ||

3973 Name.starts_with("fma.vfnmsub.")) {

3974 bool NegMul = Name[6] == 'n';

3975 bool NegAcc = NegMul ? Name[8] == 's' : Name[7] == 's';

3976 bool IsScalar = NegMul ? Name[12] == 's' : Name[11] == 's';

3977

3980

3981 if (IsScalar) {

3982 Ops[0] = Builder.CreateExtractElement(Ops[0], (uint64_t)0);

3983 Ops[1] = Builder.CreateExtractElement(Ops[1], (uint64_t)0);

3984 Ops[2] = Builder.CreateExtractElement(Ops[2], (uint64_t)0);

3985 }

3986

3987 if (NegMul && !IsScalar)

3988 Ops[0] = Builder.CreateFNeg(Ops[0]);

3989 if (NegMul && IsScalar)

3990 Ops[1] = Builder.CreateFNeg(Ops[1]);

3991 if (NegAcc)

3992 Ops[2] = Builder.CreateFNeg(Ops[2]);

3993

3994 Rep = Builder.CreateIntrinsic(Intrinsic::fma, Ops[0]->getType(), Ops);

3995

3996 if (IsScalar)

3998 } else if (Name.starts_with("fma4.vfmadd.s")) {

4001

4002 Ops[0] = Builder.CreateExtractElement(Ops[0], (uint64_t)0);

4003 Ops[1] = Builder.CreateExtractElement(Ops[1], (uint64_t)0);

4004 Ops[2] = Builder.CreateExtractElement(Ops[2], (uint64_t)0);

4005

4006 Rep = Builder.CreateIntrinsic(Intrinsic::fma, Ops[0]->getType(), Ops);

4007

4010 } else if (Name.starts_with("avx512.mask.vfmadd.s") ||

4011 Name.starts_with("avx512.maskz.vfmadd.s") ||

4012 Name.starts_with("avx512.mask3.vfmadd.s") ||

4013 Name.starts_with("avx512.mask3.vfmsub.s") ||

4014 Name.starts_with("avx512.mask3.vfnmsub.s")) {

4015 bool IsMask3 = Name[11] == '3';

4016 bool IsMaskZ = Name[11] == 'z';

4017

4018 Name = Name.drop_front(IsMask3 || IsMaskZ ? 13 : 12);

4019 bool NegMul = Name[2] == 'n';

4020 bool NegAcc = NegMul ? Name[4] == 's' : Name[3] == 's';

4021

4025

4026 if (NegMul && (IsMask3 || IsMaskZ))

4027 A = Builder.CreateFNeg(A);

4028 if (NegMul && !(IsMask3 || IsMaskZ))

4029 B = Builder.CreateFNeg(B);

4030 if (NegAcc)

4031 C = Builder.CreateFNeg(C);

4032

4033 A = Builder.CreateExtractElement(A, (uint64_t)0);

4034 B = Builder.CreateExtractElement(B, (uint64_t)0);

4035 C = Builder.CreateExtractElement(C, (uint64_t)0);

4036

4040

4042 if (Name.back() == 'd')

4043 IID = Intrinsic::x86_avx512_vfmadd_f64;

4044 else

4045 IID = Intrinsic::x86_avx512_vfmadd_f32;

4046 Rep = Builder.CreateIntrinsic(IID, Ops);

4047 } else {

4048 Rep = Builder.CreateFMA(A, B, C);

4049 }

4050

4052 : IsMask3 ? C

4053 : A;

4054

4055

4056

4057 if (NegAcc && IsMask3)

4058 PassThru =

4060

4062 Rep = Builder.CreateInsertElement(CI->getArgOperand(IsMask3 ? 2 : 0), Rep,

4064 } else if (Name.starts_with("avx512.mask.vfmadd.p") ||

4065 Name.starts_with("avx512.mask.vfnmadd.p") ||

4066 Name.starts_with("avx512.mask.vfnmsub.p") ||

4067 Name.starts_with("avx512.mask3.vfmadd.p") ||

4068 Name.starts_with("avx512.mask3.vfmsub.p") ||

4069 Name.starts_with("avx512.mask3.vfnmsub.p") ||

4070 Name.starts_with("avx512.maskz.vfmadd.p")) {

4071 bool IsMask3 = Name[11] == '3';

4072 bool IsMaskZ = Name[11] == 'z';

4073

4074 Name = Name.drop_front(IsMask3 || IsMaskZ ? 13 : 12);

4075 bool NegMul = Name[2] == 'n';

4076 bool NegAcc = NegMul ? Name[4] == 's' : Name[3] == 's';

4077

4081

4082 if (NegMul && (IsMask3 || IsMaskZ))

4083 A = Builder.CreateFNeg(A);

4084 if (NegMul && !(IsMask3 || IsMaskZ))

4085 B = Builder.CreateFNeg(B);

4086 if (NegAcc)

4087 C = Builder.CreateFNeg(C);

4088

4093

4094 if (Name[Name.size() - 5] == 's')

4095 IID = Intrinsic::x86_avx512_vfmadd_ps_512;

4096 else

4097 IID = Intrinsic::x86_avx512_vfmadd_pd_512;

4098

4099 Rep = Builder.CreateIntrinsic(IID, {A, B, C, CI->getArgOperand(4)});

4100 } else {

4101 Rep = Builder.CreateFMA(A, B, C);

4102 }

4103

4107

4109 } else if (Name.starts_with("fma.vfmsubadd.p")) {

4113 if (VecWidth == 128 && EltWidth == 32)

4114 IID = Intrinsic::x86_fma_vfmaddsub_ps;

4115 else if (VecWidth == 256 && EltWidth == 32)

4116 IID = Intrinsic::x86_fma_vfmaddsub_ps_256;

4117 else if (VecWidth == 128 && EltWidth == 64)

4118 IID = Intrinsic::x86_fma_vfmaddsub_pd;

4119 else if (VecWidth == 256 && EltWidth == 64)

4120 IID = Intrinsic::x86_fma_vfmaddsub_pd_256;

4121 else

4123

4126 Ops[2] = Builder.CreateFNeg(Ops[2]);

4127 Rep = Builder.CreateIntrinsic(IID, Ops);

4128 } else if (Name.starts_with("avx512.mask.vfmaddsub.p") ||

4129 Name.starts_with("avx512.mask3.vfmaddsub.p") ||

4130 Name.starts_with("avx512.maskz.vfmaddsub.p") ||

4131 Name.starts_with("avx512.mask3.vfmsubadd.p")) {

4132 bool IsMask3 = Name[11] == '3';

4133 bool IsMaskZ = Name[11] == 'z';

4134

4135 Name = Name.drop_front(IsMask3 || IsMaskZ ? 13 : 12);

4136 bool IsSubAdd = Name[3] == 's';

4139

4140 if (Name[Name.size() - 5] == 's')

4141 IID = Intrinsic::x86_avx512_vfmaddsub_ps_512;

4142 else

4143 IID = Intrinsic::x86_avx512_vfmaddsub_pd_512;

4144

4147 if (IsSubAdd)

4148 Ops[2] = Builder.CreateFNeg(Ops[2]);

4149

4150 Rep = Builder.CreateIntrinsic(IID, Ops);

4151 } else {

4153

4156

4158 CI->getModule(), Intrinsic::fma, Ops[0]->getType());

4159 Value *Odd = Builder.CreateCall(FMA, Ops);

4160 Ops[2] = Builder.CreateFNeg(Ops[2]);

4161 Value *Even = Builder.CreateCall(FMA, Ops);

4162

4163 if (IsSubAdd)

4165

4167 for (int i = 0; i != NumElts; ++i)

4168 Idxs[i] = i + (i % 2) * NumElts;

4169

4170 Rep = Builder.CreateShuffleVector(Even, Odd, Idxs);

4171 }

4172

4176

4178 } else if (Name.starts_with("avx512.mask.pternlog.") ||

4179 Name.starts_with("avx512.maskz.pternlog.")) {

4180 bool ZeroMask = Name[11] == 'z';

4184 if (VecWidth == 128 && EltWidth == 32)

4185 IID = Intrinsic::x86_avx512_pternlog_d_128;

4186 else if (VecWidth == 256 && EltWidth == 32)

4187 IID = Intrinsic::x86_avx512_pternlog_d_256;

4188 else if (VecWidth == 512 && EltWidth == 32)

4189 IID = Intrinsic::x86_avx512_pternlog_d_512;

4190 else if (VecWidth == 128 && EltWidth == 64)

4191 IID = Intrinsic::x86_avx512_pternlog_q_128;

4192 else if (VecWidth == 256 && EltWidth == 64)

4193 IID = Intrinsic::x86_avx512_pternlog_q_256;

4194 else if (VecWidth == 512 && EltWidth == 64)

4195 IID = Intrinsic::x86_avx512_pternlog_q_512;

4196 else

4198

4201 Rep = Builder.CreateIntrinsic(IID, Args);

4205 } else if (Name.starts_with("avx512.mask.vpmadd52") ||

4206 Name.starts_with("avx512.maskz.vpmadd52")) {

4207 bool ZeroMask = Name[11] == 'z';

4208 bool High = Name[20] == 'h' || Name[21] == 'h';

4211 if (VecWidth == 128 && High)

4212 IID = Intrinsic::x86_avx512_vpmadd52l_uq_128;

4213 else if (VecWidth == 256 && High)

4214 IID = Intrinsic::x86_avx512_vpmadd52l_uq_256;

4215 else if (VecWidth == 512 && High)

4216 IID = Intrinsic::x86_avx512_vpmadd52l_uq_512;

4217 else if (VecWidth == 128 && High)

4218 IID = Intrinsic::x86_avx512_vpmadd52h_uq_128;

4219 else if (VecWidth == 256 && High)

4220 IID = Intrinsic::x86_avx512_vpmadd52h_uq_256;

4221 else if (VecWidth == 512 && High)

4222 IID = Intrinsic::x86_avx512_vpmadd52h_uq_512;

4223 else

4225

4228 Rep = Builder.CreateIntrinsic(IID, Args);

4232 } else if (Name.starts_with("avx512.mask.vpermi2var.") ||

4233 Name.starts_with("avx512.mask.vpermt2var.") ||

4234 Name.starts_with("avx512.maskz.vpermt2var.")) {

4235 bool ZeroMask = Name[11] == 'z';

4236 bool IndexForm = Name[17] == 'i';

4238 } else if (Name.starts_with("avx512.mask.vpdpbusd.") ||

4239 Name.starts_with("avx512.maskz.vpdpbusd.") ||

4240 Name.starts_with("avx512.mask.vpdpbusds.") ||

4241 Name.starts_with("avx512.maskz.vpdpbusds.")) {

4242 bool ZeroMask = Name[11] == 'z';

4243 bool IsSaturating = Name[ZeroMask ? 21 : 20] == 's';

4246 if (VecWidth == 128 && !IsSaturating)

4247 IID = Intrinsic::x86_avx512_vpdpbusd_128;

4248 else if (VecWidth == 256 && !IsSaturating)

4249 IID = Intrinsic::x86_avx512_vpdpbusd_256;

4250 else if (VecWidth == 512 && !IsSaturating)

4251 IID = Intrinsic::x86_avx512_vpdpbusd_512;

4252 else if (VecWidth == 128 && IsSaturating)

4253 IID = Intrinsic::x86_avx512_vpdpbusds_128;

4254 else if (VecWidth == 256 && IsSaturating)

4255 IID = Intrinsic::x86_avx512_vpdpbusds_256;

4256 else if (VecWidth == 512 && IsSaturating)

4257 IID = Intrinsic::x86_avx512_vpdpbusds_512;

4258 else

4260

4263

4264

4265

4266

4267 if (Args[1]->getType()->isVectorTy() &&

4269 ->getElementType()

4270 ->isIntegerTy(32) &&

4271 Args[2]->getType()->isVectorTy() &&

4273 ->getElementType()

4274 ->isIntegerTy(32)) {

4275 Type *NewArgType = nullptr;

4276 if (VecWidth == 128)

4277 NewArgType = VectorType::get(Builder.getInt8Ty(), 16, false);

4278 else if (VecWidth == 256)

4279 NewArgType = VectorType::get(Builder.getInt8Ty(), 32, false);

4280 else if (VecWidth == 512)

4281 NewArgType = VectorType::get(Builder.getInt8Ty(), 64, false);

4282 else

4284

4285 Args[1] = Builder.CreateBitCast(Args[1], NewArgType);

4286 Args[2] = Builder.CreateBitCast(Args[2], NewArgType);

4287 }

4288

4289 Rep = Builder.CreateIntrinsic(IID, Args);

4293 } else if (Name.starts_with("avx512.mask.vpdpwssd.") ||

4294 Name.starts_with("avx512.maskz.vpdpwssd.") ||

4295 Name.starts_with("avx512.mask.vpdpwssds.") ||

4296 Name.starts_with("avx512.maskz.vpdpwssds.")) {

4297 bool ZeroMask = Name[11] == 'z';

4298 bool IsSaturating = Name[ZeroMask ? 21 : 20] == 's';

4301 if (VecWidth == 128 && !IsSaturating)

4302 IID = Intrinsic::x86_avx512_vpdpwssd_128;

4303 else if (VecWidth == 256 && !IsSaturating)

4304 IID = Intrinsic::x86_avx512_vpdpwssd_256;

4305 else if (VecWidth == 512 && !IsSaturating)

4306 IID = Intrinsic::x86_avx512_vpdpwssd_512;

4307 else if (VecWidth == 128 && IsSaturating)

4308 IID = Intrinsic::x86_avx512_vpdpwssds_128;

4309 else if (VecWidth == 256 && IsSaturating)

4310 IID = Intrinsic::x86_avx512_vpdpwssds_256;

4311 else if (VecWidth == 512 && IsSaturating)

4312 IID = Intrinsic::x86_avx512_vpdpwssds_512;

4313 else

4315

4318 Rep = Builder.CreateIntrinsic(IID, Args);

4322 } else if (Name == "addcarryx.u32" || Name == "addcarryx.u64" ||

4323 Name == "addcarry.u32" || Name == "addcarry.u64" ||

4324 Name == "subborrow.u32" || Name == "subborrow.u64") {

4326 if (Name[0] == 'a' && Name.back() == '2')

4327 IID = Intrinsic::x86_addcarry_32;

4328 else if (Name[0] == 'a' && Name.back() == '4')

4329 IID = Intrinsic::x86_addcarry_64;

4330 else if (Name[0] == 's' && Name.back() == '2')

4331 IID = Intrinsic::x86_subborrow_32;

4332 else if (Name[0] == 's' && Name.back() == '4')

4333 IID = Intrinsic::x86_subborrow_64;

4334 else

4336

4337

4340 Value *NewCall = Builder.CreateIntrinsic(IID, Args);

4341

4342

4343 Value *Data = Builder.CreateExtractValue(NewCall, 1);

4345

4346 Value *CF = Builder.CreateExtractValue(NewCall, 0);

4347

4349 Rep = nullptr;

4350 } else if (Name.starts_with("avx512.mask.") &&

4352

4353 }

4354

4355 return Rep;

4356}

4357

4360 if (Name.starts_with("neon.bfcvt")) {

4361 if (Name.starts_with("neon.bfcvtn2")) {

4363 std::iota(LoMask.begin(), LoMask.end(), 0);

4365 std::iota(ConcatMask.begin(), ConcatMask.end(), 0);

4366 Value *Inactive = Builder.CreateShuffleVector(CI->getOperand(0), LoMask);

4369 return Builder.CreateShuffleVector(Inactive, Trunc, ConcatMask);

4370 } else if (Name.starts_with("neon.bfcvtn")) {

4372 std::iota(ConcatMask.begin(), ConcatMask.end(), 0);

4373 Type *V4BF16 =

4375 Value *Trunc = Builder.CreateFPTrunc(CI->getOperand(0), V4BF16);

4376 dbgs() << "Trunc: " << *Trunc << "\n";

4377 return Builder.CreateShuffleVector(

4379 } else {

4380 return Builder.CreateFPTrunc(CI->getOperand(0),

4382 }

4383 } else if (Name.starts_with("sve.fcvt")) {

4386 .Case("sve.fcvt.bf16f32", Intrinsic::aarch64_sve_fcvt_bf16f32_v2)

4387 .Case("sve.fcvtnt.bf16f32",

4388 Intrinsic::aarch64_sve_fcvtnt_bf16f32_v2)

4392

4394

4395

4396

4399

4400 if (Args[1]->getType() != BadPredTy)

4402

4403 Args[1] = Builder.CreateIntrinsic(Intrinsic::aarch64_sve_convert_to_svbool,

4404 BadPredTy, Args[1]);

4405 Args[1] = Builder.CreateIntrinsic(

4406 Intrinsic::aarch64_sve_convert_from_svbool, GoodPredTy, Args[1]);

4407

4408 return Builder.CreateIntrinsic(NewID, Args, nullptr,

4410 }

4411

4413}

4414

4417 if (Name == "mve.vctp64.old") {

4418

4419

4420 Value *VCTP = Builder.CreateIntrinsic(Intrinsic::arm_mve_vctp64, {},

4422 nullptr, CI->getName());

4423 Value *C1 = Builder.CreateIntrinsic(

4424 Intrinsic::arm_mve_pred_v2i,

4425 {VectorType::get(Builder.getInt1Ty(), 2, false)}, VCTP);

4426 return Builder.CreateIntrinsic(

4427 Intrinsic::arm_mve_pred_i2v,

4429 } else if (Name == "mve.mull.int.predicated.v2i64.v4i32.v4i1" ||

4430 Name == "mve.vqdmull.predicated.v2i64.v4i32.v4i1" ||

4431 Name == "mve.vldr.gather.base.predicated.v2i64.v2i64.v4i1" ||

4432 Name == "mve.vldr.gather.base.wb.predicated.v2i64.v2i64.v4i1" ||

4433 Name ==

4434 "mve.vldr.gather.offset.predicated.v2i64.p0i64.v2i64.v4i1" ||

4435 Name == "mve.vldr.gather.offset.predicated.v2i64.p0.v2i64.v4i1" ||

4436 Name == "mve.vstr.scatter.base.predicated.v2i64.v2i64.v4i1" ||

4437 Name == "mve.vstr.scatter.base.wb.predicated.v2i64.v2i64.v4i1" ||

4438 Name ==

4439 "mve.vstr.scatter.offset.predicated.p0i64.v2i64.v2i64.v4i1" ||

4440 Name == "mve.vstr.scatter.offset.predicated.p0.v2i64.v2i64.v4i1" ||

4441 Name == "cde.vcx1q.predicated.v2i64.v4i1" ||

4442 Name == "cde.vcx1qa.predicated.v2i64.v4i1" ||

4443 Name == "cde.vcx2q.predicated.v2i64.v4i1" ||

4444 Name == "cde.vcx2qa.predicated.v2i64.v4i1" ||

4445 Name == "cde.vcx3q.predicated.v2i64.v4i1" ||

4446 Name == "cde.vcx3qa.predicated.v2i64.v4i1") {

4447 std::vector<Type *> Tys;

4450 switch (ID) {

4451 case Intrinsic::arm_mve_mull_int_predicated:

4452 case Intrinsic::arm_mve_vqdmull_predicated:

4453 case Intrinsic::arm_mve_vldr_gather_base_predicated:

4455 break;

4456 case Intrinsic::arm_mve_vldr_gather_base_wb_predicated:

4457 case Intrinsic::arm_mve_vstr_scatter_base_predicated:

4458 case Intrinsic::arm_mve_vstr_scatter_base_wb_predicated:

4460 V2I1Ty};

4461 break;

4462 case Intrinsic::arm_mve_vldr_gather_offset_predicated:

4465 break;

4466 case Intrinsic::arm_mve_vstr_scatter_offset_predicated:

4469 break;

4470 case Intrinsic::arm_cde_vcx1q_predicated:

4471 case Intrinsic::arm_cde_vcx1qa_predicated:

4472 case Intrinsic::arm_cde_vcx2q_predicated:

4473 case Intrinsic::arm_cde_vcx2qa_predicated:

4474 case Intrinsic::arm_cde_vcx3q_predicated:

4475 case Intrinsic::arm_cde_vcx3qa_predicated:

4477 break;

4478 default:

4480 }

4481

4482 std::vector<Value *> Ops;

4484 Type *Ty = Op->getType();

4485 if (Ty->getScalarSizeInBits() == 1) {

4486 Value *C1 = Builder.CreateIntrinsic(

4487 Intrinsic::arm_mve_pred_v2i,

4489 Op = Builder.CreateIntrinsic(Intrinsic::arm_mve_pred_i2v, {V2I1Ty}, C1);

4490 }

4491 Ops.push_back(Op);

4492 }

4493

4494 return Builder.CreateIntrinsic(ID, Tys, Ops, nullptr,

4496 }

4497 llvm_unreachable("Unknown function for ARM CallBase upgrade.");

4498}

4499

4500

4501

4502

4503

4504

4520

4522 if (NumOperands < 3)

4523 return nullptr;

4524

4527 if (!PtrTy)

4528 return nullptr;

4529

4532 return nullptr;

4533

4535 bool IsVolatile = false;

4536

4537

4538

4539 if (NumOperands > 3)

4541

4542

4543

4544 if (NumOperands > 5) {

4546 IsVolatile = !VolatileArg || !VolatileArg->isZero();

4547 }

4548

4554

4556

4557

4560 if (VT->getElementType()->isIntegerTy(16)) {

4563 Val = Builder.CreateBitCast(Val, AsBF16);

4564 }

4565 }

4566

4567

4568

4569 SyncScope::ID SSID = Ctx.getOrInsertSyncScopeID("agent");

4571 Builder.CreateAtomicRMW(RMWOp, Ptr, Val, std::nullopt, Order, SSID);

4572

4573 unsigned AddrSpace = PtrTy->getAddressSpace();

4576 RMW->setMetadata("amdgpu.no.fine.grained.memory", EmptyMD);

4578 RMW->setMetadata("amdgpu.ignore.denormal.mode", EmptyMD);

4579 }

4580

4583 MDNode *RangeNotPrivate =

4586 RMW->setMetadata(LLVMContext::MD_noalias_addrspace, RangeNotPrivate);

4587 }

4588

4589 if (IsVolatile)

4591

4592 return Builder.CreateBitCast(RMW, RetTy);

4593}

4594

4595

4596

4597

4602 Metadata *MD = MAV->getMetadata();

4604 }

4605 }

4606 return nullptr;

4607}

4608

4609

4613 return MAV->getMetadata();

4614 return nullptr;

4615}

4616

4618

4619

4620 return I->getDebugLoc().getAsMDNode();

4621}

4622

4623

4624

4625

4628 if (Name == "label") {

4631 } else if (Name == "assign") {

4636

4638 } else if (Name == "declare") {

4643 } else if (Name == "addr") {

4644

4646

4647

4650 }

4653 unwrapMAVOp(CI, 1), ExprNode, nullptr, nullptr, nullptr,

4655 } else if (Name == "value") {

4656

4657 unsigned VarOp = 1;

4658 unsigned ExprOp = 2;

4661

4663 return;

4664 VarOp = 2;

4665 ExprOp = 3;

4666 }

4671 }

4672 assert(DR && "Unhandled intrinsic kind in upgrade to DbgRecord");

4674}

4675

4676

4677

4679

4680

4681

4683 if (F)

4684 return;

4685

4689

4690 if (!NewFn) {

4691

4693

4694 assert(Name.starts_with("llvm.") && "Intrinsic doesn't start with 'llvm.'");

4695 Name = Name.substr(5);

4696

4697 bool IsX86 = Name.consume_front("x86.");

4698 bool IsNVVM = Name.consume_front("nvvm.");

4699 bool IsAArch64 = Name.consume_front("aarch64.");

4700 bool IsARM = Name.consume_front("arm.");

4701 bool IsAMDGCN = Name.consume_front("amdgcn.");

4702 bool IsDbg = Name.consume_front("dbg.");

4703 Value *Rep = nullptr;

4704

4705 if (!IsX86 && Name == "stackprotectorcheck") {

4706 Rep = nullptr;

4707 } else if (IsNVVM) {

4709 } else if (IsX86) {

4711 } else if (IsAArch64) {

4713 } else if (IsARM) {

4715 } else if (IsAMDGCN) {

4717 } else if (IsDbg) {

4719 } else {

4721 }

4722

4723 if (Rep)

4726 return;

4727 }

4728

4729 const auto &DefaultCase = [&]() -> void {

4730 if (F == NewFn)

4731 return;

4732

4734

4737 "Unknown function for CallBase upgrade and isn't just a name change");

4739 return;

4740 }

4741

4742

4745 "Return type must have changed");

4746 assert(OldST->getNumElements() ==

4748 "Must have same number of elements");

4749

4751 CallInst *NewCI = Builder.CreateCall(NewFn, Args);

4754 for (unsigned Idx = 0; Idx < OldST->getNumElements(); ++Idx) {

4755 Value *Elem = Builder.CreateExtractValue(NewCI, Idx);

4756 Res = Builder.CreateInsertValue(Res, Elem, Idx);

4757 }

4760 return;

4761 }

4762

4763

4764

4767 return;

4768 };

4769 CallInst *NewCall = nullptr;

4771 default: {

4772 DefaultCase();

4773 return;

4774 }

4775 case Intrinsic::arm_neon_vst1:

4776 case Intrinsic::arm_neon_vst2:

4777 case Intrinsic::arm_neon_vst3:

4778 case Intrinsic::arm_neon_vst4:

4779 case Intrinsic::arm_neon_vst2lane:

4780 case Intrinsic::arm_neon_vst3lane:

4781 case Intrinsic::arm_neon_vst4lane: {

4783 NewCall = Builder.CreateCall(NewFn, Args);

4784 break;

4785 }

4786 case Intrinsic::aarch64_sve_bfmlalb_lane_v2:

4787 case Intrinsic::aarch64_sve_bfmlalt_lane_v2:

4788 case Intrinsic::aarch64_sve_bfdot_lane_v2: {

4789 LLVMContext &Ctx = F->getParent()->getContext();

4793 NewCall = Builder.CreateCall(NewFn, Args);

4794 break;

4795 }

4796 case Intrinsic::aarch64_sve_ld3_sret:

4797 case Intrinsic::aarch64_sve_ld4_sret:

4798 case Intrinsic::aarch64_sve_ld2_sret: {

4800 Name = Name.substr(5);

4807 unsigned MinElts = RetTy->getMinNumElements() / N;

4809 Value *NewLdCall = Builder.CreateCall(NewFn, Args);

4811 for (unsigned I = 0; I < N; I++) {

4812 Value *SRet = Builder.CreateExtractValue(NewLdCall, I);

4813 Ret = Builder.CreateInsertVector(RetTy, Ret, SRet, I * MinElts);

4814 }

4816 break;

4817 }

4818

4819 case Intrinsic::coro_end: {

4822 NewCall = Builder.CreateCall(NewFn, Args);

4823 break;

4824 }

4825

4826 case Intrinsic::vector_extract: {

4828 Name = Name.substr(5);

4829 if (!Name.starts_with("aarch64.sve.tuple.get")) {

4830 DefaultCase();

4831 return;

4832 }

4834 unsigned MinElts = RetTy->getMinNumElements();

4837 NewCall = Builder.CreateCall(NewFn, {CI->getArgOperand(0), NewIdx});

4838 break;

4839 }

4840

4841 case Intrinsic::vector_insert: {

4843 Name = Name.substr(5);

4844 if (!Name.starts_with("aarch64.sve.tuple")) {

4845 DefaultCase();

4846 return;

4847 }

4848 if (Name.starts_with("aarch64.sve.tuple.set")) {

4853 NewCall = Builder.CreateCall(

4855 break;

4856 }

4857 if (Name.starts_with("aarch64.sve.tuple.create")) {

4859 .StartsWith("aarch64.sve.tuple.create2", 2)

4860 .StartsWith("aarch64.sve.tuple.create3", 3)

4861 .StartsWith("aarch64.sve.tuple.create4", 4)

4863 assert(N > 1 && "Create is expected to be between 2-4");

4866 unsigned MinElts = RetTy->getMinNumElements() / N;

4867 for (unsigned I = 0; I < N; I++) {

4869 Ret = Builder.CreateInsertVector(RetTy, Ret, V, I * MinElts);

4870 }

4872 }

4873 break;

4874 }

4875

4876 case Intrinsic::arm_neon_bfdot:

4877 case Intrinsic::arm_neon_bfmmla:

4878 case Intrinsic::arm_neon_bfmlalb:

4879 case Intrinsic::arm_neon_bfmlalt:

4880 case Intrinsic::aarch64_neon_bfdot:

4881 case Intrinsic::aarch64_neon_bfmmla:

4882 case Intrinsic::aarch64_neon_bfmlalb:

4883 case Intrinsic::aarch64_neon_bfmlalt: {

4886 "Mismatch between function args and call args");

4887 size_t OperandWidth =

4889 assert((OperandWidth == 64 || OperandWidth == 128) &&

4890 "Unexpected operand width");

4892 auto Iter = CI->args().begin();

4893 Args.push_back(*Iter++);

4894 Args.push_back(Builder.CreateBitCast(*Iter++, NewTy));

4895 Args.push_back(Builder.CreateBitCast(*Iter++, NewTy));

4896 NewCall = Builder.CreateCall(NewFn, Args);

4897 break;

4898 }

4899

4900 case Intrinsic::bitreverse:

4901 NewCall = Builder.CreateCall(NewFn, {CI->getArgOperand(0)});

4902 break;

4903

4904 case Intrinsic::ctlz:

4905 case Intrinsic::cttz:

4907 "Mismatch between function args and call args");

4908 NewCall =

4909 Builder.CreateCall(NewFn, {CI->getArgOperand(0), Builder.getFalse()});

4910 break;

4911

4912 case Intrinsic::objectsize: {

4913 Value *NullIsUnknownSize =

4917 NewCall = Builder.CreateCall(

4919 break;

4920 }

4921

4922 case Intrinsic::ctpop:

4923 NewCall = Builder.CreateCall(NewFn, {CI->getArgOperand(0)});

4924 break;

4925

4926 case Intrinsic::convert_from_fp16:

4927 NewCall = Builder.CreateCall(NewFn, {CI->getArgOperand(0)});

4928 break;

4929

4930 case Intrinsic::dbg_value: {

4932 Name = Name.substr(5);

4933

4934 if (Name.starts_with("dbg.addr")) {

4938 NewCall =

4941 break;

4942 }

4943

4944

4946

4948 if (Offset->isZeroValue()) {

4949 NewCall = Builder.CreateCall(

4950 NewFn,

4952 break;

4953 }

4955 return;

4956 }

4957

4958 case Intrinsic::ptr_annotation:

4959

4961 DefaultCase();

4962 return;

4963 }

4964

4965

4966 NewCall = Builder.CreateCall(

4967 NewFn,

4973 return;

4974

4975 case Intrinsic::var_annotation:

4976

4978 DefaultCase();

4979 return;

4980 }

4981

4982 NewCall = Builder.CreateCall(

4983 NewFn,

4989 return;

4990

4991 case Intrinsic::riscv_aes32dsi:

4992 case Intrinsic::riscv_aes32dsmi:

4993 case Intrinsic::riscv_aes32esi:

4994 case Intrinsic::riscv_aes32esmi:

4995 case Intrinsic::riscv_sm4ks:

4996 case Intrinsic::riscv_sm4ed: {

4997

4998

5001 return;

5002

5006 Arg0 = Builder.CreateTrunc(Arg0, Builder.getInt32Ty());

5007 Arg1 = Builder.CreateTrunc(Arg1, Builder.getInt32Ty());

5008 }

5009

5012

5013 NewCall = Builder.CreateCall(NewFn, {Arg0, Arg1, Arg2});

5014 Value *Res = NewCall;

5016 Res = Builder.CreateIntCast(NewCall, CI->getType(), true);

5020 return;

5021 }

5022 case Intrinsic::nvvm_mapa_shared_cluster: {

5023

5024 NewCall =

5026 Value *Res = NewCall;

5027 Res = Builder.CreateAddrSpaceCast(

5032 return;

5033 }

5034 case Intrinsic::nvvm_cp_async_bulk_global_to_shared_cluster:

5035 case Intrinsic::nvvm_cp_async_bulk_shared_cta_to_cluster: {

5036

5038 Args[0] = Builder.CreateAddrSpaceCast(

5040

5041 NewCall = Builder.CreateCall(NewFn, Args);

5045 return;

5046 }

5047 case Intrinsic::nvvm_cp_async_bulk_tensor_g2s_im2col_3d:

5048 case Intrinsic::nvvm_cp_async_bulk_tensor_g2s_im2col_4d:

5049 case Intrinsic::nvvm_cp_async_bulk_tensor_g2s_im2col_5d:

5050 case Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_1d:

5051 case Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_2d:

5052 case Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_3d:

5053 case Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_4d:

5054 case Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_5d: {

5056

5057

5058

5061 Args[0] = Builder.CreateAddrSpaceCast(

5063

5064

5065

5066

5067 size_t NumArgs = CI->arg_size();

5070 Args.push_back(ConstantInt::get(Builder.getInt32Ty(), 0));

5071

5072 NewCall = Builder.CreateCall(NewFn, Args);

5076 return;

5077 }

5078 case Intrinsic::riscv_sha256sig0:

5079 case Intrinsic::riscv_sha256sig1:

5080 case Intrinsic::riscv_sha256sum0:

5081 case Intrinsic::riscv_sha256sum1:

5082 case Intrinsic::riscv_sm3p0:

5083 case Intrinsic::riscv_sm3p1: {

5084

5085

5087 return;

5088

5090 Builder.CreateTrunc(CI->getArgOperand(0), Builder.getInt32Ty());

5091

5092 NewCall = Builder.CreateCall(NewFn, Arg);

5094 Builder.CreateIntCast(NewCall, CI->getType(), true);

5098 return;

5099 }

5100

5101 case Intrinsic::x86_xop_vfrcz_ss:

5102 case Intrinsic::x86_xop_vfrcz_sd:

5103 NewCall = Builder.CreateCall(NewFn, {CI->getArgOperand(1)});

5104 break;

5105

5106 case Intrinsic::x86_xop_vpermil2pd:

5107 case Intrinsic::x86_xop_vpermil2ps:

5108 case Intrinsic::x86_xop_vpermil2pd_256:

5109 case Intrinsic::x86_xop_vpermil2ps_256: {

5113 Args[2] = Builder.CreateBitCast(Args[2], IntIdxTy);

5114 NewCall = Builder.CreateCall(NewFn, Args);

5115 break;

5116 }

5117

5118 case Intrinsic::x86_sse41_ptestc:

5119 case Intrinsic::x86_sse41_ptestz:

5120 case Intrinsic::x86_sse41_ptestnzc: {

5121

5122

5123

5124

5127 return;

5128

5129

5131

5133

5134 Value *BC0 = Builder.CreateBitCast(Arg0, NewVecTy, "cast");

5135 Value *BC1 = Builder.CreateBitCast(Arg1, NewVecTy, "cast");

5136

5137 NewCall = Builder.CreateCall(NewFn, {BC0, BC1});

5138 break;

5139 }

5140

5141 case Intrinsic::x86_rdtscp: {

5142

5143

5145 return;

5146

5147 NewCall = Builder.CreateCall(NewFn);

5148

5149 Value *Data = Builder.CreateExtractValue(NewCall, 1);

5151

5152 Value *TSC = Builder.CreateExtractValue(NewCall, 0);

5153

5157 return;

5158 }

5159

5160 case Intrinsic::x86_sse41_insertps:

5161 case Intrinsic::x86_sse41_dppd:

5162 case Intrinsic::x86_sse41_dpps:

5163 case Intrinsic::x86_sse41_mpsadbw:

5164 case Intrinsic::x86_avx_dp_ps_256:

5165 case Intrinsic::x86_avx2_mpsadbw: {

5166

5167

5169

5170

5171 Args.back() = Builder.CreateTrunc(Args.back(), Type::getInt8Ty(C), "trunc");

5172 NewCall = Builder.CreateCall(NewFn, Args);

5173 break;

5174 }

5175

5176 case Intrinsic::x86_avx512_mask_cmp_pd_128:

5177 case Intrinsic::x86_avx512_mask_cmp_pd_256:

5178 case Intrinsic::x86_avx512_mask_cmp_pd_512:

5179 case Intrinsic::x86_avx512_mask_cmp_ps_128:

5180 case Intrinsic::x86_avx512_mask_cmp_ps_256:

5181 case Intrinsic::x86_avx512_mask_cmp_ps_512: {

5183 unsigned NumElts =

5185 Args[3] = getX86MaskVec(Builder, Args[3], NumElts);

5186

5187 NewCall = Builder.CreateCall(NewFn, Args);

5189

5193 return;

5194 }

5195

5196 case Intrinsic::x86_avx512bf16_cvtne2ps2bf16_128:

5197 case Intrinsic::x86_avx512bf16_cvtne2ps2bf16_256:

5198 case Intrinsic::x86_avx512bf16_cvtne2ps2bf16_512:

5199 case Intrinsic::x86_avx512bf16_mask_cvtneps2bf16_128:

5200 case Intrinsic::x86_avx512bf16_cvtneps2bf16_256:

5201 case Intrinsic::x86_avx512bf16_cvtneps2bf16_512: {

5205 Intrinsic::x86_avx512bf16_mask_cvtneps2bf16_128)

5206 Args[1] = Builder.CreateBitCast(

5208

5209 NewCall = Builder.CreateCall(NewFn, Args);

5210 Value *Res = Builder.CreateBitCast(

5212

5216 return;

5217 }

5218 case Intrinsic::x86_avx512bf16_dpbf16ps_128:

5219 case Intrinsic::x86_avx512bf16_dpbf16ps_256:

5220 case Intrinsic::x86_avx512bf16_dpbf16ps_512:{

5222 unsigned NumElts =

5224 Args[1] = Builder.CreateBitCast(

5226 Args[2] = Builder.CreateBitCast(

5228

5229 NewCall = Builder.CreateCall(NewFn, Args);

5230 break;

5231 }

5232

5233 case Intrinsic::thread_pointer: {

5234 NewCall = Builder.CreateCall(NewFn, {});

5235 break;

5236 }

5237

5238 case Intrinsic::memcpy:

5239 case Intrinsic::memmove:

5240 case Intrinsic::memset: {

5241

5242

5243

5244

5245

5246

5247

5249 DefaultCase();

5250 return;

5251 }

5252

5253

5256 NewCall = Builder.CreateCall(NewFn, Args);

5258 AttributeList NewAttrs = AttributeList::get(

5259 C, OldAttrs.getFnAttrs(), OldAttrs.getRetAttrs(),

5260 {OldAttrs.getParamAttrs(0), OldAttrs.getParamAttrs(1),

5261 OldAttrs.getParamAttrs(2), OldAttrs.getParamAttrs(4)});

5264

5266 MemCI->setDestAlignment(Align->getMaybeAlignValue());

5267

5269 MTI->setSourceAlignment(Align->getMaybeAlignValue());

5270 break;

5271 }

5272

5273 case Intrinsic::masked_load:

5274 case Intrinsic::masked_gather:

5275 case Intrinsic::masked_store:

5276 case Intrinsic::masked_scatter: {

5278 DefaultCase();

5279 return;

5280 }

5281

5282 auto GetMaybeAlign = [](Value *Op) {

5284 uint64_t Val = CI->getZExtValue();

5285 if (Val == 0)

5289 }

5291 };

5292 auto GetAlign = [&](Value *Op) {

5297 };

5298

5301 case Intrinsic::masked_load:

5302 NewCall = Builder.CreateMaskedLoad(

5305 break;

5306 case Intrinsic::masked_gather:

5307 NewCall = Builder.CreateMaskedGather(

5309 DL.getValueOrABITypeAlignment(GetMaybeAlign(CI->getArgOperand(1)),

5312 break;

5313 case Intrinsic::masked_store:

5314 NewCall = Builder.CreateMaskedStore(

5317 break;

5318 case Intrinsic::masked_scatter:

5319 NewCall = Builder.CreateMaskedScatter(

5321 DL.getValueOrABITypeAlignment(

5325 break;

5326 default:

5328 }

5329

5332 break;

5333 }

5334

5335 case Intrinsic::lifetime_start:

5336 case Intrinsic::lifetime_end: {

5338 DefaultCase();

5339 return;

5340 }

5341

5343

5346

5347 if (NewFn->getIntrinsicID() == Intrinsic::lifetime_start)

5348 NewCall = Builder.CreateLifetimeStart(Ptr);

5349 else

5350 NewCall = Builder.CreateLifetimeEnd(Ptr);

5351 break;

5352 }

5353

5354

5356 return;

5357 }

5358

5359 case Intrinsic::x86_avx512_vpdpbusd_128:

5360 case Intrinsic::x86_avx512_vpdpbusd_256:

5361 case Intrinsic::x86_avx512_vpdpbusd_512:

5362 case Intrinsic::x86_avx512_vpdpbusds_128:

5363 case Intrinsic::x86_avx512_vpdpbusds_256:

5364 case Intrinsic::x86_avx512_vpdpbusds_512:

5365 case Intrinsic::x86_avx2_vpdpbssd_128:

5366 case Intrinsic::x86_avx2_vpdpbssd_256:

5367 case Intrinsic::x86_avx10_vpdpbssd_512:

5368 case Intrinsic::x86_avx2_vpdpbssds_128:

5369 case Intrinsic::x86_avx2_vpdpbssds_256:

5370 case Intrinsic::x86_avx10_vpdpbssds_512:

5371 case Intrinsic::x86_avx2_vpdpbsud_128:

5372 case Intrinsic::x86_avx2_vpdpbsud_256:

5373 case Intrinsic::x86_avx10_vpdpbsud_512:

5374 case Intrinsic::x86_avx2_vpdpbsuds_128:

5375 case Intrinsic::x86_avx2_vpdpbsuds_256:

5376 case Intrinsic::x86_avx10_vpdpbsuds_512:

5377 case Intrinsic::x86_avx2_vpdpbuud_128:

5378 case Intrinsic::x86_avx2_vpdpbuud_256:

5379 case Intrinsic::x86_avx10_vpdpbuud_512:

5380 case Intrinsic::x86_avx2_vpdpbuuds_128:

5381 case Intrinsic::x86_avx2_vpdpbuuds_256:

5382 case Intrinsic::x86_avx10_vpdpbuuds_512: {

5386 Type *NewArgType = VectorType::get(Builder.getInt8Ty(), NumElts, false);

5387 Args[1] = Builder.CreateBitCast(Args[1], NewArgType);

5388 Args[2] = Builder.CreateBitCast(Args[2], NewArgType);

5389

5390 NewCall = Builder.CreateCall(NewFn, Args);

5391 break;

5392 }

5393 }

5394 assert(NewCall && "Should have either set this variable or returned through "

5395 "the default case");

5399}

5400

5402 assert(F && "Illegal attempt to upgrade a non-existent intrinsic.");

5403

5404

5405

5408

5409

5413

5414

5415 if (F != NewFn)

5416 F->eraseFromParent();

5417 }

5418}

5419

5422 if (NumOperands == 0)

5423 return &MD;

5424

5425

5427 return &MD;

5428

5430 if (NumOperands == 3) {

5433

5434 Metadata *Elts2[] = {ScalarType, ScalarType,

5439 }

5440

5444}

5445

5448 if (Opc != Instruction::BitCast)

5449 return nullptr;

5450

5451 Temp = nullptr;

5452 Type *SrcTy = V->getType();

5456

5457

5458

5461

5462 return CastInst::Create(Instruction::IntToPtr, Temp, DestTy);

5463 }

5464

5465 return nullptr;

5466}

5467

5469 if (Opc != Instruction::BitCast)

5470 return nullptr;

5471

5472 Type *SrcTy = C->getType();

5476

5477

5478

5480

5482 DestTy);

5483 }

5484

5485 return nullptr;

5486}

5487

5488

5489

5492 return false;

5493

5495

5496

5497

5499 if (NamedMDNode *ModFlags = M.getModuleFlagsMetadata()) {

5500 auto OpIt = find_if(ModFlags->operands(), [](const MDNode *Flag) {

5501 if (Flag->getNumOperands() < 3)

5502 return false;

5503 if (MDString *K = dyn_cast_or_null(Flag->getOperand(1)))

5504 return K->getString() == "Debug Info Version";

5505 return false;

5506 });

5507 if (OpIt != ModFlags->op_end()) {

5508 const MDOperand &ValOp = (*OpIt)->getOperand(2);

5510 Version = CI->getZExtValue();

5511 }

5512 }

5513

5515 bool BrokenDebugInfo = false;

5518 if (!BrokenDebugInfo)

5519

5520 return false;

5521 else {

5522

5524 M.getContext().diagnose(Diag);

5525 }

5526 }

5529

5531 M.getContext().diagnose(DiagVersion);

5532 }

5534}

5535

5539

5541 StringRef Vect3[3] = {DefaultValue, DefaultValue, DefaultValue};

5542 unsigned Length = 0;

5543

5544 if (F->hasFnAttribute(Attr)) {

5545

5546

5547 StringRef S = F->getFnAttribute(Attr).getValueAsString();

5549 auto [Part, Rest] = S.split(',');

5551 S = Rest;

5552 }

5553 }

5554

5555 const unsigned Dim = DimC - 'x';

5556 assert(Dim < 3 && "Unexpected dim char");

5557

5559

5560

5561 const std::string VStr = llvm::utostr(VInt);

5562 Vect3[Dim] = VStr;

5564

5566 F->addFnAttr(Attr, NewAttr);

5567}

5568

5570 return S == "x" || S == "y" || S == "z";

5571}

5572

5575 if (K == "kernel") {

5578 return true;

5579 }

5580 if (K == "align") {

5581

5582

5583

5584

5585 const uint64_t AlignIdxValuePair =

5587 const unsigned Idx = (AlignIdxValuePair >> 16);

5588 const Align StackAlign = Align(AlignIdxValuePair & 0xFFFF);

5591 return true;

5592 }

5593 if (K == "maxclusterrank" || K == "cluster_max_blocks") {

5596 return true;

5597 }

5598 if (K == "minctasm") {

5601 return true;

5602 }

5603 if (K == "maxnreg") {

5606 return true;

5607 }

5608 if (K.consume_front("maxntid") && isXYZ(K)) {

5610 return true;

5611 }

5612 if (K.consume_front("reqntid") && isXYZ(K)) {

5614 return true;

5615 }

5616 if (K.consume_front("cluster_dim_") && isXYZ(K)) {

5618 return true;

5619 }

5620 if (K == "grid_constant") {

5622 for (const auto &Op : cast(V)->operands()) {

5623

5624

5627 }

5628 return true;

5629 }

5630

5631 return false;

5632}

5633

5635 NamedMDNode *NamedMD = M.getNamedMetadata("nvvm.annotations");

5636 if (!NamedMD)

5637 return;

5638

5642 if (!SeenNodes.insert(MD).second)

5643 continue;

5644

5646 if (!GV)

5647 continue;

5648

5649 assert((MD->getNumOperands() % 2) == 1 && "Invalid number of operands");

5650

5652

5653

5654

5655

5656 for (unsigned j = 1, je = MD->getNumOperands(); j < je; j += 2) {

5658 const MDOperand &V = MD->getOperand(j + 1);

5660 if (!Upgraded)

5661 NewOperands.append({K, V});

5662 }

5663

5664 if (NewOperands.size() > 1)

5666 }

5667

5669 for (MDNode *N : NewNodes)

5671}

5672

5673

5674

5677 const char *MarkerKey = "clang.arc.retainAutoreleasedReturnValueMarker";

5678 NamedMDNode *ModRetainReleaseMarker = M.getNamedMetadata(MarkerKey);

5679 if (ModRetainReleaseMarker) {

5681 if (Op) {

5683 if (ID) {

5685 ID->getString().split(ValueComp, "#");

5686 if (ValueComp.size() == 2) {

5687 std::string NewValue = ValueComp[0].str() + ";" + ValueComp[1].str();

5689 }

5691 M.eraseNamedMetadata(ModRetainReleaseMarker);

5693 }

5694 }

5695 }

5697}

5698

5700

5701

5702 auto UpgradeToIntrinsic = [&](const char *OldFunc,

5705

5706 if (!Fn)

5707 return;

5708

5711

5715 continue;

5716

5720

5721

5722

5726 continue;

5727

5728 bool InvalidCast = false;

5729

5730 for (unsigned I = 0, E = CI->arg_size(); I != E; ++I) {

5732

5733

5734

5736

5737

5740 InvalidCast = true;

5741 break;

5742 }

5743 Arg = Builder.CreateBitCast(Arg, NewFuncTy->getParamType(I));

5744 }

5745 Args.push_back(Arg);

5746 }

5747

5748 if (InvalidCast)

5749 continue;

5750

5751

5752 CallInst *NewCall = Builder.CreateCall(NewFuncTy, NewFn, Args);

5755

5756

5757 Value *NewRetVal = Builder.CreateBitCast(NewCall, CI->getType());

5758

5762 }

5763

5766 };

5767

5768

5769

5770 UpgradeToIntrinsic("clang.arc.use", llvm::Intrinsic::objc_clang_arc_use);

5771

5772

5773

5774

5776 return;

5777

5778 std::pair<const char *, llvm::Intrinsic::ID> RuntimeFuncs[] = {

5779 {"objc_autorelease", llvm::Intrinsic::objc_autorelease},

5780 {"objc_autoreleasePoolPop", llvm::Intrinsic::objc_autoreleasePoolPop},

5781 {"objc_autoreleasePoolPush", llvm::Intrinsic::objc_autoreleasePoolPush},

5782 {"objc_autoreleaseReturnValue",

5783 llvm::Intrinsic::objc_autoreleaseReturnValue},

5784 {"objc_copyWeak", llvm::Intrinsic::objc_copyWeak},

5785 {"objc_destroyWeak", llvm::Intrinsic::objc_destroyWeak},

5786 {"objc_initWeak", llvm::Intrinsic::objc_initWeak},

5787 {"objc_loadWeak", llvm::Intrinsic::objc_loadWeak},

5788 {"objc_loadWeakRetained", llvm::Intrinsic::objc_loadWeakRetained},

5789 {"objc_moveWeak", llvm::Intrinsic::objc_moveWeak},

5790 {"objc_release", llvm::Intrinsic::objc_release},

5791 {"objc_retain", llvm::Intrinsic::objc_retain},

5792 {"objc_retainAutorelease", llvm::Intrinsic::objc_retainAutorelease},

5793 {"objc_retainAutoreleaseReturnValue",

5794 llvm::Intrinsic::objc_retainAutoreleaseReturnValue},

5795 {"objc_retainAutoreleasedReturnValue",

5796 llvm::Intrinsic::objc_retainAutoreleasedReturnValue},

5797 {"objc_retainBlock", llvm::Intrinsic::objc_retainBlock},

5798 {"objc_storeStrong", llvm::Intrinsic::objc_storeStrong},

5799 {"objc_storeWeak", llvm::Intrinsic::objc_storeWeak},

5800 {"objc_unsafeClaimAutoreleasedReturnValue",

5801 llvm::Intrinsic::objc_unsafeClaimAutoreleasedReturnValue},

5802 {"objc_retainedObject", llvm::Intrinsic::objc_retainedObject},

5803 {"objc_unretainedObject", llvm::Intrinsic::objc_unretainedObject},

5804 {"objc_unretainedPointer", llvm::Intrinsic::objc_unretainedPointer},

5805 {"objc_retain_autorelease", llvm::Intrinsic::objc_retain_autorelease},

5806 {"objc_sync_enter", llvm::Intrinsic::objc_sync_enter},

5807 {"objc_sync_exit", llvm::Intrinsic::objc_sync_exit},

5808 {"objc_arc_annotation_topdown_bbstart",

5809 llvm::Intrinsic::objc_arc_annotation_topdown_bbstart},

5810 {"objc_arc_annotation_topdown_bbend",

5811 llvm::Intrinsic::objc_arc_annotation_topdown_bbend},

5812 {"objc_arc_annotation_bottomup_bbstart",

5813 llvm::Intrinsic::objc_arc_annotation_bottomup_bbstart},

5814 {"objc_arc_annotation_bottomup_bbend",

5815 llvm::Intrinsic::objc_arc_annotation_bottomup_bbend}};

5816

5817 for (auto &I : RuntimeFuncs)

5818 UpgradeToIntrinsic(I.first, I.second);

5819}

5820

5822 NamedMDNode *ModFlags = M.getModuleFlagsMetadata();

5823 if (!ModFlags)

5824 return false;

5825

5826 bool HasObjCFlag = false, HasClassProperties = false, Changed = false;

5827 bool HasSwiftVersionFlag = false;

5828 uint8_t SwiftMajorVersion, SwiftMinorVersion;

5832

5833 for (unsigned I = 0, E = ModFlags->getNumOperands(); I != E; ++I) {

5835 if (Op->getNumOperands() != 3)

5836 continue;

5838 if (ID)

5839 continue;

5844 Op->getOperand(2)};

5847 };

5848

5849 if (ID->getString() == "Objective-C Image Info Version")

5850 HasObjCFlag = true;

5851 if (ID->getString() == "Objective-C Class Properties")

5852 HasClassProperties = true;

5853

5854 if (ID->getString() == "PIC Level") {

5855 if (auto *Behavior =

5857 uint64_t V = Behavior->getLimitedValue();

5860 }

5861 }

5862

5863 if (ID->getString() == "PIE Level")

5864 if (auto *Behavior =

5866 if (Behavior->getLimitedValue() == Module::Error)

5868

5869

5870

5871 if (ID->getString() == "branch-target-enforcement" ||

5872 ID->getString().starts_with("sign-return-address")) {

5873 if (auto *Behavior =

5875 if (Behavior->getLimitedValue() == Module::Error) {

5879 Op->getOperand(1), Op->getOperand(2)};

5882 }

5883 }

5884 }

5885

5886

5887

5888

5889 if (ID->getString() == "Objective-C Image Info Section") {

5892 Value->getString().split(ValueComp, " ");

5893 if (ValueComp.size() != 1) {

5894 std::string NewValue;

5895 for (auto &S : ValueComp)

5896 NewValue += S.str();

5897 Metadata *Ops[3] = {Op->getOperand(0), Op->getOperand(1),

5901 }

5902 }

5903 }

5904

5905

5906

5907 if (ID->getString() == "Objective-C Garbage Collection") {

5909 if (Md) {

5910 assert(Md->getValue() && "Expected non-empty metadata");

5911 auto Type = Md->getValue()->getType();

5912 if (Type == Int8Ty)

5913 continue;

5914 unsigned Val = Md->getValue()->getUniqueInteger().getZExtValue();

5915 if ((Val & 0xff) != Val) {

5916 HasSwiftVersionFlag = true;

5917 SwiftABIVersion = (Val & 0xff00) >> 8;

5918 SwiftMajorVersion = (Val & 0xff000000) >> 24;

5919 SwiftMinorVersion = (Val & 0xff0000) >> 16;

5920 }

5923 Op->getOperand(1),

5927 }

5928 }

5929

5930 if (ID->getString() == "amdgpu_code_object_version") {

5932 Op->getOperand(0),

5933 MDString::get(M.getContext(), "amdhsa_code_object_version"),

5934 Op->getOperand(2)};

5937 }

5938 }

5939

5940

5941

5942

5943

5944

5945 if (HasObjCFlag && !HasClassProperties) {

5949 }

5950

5951 if (HasSwiftVersionFlag) {

5952 M.addModuleFlag(Module::Error, "Swift ABI Version",

5953 SwiftABIVersion);

5954 M.addModuleFlag(Module::Error, "Swift Major Version",

5955 ConstantInt::get(Int8Ty, SwiftMajorVersion));

5956 M.addModuleFlag(Module::Error, "Swift Minor Version",

5957 ConstantInt::get(Int8Ty, SwiftMinorVersion));

5959 }

5960

5962}

5963

5965 auto TrimSpaces = [](StringRef Section) -> std::string {

5967 Section.split(Components, ',');

5968

5971

5972 for (auto Component : Components)

5973 OS << ',' << Component.trim();

5974

5975 return std::string(OS.str().substr(1));

5976 };

5977

5978 for (auto &GV : M.globals()) {

5979 if (!GV.hasSection())

5980 continue;

5981

5982 StringRef Section = GV.getSection();

5983

5984 if (!Section.starts_with("__DATA, __objc_catlist"))

5985 continue;

5986

5987

5988

5989 GV.setSection(TrimSpaces(Section));

5990 }

5991}

5992

5993namespace {

5994

5995

5996

5997

5998

5999

6000

6001

6002

6003

6004

6005struct StrictFPUpgradeVisitor : public InstVisitor {

6006 StrictFPUpgradeVisitor() = default;

6007

6009 if (Call.isStrictFP())

6010 return;

6012 return;

6013

6014

6015 Call.removeFnAttr(Attribute::StrictFP);

6016 Call.addFnAttr(Attribute::NoBuiltin);

6017 }

6018};

6019

6020

6021struct AMDGPUUnsafeFPAtomicsUpgradeVisitor

6022 : public InstVisitor {

6023 AMDGPUUnsafeFPAtomicsUpgradeVisitor() = default;

6024

6025 void visitAtomicRMWInst(AtomicRMWInst &RMW) {

6027 return;

6028

6030 RMW.setMetadata("amdgpu.no.fine.grained.host.memory", Empty);

6033 }

6034};

6035}

6036

6038

6039

6040 if (F.isDeclaration() && F.hasFnAttribute(Attribute::StrictFP)) {

6041 StrictFPUpgradeVisitor SFPV;

6042 SFPV.visit(F);

6043 }

6044

6045

6046 F.removeRetAttrs(AttributeFuncs::typeIncompatible(

6047 F.getReturnType(), F.getAttributes().getRetAttrs()));

6048 for (auto &Arg : F.args())

6049 Arg.removeAttrs(

6050 AttributeFuncs::typeIncompatible(Arg.getType(), Arg.getAttributes()));

6051

6052

6053

6054 if (Attribute A = F.getFnAttribute("implicit-section-name");

6055 A.isValid() && A.isStringAttribute()) {

6056 F.setSection(A.getValueAsString());

6057 F.removeFnAttr("implicit-section-name");

6058 }

6059

6060 if (F.empty()) {

6061

6062

6063

6064 if (Attribute A = F.getFnAttribute("amdgpu-unsafe-fp-atomics");

6065 A.isValid()) {

6066

6067 if (A.getValueAsBool()) {

6068 AMDGPUUnsafeFPAtomicsUpgradeVisitor Visitor;

6069 Visitor.visit(F);

6070 }

6071

6072

6073

6074 F.removeFnAttr("amdgpu-unsafe-fp-atomics");

6075 }

6076 }

6077}

6078

6079

6082 if (F.hasFnAttribute(FnAttrName))

6083 F.addFnAttr(FnAttrName, Value);

6084}

6085

6086

6087

6088

6090 if (F.hasFnAttribute(FnAttrName)) {

6091 if (Set)

6092 F.addFnAttr(FnAttrName);

6093 } else {

6094 auto A = F.getFnAttribute(FnAttrName);

6095 if ("false" == A.getValueAsString())

6096 F.removeFnAttr(FnAttrName);

6097 else if ("true" == A.getValueAsString()) {

6098 F.removeFnAttr(FnAttrName);

6099 F.addFnAttr(FnAttrName);

6100 }

6101 }

6102}

6103

6105 Triple T(M.getTargetTriple());

6106 if (T.isThumb() && T.isARM() && T.isAArch64())

6107 return;

6108

6115

6116 NamedMDNode *ModFlags = M.getModuleFlagsMetadata();

6117 if (ModFlags) {

6118 for (unsigned I = 0, E = ModFlags->getNumOperands(); I != E; ++I) {

6120 if (Op->getNumOperands() != 3)

6121 continue;

6122

6125 if (ID || !CI)

6126 continue;

6127

6129 uint64_t *ValPtr = IDStr == "branch-target-enforcement" ? &BTEValue

6130 : IDStr == "branch-protection-pauth-lr" ? &BPPLRValue

6131 : IDStr == "guarded-control-stack" ? &GCSValue

6132 : IDStr == "sign-return-address" ? &SRAValue

6133 : IDStr == "sign-return-address-all" ? &SRAALLValue

6134 : IDStr == "sign-return-address-with-bkey"

6135 ? &SRABKeyValue

6136 : nullptr;

6137 if (!ValPtr)

6138 continue;

6139

6140 *ValPtr = CI->getZExtValue();

6141 if (*ValPtr == 2)

6142 return;

6143 }

6144 }

6145

6146 bool BTE = BTEValue == 1;

6147 bool BPPLR = BPPLRValue == 1;

6148 bool GCS = GCSValue == 1;

6149 bool SRA = SRAValue == 1;

6150

6151 StringRef SignTypeValue = "non-leaf";

6152 if (SRA && SRAALLValue == 1)

6153 SignTypeValue = "all";

6154

6155 StringRef SignKeyValue = "a_key";

6156 if (SRA && SRABKeyValue == 1)

6157 SignKeyValue = "b_key";

6158

6159 for (Function &F : M.getFunctionList()) {

6160 if (F.isDeclaration())

6161 continue;

6162

6163 if (SRA) {

6166 } else {

6167 if (auto A = F.getFnAttribute("sign-return-address");

6168 A.isValid() && "none" == A.getValueAsString()) {

6169 F.removeFnAttr("sign-return-address");

6170 F.removeFnAttr("sign-return-address-key");

6171 }

6172 }

6176 }

6177

6178 if (BTE)

6179 M.setModuleFlag(llvm::Module::Min, "branch-target-enforcement", 2);

6180 if (BPPLR)

6181 M.setModuleFlag(llvm::Module::Min, "branch-protection-pauth-lr", 2);

6182 if (GCS)

6184 if (SRA) {

6186 if (SRAALLValue == 1)

6187 M.setModuleFlag(llvm::Module::Min, "sign-return-address-all", 2);

6188 if (SRABKeyValue == 1)

6189 M.setModuleFlag(llvm::Module::Min, "sign-return-address-with-bkey", 2);

6190 }

6191}

6192

6195 if (T)

6196 return false;

6197 if (T->getNumOperands() < 1)

6198 return false;

6200 if (!S)

6201 return false;

6202 return S->getString().starts_with("llvm.vectorizer.");

6203}

6204

6206 StringRef OldPrefix = "llvm.vectorizer.";

6208

6209 if (OldTag == "llvm.vectorizer.unroll")

6210 return MDString::get(C, "llvm.loop.interleave.count");

6211

6214 .str());

6215}

6216

6219 if (T)

6220 return MD;

6221 if (T->getNumOperands() < 1)

6222 return MD;

6224 if (!OldTag)

6225 return MD;

6226 if (!OldTag->getString().starts_with("llvm.vectorizer."))

6227 return MD;

6228

6229

6231 Ops.reserve(T->getNumOperands());

6232 Ops.push_back(upgradeLoopTag(T->getContext(), OldTag->getString()));

6233 for (unsigned I = 1, E = T->getNumOperands(); I != E; ++I)

6234 Ops.push_back(T->getOperand(I));

6235

6237}

6238

6241 if (T)

6242 return &N;

6243

6245 return &N;

6246

6248 Ops.reserve(T->getNumOperands());

6249 for (Metadata *MD : T->operands())

6251

6253}

6254

6257

6258

6259 if ((T.isSPIR() || (T.isSPIRV() && T.isSPIRVLogical())) &&

6260 DL.contains("-G") && DL.starts_with("G")) {

6261 return DL.empty() ? std::string("G1") : (DL + "-G1").str();

6262 }

6263

6264 if (T.isLoongArch64() || T.isRISCV64()) {

6265

6266 auto I = DL.find("-n64-");

6268 return (DL.take_front(I) + "-n32:64-" + DL.drop_front(I + 5)).str();

6269 return DL.str();

6270 }

6271

6272

6273 std::string Res = DL.str();

6274 if (T.isAMDGPU()) {

6275

6276 if (DL.contains("-G") && DL.starts_with("G"))

6277 Res.append(Res.empty() ? "G1" : "-G1");

6278

6279

6280 if (T.isAMDGCN()) {

6281

6282

6283

6284

6285 if (DL.contains("-ni") && DL.starts_with("ni"))

6286 Res.append("-ni:7:8:9");

6287

6288 if (DL.ends_with("ni:7"))

6289 Res.append(":8:9");

6290 if (DL.ends_with("ni:7:8"))

6291 Res.append(":9");

6292

6293

6294

6295 if (DL.contains("-p7") && DL.starts_with("p7"))

6296 Res.append("-p7:160:256:256:32");

6297 if (DL.contains("-p8") && DL.starts_with("p8"))

6298 Res.append("-p8:128:128:128:48");

6299 constexpr StringRef OldP8("-p8:128:128-");

6300 if (DL.contains(OldP8))

6301 Res.replace(Res.find(OldP8), OldP8.size(), "-p8:128:128:128:48-");

6302 if (DL.contains("-p9") && DL.starts_with("p9"))

6303 Res.append("-p9:192:256:256:32");

6304 }

6305

6306

6307 if (DL.contains("m:e"))

6308 Res = Res.empty() ? "m:e" : "m:e-" + Res;

6309

6310 return Res;

6311 }

6312

6313 auto AddPtr32Ptr64AddrSpaces = [&DL, &Res]() {

6314

6315

6316 StringRef AddrSpaces{"-p270:32:32-p271:32:32-p272:64:64"};

6317 if (DL.contains(AddrSpaces)) {

6319 Regex R("^([Ee]-m:[a-z](-p:32:32)?)(-.*)$");

6320 if (R.match(Res, &Groups))

6321 Res = (Groups[1] + AddrSpaces + Groups[3]).str();

6322 }

6323 };

6324

6325

6326 if (T.isAArch64()) {

6327

6328 if (DL.empty() && DL.contains("-Fn32"))

6329 Res.append("-Fn32");

6330 AddPtr32Ptr64AddrSpaces();

6331 return Res;

6332 }

6333

6334 if (T.isSPARC() || (T.isMIPS64() && DL.contains("m:m")) || T.isPPC64() ||

6335 T.isWasm()) {

6336

6337

6338 std::string I64 = "-i64:64";

6339 std::string I128 = "-i128:128";

6341 size_t Pos = Res.find(I64);

6342 if (Pos != size_t(-1))

6343 Res.insert(Pos + I64.size(), I128);

6344 }

6345 return Res;

6346 }

6347

6348 if (T.isX86())

6349 return Res;

6350

6351 AddPtr32Ptr64AddrSpaces();

6352

6353

6354

6355

6356

6357

6358

6359 if (T.isOSIAMCU()) {

6360 std::string I128 = "-i128:128";

6363 Regex R("^(e(-[mpi][^-]*)*)((-[^mpi][^-]*)*)$");

6364 if (R.match(Res, &Groups))

6366 }

6367 }

6368

6369

6370

6371

6372 if (T.isWindowsMSVCEnvironment() && T.isArch64Bit()) {

6374 auto I = Ref.find("-f80:32-");

6376 Res = (Ref.take_front(I) + "-f80:128-" + Ref.drop_front(I + 8)).str();

6377 }

6378

6379 return Res;

6380}

6381

6384 Attribute A = B.getAttribute("no-frame-pointer-elim");

6385 if (A.isValid()) {

6386

6387 FramePointer = A.getValueAsString() == "true" ? "all" : "none";

6388 B.removeAttribute("no-frame-pointer-elim");

6389 }

6390 if (B.contains("no-frame-pointer-elim-non-leaf")) {

6391

6392 if (FramePointer != "all")

6393 FramePointer = "non-leaf";

6394 B.removeAttribute("no-frame-pointer-elim-non-leaf");

6395 }

6396 if (!FramePointer.empty())

6397 B.addAttribute("frame-pointer", FramePointer);

6398

6399 A = B.getAttribute("null-pointer-is-valid");

6400 if (A.isValid()) {

6401

6402 bool NullPointerIsValid = A.getValueAsString() == "true";

6403 B.removeAttribute("null-pointer-is-valid");

6404 if (NullPointerIsValid)

6405 B.addAttribute(Attribute::NullPointerIsValid);

6406 }

6407}

6408

6410

6411

6412

6413

6415 return OBD.getTag() == "clang.arc.attachedcall" &&

6416 OBD.inputs().empty();

6417 });

6418}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

AMDGPU address space definition.

AMDGPU Register Bank Select

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

This file contains the simple types necessary to represent the attributes associated with functions a...

static Value * upgradeX86VPERMT2Intrinsics(IRBuilder<> &Builder, CallBase &CI, bool ZeroMask, bool IndexForm)

Definition AutoUpgrade.cpp:1960

static Metadata * upgradeLoopArgument(Metadata *MD)

Definition AutoUpgrade.cpp:6217

static bool isXYZ(StringRef S)

Definition AutoUpgrade.cpp:5569

static bool upgradeIntrinsicFunction1(Function *F, Function *&NewFn, bool CanUpgradeDebugIntrinsicsToRecords)

Definition AutoUpgrade.cpp:1184

static Value * upgradeX86PSLLDQIntrinsics(IRBuilder<> &Builder, Value *Op, unsigned Shift)

Definition AutoUpgrade.cpp:1800

static Intrinsic::ID shouldUpgradeNVPTXSharedClusterIntrinsic(Function *F, StringRef Name)

Definition AutoUpgrade.cpp:1079

static bool upgradeRetainReleaseMarker(Module &M)

This checks for objc retain release marker which should be upgraded.

Definition AutoUpgrade.cpp:5675

static Value * upgradeX86vpcom(IRBuilder<> &Builder, CallBase &CI, unsigned Imm, bool IsSigned)

Definition AutoUpgrade.cpp:2061

static Value * upgradeMaskToInt(IRBuilder<> &Builder, CallBase &CI)

Definition AutoUpgrade.cpp:2287

static Value * upgradeX86Rotate(IRBuilder<> &Builder, CallBase &CI, bool IsRotateRight)

Definition AutoUpgrade.cpp:2035

static bool upgradeX86MultiplyAddBytes(Function *F, Intrinsic::ID IID, Function *&NewFn)

Definition AutoUpgrade.cpp:112

static void setFunctionAttrIfNotSet(Function &F, StringRef FnAttrName, StringRef Value)

Definition AutoUpgrade.cpp:6080

static Intrinsic::ID shouldUpgradeNVPTXBF16Intrinsic(StringRef Name)

Definition AutoUpgrade.cpp:1104

static bool upgradeSingleNVVMAnnotation(GlobalValue *GV, StringRef K, const Metadata *V)

Definition AutoUpgrade.cpp:5573

static MDNode * unwrapMAVOp(CallBase *CI, unsigned Op)

Helper to unwrap intrinsic call MetadataAsValue operands.

Definition AutoUpgrade.cpp:4598

static MDString * upgradeLoopTag(LLVMContext &C, StringRef OldTag)

Definition AutoUpgrade.cpp:6205

static void upgradeNVVMFnVectorAttr(const StringRef Attr, const char DimC, GlobalValue *GV, const Metadata *V)

Definition AutoUpgrade.cpp:5536

static bool upgradeX86MaskedFPCompare(Function *F, Intrinsic::ID IID, Function *&NewFn)

Definition AutoUpgrade.cpp:99

static Value * upgradeX86ALIGNIntrinsics(IRBuilder<> &Builder, Value *Op0, Value *Op1, Value *Shift, Value *Passthru, Value *Mask, bool IsVALIGN)

Definition AutoUpgrade.cpp:1915

static Value * upgradeAbs(IRBuilder<> &Builder, CallBase &CI)

Definition AutoUpgrade.cpp:2172

static Value * emitX86Select(IRBuilder<> &Builder, Value *Mask, Value *Op0, Value *Op1)

Definition AutoUpgrade.cpp:1886

static Value * upgradeAArch64IntrinsicCall(StringRef Name, CallBase *CI, Function *F, IRBuilder<> &Builder)

Definition AutoUpgrade.cpp:4358

static Value * upgradeMaskedMove(IRBuilder<> &Builder, CallBase &CI)

Definition AutoUpgrade.cpp:2273

static bool upgradeX86IntrinsicFunction(Function *F, StringRef Name, Function *&NewFn)

Definition AutoUpgrade.cpp:515

static Value * applyX86MaskOn1BitsVec(IRBuilder<> &Builder, Value *Vec, Value *Mask)

Definition AutoUpgrade.cpp:2212

static bool consumeNVVMPtrAddrSpace(StringRef &Name)

Definition AutoUpgrade.cpp:1178

static bool shouldUpgradeX86Intrinsic(Function *F, StringRef Name)

Definition AutoUpgrade.cpp:148

static Value * upgradeX86PSRLDQIntrinsics(IRBuilder<> &Builder, Value *Op, unsigned Shift)

Definition AutoUpgrade.cpp:1834

static Intrinsic::ID shouldUpgradeNVPTXTMAG2SIntrinsics(Function *F, StringRef Name)

Definition AutoUpgrade.cpp:1032

static bool isOldLoopArgument(Metadata *MD)

Definition AutoUpgrade.cpp:6193

static Value * upgradeARMIntrinsicCall(StringRef Name, CallBase *CI, Function *F, IRBuilder<> &Builder)

Definition AutoUpgrade.cpp:4415

static bool upgradeX86IntrinsicsWith8BitMask(Function *F, Intrinsic::ID IID, Function *&NewFn)

Definition AutoUpgrade.cpp:83

static Value * upgradeAMDGCNIntrinsicCall(StringRef Name, CallBase *CI, Function *F, IRBuilder<> &Builder)

Definition AutoUpgrade.cpp:4505

static Value * upgradeMaskedLoad(IRBuilder<> &Builder, Value *Ptr, Value *Passthru, Value *Mask, bool Aligned)

Definition AutoUpgrade.cpp:2151

static Metadata * unwrapMAVMetadataOp(CallBase *CI, unsigned Op)

Helper to unwrap Metadata MetadataAsValue operands, such as the Value field.

Definition AutoUpgrade.cpp:4610

static bool upgradeX86BF16Intrinsic(Function *F, Intrinsic::ID IID, Function *&NewFn)

Definition AutoUpgrade.cpp:128

static bool upgradeArmOrAarch64IntrinsicFunction(bool IsArm, Function *F, StringRef Name, Function *&NewFn)

Definition AutoUpgrade.cpp:707

static Value * getX86MaskVec(IRBuilder<> &Builder, Value *Mask, unsigned NumElts)

Definition AutoUpgrade.cpp:1866

static Value * emitX86ScalarSelect(IRBuilder<> &Builder, Value *Mask, Value *Op0, Value *Op1)

Definition AutoUpgrade.cpp:1898

static Value * upgradeX86ConcatShift(IRBuilder<> &Builder, CallBase &CI, bool IsShiftRight, bool ZeroMask)

Definition AutoUpgrade.cpp:2100

static void rename(GlobalValue *GV)

Definition AutoUpgrade.cpp:63

static bool upgradePTESTIntrinsic(Function *F, Intrinsic::ID IID, Function *&NewFn)

Definition AutoUpgrade.cpp:67

static bool upgradeX86BF16DPIntrinsic(Function *F, Intrinsic::ID IID, Function *&NewFn)

Definition AutoUpgrade.cpp:138

static cl::opt< bool > DisableAutoUpgradeDebugInfo("disable-auto-upgrade-debug-info", cl::desc("Disable autoupgrade of debug info"))

static Value * upgradeMaskedCompare(IRBuilder<> &Builder, CallBase &CI, unsigned CC, bool Signed)

Definition AutoUpgrade.cpp:2234

static Value * upgradeX86BinaryIntrinsics(IRBuilder<> &Builder, CallBase &CI, Intrinsic::ID IID)

Definition AutoUpgrade.cpp:2020

static Value * upgradeNVVMIntrinsicCall(StringRef Name, CallBase *CI, Function *F, IRBuilder<> &Builder)

Definition AutoUpgrade.cpp:2544

static Value * upgradeX86MaskedShift(IRBuilder<> &Builder, CallBase &CI, Intrinsic::ID IID)

Definition AutoUpgrade.cpp:2266

static bool upgradeAVX512MaskToSelect(StringRef Name, IRBuilder<> &Builder, CallBase &CI, Value *&Rep)

Definition AutoUpgrade.cpp:2296

static void upgradeDbgIntrinsicToDbgRecord(StringRef Name, CallBase *CI)

Convert debug intrinsic calls to non-instruction debug records.

Definition AutoUpgrade.cpp:4626

static void ConvertFunctionAttr(Function &F, bool Set, StringRef FnAttrName)

Definition AutoUpgrade.cpp:6089

static Value * upgradePMULDQ(IRBuilder<> &Builder, CallBase &CI, bool IsSigned)

Definition AutoUpgrade.cpp:2182

static Value * upgradeMaskedStore(IRBuilder<> &Builder, Value *Ptr, Value *Data, Value *Mask, bool Aligned)

Definition AutoUpgrade.cpp:2133

static MDNode * getDebugLocSafe(const Instruction *I)

Definition AutoUpgrade.cpp:4617

static Value * upgradeX86IntrinsicCall(StringRef Name, CallBase *CI, Function *F, IRBuilder<> &Builder)

Definition AutoUpgrade.cpp:2706

static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

This file contains the declarations for the subclasses of Constant, which represent the different fla...

This file contains constants used for implementing Dwarf debug support.

Module.h This file contains the declarations for the Module class.

const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]

static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)

NVPTX address space definition.

static unsigned getNumElements(Type *Ty)

static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)

This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...

static SymbolRef::Type getType(const Symbol *Sym)

LocallyHashedType DenseMapInfo< LocallyHashedType >::Empty

static const X86InstrFMA3Group Groups[]

Class for arbitrary precision integers.

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

Class to represent array types.

static LLVM_ABI ArrayType * get(Type *ElementType, uint64_t NumElements)

This static method is the primary way to construct an ArrayType.

Type * getElementType() const

an instruction that atomically reads a memory location, combines it with another value,...

void setVolatile(bool V)

Specify whether this is a volatile RMW or not.

BinOp

This enumeration lists the possible modifications atomicrmw can make.

@ UIncWrap

Increment one up to a maximum value.

@ FMin

*p = minnum(old, v) minnum matches the behavior of llvm.minnum.

@ FMax

*p = maxnum(old, v) maxnum matches the behavior of llvm.maxnum.

@ UDecWrap

Decrement one until a minimum value or zero.

bool isFloatingPointOperation() const

Functions, function parameters, and return types can have attributes to indicate how they should be t...

static LLVM_ABI Attribute getWithStackAlignment(LLVMContext &Context, Align Alignment)

static LLVM_ABI Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val=0)

Return a uniquified Attribute object.

Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...

Function * getCalledFunction() const

Returns the function called, or null if this is an indirect function invocation or the function signa...

Value * getCalledOperand() const

void setAttributes(AttributeList A)

Set the attributes for this call.

Value * getArgOperand(unsigned i) const

FunctionType * getFunctionType() const

LLVM_ABI Intrinsic::ID getIntrinsicID() const

Returns the intrinsic ID of the intrinsic called or Intrinsic::not_intrinsic if the called function i...

iterator_range< User::op_iterator > args()

Iteration adapter for range-for loops.

void setCalledOperand(Value *V)

unsigned arg_size() const

AttributeList getAttributes() const

Return the attributes for this call.

void setCalledFunction(Function *Fn)

Sets the function called, including updating the function type.

This class represents a function call, abstracting a target machine's calling convention.

void setTailCallKind(TailCallKind TCK)

static LLVM_ABI CastInst * Create(Instruction::CastOps, Value *S, Type *Ty, const Twine &Name="", InsertPosition InsertBefore=nullptr)

Provides a way to construct any of the CastInst subclasses using an opcode instead of the subclass's ...

static LLVM_ABI bool castIsValid(Instruction::CastOps op, Type *SrcTy, Type *DstTy)

This method can be used to determine if a cast from SrcTy to DstTy using Opcode op is valid or not.

Predicate

This enumeration lists the possible predicates for CmpInst subclasses.

@ ICMP_SLT

signed less than

@ ICMP_SLE

signed less or equal

@ ICMP_UGE

unsigned greater or equal

@ ICMP_UGT

unsigned greater than

@ ICMP_SGT

signed greater than

@ ICMP_ULT

unsigned less than

@ ICMP_SGE

signed greater or equal

@ ICMP_ULE

unsigned less or equal

static LLVM_ABI ConstantAggregateZero * get(Type *Ty)

static LLVM_ABI Constant * get(ArrayType *T, ArrayRef< Constant * > V)

static LLVM_ABI Constant * getIntToPtr(Constant *C, Type *Ty, bool OnlyIfReduced=false)

static LLVM_ABI Constant * getPointerCast(Constant *C, Type *Ty)

Create a BitCast, AddrSpaceCast, or a PtrToInt cast constant expression.

static LLVM_ABI Constant * getPtrToInt(Constant *C, Type *Ty, bool OnlyIfReduced=false)

This is the shared class of boolean and integer constants.

bool isZero() const

This is just a convenience method to make client code smaller for a common code.

uint64_t getZExtValue() const

Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...

static LLVM_ABI ConstantPointerNull * get(PointerType *T)

Static factory methods - Return objects of the specified value.

static LLVM_ABI Constant * get(StructType *T, ArrayRef< Constant * > V)

static LLVM_ABI ConstantTokenNone * get(LLVMContext &Context)

Return the ConstantTokenNone.

This is an important base class in LLVM.

static LLVM_ABI Constant * getAllOnesValue(Type *Ty)

static LLVM_ABI Constant * getNullValue(Type *Ty)

Constructor to create a '0' constant of arbitrary type.

static LLVM_ABI DIExpression * append(const DIExpression *Expr, ArrayRef< uint64_t > Ops)

Append the opcodes Ops to DIExpr.

A parsed version of the target data layout string in and methods for querying it.

static LLVM_ABI DbgLabelRecord * createUnresolvedDbgLabelRecord(MDNode *Label, MDNode *DL)

For use during parsing; creates a DbgLabelRecord from as-of-yet unresolved MDNodes.

Base class for non-instruction debug metadata records that have positions within IR.

static LLVM_ABI DbgVariableRecord * createUnresolvedDbgVariableRecord(LocationType Type, Metadata *Val, MDNode *Variable, MDNode *Expression, MDNode *AssignID, Metadata *Address, MDNode *AddressExpression, MDNode *DI)

Used to create DbgVariableRecords during parsing, where some metadata references may still be unresol...

Convenience struct for specifying and reasoning about fast-math flags.

void setApproxFunc(bool B=true)

static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)

Class to represent function types.

Type * getParamType(unsigned i) const

Parameter type accessors.

Type * getReturnType() const

static LLVM_ABI FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)

This static method is the primary way of constructing a FunctionType.

static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)

FunctionType * getFunctionType() const

Returns the FunctionType for me.

Intrinsic::ID getIntrinsicID() const LLVM_READONLY

getIntrinsicID - This method returns the ID number of the specified function, or Intrinsic::not_intri...

const Function & getFunction() const

void eraseFromParent()

eraseFromParent - This method unlinks 'this' from the containing module and deletes it.

Type * getReturnType() const

Returns the type of the ret val.

Argument * getArg(unsigned i) const

LinkageTypes getLinkage() const

Type * getValueType() const

const Constant * getInitializer() const

getInitializer - Return the initializer for this global variable.

bool hasInitializer() const

Definitions have initializers, declarations don't.

PointerType * getPtrTy(unsigned AddrSpace=0)

Fetch the type representing a pointer.

This provides a uniform API for creating instructions and inserting them into a basic block: either a...

Base class for instruction visitors.

const DebugLoc & getDebugLoc() const

Return the debug location for this node as a DebugLoc.

LLVM_ABI const Module * getModule() const

Return the module owning the function this instruction belongs to or nullptr it the function does not...

LLVM_ABI InstListType::iterator eraseFromParent()

This method unlinks 'this' from the containing basic block and deletes it.

LLVM_ABI void setMetadata(unsigned KindID, MDNode *Node)

Set the metadata of the specified kind to the specified node.

LLVM_ABI void copyMetadata(const Instruction &SrcInst, ArrayRef< unsigned > WL=ArrayRef< unsigned >())

Copy metadata from SrcInst to this instruction.

LLVM_ABI const DataLayout & getDataLayout() const

Get the data layout of the module this instruction belongs to.

This is an important class for using LLVM in a threaded context.

An instruction for reading from memory.

LLVM_ABI MDNode * createRange(const APInt &Lo, const APInt &Hi)

Return metadata describing the range [Lo, Hi).

const MDOperand & getOperand(unsigned I) const

static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)

unsigned getNumOperands() const

Return number of MDNode operands.

LLVMContext & getContext() const

Tracking metadata reference owned by Metadata.

static LLVM_ABI MDString * get(LLVMContext &Context, StringRef Str)

static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)

A Module instance is used to store all the information related to an LLVM module.

ModFlagBehavior

This enumeration defines the supported behaviors of module flags.

@ Override

Uses the specified value, regardless of the behavior or value of the other module.

@ Error

Emits an error if two values disagree, otherwise the resulting value is that of the operands.

@ Min

Takes the min of the two values, which are required to be integers.

@ Max

Takes the max of the two values, which are required to be integers.

LLVM_ABI void setOperand(unsigned I, MDNode *New)

LLVM_ABI MDNode * getOperand(unsigned i) const

LLVM_ABI unsigned getNumOperands() const

LLVM_ABI void clearOperands()

Drop all references to this node's operands.

iterator_range< op_iterator > operands()

LLVM_ABI void addOperand(MDNode *M)

ArrayRef< InputTy > inputs() const

static LLVM_ABI PoisonValue * get(Type *T)

Static factory methods - Return an 'poison' object of the specified type.

LLVM_ABI bool match(StringRef String, SmallVectorImpl< StringRef > *Matches=nullptr, std::string *Error=nullptr) const

matches - Match the regex against a given String.

static LLVM_ABI ScalableVectorType * get(Type *ElementType, unsigned MinNumElts)

ArrayRef< int > getShuffleMask() const

std::pair< iterator, bool > insert(PtrType Ptr)

Inserts Ptr if and only if there is no element in the container equal to Ptr.

SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.

SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...

void append(ItTy in_start, ItTy in_end)

Add the specified range to the end of the SmallVector.

void push_back(const T &Elt)

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

An instruction for storing to memory.

A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...

StringRef - Represent a constant reference to a string, i.e.

std::pair< StringRef, StringRef > split(char Separator) const

Split into two substrings around the first occurrence of a separator character.

static constexpr size_t npos

constexpr StringRef substr(size_t Start, size_t N=npos) const

Return a reference to the substring from [Start, Start + N).

bool starts_with(StringRef Prefix) const

Check if this string starts with the given Prefix.

constexpr bool empty() const

empty - Check if the string is empty.

StringRef drop_front(size_t N=1) const

Return a StringRef equal to 'this' but with the first N elements dropped.

constexpr size_t size() const

size - Get the string size.

StringRef trim(char Char) const

Return string with consecutive Char characters starting from the left and right removed.

A switch()-like statement whose cases are string literals.

StringSwitch & Case(StringLiteral S, T Value)

StringSwitch & StartsWith(StringLiteral S, T Value)

StringSwitch & Cases(std::initializer_list< StringLiteral > CaseStrings, T Value)

Class to represent struct types.

static LLVM_ABI StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)

This static method is the primary way to create a literal StructType.

unsigned getNumElements() const

Random access to the elements.

Type * getElementType(unsigned N) const

The TimeTraceScope is a helper class to call the begin and end functions of the time trace profiler.

Triple - Helper class for working with autoconf configuration names.

Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...

The instances of the Type class are immutable: once they are created, they are never changed.

static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)

bool isVectorTy() const

True if this is an instance of VectorType.

static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)

bool isFloatTy() const

Return true if this is 'float', a 32-bit IEEE fp type.

bool isBFloatTy() const

Return true if this is 'bfloat', a 16-bit bfloat type.

LLVM_ABI unsigned getPointerAddressSpace() const

Get the address space of this pointer or pointer vector type.

static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)

Type * getScalarType() const

If this is a vector type, return the element type, otherwise return 'this'.

LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY

Return the basic size of this type if it is a primitive type.

LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY

If this is a vector type, return the getPrimitiveSizeInBits value for the element type.

bool isPtrOrPtrVectorTy() const

Return true if this is a pointer type or a vector of pointer types.

bool isIntegerTy() const

True if this is an instance of IntegerType.

bool isFPOrFPVectorTy() const

Return true if this is a FP type or a vector of FP.

static LLVM_ABI Type * getFloatTy(LLVMContext &C)

static LLVM_ABI Type * getBFloatTy(LLVMContext &C)

static LLVM_ABI Type * getHalfTy(LLVMContext &C)

Value * getOperand(unsigned i) const

unsigned getNumOperands() const

LLVM Value Representation.

Type * getType() const

All values are typed, get the type of this value.

LLVM_ABI void setName(const Twine &Name)

Change the name of the value.

LLVM_ABI void replaceAllUsesWith(Value *V)

Change all uses of this to point to a new Value.

iterator_range< user_iterator > users()

LLVM_ABI const Value * stripPointerCasts() const

Strip off pointer casts, all-zero GEPs and address space casts.

LLVM_ABI LLVMContext & getContext() const

All values hold a context through their type.

LLVM_ABI StringRef getName() const

Return a constant reference to the value's name.

LLVM_ABI void takeName(Value *V)

Transfer the name from V to this value.

Base class of all SIMD vector types.

static VectorType * getInteger(VectorType *VTy)

This static method gets a VectorType with the same number of elements as the input type,...

static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)

This static method is the primary way to construct an VectorType.

constexpr ScalarTy getFixedValue() const

const ParentTy * getParent() const

self_iterator getIterator()

A raw_ostream that writes to an SmallVector or SmallString.

StringRef str() const

Return a StringRef for the vector contents.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

@ LOCAL_ADDRESS

Address space for local memory.

@ FLAT_ADDRESS

Address space for flat memory.

@ PRIVATE_ADDRESS

Address space for private memory.

unsigned ID

LLVM IR allows to use arbitrary numbers as calling convention identifiers.

@ PTX_Kernel

Call to a PTX kernel. Passes all arguments in parameter space.

@ C

The default llvm calling convention, compatible with C.

LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > Tys={})

Look up the Function declaration of the intrinsic id in the Module M.

LLVM_ABI void getIntrinsicInfoTableEntries(ID id, SmallVectorImpl< IITDescriptor > &T)

Return the IIT table descriptor for the specified intrinsic into an array of IITDescriptors.

LLVM_ABI std::optional< Function * > remangleIntrinsicFunction(Function *F)

LLVM_ABI AttributeList getAttributes(LLVMContext &C, ID id, FunctionType *FT)

Return the attributes for an intrinsic.

LLVM_ABI bool getIntrinsicSignature(Intrinsic::ID, FunctionType *FT, SmallVectorImpl< Type * > &ArgTys)

Gets the type arguments of an intrinsic call by matching type contraints specified by the ....

@ ADDRESS_SPACE_SHARED_CLUSTER

std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > dyn_extract_or_null(Y &&MD)

Extract a Value from Metadata, if any, allowing null.

std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > dyn_extract(Y &&MD)

Extract a Value from Metadata, if any.

std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract(Y &&MD)

Extract a Value from Metadata.

This is an optimization pass for GlobalISel generic memory operations.

LLVM_ABI void UpgradeIntrinsicCall(CallBase *CB, Function *NewFn)

This is the complement to the above, replacing a specific call to an intrinsic function with a call t...

Definition AutoUpgrade.cpp:4678

LLVM_ABI void UpgradeSectionAttributes(Module &M)

Definition AutoUpgrade.cpp:5964

auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)

Get the size of a range.

LLVM_ABI void UpgradeInlineAsmString(std::string *AsmStr)

Upgrade comment in call to inline asm that represents an objc retain release marker.

Definition AutoUpgrade.cpp:2535

bool isValidAtomicOrdering(Int I)

decltype(auto) dyn_cast(const From &Val)

dyn_cast - Return the argument parameter cast to the specified type.

FunctionAddr VTableAddr uintptr_t uintptr_t Int32Ty

LLVM_ABI bool UpgradeIntrinsicFunction(Function *F, Function *&NewFn, bool CanUpgradeDebugIntrinsicsToRecords=true)

This is a more granular function that simply checks an intrinsic function for upgrading,...

Definition AutoUpgrade.cpp:1748

LLVM_ABI MDNode * upgradeInstructionLoopAttachment(MDNode &N)

Upgrade the loop attachment metadata node.

Definition AutoUpgrade.cpp:6239

auto dyn_cast_if_present(const Y &Val)

dyn_cast_if_present - Functionally identical to dyn_cast, except that a null (or none in the case ...

LLVM_ABI void UpgradeAttributes(AttrBuilder &B)

Upgrade attributes that changed format or kind.

Definition AutoUpgrade.cpp:6382

LLVM_ABI void UpgradeCallsToIntrinsic(Function *F)

This is an auto-upgrade hook for any old intrinsic function syntaxes which need to have both the func...

Definition AutoUpgrade.cpp:5401

LLVM_ABI void UpgradeNVVMAnnotations(Module &M)

Convert legacy nvvm.annotations metadata to appropriate function attributes.

Definition AutoUpgrade.cpp:5634

iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)

Make a range that does early increment to allow mutation of the underlying range without disrupting i...

LLVM_ABI bool UpgradeModuleFlags(Module &M)

This checks for module flags which should be upgraded.

Definition AutoUpgrade.cpp:5821

std::string utostr(uint64_t X, bool isNeg=false)

constexpr bool isPowerOf2_64(uint64_t Value)

Return true if the argument is a power of two > 0 (64 bit edition.)

void copyModuleAttrToFunctions(Module &M)

Copies module attributes to the functions in the module.

Definition AutoUpgrade.cpp:6104

LLVM_ABI void UpgradeOperandBundles(std::vector< OperandBundleDef > &OperandBundles)

Upgrade operand bundles (without knowing about their user instruction).

Definition AutoUpgrade.cpp:6409

LLVM_ABI Constant * UpgradeBitCastExpr(unsigned Opc, Constant *C, Type *DestTy)

This is an auto-upgrade for bitcast constant expression between pointers with different address space...

Definition AutoUpgrade.cpp:5468

auto dyn_cast_or_null(const Y &Val)

FunctionAddr VTableAddr uintptr_t uintptr_t Version

constexpr bool isPowerOf2_32(uint32_t Value)

Return true if the argument is a power of two > 0.

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

LLVM_ABI std::string UpgradeDataLayoutString(StringRef DL, StringRef Triple)

Upgrade the datalayout string by adding a section for address space pointers.

Definition AutoUpgrade.cpp:6255

bool none_of(R &&Range, UnaryPredicate P)

Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.

LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)

bool isa(const From &Val)

isa - Return true if the parameter to the template is an instance of one of the template type argu...

LLVM_ABI GlobalVariable * UpgradeGlobalVariable(GlobalVariable *GV)

This checks for global variables which should be upgraded.

Definition AutoUpgrade.cpp:1767

LLVM_ABI raw_fd_ostream & errs()

This returns a reference to a raw_ostream for standard error.

LLVM_ABI bool StripDebugInfo(Module &M)

Strip debug info in the module if it exists.

AtomicOrdering

Atomic ordering for LLVM's memory model.

@ Ref

The access may reference the value stored in memory.

std::string join(IteratorT Begin, IteratorT End, StringRef Separator)

Joins the strings in the range [Begin, End), adding Separator between the elements.

FunctionAddr VTableAddr uintptr_t uintptr_t Data

OperandBundleDefT< Value * > OperandBundleDef

LLVM_ABI Instruction * UpgradeBitCastInst(unsigned Opc, Value *V, Type *DestTy, Instruction *&Temp)

This is an auto-upgrade for bitcast between pointers with different address spaces: the instruction i...

Definition AutoUpgrade.cpp:5446

DWARFExpression::Operation Op

@ Dynamic

Denotes mode unknown at compile time.

ArrayRef(const T &OneElt) -> ArrayRef< T >

decltype(auto) cast(const From &Val)

cast - Return the argument parameter cast to the specified type.

auto find_if(R &&Range, UnaryPredicate P)

Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.

void erase_if(Container &C, UnaryPredicate P)

Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...

LLVM_ABI bool UpgradeDebugInfo(Module &M)

Check the debug info version number, if it is out-dated, drop the debug info.

Definition AutoUpgrade.cpp:5490

LLVM_ABI void UpgradeFunctionAttributes(Function &F)

Correct any IR that is relying on old function attribute behavior.

Definition AutoUpgrade.cpp:6037

@ Default

The result values are uniform if and only if all operands are uniform.

LLVM_ABI MDNode * UpgradeTBAANode(MDNode &TBAANode)

If the given TBAA tag uses the scalar TBAA format, create a new node corresponding to the upgrade to ...

Definition AutoUpgrade.cpp:5420

LLVM_ABI void UpgradeARCRuntime(Module &M)

Convert calls to ARC runtime functions to intrinsic calls and upgrade the old retain release marker t...

Definition AutoUpgrade.cpp:5699

LLVM_ABI bool verifyModule(const Module &M, raw_ostream *OS=nullptr, bool *BrokenDebugInfo=nullptr)

Check a module for errors.

LLVM_ABI void reportFatalUsageError(Error Err)

Report a fatal error that does not indicate a bug in LLVM.

void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)

Implement std::swap in terms of BitVector swap.

This struct is a compact representation of a valid (non-zero power of two) alignment.

This struct is a compact representation of a valid (power of two) or undefined (0) alignment.