34#include "llvm/IR/IntrinsicsAArch64.h"
35#include "llvm/IR/IntrinsicsAMDGPU.h"
36#include "llvm/IR/IntrinsicsARM.h"
37#include "llvm/IR/IntrinsicsNVPTX.h"
38#include "llvm/IR/IntrinsicsRISCV.h"
39#include "llvm/IR/IntrinsicsWebAssembly.h"
40#include "llvm/IR/IntrinsicsX86.h"
62 cl::desc(
"Disable autoupgrade of debug info"));
72 Type *Arg0Type =
F->getFunctionType()->getParamType(0);
87 Type *LastArgType =
F->getFunctionType()->getParamType(
88 F->getFunctionType()->getNumParams() - 1);
103 if (
F->getReturnType()->isVectorTy())
116 Type *Arg1Type =
F->getFunctionType()->getParamType(1);
117 Type *Arg2Type =
F->getFunctionType()->getParamType(2);
134 Type *Arg1Type =
F->getFunctionType()->getParamType(1);
135 Type *Arg2Type =
F->getFunctionType()->getParamType(2);
149 if (
F->getReturnType()->getScalarType()->isBFloatTy())
159 if (
F->getFunctionType()->getParamType(1)->getScalarType()->isBFloatTy())
173 if (Name.consume_front(
"avx."))
174 return (Name.starts_with(
"blend.p") ||
175 Name ==
"cvt.ps2.pd.256" ||
176 Name ==
"cvtdq2.pd.256" ||
177 Name ==
"cvtdq2.ps.256" ||
178 Name.starts_with(
"movnt.") ||
179 Name.starts_with(
"sqrt.p") ||
180 Name.starts_with(
"storeu.") ||
181 Name.starts_with(
"vbroadcast.s") ||
182 Name.starts_with(
"vbroadcastf128") ||
183 Name.starts_with(
"vextractf128.") ||
184 Name.starts_with(
"vinsertf128.") ||
185 Name.starts_with(
"vperm2f128.") ||
186 Name.starts_with(
"vpermil."));
188 if (Name.consume_front(
"avx2."))
189 return (Name ==
"movntdqa" ||
190 Name.starts_with(
"pabs.") ||
191 Name.starts_with(
"padds.") ||
192 Name.starts_with(
"paddus.") ||
193 Name.starts_with(
"pblendd.") ||
195 Name.starts_with(
"pbroadcast") ||
196 Name.starts_with(
"pcmpeq.") ||
197 Name.starts_with(
"pcmpgt.") ||
198 Name.starts_with(
"pmax") ||
199 Name.starts_with(
"pmin") ||
200 Name.starts_with(
"pmovsx") ||
201 Name.starts_with(
"pmovzx") ||
203 Name ==
"pmulu.dq" ||
204 Name.starts_with(
"psll.dq") ||
205 Name.starts_with(
"psrl.dq") ||
206 Name.starts_with(
"psubs.") ||
207 Name.starts_with(
"psubus.") ||
208 Name.starts_with(
"vbroadcast") ||
209 Name ==
"vbroadcasti128" ||
210 Name ==
"vextracti128" ||
211 Name ==
"vinserti128" ||
212 Name ==
"vperm2i128");
214 if (Name.consume_front(
"avx512.")) {
215 if (Name.consume_front(
"mask."))
217 return (Name.starts_with(
"add.p") ||
218 Name.starts_with(
"and.") ||
219 Name.starts_with(
"andn.") ||
220 Name.starts_with(
"broadcast.s") ||
221 Name.starts_with(
"broadcastf32x4.") ||
222 Name.starts_with(
"broadcastf32x8.") ||
223 Name.starts_with(
"broadcastf64x2.") ||
224 Name.starts_with(
"broadcastf64x4.") ||
225 Name.starts_with(
"broadcasti32x4.") ||
226 Name.starts_with(
"broadcasti32x8.") ||
227 Name.starts_with(
"broadcasti64x2.") ||
228 Name.starts_with(
"broadcasti64x4.") ||
229 Name.starts_with(
"cmp.b") ||
230 Name.starts_with(
"cmp.d") ||
231 Name.starts_with(
"cmp.q") ||
232 Name.starts_with(
"cmp.w") ||
233 Name.starts_with(
"compress.b") ||
234 Name.starts_with(
"compress.d") ||
235 Name.starts_with(
"compress.p") ||
236 Name.starts_with(
"compress.q") ||
237 Name.starts_with(
"compress.store.") ||
238 Name.starts_with(
"compress.w") ||
239 Name.starts_with(
"conflict.") ||
240 Name.starts_with(
"cvtdq2pd.") ||
241 Name.starts_with(
"cvtdq2ps.") ||
242 Name ==
"cvtpd2dq.256" ||
243 Name ==
"cvtpd2ps.256" ||
244 Name ==
"cvtps2pd.128" ||
245 Name ==
"cvtps2pd.256" ||
246 Name.starts_with(
"cvtqq2pd.") ||
247 Name ==
"cvtqq2ps.256" ||
248 Name ==
"cvtqq2ps.512" ||
249 Name ==
"cvttpd2dq.256" ||
250 Name ==
"cvttps2dq.128" ||
251 Name ==
"cvttps2dq.256" ||
252 Name.starts_with(
"cvtudq2pd.") ||
253 Name.starts_with(
"cvtudq2ps.") ||
254 Name.starts_with(
"cvtuqq2pd.") ||
255 Name ==
"cvtuqq2ps.256" ||
256 Name ==
"cvtuqq2ps.512" ||
257 Name.starts_with(
"dbpsadbw.") ||
258 Name.starts_with(
"div.p") ||
259 Name.starts_with(
"expand.b") ||
260 Name.starts_with(
"expand.d") ||
261 Name.starts_with(
"expand.load.") ||
262 Name.starts_with(
"expand.p") ||
263 Name.starts_with(
"expand.q") ||
264 Name.starts_with(
"expand.w") ||
265 Name.starts_with(
"fpclass.p") ||
266 Name.starts_with(
"insert") ||
267 Name.starts_with(
"load.") ||
268 Name.starts_with(
"loadu.") ||
269 Name.starts_with(
"lzcnt.") ||
270 Name.starts_with(
"max.p") ||
271 Name.starts_with(
"min.p") ||
272 Name.starts_with(
"movddup") ||
273 Name.starts_with(
"move.s") ||
274 Name.starts_with(
"movshdup") ||
275 Name.starts_with(
"movsldup") ||
276 Name.starts_with(
"mul.p") ||
277 Name.starts_with(
"or.") ||
278 Name.starts_with(
"pabs.") ||
279 Name.starts_with(
"packssdw.") ||
280 Name.starts_with(
"packsswb.") ||
281 Name.starts_with(
"packusdw.") ||
282 Name.starts_with(
"packuswb.") ||
283 Name.starts_with(
"padd.") ||
284 Name.starts_with(
"padds.") ||
285 Name.starts_with(
"paddus.") ||
286 Name.starts_with(
"palignr.") ||
287 Name.starts_with(
"pand.") ||
288 Name.starts_with(
"pandn.") ||
289 Name.starts_with(
"pavg") ||
290 Name.starts_with(
"pbroadcast") ||
291 Name.starts_with(
"pcmpeq.") ||
292 Name.starts_with(
"pcmpgt.") ||
293 Name.starts_with(
"perm.df.") ||
294 Name.starts_with(
"perm.di.") ||
295 Name.starts_with(
"permvar.") ||
296 Name.starts_with(
"pmaddubs.w.") ||
297 Name.starts_with(
"pmaddw.d.") ||
298 Name.starts_with(
"pmax") ||
299 Name.starts_with(
"pmin") ||
300 Name ==
"pmov.qd.256" ||
301 Name ==
"pmov.qd.512" ||
302 Name ==
"pmov.wb.256" ||
303 Name ==
"pmov.wb.512" ||
304 Name.starts_with(
"pmovsx") ||
305 Name.starts_with(
"pmovzx") ||
306 Name.starts_with(
"pmul.dq.") ||
307 Name.starts_with(
"pmul.hr.sw.") ||
308 Name.starts_with(
"pmulh.w.") ||
309 Name.starts_with(
"pmulhu.w.") ||
310 Name.starts_with(
"pmull.") ||
311 Name.starts_with(
"pmultishift.qb.") ||
312 Name.starts_with(
"pmulu.dq.") ||
313 Name.starts_with(
"por.") ||
314 Name.starts_with(
"prol.") ||
315 Name.starts_with(
"prolv.") ||
316 Name.starts_with(
"pror.") ||
317 Name.starts_with(
"prorv.") ||
318 Name.starts_with(
"pshuf.b.") ||
319 Name.starts_with(
"pshuf.d.") ||
320 Name.starts_with(
"pshufh.w.") ||
321 Name.starts_with(
"pshufl.w.") ||
322 Name.starts_with(
"psll.d") ||
323 Name.starts_with(
"psll.q") ||
324 Name.starts_with(
"psll.w") ||
325 Name.starts_with(
"pslli") ||
326 Name.starts_with(
"psllv") ||
327 Name.starts_with(
"psra.d") ||
328 Name.starts_with(
"psra.q") ||
329 Name.starts_with(
"psra.w") ||
330 Name.starts_with(
"psrai") ||
331 Name.starts_with(
"psrav") ||
332 Name.starts_with(
"psrl.d") ||
333 Name.starts_with(
"psrl.q") ||
334 Name.starts_with(
"psrl.w") ||
335 Name.starts_with(
"psrli") ||
336 Name.starts_with(
"psrlv") ||
337 Name.starts_with(
"psub.") ||
338 Name.starts_with(
"psubs.") ||
339 Name.starts_with(
"psubus.") ||
340 Name.starts_with(
"pternlog.") ||
341 Name.starts_with(
"punpckh") ||
342 Name.starts_with(
"punpckl") ||
343 Name.starts_with(
"pxor.") ||
344 Name.starts_with(
"shuf.f") ||
345 Name.starts_with(
"shuf.i") ||
346 Name.starts_with(
"shuf.p") ||
347 Name.starts_with(
"sqrt.p") ||
348 Name.starts_with(
"store.b.") ||
349 Name.starts_with(
"store.d.") ||
350 Name.starts_with(
"store.p") ||
351 Name.starts_with(
"store.q.") ||
352 Name.starts_with(
"store.w.") ||
353 Name ==
"store.ss" ||
354 Name.starts_with(
"storeu.") ||
355 Name.starts_with(
"sub.p") ||
356 Name.starts_with(
"ucmp.") ||
357 Name.starts_with(
"unpckh.") ||
358 Name.starts_with(
"unpckl.") ||
359 Name.starts_with(
"valign.") ||
360 Name ==
"vcvtph2ps.128" ||
361 Name ==
"vcvtph2ps.256" ||
362 Name.starts_with(
"vextract") ||
363 Name.starts_with(
"vfmadd.") ||
364 Name.starts_with(
"vfmaddsub.") ||
365 Name.starts_with(
"vfnmadd.") ||
366 Name.starts_with(
"vfnmsub.") ||
367 Name.starts_with(
"vpdpbusd.") ||
368 Name.starts_with(
"vpdpbusds.") ||
369 Name.starts_with(
"vpdpwssd.") ||
370 Name.starts_with(
"vpdpwssds.") ||
371 Name.starts_with(
"vpermi2var.") ||
372 Name.starts_with(
"vpermil.p") ||
373 Name.starts_with(
"vpermilvar.") ||
374 Name.starts_with(
"vpermt2var.") ||
375 Name.starts_with(
"vpmadd52") ||
376 Name.starts_with(
"vpshld.") ||
377 Name.starts_with(
"vpshldv.") ||
378 Name.starts_with(
"vpshrd.") ||
379 Name.starts_with(
"vpshrdv.") ||
380 Name.starts_with(
"vpshufbitqmb.") ||
381 Name.starts_with(
"xor."));
383 if (Name.consume_front(
"mask3."))
385 return (Name.starts_with(
"vfmadd.") ||
386 Name.starts_with(
"vfmaddsub.") ||
387 Name.starts_with(
"vfmsub.") ||
388 Name.starts_with(
"vfmsubadd.") ||
389 Name.starts_with(
"vfnmsub."));
391 if (Name.consume_front(
"maskz."))
393 return (Name.starts_with(
"pternlog.") ||
394 Name.starts_with(
"vfmadd.") ||
395 Name.starts_with(
"vfmaddsub.") ||
396 Name.starts_with(
"vpdpbusd.") ||
397 Name.starts_with(
"vpdpbusds.") ||
398 Name.starts_with(
"vpdpwssd.") ||
399 Name.starts_with(
"vpdpwssds.") ||
400 Name.starts_with(
"vpermt2var.") ||
401 Name.starts_with(
"vpmadd52") ||
402 Name.starts_with(
"vpshldv.") ||
403 Name.starts_with(
"vpshrdv."));
406 return (Name ==
"movntdqa" ||
407 Name ==
"pmul.dq.512" ||
408 Name ==
"pmulu.dq.512" ||
409 Name.starts_with(
"broadcastm") ||
410 Name.starts_with(
"cmp.p") ||
411 Name.starts_with(
"cvtb2mask.") ||
412 Name.starts_with(
"cvtd2mask.") ||
413 Name.starts_with(
"cvtmask2") ||
414 Name.starts_with(
"cvtq2mask.") ||
415 Name ==
"cvtusi2sd" ||
416 Name.starts_with(
"cvtw2mask.") ||
421 Name ==
"kortestc.w" ||
422 Name ==
"kortestz.w" ||
423 Name.starts_with(
"kunpck") ||
426 Name.starts_with(
"padds.") ||
427 Name.starts_with(
"pbroadcast") ||
428 Name.starts_with(
"prol") ||
429 Name.starts_with(
"pror") ||
430 Name.starts_with(
"psll.dq") ||
431 Name.starts_with(
"psrl.dq") ||
432 Name.starts_with(
"psubs.") ||
433 Name.starts_with(
"ptestm") ||
434 Name.starts_with(
"ptestnm") ||
435 Name.starts_with(
"storent.") ||
436 Name.starts_with(
"vbroadcast.s") ||
437 Name.starts_with(
"vpshld.") ||
438 Name.starts_with(
"vpshrd."));
441 if (Name.consume_front(
"fma."))
442 return (Name.starts_with(
"vfmadd.") ||
443 Name.starts_with(
"vfmsub.") ||
444 Name.starts_with(
"vfmsubadd.") ||
445 Name.starts_with(
"vfnmadd.") ||
446 Name.starts_with(
"vfnmsub."));
448 if (Name.consume_front(
"fma4."))
449 return Name.starts_with(
"vfmadd.s");
451 if (Name.consume_front(
"sse."))
452 return (Name ==
"add.ss" ||
453 Name ==
"cvtsi2ss" ||
454 Name ==
"cvtsi642ss" ||
457 Name.starts_with(
"sqrt.p") ||
459 Name.starts_with(
"storeu.") ||
462 if (Name.consume_front(
"sse2."))
463 return (Name ==
"add.sd" ||
464 Name ==
"cvtdq2pd" ||
465 Name ==
"cvtdq2ps" ||
466 Name ==
"cvtps2pd" ||
467 Name ==
"cvtsi2sd" ||
468 Name ==
"cvtsi642sd" ||
469 Name ==
"cvtss2sd" ||
472 Name.starts_with(
"padds.") ||
473 Name.starts_with(
"paddus.") ||
474 Name.starts_with(
"pcmpeq.") ||
475 Name.starts_with(
"pcmpgt.") ||
480 Name ==
"pmulu.dq" ||
481 Name.starts_with(
"pshuf") ||
482 Name.starts_with(
"psll.dq") ||
483 Name.starts_with(
"psrl.dq") ||
484 Name.starts_with(
"psubs.") ||
485 Name.starts_with(
"psubus.") ||
486 Name.starts_with(
"sqrt.p") ||
488 Name ==
"storel.dq" ||
489 Name.starts_with(
"storeu.") ||
492 if (Name.consume_front(
"sse41."))
493 return (Name.starts_with(
"blendp") ||
494 Name ==
"movntdqa" ||
504 Name.starts_with(
"pmovsx") ||
505 Name.starts_with(
"pmovzx") ||
508 if (Name.consume_front(
"sse42."))
509 return Name ==
"crc32.64.8";
511 if (Name.consume_front(
"sse4a."))
512 return Name.starts_with(
"movnt.");
514 if (Name.consume_front(
"ssse3."))
515 return (Name ==
"pabs.b.128" ||
516 Name ==
"pabs.d.128" ||
517 Name ==
"pabs.w.128");
519 if (Name.consume_front(
"xop."))
520 return (Name ==
"vpcmov" ||
521 Name ==
"vpcmov.256" ||
522 Name.starts_with(
"vpcom") ||
523 Name.starts_with(
"vprot"));
525 return (Name ==
"addcarry.u32" ||
526 Name ==
"addcarry.u64" ||
527 Name ==
"addcarryx.u32" ||
528 Name ==
"addcarryx.u64" ||
529 Name ==
"subborrow.u32" ||
530 Name ==
"subborrow.u64" ||
531 Name.starts_with(
"vcvtph2ps."));
537 if (!Name.consume_front(
"x86."))
545 if (Name ==
"rdtscp") {
547 if (
F->getFunctionType()->getNumParams() == 0)
552 Intrinsic::x86_rdtscp);
559 if (Name.consume_front(
"sse41.ptest")) {
561 .
Case(
"c", Intrinsic::x86_sse41_ptestc)
562 .
Case(
"z", Intrinsic::x86_sse41_ptestz)
563 .
Case(
"nzc", Intrinsic::x86_sse41_ptestnzc)
576 .
Case(
"sse41.insertps", Intrinsic::x86_sse41_insertps)
577 .
Case(
"sse41.dppd", Intrinsic::x86_sse41_dppd)
578 .
Case(
"sse41.dpps", Intrinsic::x86_sse41_dpps)
579 .
Case(
"sse41.mpsadbw", Intrinsic::x86_sse41_mpsadbw)
580 .
Case(
"avx.dp.ps.256", Intrinsic::x86_avx_dp_ps_256)
581 .
Case(
"avx2.mpsadbw", Intrinsic::x86_avx2_mpsadbw)
586 if (Name.consume_front(
"avx512.")) {
587 if (Name.consume_front(
"mask.cmp.")) {
590 .
Case(
"pd.128", Intrinsic::x86_avx512_mask_cmp_pd_128)
591 .
Case(
"pd.256", Intrinsic::x86_avx512_mask_cmp_pd_256)
592 .
Case(
"pd.512", Intrinsic::x86_avx512_mask_cmp_pd_512)
593 .
Case(
"ps.128", Intrinsic::x86_avx512_mask_cmp_ps_128)
594 .
Case(
"ps.256", Intrinsic::x86_avx512_mask_cmp_ps_256)
595 .
Case(
"ps.512", Intrinsic::x86_avx512_mask_cmp_ps_512)
599 }
else if (Name.starts_with(
"vpdpbusd.") ||
600 Name.starts_with(
"vpdpbusds.")) {
603 .
Case(
"vpdpbusd.128", Intrinsic::x86_avx512_vpdpbusd_128)
604 .
Case(
"vpdpbusd.256", Intrinsic::x86_avx512_vpdpbusd_256)
605 .
Case(
"vpdpbusd.512", Intrinsic::x86_avx512_vpdpbusd_512)
606 .
Case(
"vpdpbusds.128", Intrinsic::x86_avx512_vpdpbusds_128)
607 .
Case(
"vpdpbusds.256", Intrinsic::x86_avx512_vpdpbusds_256)
608 .
Case(
"vpdpbusds.512", Intrinsic::x86_avx512_vpdpbusds_512)
612 }
else if (Name.starts_with(
"vpdpwssd.") ||
613 Name.starts_with(
"vpdpwssds.")) {
616 .
Case(
"vpdpwssd.128", Intrinsic::x86_avx512_vpdpwssd_128)
617 .
Case(
"vpdpwssd.256", Intrinsic::x86_avx512_vpdpwssd_256)
618 .
Case(
"vpdpwssd.512", Intrinsic::x86_avx512_vpdpwssd_512)
619 .
Case(
"vpdpwssds.128", Intrinsic::x86_avx512_vpdpwssds_128)
620 .
Case(
"vpdpwssds.256", Intrinsic::x86_avx512_vpdpwssds_256)
621 .
Case(
"vpdpwssds.512", Intrinsic::x86_avx512_vpdpwssds_512)
629 if (Name.consume_front(
"avx2.")) {
630 if (Name.consume_front(
"vpdpb")) {
633 .
Case(
"ssd.128", Intrinsic::x86_avx2_vpdpbssd_128)
634 .
Case(
"ssd.256", Intrinsic::x86_avx2_vpdpbssd_256)
635 .
Case(
"ssds.128", Intrinsic::x86_avx2_vpdpbssds_128)
636 .
Case(
"ssds.256", Intrinsic::x86_avx2_vpdpbssds_256)
637 .
Case(
"sud.128", Intrinsic::x86_avx2_vpdpbsud_128)
638 .
Case(
"sud.256", Intrinsic::x86_avx2_vpdpbsud_256)
639 .
Case(
"suds.128", Intrinsic::x86_avx2_vpdpbsuds_128)
640 .
Case(
"suds.256", Intrinsic::x86_avx2_vpdpbsuds_256)
641 .
Case(
"uud.128", Intrinsic::x86_avx2_vpdpbuud_128)
642 .
Case(
"uud.256", Intrinsic::x86_avx2_vpdpbuud_256)
643 .
Case(
"uuds.128", Intrinsic::x86_avx2_vpdpbuuds_128)
644 .
Case(
"uuds.256", Intrinsic::x86_avx2_vpdpbuuds_256)
648 }
else if (Name.consume_front(
"vpdpw")) {
651 .
Case(
"sud.128", Intrinsic::x86_avx2_vpdpwsud_128)
652 .
Case(
"sud.256", Intrinsic::x86_avx2_vpdpwsud_256)
653 .
Case(
"suds.128", Intrinsic::x86_avx2_vpdpwsuds_128)
654 .
Case(
"suds.256", Intrinsic::x86_avx2_vpdpwsuds_256)
655 .
Case(
"usd.128", Intrinsic::x86_avx2_vpdpwusd_128)
656 .
Case(
"usd.256", Intrinsic::x86_avx2_vpdpwusd_256)
657 .
Case(
"usds.128", Intrinsic::x86_avx2_vpdpwusds_128)
658 .
Case(
"usds.256", Intrinsic::x86_avx2_vpdpwusds_256)
659 .
Case(
"uud.128", Intrinsic::x86_avx2_vpdpwuud_128)
660 .
Case(
"uud.256", Intrinsic::x86_avx2_vpdpwuud_256)
661 .
Case(
"uuds.128", Intrinsic::x86_avx2_vpdpwuuds_128)
662 .
Case(
"uuds.256", Intrinsic::x86_avx2_vpdpwuuds_256)
670 if (Name.consume_front(
"avx10.")) {
671 if (Name.consume_front(
"vpdpb")) {
674 .
Case(
"ssd.512", Intrinsic::x86_avx10_vpdpbssd_512)
675 .
Case(
"ssds.512", Intrinsic::x86_avx10_vpdpbssds_512)
676 .
Case(
"sud.512", Intrinsic::x86_avx10_vpdpbsud_512)
677 .
Case(
"suds.512", Intrinsic::x86_avx10_vpdpbsuds_512)
678 .
Case(
"uud.512", Intrinsic::x86_avx10_vpdpbuud_512)
679 .
Case(
"uuds.512", Intrinsic::x86_avx10_vpdpbuuds_512)
683 }
else if (Name.consume_front(
"vpdpw")) {
685 .
Case(
"sud.512", Intrinsic::x86_avx10_vpdpwsud_512)
686 .
Case(
"suds.512", Intrinsic::x86_avx10_vpdpwsuds_512)
687 .
Case(
"usd.512", Intrinsic::x86_avx10_vpdpwusd_512)
688 .
Case(
"usds.512", Intrinsic::x86_avx10_vpdpwusds_512)
689 .
Case(
"uud.512", Intrinsic::x86_avx10_vpdpwuud_512)
690 .
Case(
"uuds.512", Intrinsic::x86_avx10_vpdpwuuds_512)
698 if (Name.consume_front(
"avx512bf16.")) {
701 .
Case(
"cvtne2ps2bf16.128",
702 Intrinsic::x86_avx512bf16_cvtne2ps2bf16_128)
703 .
Case(
"cvtne2ps2bf16.256",
704 Intrinsic::x86_avx512bf16_cvtne2ps2bf16_256)
705 .
Case(
"cvtne2ps2bf16.512",
706 Intrinsic::x86_avx512bf16_cvtne2ps2bf16_512)
707 .
Case(
"mask.cvtneps2bf16.128",
708 Intrinsic::x86_avx512bf16_mask_cvtneps2bf16_128)
709 .
Case(
"cvtneps2bf16.256",
710 Intrinsic::x86_avx512bf16_cvtneps2bf16_256)
711 .
Case(
"cvtneps2bf16.512",
712 Intrinsic::x86_avx512bf16_cvtneps2bf16_512)
719 .
Case(
"dpbf16ps.128", Intrinsic::x86_avx512bf16_dpbf16ps_128)
720 .
Case(
"dpbf16ps.256", Intrinsic::x86_avx512bf16_dpbf16ps_256)
721 .
Case(
"dpbf16ps.512", Intrinsic::x86_avx512bf16_dpbf16ps_512)
728 if (Name.consume_front(
"xop.")) {
730 if (Name.starts_with(
"vpermil2")) {
733 auto Idx =
F->getFunctionType()->getParamType(2);
734 if (Idx->isFPOrFPVectorTy()) {
735 unsigned IdxSize = Idx->getPrimitiveSizeInBits();
736 unsigned EltSize = Idx->getScalarSizeInBits();
737 if (EltSize == 64 && IdxSize == 128)
738 ID = Intrinsic::x86_xop_vpermil2pd;
739 else if (EltSize == 32 && IdxSize == 128)
740 ID = Intrinsic::x86_xop_vpermil2ps;
741 else if (EltSize == 64 && IdxSize == 256)
742 ID = Intrinsic::x86_xop_vpermil2pd_256;
744 ID = Intrinsic::x86_xop_vpermil2ps_256;
746 }
else if (
F->arg_size() == 2)
749 .
Case(
"vfrcz.ss", Intrinsic::x86_xop_vfrcz_ss)
750 .
Case(
"vfrcz.sd", Intrinsic::x86_xop_vfrcz_sd)
761 if (Name ==
"seh.recoverfp") {
763 Intrinsic::eh_recoverfp);
775 if (Name.starts_with(
"rbit")) {
778 F->getParent(), Intrinsic::bitreverse,
F->arg_begin()->getType());
782 if (Name ==
"thread.pointer") {
785 F->getParent(), Intrinsic::thread_pointer,
F->getReturnType());
789 bool Neon = Name.consume_front(
"neon.");
794 if (Name.consume_front(
"bfdot.")) {
798 .
Cases({
"v2f32.v8i8",
"v4f32.v16i8"},
803 size_t OperandWidth =
F->getReturnType()->getPrimitiveSizeInBits();
804 assert((OperandWidth == 64 || OperandWidth == 128) &&
805 "Unexpected operand width");
807 std::array<Type *, 2> Tys{
818 if (Name.consume_front(
"bfm")) {
820 if (Name.consume_back(
".v4f32.v16i8")) {
866 F->arg_begin()->getType());
870 if (Name.consume_front(
"vst")) {
872 static const Regex vstRegex(
"^([1234]|[234]lane)\\.v[a-z0-9]*$");
876 Intrinsic::arm_neon_vst1, Intrinsic::arm_neon_vst2,
877 Intrinsic::arm_neon_vst3, Intrinsic::arm_neon_vst4};
880 Intrinsic::arm_neon_vst2lane, Intrinsic::arm_neon_vst3lane,
881 Intrinsic::arm_neon_vst4lane};
883 auto fArgs =
F->getFunctionType()->params();
884 Type *Tys[] = {fArgs[0], fArgs[1]};
887 F->getParent(), StoreInts[fArgs.size() - 3], Tys);
890 F->getParent(), StoreLaneInts[fArgs.size() - 5], Tys);
899 if (Name.consume_front(
"mve.")) {
901 if (Name ==
"vctp64") {
911 if (Name.starts_with(
"vrintn.v")) {
913 F->getParent(), Intrinsic::roundeven,
F->arg_begin()->getType());
918 if (Name.consume_back(
".v4i1")) {
920 if (Name.consume_back(
".predicated.v2i64.v4i32"))
922 return Name ==
"mull.int" || Name ==
"vqdmull";
924 if (Name.consume_back(
".v2i64")) {
926 bool IsGather = Name.consume_front(
"vldr.gather.");
927 if (IsGather || Name.consume_front(
"vstr.scatter.")) {
928 if (Name.consume_front(
"base.")) {
930 Name.consume_front(
"wb.");
933 return Name ==
"predicated.v2i64";
936 if (Name.consume_front(
"offset.predicated."))
937 return Name == (IsGather ?
"v2i64.p0i64" :
"p0i64.v2i64") ||
938 Name == (IsGather ?
"v2i64.p0" :
"p0.v2i64");
951 if (Name.consume_front(
"cde.vcx")) {
953 if (Name.consume_back(
".predicated.v2i64.v4i1"))
955 return Name ==
"1q" || Name ==
"1qa" || Name ==
"2q" || Name ==
"2qa" ||
956 Name ==
"3q" || Name ==
"3qa";
970 F->arg_begin()->getType());
974 if (Name.starts_with(
"addp")) {
976 if (
F->arg_size() != 2)
979 if (Ty && Ty->getElementType()->isFloatingPointTy()) {
981 F->getParent(), Intrinsic::aarch64_neon_faddp, Ty);
987 if (Name.starts_with(
"bfcvt")) {
994 if (Name.consume_front(
"sve.")) {
996 if (Name.consume_front(
"bf")) {
997 if (Name.consume_back(
".lane")) {
1001 .
Case(
"dot", Intrinsic::aarch64_sve_bfdot_lane_v2)
1002 .
Case(
"mlalb", Intrinsic::aarch64_sve_bfmlalb_lane_v2)
1003 .
Case(
"mlalt", Intrinsic::aarch64_sve_bfmlalt_lane_v2)
1015 if (Name ==
"fcvt.bf16f32" || Name ==
"fcvtnt.bf16f32") {
1020 if (Name.consume_front(
"addqv")) {
1022 if (!
F->getReturnType()->isFPOrFPVectorTy())
1025 auto Args =
F->getFunctionType()->params();
1026 Type *Tys[] = {
F->getReturnType(), Args[1]};
1028 F->getParent(), Intrinsic::aarch64_sve_faddqv, Tys);
1032 if (Name.consume_front(
"ld")) {
1034 static const Regex LdRegex(
"^[234](.nxv[a-z0-9]+|$)");
1035 if (LdRegex.
match(Name)) {
1042 Intrinsic::aarch64_sve_ld2_sret,
1043 Intrinsic::aarch64_sve_ld3_sret,
1044 Intrinsic::aarch64_sve_ld4_sret,
1047 LoadIDs[Name[0] -
'2'], Ty);
1053 if (Name.consume_front(
"tuple.")) {
1055 if (Name.starts_with(
"get")) {
1057 Type *Tys[] = {
F->getReturnType(),
F->arg_begin()->getType()};
1059 F->getParent(), Intrinsic::vector_extract, Tys);
1063 if (Name.starts_with(
"set")) {
1065 auto Args =
F->getFunctionType()->params();
1066 Type *Tys[] = {Args[0], Args[2], Args[1]};
1068 F->getParent(), Intrinsic::vector_insert, Tys);
1072 static const Regex CreateTupleRegex(
"^create[234](.nxv[a-z0-9]+|$)");
1073 if (CreateTupleRegex.
match(Name)) {
1075 auto Args =
F->getFunctionType()->params();
1076 Type *Tys[] = {
F->getReturnType(), Args[1]};
1078 F->getParent(), Intrinsic::vector_insert, Tys);
1084 if (Name.starts_with(
"rev.nxv")) {
1087 F->getParent(), Intrinsic::vector_reverse,
F->getReturnType());
1099 if (Name.consume_front(
"cp.async.bulk.tensor.g2s.")) {
1103 Intrinsic::nvvm_cp_async_bulk_tensor_g2s_im2col_3d)
1105 Intrinsic::nvvm_cp_async_bulk_tensor_g2s_im2col_4d)
1107 Intrinsic::nvvm_cp_async_bulk_tensor_g2s_im2col_5d)
1108 .
Case(
"tile.1d", Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_1d)
1109 .
Case(
"tile.2d", Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_2d)
1110 .
Case(
"tile.3d", Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_3d)
1111 .
Case(
"tile.4d", Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_4d)
1112 .
Case(
"tile.5d", Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_5d)
1121 if (
F->getArg(0)->getType()->getPointerAddressSpace() ==
1135 size_t FlagStartIndex =
F->getFunctionType()->getNumParams() - 3;
1136 Type *ArgType =
F->getFunctionType()->getParamType(FlagStartIndex);
1146 if (Name.consume_front(
"mapa.shared.cluster"))
1147 if (
F->getReturnType()->getPointerAddressSpace() ==
1149 return Intrinsic::nvvm_mapa_shared_cluster;
1151 if (Name.consume_front(
"cp.async.bulk.")) {
1154 .
Case(
"global.to.shared.cluster",
1155 Intrinsic::nvvm_cp_async_bulk_global_to_shared_cluster)
1156 .
Case(
"shared.cta.to.cluster",
1157 Intrinsic::nvvm_cp_async_bulk_shared_cta_to_cluster)
1161 if (
F->getArg(0)->getType()->getPointerAddressSpace() ==
1170 if (Name.consume_front(
"fma.rn."))
1172 .
Case(
"bf16", Intrinsic::nvvm_fma_rn_bf16)
1173 .
Case(
"bf16x2", Intrinsic::nvvm_fma_rn_bf16x2)
1174 .
Case(
"ftz.bf16", Intrinsic::nvvm_fma_rn_ftz_bf16)
1175 .
Case(
"ftz.bf16x2", Intrinsic::nvvm_fma_rn_ftz_bf16x2)
1176 .
Case(
"ftz.relu.bf16", Intrinsic::nvvm_fma_rn_ftz_relu_bf16)
1177 .
Case(
"ftz.relu.bf16x2", Intrinsic::nvvm_fma_rn_ftz_relu_bf16x2)
1178 .
Case(
"ftz.sat.bf16", Intrinsic::nvvm_fma_rn_ftz_sat_bf16)
1179 .
Case(
"ftz.sat.bf16x2", Intrinsic::nvvm_fma_rn_ftz_sat_bf16x2)
1180 .
Case(
"relu.bf16", Intrinsic::nvvm_fma_rn_relu_bf16)
1181 .
Case(
"relu.bf16x2", Intrinsic::nvvm_fma_rn_relu_bf16x2)
1182 .
Case(
"sat.bf16", Intrinsic::nvvm_fma_rn_sat_bf16)
1183 .
Case(
"sat.bf16x2", Intrinsic::nvvm_fma_rn_sat_bf16x2)
1186 if (Name.consume_front(
"fmax."))
1188 .
Case(
"bf16", Intrinsic::nvvm_fmax_bf16)
1189 .
Case(
"bf16x2", Intrinsic::nvvm_fmax_bf16x2)
1190 .
Case(
"ftz.bf16", Intrinsic::nvvm_fmax_ftz_bf16)
1191 .
Case(
"ftz.bf16x2", Intrinsic::nvvm_fmax_ftz_bf16x2)
1192 .
Case(
"ftz.nan.bf16", Intrinsic::nvvm_fmax_ftz_nan_bf16)
1193 .
Case(
"ftz.nan.bf16x2", Intrinsic::nvvm_fmax_ftz_nan_bf16x2)
1194 .
Case(
"ftz.nan.xorsign.abs.bf16",
1195 Intrinsic::nvvm_fmax_ftz_nan_xorsign_abs_bf16)
1196 .
Case(
"ftz.nan.xorsign.abs.bf16x2",
1197 Intrinsic::nvvm_fmax_ftz_nan_xorsign_abs_bf16x2)
1198 .
Case(
"ftz.xorsign.abs.bf16", Intrinsic::nvvm_fmax_ftz_xorsign_abs_bf16)
1199 .
Case(
"ftz.xorsign.abs.bf16x2",
1200 Intrinsic::nvvm_fmax_ftz_xorsign_abs_bf16x2)
1201 .
Case(
"nan.bf16", Intrinsic::nvvm_fmax_nan_bf16)
1202 .
Case(
"nan.bf16x2", Intrinsic::nvvm_fmax_nan_bf16x2)
1203 .
Case(
"nan.xorsign.abs.bf16", Intrinsic::nvvm_fmax_nan_xorsign_abs_bf16)
1204 .
Case(
"nan.xorsign.abs.bf16x2",
1205 Intrinsic::nvvm_fmax_nan_xorsign_abs_bf16x2)
1206 .
Case(
"xorsign.abs.bf16", Intrinsic::nvvm_fmax_xorsign_abs_bf16)
1207 .
Case(
"xorsign.abs.bf16x2", Intrinsic::nvvm_fmax_xorsign_abs_bf16x2)
1210 if (Name.consume_front(
"fmin."))
1212 .
Case(
"bf16", Intrinsic::nvvm_fmin_bf16)
1213 .
Case(
"bf16x2", Intrinsic::nvvm_fmin_bf16x2)
1214 .
Case(
"ftz.bf16", Intrinsic::nvvm_fmin_ftz_bf16)
1215 .
Case(
"ftz.bf16x2", Intrinsic::nvvm_fmin_ftz_bf16x2)
1216 .
Case(
"ftz.nan.bf16", Intrinsic::nvvm_fmin_ftz_nan_bf16)
1217 .
Case(
"ftz.nan.bf16x2", Intrinsic::nvvm_fmin_ftz_nan_bf16x2)
1218 .
Case(
"ftz.nan.xorsign.abs.bf16",
1219 Intrinsic::nvvm_fmin_ftz_nan_xorsign_abs_bf16)
1220 .
Case(
"ftz.nan.xorsign.abs.bf16x2",
1221 Intrinsic::nvvm_fmin_ftz_nan_xorsign_abs_bf16x2)
1222 .
Case(
"ftz.xorsign.abs.bf16", Intrinsic::nvvm_fmin_ftz_xorsign_abs_bf16)
1223 .
Case(
"ftz.xorsign.abs.bf16x2",
1224 Intrinsic::nvvm_fmin_ftz_xorsign_abs_bf16x2)
1225 .
Case(
"nan.bf16", Intrinsic::nvvm_fmin_nan_bf16)
1226 .
Case(
"nan.bf16x2", Intrinsic::nvvm_fmin_nan_bf16x2)
1227 .
Case(
"nan.xorsign.abs.bf16", Intrinsic::nvvm_fmin_nan_xorsign_abs_bf16)
1228 .
Case(
"nan.xorsign.abs.bf16x2",
1229 Intrinsic::nvvm_fmin_nan_xorsign_abs_bf16x2)
1230 .
Case(
"xorsign.abs.bf16", Intrinsic::nvvm_fmin_xorsign_abs_bf16)
1231 .
Case(
"xorsign.abs.bf16x2", Intrinsic::nvvm_fmin_xorsign_abs_bf16x2)
1234 if (Name.consume_front(
"neg."))
1236 .
Case(
"bf16", Intrinsic::nvvm_neg_bf16)
1237 .
Case(
"bf16x2", Intrinsic::nvvm_neg_bf16x2)
1244 return Name.consume_front(
"local") || Name.consume_front(
"shared") ||
1245 Name.consume_front(
"global") || Name.consume_front(
"constant") ||
1246 Name.consume_front(
"param");
1250 bool CanUpgradeDebugIntrinsicsToRecords) {
1251 assert(
F &&
"Illegal to upgrade a non-existent Function.");
1256 if (!Name.consume_front(
"llvm.") || Name.empty())
1262 bool IsArm = Name.consume_front(
"arm.");
1263 if (IsArm || Name.consume_front(
"aarch64.")) {
1269 if (Name.consume_front(
"amdgcn.")) {
1270 if (Name ==
"alignbit") {
1273 F->getParent(), Intrinsic::fshr, {F->getReturnType()});
1277 if (Name.consume_front(
"atomic.")) {
1278 if (Name.starts_with(
"inc") || Name.starts_with(
"dec") ||
1279 Name.starts_with(
"cond.sub") || Name.starts_with(
"csub")) {
1289 if (
F->getIntrinsicID() == Intrinsic::amdgcn_wmma_i32_16x16x64_iu8 &&
1290 F->arg_size() == 7) {
1294 if (
F->getIntrinsicID() == Intrinsic::amdgcn_swmmac_i32_16x16x128_iu8 &&
1295 F->arg_size() == 8) {
1300 if (Name.consume_front(
"ds.") || Name.consume_front(
"global.atomic.") ||
1301 Name.consume_front(
"flat.atomic.")) {
1302 if (Name.starts_with(
"fadd") ||
1304 (Name.starts_with(
"fmin") && !Name.starts_with(
"fmin.num")) ||
1305 (Name.starts_with(
"fmax") && !Name.starts_with(
"fmax.num"))) {
1313 if (Name.starts_with(
"ldexp.")) {
1316 F->getParent(), Intrinsic::ldexp,
1317 {F->getReturnType(), F->getArg(1)->getType()});
1326 if (
F->arg_size() == 1) {
1334 F->arg_begin()->getType());
1339 if (
F->arg_size() == 2 && Name ==
"coro.end") {
1342 Intrinsic::coro_end);
1349 if (Name.consume_front(
"dbg.")) {
1351 if (CanUpgradeDebugIntrinsicsToRecords) {
1352 if (Name ==
"addr" || Name ==
"value" || Name ==
"assign" ||
1353 Name ==
"declare" || Name ==
"label") {
1362 if (Name ==
"addr" || (Name ==
"value" &&
F->arg_size() == 4)) {
1365 Intrinsic::dbg_value);
1372 if (Name.consume_front(
"experimental.vector.")) {
1378 .
StartsWith(
"extract.", Intrinsic::vector_extract)
1379 .
StartsWith(
"insert.", Intrinsic::vector_insert)
1380 .
StartsWith(
"reverse.", Intrinsic::vector_reverse)
1381 .
StartsWith(
"interleave2.", Intrinsic::vector_interleave2)
1382 .
StartsWith(
"deinterleave2.", Intrinsic::vector_deinterleave2)
1384 Intrinsic::vector_partial_reduce_add)
1387 const auto *FT =
F->getFunctionType();
1389 if (
ID == Intrinsic::vector_extract ||
1390 ID == Intrinsic::vector_interleave2)
1393 if (
ID != Intrinsic::vector_interleave2)
1395 if (
ID == Intrinsic::vector_insert ||
1396 ID == Intrinsic::vector_partial_reduce_add)
1404 if (Name.consume_front(
"reduce.")) {
1406 static const Regex R(
"^([a-z]+)\\.[a-z][0-9]+");
1407 if (R.match(Name, &
Groups))
1409 .
Case(
"add", Intrinsic::vector_reduce_add)
1410 .
Case(
"mul", Intrinsic::vector_reduce_mul)
1411 .
Case(
"and", Intrinsic::vector_reduce_and)
1412 .
Case(
"or", Intrinsic::vector_reduce_or)
1413 .
Case(
"xor", Intrinsic::vector_reduce_xor)
1414 .
Case(
"smax", Intrinsic::vector_reduce_smax)
1415 .
Case(
"smin", Intrinsic::vector_reduce_smin)
1416 .
Case(
"umax", Intrinsic::vector_reduce_umax)
1417 .
Case(
"umin", Intrinsic::vector_reduce_umin)
1418 .
Case(
"fmax", Intrinsic::vector_reduce_fmax)
1419 .
Case(
"fmin", Intrinsic::vector_reduce_fmin)
1424 static const Regex R2(
"^v2\\.([a-z]+)\\.[fi][0-9]+");
1429 .
Case(
"fadd", Intrinsic::vector_reduce_fadd)
1430 .
Case(
"fmul", Intrinsic::vector_reduce_fmul)
1435 auto Args =
F->getFunctionType()->params();
1437 {Args[V2 ? 1 : 0]});
1443 if (Name.consume_front(
"splice"))
1447 if (Name.consume_front(
"experimental.stepvector.")) {
1451 F->getParent(),
ID,
F->getFunctionType()->getReturnType());
1456 if (Name.starts_with(
"flt.rounds")) {
1459 Intrinsic::get_rounding);
1464 if (Name.starts_with(
"invariant.group.barrier")) {
1466 auto Args =
F->getFunctionType()->params();
1467 Type* ObjectPtr[1] = {Args[0]};
1470 F->getParent(), Intrinsic::launder_invariant_group, ObjectPtr);
1475 if ((Name.starts_with(
"lifetime.start") ||
1476 Name.starts_with(
"lifetime.end")) &&
1477 F->arg_size() == 2) {
1479 ? Intrinsic::lifetime_start
1480 : Intrinsic::lifetime_end;
1483 F->getArg(0)->getType());
1492 .StartsWith(
"memcpy.", Intrinsic::memcpy)
1493 .StartsWith(
"memmove.", Intrinsic::memmove)
1495 if (
F->arg_size() == 5) {
1499 F->getFunctionType()->params().slice(0, 3);
1505 if (Name.starts_with(
"memset.") &&
F->arg_size() == 5) {
1508 const auto *FT =
F->getFunctionType();
1509 Type *ParamTypes[2] = {
1510 FT->getParamType(0),
1514 Intrinsic::memset, ParamTypes);
1520 .
StartsWith(
"masked.load", Intrinsic::masked_load)
1521 .
StartsWith(
"masked.gather", Intrinsic::masked_gather)
1522 .
StartsWith(
"masked.store", Intrinsic::masked_store)
1523 .
StartsWith(
"masked.scatter", Intrinsic::masked_scatter)
1525 if (MaskedID &&
F->arg_size() == 4) {
1527 if (MaskedID == Intrinsic::masked_load ||
1528 MaskedID == Intrinsic::masked_gather) {
1530 F->getParent(), MaskedID,
1531 {F->getReturnType(), F->getArg(0)->getType()});
1535 F->getParent(), MaskedID,
1536 {F->getArg(0)->getType(), F->getArg(1)->getType()});
1542 if (Name.consume_front(
"nvvm.")) {
1544 if (
F->arg_size() == 1) {
1547 .
Cases({
"brev32",
"brev64"}, Intrinsic::bitreverse)
1548 .Case(
"clz.i", Intrinsic::ctlz)
1549 .
Case(
"popc.i", Intrinsic::ctpop)
1553 {F->getReturnType()});
1556 }
else if (
F->arg_size() == 2) {
1559 .
Cases({
"max.s",
"max.i",
"max.ll"}, Intrinsic::smax)
1560 .Cases({
"min.s",
"min.i",
"min.ll"}, Intrinsic::smin)
1561 .Cases({
"max.us",
"max.ui",
"max.ull"}, Intrinsic::umax)
1562 .Cases({
"min.us",
"min.ui",
"min.ull"}, Intrinsic::umin)
1566 {F->getReturnType()});
1572 if (!
F->getReturnType()->getScalarType()->isBFloatTy()) {
1600 bool Expand =
false;
1601 if (Name.consume_front(
"abs."))
1604 Name ==
"i" || Name ==
"ll" || Name ==
"bf16" || Name ==
"bf16x2";
1605 else if (Name.consume_front(
"fabs."))
1607 Expand = Name ==
"f" || Name ==
"ftz.f" || Name ==
"d";
1608 else if (Name.consume_front(
"ex2.approx."))
1611 Name ==
"f" || Name ==
"ftz.f" || Name ==
"d" || Name ==
"f16x2";
1612 else if (Name.consume_front(
"atomic.load."))
1621 else if (Name.consume_front(
"bitcast."))
1624 Name ==
"f2i" || Name ==
"i2f" || Name ==
"ll2d" || Name ==
"d2ll";
1625 else if (Name.consume_front(
"rotate."))
1627 Expand = Name ==
"b32" || Name ==
"b64" || Name ==
"right.b64";
1628 else if (Name.consume_front(
"ptr.gen.to."))
1631 else if (Name.consume_front(
"ptr."))
1634 else if (Name.consume_front(
"ldg.global."))
1636 Expand = (Name.starts_with(
"i.") || Name.starts_with(
"f.") ||
1637 Name.starts_with(
"p."));
1640 .
Case(
"barrier0",
true)
1641 .
Case(
"barrier.n",
true)
1642 .
Case(
"barrier.sync.cnt",
true)
1643 .
Case(
"barrier.sync",
true)
1644 .
Case(
"barrier",
true)
1645 .
Case(
"bar.sync",
true)
1646 .
Case(
"barrier0.popc",
true)
1647 .
Case(
"barrier0.and",
true)
1648 .
Case(
"barrier0.or",
true)
1649 .
Case(
"clz.ll",
true)
1650 .
Case(
"popc.ll",
true)
1652 .
Case(
"swap.lo.hi.b64",
true)
1653 .
Case(
"tanh.approx.f32",
true)
1665 if (Name.starts_with(
"objectsize.")) {
1666 Type *Tys[2] = {
F->getReturnType(),
F->arg_begin()->getType() };
1667 if (
F->arg_size() == 2 ||
F->arg_size() == 3) {
1670 Intrinsic::objectsize, Tys);
1677 if (Name.starts_with(
"ptr.annotation.") &&
F->arg_size() == 4) {
1680 F->getParent(), Intrinsic::ptr_annotation,
1681 {F->arg_begin()->getType(), F->getArg(1)->getType()});
1687 if (Name.consume_front(
"riscv.")) {
1690 .
Case(
"aes32dsi", Intrinsic::riscv_aes32dsi)
1691 .
Case(
"aes32dsmi", Intrinsic::riscv_aes32dsmi)
1692 .
Case(
"aes32esi", Intrinsic::riscv_aes32esi)
1693 .
Case(
"aes32esmi", Intrinsic::riscv_aes32esmi)
1696 if (!
F->getFunctionType()->getParamType(2)->isIntegerTy(32)) {
1709 if (!
F->getFunctionType()->getParamType(2)->isIntegerTy(32) ||
1710 F->getFunctionType()->getReturnType()->isIntegerTy(64)) {
1719 .
StartsWith(
"sha256sig0", Intrinsic::riscv_sha256sig0)
1720 .
StartsWith(
"sha256sig1", Intrinsic::riscv_sha256sig1)
1721 .
StartsWith(
"sha256sum0", Intrinsic::riscv_sha256sum0)
1722 .
StartsWith(
"sha256sum1", Intrinsic::riscv_sha256sum1)
1727 if (
F->getFunctionType()->getReturnType()->isIntegerTy(64)) {
1739 if (Name ==
"stackprotectorcheck") {
1746 if (Name ==
"thread.pointer") {
1748 F->getParent(), Intrinsic::thread_pointer,
F->getReturnType());
1754 if (Name ==
"var.annotation" &&
F->arg_size() == 4) {
1757 F->getParent(), Intrinsic::var_annotation,
1758 {{F->arg_begin()->getType(), F->getArg(1)->getType()}});
1761 if (Name.consume_front(
"vector.splice")) {
1762 if (Name.starts_with(
".left") || Name.starts_with(
".right"))
1770 if (Name.consume_front(
"wasm.")) {
1773 .
StartsWith(
"fma.", Intrinsic::wasm_relaxed_madd)
1774 .
StartsWith(
"fms.", Intrinsic::wasm_relaxed_nmadd)
1775 .
StartsWith(
"laneselect.", Intrinsic::wasm_relaxed_laneselect)
1780 F->getReturnType());
1784 if (Name.consume_front(
"dot.i8x16.i7x16.")) {
1786 .
Case(
"signed", Intrinsic::wasm_relaxed_dot_i8x16_i7x16_signed)
1788 Intrinsic::wasm_relaxed_dot_i8x16_i7x16_add_signed)
1807 if (ST && (!
ST->isLiteral() ||
ST->isPacked()) &&
1816 auto *FT =
F->getFunctionType();
1819 std::string
Name =
F->getName().str();
1822 Name,
F->getParent());
1833 if (Result != std::nullopt) {
1846 bool CanUpgradeDebugIntrinsicsToRecords) {
1866 GV->
getName() ==
"llvm.global_dtors")) ||
1881 unsigned N =
Init->getNumOperands();
1882 std::vector<Constant *> NewCtors(
N);
1883 for (
unsigned i = 0; i !=
N; ++i) {
1886 Ctor->getAggregateElement(1),
1900 unsigned NumElts = ResultTy->getNumElements() * 8;
1904 Op = Builder.CreateBitCast(
Op, VecTy,
"cast");
1914 for (
unsigned l = 0; l != NumElts; l += 16)
1915 for (
unsigned i = 0; i != 16; ++i) {
1916 unsigned Idx = NumElts + i - Shift;
1918 Idx -= NumElts - 16;
1919 Idxs[l + i] = Idx + l;
1922 Res = Builder.CreateShuffleVector(Res,
Op,
ArrayRef(Idxs, NumElts));
1926 return Builder.CreateBitCast(Res, ResultTy,
"cast");
1934 unsigned NumElts = ResultTy->getNumElements() * 8;
1938 Op = Builder.CreateBitCast(
Op, VecTy,
"cast");
1948 for (
unsigned l = 0; l != NumElts; l += 16)
1949 for (
unsigned i = 0; i != 16; ++i) {
1950 unsigned Idx = i + Shift;
1952 Idx += NumElts - 16;
1953 Idxs[l + i] = Idx + l;
1956 Res = Builder.CreateShuffleVector(
Op, Res,
ArrayRef(Idxs, NumElts));
1960 return Builder.CreateBitCast(Res, ResultTy,
"cast");
1968 Mask = Builder.CreateBitCast(Mask, MaskTy);
1974 for (
unsigned i = 0; i != NumElts; ++i)
1976 Mask = Builder.CreateShuffleVector(Mask, Mask,
ArrayRef(Indices, NumElts),
1987 if (
C->isAllOnesValue())
1992 return Builder.CreateSelect(Mask, Op0, Op1);
1999 if (
C->isAllOnesValue())
2003 Mask->getType()->getIntegerBitWidth());
2004 Mask = Builder.CreateBitCast(Mask, MaskTy);
2005 Mask = Builder.CreateExtractElement(Mask, (
uint64_t)0);
2006 return Builder.CreateSelect(Mask, Op0, Op1);
2019 assert((IsVALIGN || NumElts % 16 == 0) &&
"Illegal NumElts for PALIGNR!");
2020 assert((!IsVALIGN || NumElts <= 16) &&
"NumElts too large for VALIGN!");
2025 ShiftVal &= (NumElts - 1);
2034 if (ShiftVal > 16) {
2042 for (
unsigned l = 0; l < NumElts; l += 16) {
2043 for (
unsigned i = 0; i != 16; ++i) {
2044 unsigned Idx = ShiftVal + i;
2045 if (!IsVALIGN && Idx >= 16)
2046 Idx += NumElts - 16;
2047 Indices[l + i] = Idx + l;
2052 Op1, Op0,
ArrayRef(Indices, NumElts),
"palignr");
2058 bool ZeroMask,
bool IndexForm) {
2061 unsigned EltWidth = Ty->getScalarSizeInBits();
2062 bool IsFloat = Ty->isFPOrFPVectorTy();
2064 if (VecWidth == 128 && EltWidth == 32 && IsFloat)
2065 IID = Intrinsic::x86_avx512_vpermi2var_ps_128;
2066 else if (VecWidth == 128 && EltWidth == 32 && !IsFloat)
2067 IID = Intrinsic::x86_avx512_vpermi2var_d_128;
2068 else if (VecWidth == 128 && EltWidth == 64 && IsFloat)
2069 IID = Intrinsic::x86_avx512_vpermi2var_pd_128;
2070 else if (VecWidth == 128 && EltWidth == 64 && !IsFloat)
2071 IID = Intrinsic::x86_avx512_vpermi2var_q_128;
2072 else if (VecWidth == 256 && EltWidth == 32 && IsFloat)
2073 IID = Intrinsic::x86_avx512_vpermi2var_ps_256;
2074 else if (VecWidth == 256 && EltWidth == 32 && !IsFloat)
2075 IID = Intrinsic::x86_avx512_vpermi2var_d_256;
2076 else if (VecWidth == 256 && EltWidth == 64 && IsFloat)
2077 IID = Intrinsic::x86_avx512_vpermi2var_pd_256;
2078 else if (VecWidth == 256 && EltWidth == 64 && !IsFloat)
2079 IID = Intrinsic::x86_avx512_vpermi2var_q_256;
2080 else if (VecWidth == 512 && EltWidth == 32 && IsFloat)
2081 IID = Intrinsic::x86_avx512_vpermi2var_ps_512;
2082 else if (VecWidth == 512 && EltWidth == 32 && !IsFloat)
2083 IID = Intrinsic::x86_avx512_vpermi2var_d_512;
2084 else if (VecWidth == 512 && EltWidth == 64 && IsFloat)
2085 IID = Intrinsic::x86_avx512_vpermi2var_pd_512;
2086 else if (VecWidth == 512 && EltWidth == 64 && !IsFloat)
2087 IID = Intrinsic::x86_avx512_vpermi2var_q_512;
2088 else if (VecWidth == 128 && EltWidth == 16)
2089 IID = Intrinsic::x86_avx512_vpermi2var_hi_128;
2090 else if (VecWidth == 256 && EltWidth == 16)
2091 IID = Intrinsic::x86_avx512_vpermi2var_hi_256;
2092 else if (VecWidth == 512 && EltWidth == 16)
2093 IID = Intrinsic::x86_avx512_vpermi2var_hi_512;
2094 else if (VecWidth == 128 && EltWidth == 8)
2095 IID = Intrinsic::x86_avx512_vpermi2var_qi_128;
2096 else if (VecWidth == 256 && EltWidth == 8)
2097 IID = Intrinsic::x86_avx512_vpermi2var_qi_256;
2098 else if (VecWidth == 512 && EltWidth == 8)
2099 IID = Intrinsic::x86_avx512_vpermi2var_qi_512;
2110 Value *V = Builder.CreateIntrinsic(IID, Args);
2122 Value *Res = Builder.CreateIntrinsic(IID, Ty, {Op0, Op1});
2133 bool IsRotateRight) {
2143 Amt = Builder.CreateIntCast(Amt, Ty->getScalarType(),
false);
2144 Amt = Builder.CreateVectorSplat(NumElts, Amt);
2147 Intrinsic::ID IID = IsRotateRight ? Intrinsic::fshr : Intrinsic::fshl;
2148 Value *Res = Builder.CreateIntrinsic(IID, Ty, {Src, Src, Amt});
2193 Value *Ext = Builder.CreateSExt(Cmp, Ty);
2198 bool IsShiftRight,
bool ZeroMask) {
2212 Amt = Builder.CreateIntCast(Amt, Ty->getScalarType(),
false);
2213 Amt = Builder.CreateVectorSplat(NumElts, Amt);
2216 Intrinsic::ID IID = IsShiftRight ? Intrinsic::fshr : Intrinsic::fshl;
2217 Value *Res = Builder.CreateIntrinsic(IID, Ty, {Op0, Op1, Amt});
2232 const Align Alignment =
2234 ?
Align(
Data->getType()->getPrimitiveSizeInBits().getFixedValue() / 8)
2239 if (
C->isAllOnesValue())
2240 return Builder.CreateAlignedStore(
Data, Ptr, Alignment);
2245 return Builder.CreateMaskedStore(
Data, Ptr, Alignment, Mask);
2251 const Align Alignment =
2260 if (
C->isAllOnesValue())
2261 return Builder.CreateAlignedLoad(ValTy, Ptr, Alignment);
2266 return Builder.CreateMaskedLoad(ValTy, Ptr, Alignment, Mask, Passthru);
2272 Value *Res = Builder.CreateIntrinsic(Intrinsic::abs, Ty,
2273 {Op0, Builder.getInt1(
false)});
2288 Constant *ShiftAmt = ConstantInt::get(Ty, 32);
2289 LHS = Builder.CreateShl(
LHS, ShiftAmt);
2290 LHS = Builder.CreateAShr(
LHS, ShiftAmt);
2291 RHS = Builder.CreateShl(
RHS, ShiftAmt);
2292 RHS = Builder.CreateAShr(
RHS, ShiftAmt);
2295 Constant *Mask = ConstantInt::get(Ty, 0xffffffff);
2296 LHS = Builder.CreateAnd(
LHS, Mask);
2297 RHS = Builder.CreateAnd(
RHS, Mask);
2314 if (!
C || !
C->isAllOnesValue())
2315 Vec = Builder.CreateAnd(Vec,
getX86MaskVec(Builder, Mask, NumElts));
2320 for (
unsigned i = 0; i != NumElts; ++i)
2322 for (
unsigned i = NumElts; i != 8; ++i)
2323 Indices[i] = NumElts + i % NumElts;
2324 Vec = Builder.CreateShuffleVector(Vec,
2328 return Builder.CreateBitCast(Vec, Builder.getIntNTy(std::max(NumElts, 8U)));
2332 unsigned CC,
bool Signed) {
2340 }
else if (CC == 7) {
2376 Value* AndNode = Builder.CreateAnd(Mask,
APInt(8, 1));
2377 Value* Cmp = Builder.CreateIsNotNull(AndNode);
2379 Value* Extract2 = Builder.CreateExtractElement(Src, (
uint64_t)0);
2380 Value*
Select = Builder.CreateSelect(Cmp, Extract1, Extract2);
2389 return Builder.CreateSExt(Mask, ReturnOp,
"vpmovm2");
2395 Name = Name.substr(12);
2400 if (Name.starts_with(
"max.p")) {
2401 if (VecWidth == 128 && EltWidth == 32)
2402 IID = Intrinsic::x86_sse_max_ps;
2403 else if (VecWidth == 128 && EltWidth == 64)
2404 IID = Intrinsic::x86_sse2_max_pd;
2405 else if (VecWidth == 256 && EltWidth == 32)
2406 IID = Intrinsic::x86_avx_max_ps_256;
2407 else if (VecWidth == 256 && EltWidth == 64)
2408 IID = Intrinsic::x86_avx_max_pd_256;
2411 }
else if (Name.starts_with(
"min.p")) {
2412 if (VecWidth == 128 && EltWidth == 32)
2413 IID = Intrinsic::x86_sse_min_ps;
2414 else if (VecWidth == 128 && EltWidth == 64)
2415 IID = Intrinsic::x86_sse2_min_pd;
2416 else if (VecWidth == 256 && EltWidth == 32)
2417 IID = Intrinsic::x86_avx_min_ps_256;
2418 else if (VecWidth == 256 && EltWidth == 64)
2419 IID = Intrinsic::x86_avx_min_pd_256;
2422 }
else if (Name.starts_with(
"pshuf.b.")) {
2423 if (VecWidth == 128)
2424 IID = Intrinsic::x86_ssse3_pshuf_b_128;
2425 else if (VecWidth == 256)
2426 IID = Intrinsic::x86_avx2_pshuf_b;
2427 else if (VecWidth == 512)
2428 IID = Intrinsic::x86_avx512_pshuf_b_512;
2431 }
else if (Name.starts_with(
"pmul.hr.sw.")) {
2432 if (VecWidth == 128)
2433 IID = Intrinsic::x86_ssse3_pmul_hr_sw_128;
2434 else if (VecWidth == 256)
2435 IID = Intrinsic::x86_avx2_pmul_hr_sw;
2436 else if (VecWidth == 512)
2437 IID = Intrinsic::x86_avx512_pmul_hr_sw_512;
2440 }
else if (Name.starts_with(
"pmulh.w.")) {
2441 if (VecWidth == 128)
2442 IID = Intrinsic::x86_sse2_pmulh_w;
2443 else if (VecWidth == 256)
2444 IID = Intrinsic::x86_avx2_pmulh_w;
2445 else if (VecWidth == 512)
2446 IID = Intrinsic::x86_avx512_pmulh_w_512;
2449 }
else if (Name.starts_with(
"pmulhu.w.")) {
2450 if (VecWidth == 128)
2451 IID = Intrinsic::x86_sse2_pmulhu_w;
2452 else if (VecWidth == 256)
2453 IID = Intrinsic::x86_avx2_pmulhu_w;
2454 else if (VecWidth == 512)
2455 IID = Intrinsic::x86_avx512_pmulhu_w_512;
2458 }
else if (Name.starts_with(
"pmaddw.d.")) {
2459 if (VecWidth == 128)
2460 IID = Intrinsic::x86_sse2_pmadd_wd;
2461 else if (VecWidth == 256)
2462 IID = Intrinsic::x86_avx2_pmadd_wd;
2463 else if (VecWidth == 512)
2464 IID = Intrinsic::x86_avx512_pmaddw_d_512;
2467 }
else if (Name.starts_with(
"pmaddubs.w.")) {
2468 if (VecWidth == 128)
2469 IID = Intrinsic::x86_ssse3_pmadd_ub_sw_128;
2470 else if (VecWidth == 256)
2471 IID = Intrinsic::x86_avx2_pmadd_ub_sw;
2472 else if (VecWidth == 512)
2473 IID = Intrinsic::x86_avx512_pmaddubs_w_512;
2476 }
else if (Name.starts_with(
"packsswb.")) {
2477 if (VecWidth == 128)
2478 IID = Intrinsic::x86_sse2_packsswb_128;
2479 else if (VecWidth == 256)
2480 IID = Intrinsic::x86_avx2_packsswb;
2481 else if (VecWidth == 512)
2482 IID = Intrinsic::x86_avx512_packsswb_512;
2485 }
else if (Name.starts_with(
"packssdw.")) {
2486 if (VecWidth == 128)
2487 IID = Intrinsic::x86_sse2_packssdw_128;
2488 else if (VecWidth == 256)
2489 IID = Intrinsic::x86_avx2_packssdw;
2490 else if (VecWidth == 512)
2491 IID = Intrinsic::x86_avx512_packssdw_512;
2494 }
else if (Name.starts_with(
"packuswb.")) {
2495 if (VecWidth == 128)
2496 IID = Intrinsic::x86_sse2_packuswb_128;
2497 else if (VecWidth == 256)
2498 IID = Intrinsic::x86_avx2_packuswb;
2499 else if (VecWidth == 512)
2500 IID = Intrinsic::x86_avx512_packuswb_512;
2503 }
else if (Name.starts_with(
"packusdw.")) {
2504 if (VecWidth == 128)
2505 IID = Intrinsic::x86_sse41_packusdw;
2506 else if (VecWidth == 256)
2507 IID = Intrinsic::x86_avx2_packusdw;
2508 else if (VecWidth == 512)
2509 IID = Intrinsic::x86_avx512_packusdw_512;
2512 }
else if (Name.starts_with(
"vpermilvar.")) {
2513 if (VecWidth == 128 && EltWidth == 32)
2514 IID = Intrinsic::x86_avx_vpermilvar_ps;
2515 else if (VecWidth == 128 && EltWidth == 64)
2516 IID = Intrinsic::x86_avx_vpermilvar_pd;
2517 else if (VecWidth == 256 && EltWidth == 32)
2518 IID = Intrinsic::x86_avx_vpermilvar_ps_256;
2519 else if (VecWidth == 256 && EltWidth == 64)
2520 IID = Intrinsic::x86_avx_vpermilvar_pd_256;
2521 else if (VecWidth == 512 && EltWidth == 32)
2522 IID = Intrinsic::x86_avx512_vpermilvar_ps_512;
2523 else if (VecWidth == 512 && EltWidth == 64)
2524 IID = Intrinsic::x86_avx512_vpermilvar_pd_512;
2527 }
else if (Name ==
"cvtpd2dq.256") {
2528 IID = Intrinsic::x86_avx_cvt_pd2dq_256;
2529 }
else if (Name ==
"cvtpd2ps.256") {
2530 IID = Intrinsic::x86_avx_cvt_pd2_ps_256;
2531 }
else if (Name ==
"cvttpd2dq.256") {
2532 IID = Intrinsic::x86_avx_cvtt_pd2dq_256;
2533 }
else if (Name ==
"cvttps2dq.128") {
2534 IID = Intrinsic::x86_sse2_cvttps2dq;
2535 }
else if (Name ==
"cvttps2dq.256") {
2536 IID = Intrinsic::x86_avx_cvtt_ps2dq_256;
2537 }
else if (Name.starts_with(
"permvar.")) {
2539 if (VecWidth == 256 && EltWidth == 32 && IsFloat)
2540 IID = Intrinsic::x86_avx2_permps;
2541 else if (VecWidth == 256 && EltWidth == 32 && !IsFloat)
2542 IID = Intrinsic::x86_avx2_permd;
2543 else if (VecWidth == 256 && EltWidth == 64 && IsFloat)
2544 IID = Intrinsic::x86_avx512_permvar_df_256;
2545 else if (VecWidth == 256 && EltWidth == 64 && !IsFloat)
2546 IID = Intrinsic::x86_avx512_permvar_di_256;
2547 else if (VecWidth == 512 && EltWidth == 32 && IsFloat)
2548 IID = Intrinsic::x86_avx512_permvar_sf_512;
2549 else if (VecWidth == 512 && EltWidth == 32 && !IsFloat)
2550 IID = Intrinsic::x86_avx512_permvar_si_512;
2551 else if (VecWidth == 512 && EltWidth == 64 && IsFloat)
2552 IID = Intrinsic::x86_avx512_permvar_df_512;
2553 else if (VecWidth == 512 && EltWidth == 64 && !IsFloat)
2554 IID = Intrinsic::x86_avx512_permvar_di_512;
2555 else if (VecWidth == 128 && EltWidth == 16)
2556 IID = Intrinsic::x86_avx512_permvar_hi_128;
2557 else if (VecWidth == 256 && EltWidth == 16)
2558 IID = Intrinsic::x86_avx512_permvar_hi_256;
2559 else if (VecWidth == 512 && EltWidth == 16)
2560 IID = Intrinsic::x86_avx512_permvar_hi_512;
2561 else if (VecWidth == 128 && EltWidth == 8)
2562 IID = Intrinsic::x86_avx512_permvar_qi_128;
2563 else if (VecWidth == 256 && EltWidth == 8)
2564 IID = Intrinsic::x86_avx512_permvar_qi_256;
2565 else if (VecWidth == 512 && EltWidth == 8)
2566 IID = Intrinsic::x86_avx512_permvar_qi_512;
2569 }
else if (Name.starts_with(
"dbpsadbw.")) {
2570 if (VecWidth == 128)
2571 IID = Intrinsic::x86_avx512_dbpsadbw_128;
2572 else if (VecWidth == 256)
2573 IID = Intrinsic::x86_avx512_dbpsadbw_256;
2574 else if (VecWidth == 512)
2575 IID = Intrinsic::x86_avx512_dbpsadbw_512;
2578 }
else if (Name.starts_with(
"pmultishift.qb.")) {
2579 if (VecWidth == 128)
2580 IID = Intrinsic::x86_avx512_pmultishift_qb_128;
2581 else if (VecWidth == 256)
2582 IID = Intrinsic::x86_avx512_pmultishift_qb_256;
2583 else if (VecWidth == 512)
2584 IID = Intrinsic::x86_avx512_pmultishift_qb_512;
2587 }
else if (Name.starts_with(
"conflict.")) {
2588 if (Name[9] ==
'd' && VecWidth == 128)
2589 IID = Intrinsic::x86_avx512_conflict_d_128;
2590 else if (Name[9] ==
'd' && VecWidth == 256)
2591 IID = Intrinsic::x86_avx512_conflict_d_256;
2592 else if (Name[9] ==
'd' && VecWidth == 512)
2593 IID = Intrinsic::x86_avx512_conflict_d_512;
2594 else if (Name[9] ==
'q' && VecWidth == 128)
2595 IID = Intrinsic::x86_avx512_conflict_q_128;
2596 else if (Name[9] ==
'q' && VecWidth == 256)
2597 IID = Intrinsic::x86_avx512_conflict_q_256;
2598 else if (Name[9] ==
'q' && VecWidth == 512)
2599 IID = Intrinsic::x86_avx512_conflict_q_512;
2602 }
else if (Name.starts_with(
"pavg.")) {
2603 if (Name[5] ==
'b' && VecWidth == 128)
2604 IID = Intrinsic::x86_sse2_pavg_b;
2605 else if (Name[5] ==
'b' && VecWidth == 256)
2606 IID = Intrinsic::x86_avx2_pavg_b;
2607 else if (Name[5] ==
'b' && VecWidth == 512)
2608 IID = Intrinsic::x86_avx512_pavg_b_512;
2609 else if (Name[5] ==
'w' && VecWidth == 128)
2610 IID = Intrinsic::x86_sse2_pavg_w;
2611 else if (Name[5] ==
'w' && VecWidth == 256)
2612 IID = Intrinsic::x86_avx2_pavg_w;
2613 else if (Name[5] ==
'w' && VecWidth == 512)
2614 IID = Intrinsic::x86_avx512_pavg_w_512;
2623 Rep = Builder.CreateIntrinsic(IID, Args);
2634 if (AsmStr->find(
"mov\tfp") == 0 &&
2635 AsmStr->find(
"objc_retainAutoreleaseReturnValue") != std::string::npos &&
2636 (Pos = AsmStr->find(
"# marker")) != std::string::npos) {
2637 AsmStr->replace(Pos, 1,
";");
2643 Value *Rep =
nullptr;
2645 if (Name ==
"abs.i" || Name ==
"abs.ll") {
2647 Value *Neg = Builder.CreateNeg(Arg,
"neg");
2648 Value *Cmp = Builder.CreateICmpSGE(
2650 Rep = Builder.CreateSelect(Cmp, Arg, Neg,
"abs");
2651 }
else if (Name ==
"abs.bf16" || Name ==
"abs.bf16x2") {
2652 Type *Ty = (Name ==
"abs.bf16")
2656 Value *Abs = Builder.CreateUnaryIntrinsic(Intrinsic::nvvm_fabs, Arg);
2657 Rep = Builder.CreateBitCast(Abs, CI->
getType());
2658 }
else if (Name ==
"fabs.f" || Name ==
"fabs.ftz.f" || Name ==
"fabs.d") {
2659 Intrinsic::ID IID = (Name ==
"fabs.ftz.f") ? Intrinsic::nvvm_fabs_ftz
2660 : Intrinsic::nvvm_fabs;
2661 Rep = Builder.CreateUnaryIntrinsic(IID, CI->
getArgOperand(0));
2662 }
else if (Name.consume_front(
"ex2.approx.")) {
2664 Intrinsic::ID IID = Name.starts_with(
"ftz") ? Intrinsic::nvvm_ex2_approx_ftz
2665 : Intrinsic::nvvm_ex2_approx;
2666 Rep = Builder.CreateUnaryIntrinsic(IID, CI->
getArgOperand(0));
2667 }
else if (Name.starts_with(
"atomic.load.add.f32.p") ||
2668 Name.starts_with(
"atomic.load.add.f64.p")) {
2673 }
else if (Name.starts_with(
"atomic.load.inc.32.p") ||
2674 Name.starts_with(
"atomic.load.dec.32.p")) {
2679 Rep = Builder.CreateAtomicRMW(
Op, Ptr, Val,
MaybeAlign(),
2681 }
else if (Name ==
"clz.ll") {
2684 Value *Ctlz = Builder.CreateIntrinsic(Intrinsic::ctlz, {Arg->
getType()},
2685 {Arg, Builder.getFalse()},
2687 Rep = Builder.CreateTrunc(Ctlz, Builder.getInt32Ty(),
"ctlz.trunc");
2688 }
else if (Name ==
"popc.ll") {
2692 Value *Popc = Builder.CreateIntrinsic(Intrinsic::ctpop, {Arg->
getType()},
2693 Arg,
nullptr,
"ctpop");
2694 Rep = Builder.CreateTrunc(Popc, Builder.getInt32Ty(),
"ctpop.trunc");
2695 }
else if (Name ==
"h2f") {
2696 Rep = Builder.CreateIntrinsic(Intrinsic::convert_from_fp16,
2699 }
else if (Name.consume_front(
"bitcast.") &&
2700 (Name ==
"f2i" || Name ==
"i2f" || Name ==
"ll2d" ||
2703 }
else if (Name ==
"rotate.b32") {
2706 Rep = Builder.CreateIntrinsic(Builder.getInt32Ty(), Intrinsic::fshl,
2707 {Arg, Arg, ShiftAmt});
2708 }
else if (Name ==
"rotate.b64") {
2712 Rep = Builder.CreateIntrinsic(Int64Ty, Intrinsic::fshl,
2713 {Arg, Arg, ZExtShiftAmt});
2714 }
else if (Name ==
"rotate.right.b64") {
2718 Rep = Builder.CreateIntrinsic(Int64Ty, Intrinsic::fshr,
2719 {Arg, Arg, ZExtShiftAmt});
2720 }
else if (Name ==
"swap.lo.hi.b64") {
2723 Rep = Builder.CreateIntrinsic(Int64Ty, Intrinsic::fshl,
2724 {Arg, Arg, Builder.getInt64(32)});
2725 }
else if ((Name.consume_front(
"ptr.gen.to.") &&
2728 Name.starts_with(
".to.gen"))) {
2730 }
else if (Name.consume_front(
"ldg.global")) {
2734 Value *ASC = Builder.CreateAddrSpaceCast(Ptr, Builder.getPtrTy(1));
2737 LD->setMetadata(LLVMContext::MD_invariant_load, MD);
2739 }
else if (Name ==
"tanh.approx.f32") {
2743 Rep = Builder.CreateUnaryIntrinsic(Intrinsic::tanh, CI->
getArgOperand(0),
2745 }
else if (Name ==
"barrier0" || Name ==
"barrier.n" || Name ==
"bar.sync") {
2747 Name.ends_with(
'0') ? Builder.getInt32(0) : CI->
getArgOperand(0);
2748 Rep = Builder.CreateIntrinsic(Intrinsic::nvvm_barrier_cta_sync_aligned_all,
2750 }
else if (Name ==
"barrier") {
2751 Rep = Builder.CreateIntrinsic(
2752 Intrinsic::nvvm_barrier_cta_sync_aligned_count, {},
2754 }
else if (Name ==
"barrier.sync") {
2755 Rep = Builder.CreateIntrinsic(Intrinsic::nvvm_barrier_cta_sync_all, {},
2757 }
else if (Name ==
"barrier.sync.cnt") {
2758 Rep = Builder.CreateIntrinsic(Intrinsic::nvvm_barrier_cta_sync_count, {},
2760 }
else if (Name ==
"barrier0.popc" || Name ==
"barrier0.and" ||
2761 Name ==
"barrier0.or") {
2763 C = Builder.CreateICmpNE(
C, Builder.getInt32(0));
2767 .
Case(
"barrier0.popc",
2768 Intrinsic::nvvm_barrier_cta_red_popc_aligned_all)
2769 .
Case(
"barrier0.and",
2770 Intrinsic::nvvm_barrier_cta_red_and_aligned_all)
2771 .
Case(
"barrier0.or",
2772 Intrinsic::nvvm_barrier_cta_red_or_aligned_all);
2773 Value *Bar = Builder.CreateIntrinsic(IID, {}, {Builder.getInt32(0),
C});
2774 Rep = Builder.CreateZExt(Bar, CI->
getType());
2778 !
F->getReturnType()->getScalarType()->isBFloatTy()) {
2788 ? Builder.CreateBitCast(Arg, NewType)
2791 Rep = Builder.CreateCall(NewFn, Args);
2792 if (
F->getReturnType()->isIntegerTy())
2793 Rep = Builder.CreateBitCast(Rep,
F->getReturnType());
2803 Value *Rep =
nullptr;
2805 if (Name.starts_with(
"sse4a.movnt.")) {
2817 Builder.CreateExtractElement(Arg1, (
uint64_t)0,
"extractelement");
2820 SI->setMetadata(LLVMContext::MD_nontemporal,
Node);
2821 }
else if (Name.starts_with(
"avx.movnt.") ||
2822 Name.starts_with(
"avx512.storent.")) {
2834 SI->setMetadata(LLVMContext::MD_nontemporal,
Node);
2835 }
else if (Name ==
"sse2.storel.dq") {
2840 Value *BC0 = Builder.CreateBitCast(Arg1, NewVecTy,
"cast");
2841 Value *Elt = Builder.CreateExtractElement(BC0, (
uint64_t)0);
2842 Builder.CreateAlignedStore(Elt, Arg0,
Align(1));
2843 }
else if (Name.starts_with(
"sse.storeu.") ||
2844 Name.starts_with(
"sse2.storeu.") ||
2845 Name.starts_with(
"avx.storeu.")) {
2848 Builder.CreateAlignedStore(Arg1, Arg0,
Align(1));
2849 }
else if (Name ==
"avx512.mask.store.ss") {
2853 }
else if (Name.starts_with(
"avx512.mask.store")) {
2855 bool Aligned = Name[17] !=
'u';
2858 }
else if (Name.starts_with(
"sse2.pcmp") || Name.starts_with(
"avx2.pcmp")) {
2861 bool CmpEq = Name[9] ==
'e';
2864 Rep = Builder.CreateSExt(Rep, CI->
getType(),
"");
2865 }
else if (Name.starts_with(
"avx512.broadcastm")) {
2872 Rep = Builder.CreateVectorSplat(NumElts, Rep);
2873 }
else if (Name ==
"sse.sqrt.ss" || Name ==
"sse2.sqrt.sd") {
2875 Value *Elt0 = Builder.CreateExtractElement(Vec, (
uint64_t)0);
2876 Elt0 = Builder.CreateIntrinsic(Intrinsic::sqrt, Elt0->
getType(), Elt0);
2877 Rep = Builder.CreateInsertElement(Vec, Elt0, (
uint64_t)0);
2878 }
else if (Name.starts_with(
"avx.sqrt.p") ||
2879 Name.starts_with(
"sse2.sqrt.p") ||
2880 Name.starts_with(
"sse.sqrt.p")) {
2881 Rep = Builder.CreateIntrinsic(Intrinsic::sqrt, CI->
getType(),
2882 {CI->getArgOperand(0)});
2883 }
else if (Name.starts_with(
"avx512.mask.sqrt.p")) {
2887 Intrinsic::ID IID = Name[18] ==
's' ? Intrinsic::x86_avx512_sqrt_ps_512
2888 : Intrinsic::x86_avx512_sqrt_pd_512;
2891 Rep = Builder.CreateIntrinsic(IID, Args);
2893 Rep = Builder.CreateIntrinsic(Intrinsic::sqrt, CI->
getType(),
2894 {CI->getArgOperand(0)});
2898 }
else if (Name.starts_with(
"avx512.ptestm") ||
2899 Name.starts_with(
"avx512.ptestnm")) {
2903 Rep = Builder.CreateAnd(Op0, Op1);
2909 Rep = Builder.CreateICmp(Pred, Rep, Zero);
2911 }
else if (Name.starts_with(
"avx512.mask.pbroadcast")) {
2914 Rep = Builder.CreateVectorSplat(NumElts, CI->
getArgOperand(0));
2917 }
else if (Name.starts_with(
"avx512.kunpck")) {
2922 for (
unsigned i = 0; i != NumElts; ++i)
2931 Rep = Builder.CreateShuffleVector(
RHS,
LHS,
ArrayRef(Indices, NumElts));
2932 Rep = Builder.CreateBitCast(Rep, CI->
getType());
2933 }
else if (Name ==
"avx512.kand.w") {
2936 Rep = Builder.CreateAnd(
LHS,
RHS);
2937 Rep = Builder.CreateBitCast(Rep, CI->
getType());
2938 }
else if (Name ==
"avx512.kandn.w") {
2941 LHS = Builder.CreateNot(
LHS);
2942 Rep = Builder.CreateAnd(
LHS,
RHS);
2943 Rep = Builder.CreateBitCast(Rep, CI->
getType());
2944 }
else if (Name ==
"avx512.kor.w") {
2947 Rep = Builder.CreateOr(
LHS,
RHS);
2948 Rep = Builder.CreateBitCast(Rep, CI->
getType());
2949 }
else if (Name ==
"avx512.kxor.w") {
2952 Rep = Builder.CreateXor(
LHS,
RHS);
2953 Rep = Builder.CreateBitCast(Rep, CI->
getType());
2954 }
else if (Name ==
"avx512.kxnor.w") {
2957 LHS = Builder.CreateNot(
LHS);
2958 Rep = Builder.CreateXor(
LHS,
RHS);
2959 Rep = Builder.CreateBitCast(Rep, CI->
getType());
2960 }
else if (Name ==
"avx512.knot.w") {
2962 Rep = Builder.CreateNot(Rep);
2963 Rep = Builder.CreateBitCast(Rep, CI->
getType());
2964 }
else if (Name ==
"avx512.kortestz.w" || Name ==
"avx512.kortestc.w") {
2967 Rep = Builder.CreateOr(
LHS,
RHS);
2968 Rep = Builder.CreateBitCast(Rep, Builder.getInt16Ty());
2970 if (Name[14] ==
'c')
2974 Rep = Builder.CreateICmpEQ(Rep,
C);
2975 Rep = Builder.CreateZExt(Rep, Builder.getInt32Ty());
2976 }
else if (Name ==
"sse.add.ss" || Name ==
"sse2.add.sd" ||
2977 Name ==
"sse.sub.ss" || Name ==
"sse2.sub.sd" ||
2978 Name ==
"sse.mul.ss" || Name ==
"sse2.mul.sd" ||
2979 Name ==
"sse.div.ss" || Name ==
"sse2.div.sd") {
2982 ConstantInt::get(I32Ty, 0));
2984 ConstantInt::get(I32Ty, 0));
2986 if (Name.contains(
".add."))
2987 EltOp = Builder.CreateFAdd(Elt0, Elt1);
2988 else if (Name.contains(
".sub."))
2989 EltOp = Builder.CreateFSub(Elt0, Elt1);
2990 else if (Name.contains(
".mul."))
2991 EltOp = Builder.CreateFMul(Elt0, Elt1);
2993 EltOp = Builder.CreateFDiv(Elt0, Elt1);
2994 Rep = Builder.CreateInsertElement(CI->
getArgOperand(0), EltOp,
2995 ConstantInt::get(I32Ty, 0));
2996 }
else if (Name.starts_with(
"avx512.mask.pcmp")) {
2998 bool CmpEq = Name[16] ==
'e';
3000 }
else if (Name.starts_with(
"avx512.mask.vpshufbitqmb.")) {
3008 IID = Intrinsic::x86_avx512_vpshufbitqmb_128;
3011 IID = Intrinsic::x86_avx512_vpshufbitqmb_256;
3014 IID = Intrinsic::x86_avx512_vpshufbitqmb_512;
3021 }
else if (Name.starts_with(
"avx512.mask.fpclass.p")) {
3026 if (VecWidth == 128 && EltWidth == 32)
3027 IID = Intrinsic::x86_avx512_fpclass_ps_128;
3028 else if (VecWidth == 256 && EltWidth == 32)
3029 IID = Intrinsic::x86_avx512_fpclass_ps_256;
3030 else if (VecWidth == 512 && EltWidth == 32)
3031 IID = Intrinsic::x86_avx512_fpclass_ps_512;
3032 else if (VecWidth == 128 && EltWidth == 64)
3033 IID = Intrinsic::x86_avx512_fpclass_pd_128;
3034 else if (VecWidth == 256 && EltWidth == 64)
3035 IID = Intrinsic::x86_avx512_fpclass_pd_256;
3036 else if (VecWidth == 512 && EltWidth == 64)
3037 IID = Intrinsic::x86_avx512_fpclass_pd_512;
3044 }
else if (Name.starts_with(
"avx512.cmp.p")) {
3046 Type *OpTy = Args[0]->getType();
3050 if (VecWidth == 128 && EltWidth == 32)
3051 IID = Intrinsic::x86_avx512_mask_cmp_ps_128;
3052 else if (VecWidth == 256 && EltWidth == 32)
3053 IID = Intrinsic::x86_avx512_mask_cmp_ps_256;
3054 else if (VecWidth == 512 && EltWidth == 32)
3055 IID = Intrinsic::x86_avx512_mask_cmp_ps_512;
3056 else if (VecWidth == 128 && EltWidth == 64)
3057 IID = Intrinsic::x86_avx512_mask_cmp_pd_128;
3058 else if (VecWidth == 256 && EltWidth == 64)
3059 IID = Intrinsic::x86_avx512_mask_cmp_pd_256;
3060 else if (VecWidth == 512 && EltWidth == 64)
3061 IID = Intrinsic::x86_avx512_mask_cmp_pd_512;
3066 if (VecWidth == 512)
3068 Args.push_back(Mask);
3070 Rep = Builder.CreateIntrinsic(IID, Args);
3071 }
else if (Name.starts_with(
"avx512.mask.cmp.")) {
3075 }
else if (Name.starts_with(
"avx512.mask.ucmp.")) {
3078 }
else if (Name.starts_with(
"avx512.cvtb2mask.") ||
3079 Name.starts_with(
"avx512.cvtw2mask.") ||
3080 Name.starts_with(
"avx512.cvtd2mask.") ||
3081 Name.starts_with(
"avx512.cvtq2mask.")) {
3086 }
else if (Name ==
"ssse3.pabs.b.128" || Name ==
"ssse3.pabs.w.128" ||
3087 Name ==
"ssse3.pabs.d.128" || Name.starts_with(
"avx2.pabs") ||
3088 Name.starts_with(
"avx512.mask.pabs")) {
3090 }
else if (Name ==
"sse41.pmaxsb" || Name ==
"sse2.pmaxs.w" ||
3091 Name ==
"sse41.pmaxsd" || Name.starts_with(
"avx2.pmaxs") ||
3092 Name.starts_with(
"avx512.mask.pmaxs")) {
3094 }
else if (Name ==
"sse2.pmaxu.b" || Name ==
"sse41.pmaxuw" ||
3095 Name ==
"sse41.pmaxud" || Name.starts_with(
"avx2.pmaxu") ||
3096 Name.starts_with(
"avx512.mask.pmaxu")) {
3098 }
else if (Name ==
"sse41.pminsb" || Name ==
"sse2.pmins.w" ||
3099 Name ==
"sse41.pminsd" || Name.starts_with(
"avx2.pmins") ||
3100 Name.starts_with(
"avx512.mask.pmins")) {
3102 }
else if (Name ==
"sse2.pminu.b" || Name ==
"sse41.pminuw" ||
3103 Name ==
"sse41.pminud" || Name.starts_with(
"avx2.pminu") ||
3104 Name.starts_with(
"avx512.mask.pminu")) {
3106 }
else if (Name ==
"sse2.pmulu.dq" || Name ==
"avx2.pmulu.dq" ||
3107 Name ==
"avx512.pmulu.dq.512" ||
3108 Name.starts_with(
"avx512.mask.pmulu.dq.")) {
3110 }
else if (Name ==
"sse41.pmuldq" || Name ==
"avx2.pmul.dq" ||
3111 Name ==
"avx512.pmul.dq.512" ||
3112 Name.starts_with(
"avx512.mask.pmul.dq.")) {
3114 }
else if (Name ==
"sse.cvtsi2ss" || Name ==
"sse2.cvtsi2sd" ||
3115 Name ==
"sse.cvtsi642ss" || Name ==
"sse2.cvtsi642sd") {
3120 }
else if (Name ==
"avx512.cvtusi2sd") {
3125 }
else if (Name ==
"sse2.cvtss2sd") {
3127 Rep = Builder.CreateFPExt(
3130 }
else if (Name ==
"sse2.cvtdq2pd" || Name ==
"sse2.cvtdq2ps" ||
3131 Name ==
"avx.cvtdq2.pd.256" || Name ==
"avx.cvtdq2.ps.256" ||
3132 Name.starts_with(
"avx512.mask.cvtdq2pd.") ||
3133 Name.starts_with(
"avx512.mask.cvtudq2pd.") ||
3134 Name.starts_with(
"avx512.mask.cvtdq2ps.") ||
3135 Name.starts_with(
"avx512.mask.cvtudq2ps.") ||
3136 Name.starts_with(
"avx512.mask.cvtqq2pd.") ||
3137 Name.starts_with(
"avx512.mask.cvtuqq2pd.") ||
3138 Name ==
"avx512.mask.cvtqq2ps.256" ||
3139 Name ==
"avx512.mask.cvtqq2ps.512" ||
3140 Name ==
"avx512.mask.cvtuqq2ps.256" ||
3141 Name ==
"avx512.mask.cvtuqq2ps.512" || Name ==
"sse2.cvtps2pd" ||
3142 Name ==
"avx.cvt.ps2.pd.256" ||
3143 Name ==
"avx512.mask.cvtps2pd.128" ||
3144 Name ==
"avx512.mask.cvtps2pd.256") {
3149 unsigned NumDstElts = DstTy->getNumElements();
3151 assert(NumDstElts == 2 &&
"Unexpected vector size");
3152 Rep = Builder.CreateShuffleVector(Rep, Rep,
ArrayRef<int>{0, 1});
3155 bool IsPS2PD = SrcTy->getElementType()->isFloatTy();
3156 bool IsUnsigned = Name.contains(
"cvtu");
3158 Rep = Builder.CreateFPExt(Rep, DstTy,
"cvtps2pd");
3162 Intrinsic::ID IID = IsUnsigned ? Intrinsic::x86_avx512_uitofp_round
3163 : Intrinsic::x86_avx512_sitofp_round;
3164 Rep = Builder.CreateIntrinsic(IID, {DstTy, SrcTy},
3167 Rep = IsUnsigned ? Builder.CreateUIToFP(Rep, DstTy,
"cvt")
3168 : Builder.CreateSIToFP(Rep, DstTy,
"cvt");
3174 }
else if (Name.starts_with(
"avx512.mask.vcvtph2ps.") ||
3175 Name.starts_with(
"vcvtph2ps.")) {
3179 unsigned NumDstElts = DstTy->getNumElements();
3180 if (NumDstElts != SrcTy->getNumElements()) {
3181 assert(NumDstElts == 4 &&
"Unexpected vector size");
3182 Rep = Builder.CreateShuffleVector(Rep, Rep,
ArrayRef<int>{0, 1, 2, 3});
3184 Rep = Builder.CreateBitCast(
3186 Rep = Builder.CreateFPExt(Rep, DstTy,
"cvtph2ps");
3190 }
else if (Name.starts_with(
"avx512.mask.load")) {
3192 bool Aligned = Name[16] !=
'u';
3195 }
else if (Name.starts_with(
"avx512.mask.expand.load.")) {
3198 ResultTy->getNumElements());
3200 Rep = Builder.CreateIntrinsic(
3201 Intrinsic::masked_expandload, ResultTy,
3203 }
else if (Name.starts_with(
"avx512.mask.compress.store.")) {
3209 Rep = Builder.CreateIntrinsic(
3210 Intrinsic::masked_compressstore, ResultTy,
3212 }
else if (Name.starts_with(
"avx512.mask.compress.") ||
3213 Name.starts_with(
"avx512.mask.expand.")) {
3217 ResultTy->getNumElements());
3219 bool IsCompress = Name[12] ==
'c';
3220 Intrinsic::ID IID = IsCompress ? Intrinsic::x86_avx512_mask_compress
3221 : Intrinsic::x86_avx512_mask_expand;
3222 Rep = Builder.CreateIntrinsic(
3224 }
else if (Name.starts_with(
"xop.vpcom")) {
3226 if (Name.ends_with(
"ub") || Name.ends_with(
"uw") || Name.ends_with(
"ud") ||
3227 Name.ends_with(
"uq"))
3229 else if (Name.ends_with(
"b") || Name.ends_with(
"w") ||
3230 Name.ends_with(
"d") || Name.ends_with(
"q"))
3239 Name = Name.substr(9);
3240 if (Name.starts_with(
"lt"))
3242 else if (Name.starts_with(
"le"))
3244 else if (Name.starts_with(
"gt"))
3246 else if (Name.starts_with(
"ge"))
3248 else if (Name.starts_with(
"eq"))
3250 else if (Name.starts_with(
"ne"))
3252 else if (Name.starts_with(
"false"))
3254 else if (Name.starts_with(
"true"))
3261 }
else if (Name.starts_with(
"xop.vpcmov")) {
3263 Value *NotSel = Builder.CreateNot(Sel);
3266 Rep = Builder.CreateOr(Sel0, Sel1);
3267 }
else if (Name.starts_with(
"xop.vprot") || Name.starts_with(
"avx512.prol") ||
3268 Name.starts_with(
"avx512.mask.prol")) {
3270 }
else if (Name.starts_with(
"avx512.pror") ||
3271 Name.starts_with(
"avx512.mask.pror")) {
3273 }
else if (Name.starts_with(
"avx512.vpshld.") ||
3274 Name.starts_with(
"avx512.mask.vpshld") ||
3275 Name.starts_with(
"avx512.maskz.vpshld")) {
3276 bool ZeroMask = Name[11] ==
'z';
3278 }
else if (Name.starts_with(
"avx512.vpshrd.") ||
3279 Name.starts_with(
"avx512.mask.vpshrd") ||
3280 Name.starts_with(
"avx512.maskz.vpshrd")) {
3281 bool ZeroMask = Name[11] ==
'z';
3283 }
else if (Name ==
"sse42.crc32.64.8") {
3286 Rep = Builder.CreateIntrinsic(Intrinsic::x86_sse42_crc32_32_8,
3288 Rep = Builder.CreateZExt(Rep, CI->
getType(),
"");
3289 }
else if (Name.starts_with(
"avx.vbroadcast.s") ||
3290 Name.starts_with(
"avx512.vbroadcast.s")) {
3293 Type *EltTy = VecTy->getElementType();
3294 unsigned EltNum = VecTy->getNumElements();
3298 for (
unsigned I = 0;
I < EltNum; ++
I)
3299 Rep = Builder.CreateInsertElement(Rep, Load, ConstantInt::get(I32Ty,
I));
3300 }
else if (Name.starts_with(
"sse41.pmovsx") ||
3301 Name.starts_with(
"sse41.pmovzx") ||
3302 Name.starts_with(
"avx2.pmovsx") ||
3303 Name.starts_with(
"avx2.pmovzx") ||
3304 Name.starts_with(
"avx512.mask.pmovsx") ||
3305 Name.starts_with(
"avx512.mask.pmovzx")) {
3307 unsigned NumDstElts = DstTy->getNumElements();
3311 for (
unsigned i = 0; i != NumDstElts; ++i)
3316 bool DoSext = Name.contains(
"pmovsx");
3318 DoSext ? Builder.CreateSExt(SV, DstTy) : Builder.CreateZExt(SV, DstTy);
3323 }
else if (Name ==
"avx512.mask.pmov.qd.256" ||
3324 Name ==
"avx512.mask.pmov.qd.512" ||
3325 Name ==
"avx512.mask.pmov.wb.256" ||
3326 Name ==
"avx512.mask.pmov.wb.512") {
3331 }
else if (Name.starts_with(
"avx.vbroadcastf128") ||
3332 Name ==
"avx2.vbroadcasti128") {
3338 if (NumSrcElts == 2)
3339 Rep = Builder.CreateShuffleVector(Load,
ArrayRef<int>{0, 1, 0, 1});
3341 Rep = Builder.CreateShuffleVector(Load,
3343 }
else if (Name.starts_with(
"avx512.mask.shuf.i") ||
3344 Name.starts_with(
"avx512.mask.shuf.f")) {
3349 unsigned ControlBitsMask = NumLanes - 1;
3350 unsigned NumControlBits = NumLanes / 2;
3353 for (
unsigned l = 0; l != NumLanes; ++l) {
3354 unsigned LaneMask = (Imm >> (l * NumControlBits)) & ControlBitsMask;
3356 if (l >= NumLanes / 2)
3357 LaneMask += NumLanes;
3358 for (
unsigned i = 0; i != NumElementsInLane; ++i)
3359 ShuffleMask.push_back(LaneMask * NumElementsInLane + i);
3365 }
else if (Name.starts_with(
"avx512.mask.broadcastf") ||
3366 Name.starts_with(
"avx512.mask.broadcasti")) {
3369 unsigned NumDstElts =
3373 for (
unsigned i = 0; i != NumDstElts; ++i)
3374 ShuffleMask[i] = i % NumSrcElts;
3380 }
else if (Name.starts_with(
"avx2.pbroadcast") ||
3381 Name.starts_with(
"avx2.vbroadcast") ||
3382 Name.starts_with(
"avx512.pbroadcast") ||
3383 Name.starts_with(
"avx512.mask.broadcast.s")) {
3390 Rep = Builder.CreateShuffleVector(
Op, M);
3395 }
else if (Name.starts_with(
"sse2.padds.") ||
3396 Name.starts_with(
"avx2.padds.") ||
3397 Name.starts_with(
"avx512.padds.") ||
3398 Name.starts_with(
"avx512.mask.padds.")) {
3400 }
else if (Name.starts_with(
"sse2.psubs.") ||
3401 Name.starts_with(
"avx2.psubs.") ||
3402 Name.starts_with(
"avx512.psubs.") ||
3403 Name.starts_with(
"avx512.mask.psubs.")) {
3405 }
else if (Name.starts_with(
"sse2.paddus.") ||
3406 Name.starts_with(
"avx2.paddus.") ||
3407 Name.starts_with(
"avx512.mask.paddus.")) {
3409 }
else if (Name.starts_with(
"sse2.psubus.") ||
3410 Name.starts_with(
"avx2.psubus.") ||
3411 Name.starts_with(
"avx512.mask.psubus.")) {
3413 }
else if (Name.starts_with(
"avx512.mask.palignr.")) {
3418 }
else if (Name.starts_with(
"avx512.mask.valign.")) {
3422 }
else if (Name ==
"sse2.psll.dq" || Name ==
"avx2.psll.dq") {
3427 }
else if (Name ==
"sse2.psrl.dq" || Name ==
"avx2.psrl.dq") {
3432 }
else if (Name ==
"sse2.psll.dq.bs" || Name ==
"avx2.psll.dq.bs" ||
3433 Name ==
"avx512.psll.dq.512") {
3437 }
else if (Name ==
"sse2.psrl.dq.bs" || Name ==
"avx2.psrl.dq.bs" ||
3438 Name ==
"avx512.psrl.dq.512") {
3442 }
else if (Name ==
"sse41.pblendw" || Name.starts_with(
"sse41.blendp") ||
3443 Name.starts_with(
"avx.blend.p") || Name ==
"avx2.pblendw" ||
3444 Name.starts_with(
"avx2.pblendd.")) {
3449 unsigned NumElts = VecTy->getNumElements();
3452 for (
unsigned i = 0; i != NumElts; ++i)
3453 Idxs[i] = ((Imm >> (i % 8)) & 1) ? i + NumElts : i;
3455 Rep = Builder.CreateShuffleVector(Op0, Op1, Idxs);
3456 }
else if (Name.starts_with(
"avx.vinsertf128.") ||
3457 Name ==
"avx2.vinserti128" ||
3458 Name.starts_with(
"avx512.mask.insert")) {
3462 unsigned DstNumElts =
3464 unsigned SrcNumElts =
3466 unsigned Scale = DstNumElts / SrcNumElts;
3473 for (
unsigned i = 0; i != SrcNumElts; ++i)
3475 for (
unsigned i = SrcNumElts; i != DstNumElts; ++i)
3476 Idxs[i] = SrcNumElts;
3477 Rep = Builder.CreateShuffleVector(Op1, Idxs);
3491 for (
unsigned i = 0; i != DstNumElts; ++i)
3494 for (
unsigned i = 0; i != SrcNumElts; ++i)
3495 Idxs[i + Imm * SrcNumElts] = i + DstNumElts;
3496 Rep = Builder.CreateShuffleVector(Op0, Rep, Idxs);
3502 }
else if (Name.starts_with(
"avx.vextractf128.") ||
3503 Name ==
"avx2.vextracti128" ||
3504 Name.starts_with(
"avx512.mask.vextract")) {
3507 unsigned DstNumElts =
3509 unsigned SrcNumElts =
3511 unsigned Scale = SrcNumElts / DstNumElts;
3518 for (
unsigned i = 0; i != DstNumElts; ++i) {
3519 Idxs[i] = i + (Imm * DstNumElts);
3521 Rep = Builder.CreateShuffleVector(Op0, Op0, Idxs);
3527 }
else if (Name.starts_with(
"avx512.mask.perm.df.") ||
3528 Name.starts_with(
"avx512.mask.perm.di.")) {
3532 unsigned NumElts = VecTy->getNumElements();
3535 for (
unsigned i = 0; i != NumElts; ++i)
3536 Idxs[i] = (i & ~0x3) + ((Imm >> (2 * (i & 0x3))) & 3);
3538 Rep = Builder.CreateShuffleVector(Op0, Op0, Idxs);
3543 }
else if (Name.starts_with(
"avx.vperm2f128.") || Name ==
"avx2.vperm2i128") {
3555 unsigned HalfSize = NumElts / 2;
3567 unsigned StartIndex = (Imm & 0x01) ? HalfSize : 0;
3568 for (
unsigned i = 0; i < HalfSize; ++i)
3569 ShuffleMask[i] = StartIndex + i;
3572 StartIndex = (Imm & 0x10) ? HalfSize : 0;
3573 for (
unsigned i = 0; i < HalfSize; ++i)
3574 ShuffleMask[i + HalfSize] = NumElts + StartIndex + i;
3576 Rep = Builder.CreateShuffleVector(V0, V1, ShuffleMask);
3578 }
else if (Name.starts_with(
"avx.vpermil.") || Name ==
"sse2.pshuf.d" ||
3579 Name.starts_with(
"avx512.mask.vpermil.p") ||
3580 Name.starts_with(
"avx512.mask.pshuf.d.")) {
3584 unsigned NumElts = VecTy->getNumElements();
3586 unsigned IdxSize = 64 / VecTy->getScalarSizeInBits();
3587 unsigned IdxMask = ((1 << IdxSize) - 1);
3593 for (
unsigned i = 0; i != NumElts; ++i)
3594 Idxs[i] = ((Imm >> ((i * IdxSize) % 8)) & IdxMask) | (i & ~IdxMask);
3596 Rep = Builder.CreateShuffleVector(Op0, Op0, Idxs);
3601 }
else if (Name ==
"sse2.pshufl.w" ||
3602 Name.starts_with(
"avx512.mask.pshufl.w.")) {
3608 for (
unsigned l = 0; l != NumElts; l += 8) {
3609 for (
unsigned i = 0; i != 4; ++i)
3610 Idxs[i + l] = ((Imm >> (2 * i)) & 0x3) + l;
3611 for (
unsigned i = 4; i != 8; ++i)
3612 Idxs[i + l] = i + l;
3615 Rep = Builder.CreateShuffleVector(Op0, Op0, Idxs);
3620 }
else if (Name ==
"sse2.pshufh.w" ||
3621 Name.starts_with(
"avx512.mask.pshufh.w.")) {
3627 for (
unsigned l = 0; l != NumElts; l += 8) {
3628 for (
unsigned i = 0; i != 4; ++i)
3629 Idxs[i + l] = i + l;
3630 for (
unsigned i = 0; i != 4; ++i)
3631 Idxs[i + l + 4] = ((Imm >> (2 * i)) & 0x3) + 4 + l;
3634 Rep = Builder.CreateShuffleVector(Op0, Op0, Idxs);
3639 }
else if (Name.starts_with(
"avx512.mask.shuf.p")) {
3646 unsigned HalfLaneElts = NumLaneElts / 2;
3649 for (
unsigned i = 0; i != NumElts; ++i) {
3651 Idxs[i] = i - (i % NumLaneElts);
3653 if ((i % NumLaneElts) >= HalfLaneElts)
3657 Idxs[i] += (Imm >> ((i * HalfLaneElts) % 8)) & ((1 << HalfLaneElts) - 1);
3660 Rep = Builder.CreateShuffleVector(Op0, Op1, Idxs);
3664 }
else if (Name.starts_with(
"avx512.mask.movddup") ||
3665 Name.starts_with(
"avx512.mask.movshdup") ||
3666 Name.starts_with(
"avx512.mask.movsldup")) {
3672 if (Name.starts_with(
"avx512.mask.movshdup."))
3676 for (
unsigned l = 0; l != NumElts; l += NumLaneElts)
3677 for (
unsigned i = 0; i != NumLaneElts; i += 2) {
3678 Idxs[i + l + 0] = i + l +
Offset;
3679 Idxs[i + l + 1] = i + l +
Offset;
3682 Rep = Builder.CreateShuffleVector(Op0, Op0, Idxs);
3686 }
else if (Name.starts_with(
"avx512.mask.punpckl") ||
3687 Name.starts_with(
"avx512.mask.unpckl.")) {
3694 for (
int l = 0; l != NumElts; l += NumLaneElts)
3695 for (
int i = 0; i != NumLaneElts; ++i)
3696 Idxs[i + l] = l + (i / 2) + NumElts * (i % 2);
3698 Rep = Builder.CreateShuffleVector(Op0, Op1, Idxs);
3702 }
else if (Name.starts_with(
"avx512.mask.punpckh") ||
3703 Name.starts_with(
"avx512.mask.unpckh.")) {
3710 for (
int l = 0; l != NumElts; l += NumLaneElts)
3711 for (
int i = 0; i != NumLaneElts; ++i)
3712 Idxs[i + l] = (NumLaneElts / 2) + l + (i / 2) + NumElts * (i % 2);
3714 Rep = Builder.CreateShuffleVector(Op0, Op1, Idxs);
3718 }
else if (Name.starts_with(
"avx512.mask.and.") ||
3719 Name.starts_with(
"avx512.mask.pand.")) {
3722 Rep = Builder.CreateAnd(Builder.CreateBitCast(CI->
getArgOperand(0), ITy),
3724 Rep = Builder.CreateBitCast(Rep, FTy);
3727 }
else if (Name.starts_with(
"avx512.mask.andn.") ||
3728 Name.starts_with(
"avx512.mask.pandn.")) {
3731 Rep = Builder.CreateNot(Builder.CreateBitCast(CI->
getArgOperand(0), ITy));
3732 Rep = Builder.CreateAnd(Rep,
3734 Rep = Builder.CreateBitCast(Rep, FTy);
3737 }
else if (Name.starts_with(
"avx512.mask.or.") ||
3738 Name.starts_with(
"avx512.mask.por.")) {
3741 Rep = Builder.CreateOr(Builder.CreateBitCast(CI->
getArgOperand(0), ITy),
3743 Rep = Builder.CreateBitCast(Rep, FTy);
3746 }
else if (Name.starts_with(
"avx512.mask.xor.") ||
3747 Name.starts_with(
"avx512.mask.pxor.")) {
3750 Rep = Builder.CreateXor(Builder.CreateBitCast(CI->
getArgOperand(0), ITy),
3752 Rep = Builder.CreateBitCast(Rep, FTy);
3755 }
else if (Name.starts_with(
"avx512.mask.padd.")) {
3759 }
else if (Name.starts_with(
"avx512.mask.psub.")) {
3763 }
else if (Name.starts_with(
"avx512.mask.pmull.")) {
3767 }
else if (Name.starts_with(
"avx512.mask.add.p")) {
3768 if (Name.ends_with(
".512")) {
3770 if (Name[17] ==
's')
3771 IID = Intrinsic::x86_avx512_add_ps_512;
3773 IID = Intrinsic::x86_avx512_add_pd_512;
3775 Rep = Builder.CreateIntrinsic(
3783 }
else if (Name.starts_with(
"avx512.mask.div.p")) {
3784 if (Name.ends_with(
".512")) {
3786 if (Name[17] ==
's')
3787 IID = Intrinsic::x86_avx512_div_ps_512;
3789 IID = Intrinsic::x86_avx512_div_pd_512;
3791 Rep = Builder.CreateIntrinsic(
3799 }
else if (Name.starts_with(
"avx512.mask.mul.p")) {
3800 if (Name.ends_with(
".512")) {
3802 if (Name[17] ==
's')
3803 IID = Intrinsic::x86_avx512_mul_ps_512;
3805 IID = Intrinsic::x86_avx512_mul_pd_512;
3807 Rep = Builder.CreateIntrinsic(
3815 }
else if (Name.starts_with(
"avx512.mask.sub.p")) {
3816 if (Name.ends_with(
".512")) {
3818 if (Name[17] ==
's')
3819 IID = Intrinsic::x86_avx512_sub_ps_512;
3821 IID = Intrinsic::x86_avx512_sub_pd_512;
3823 Rep = Builder.CreateIntrinsic(
3831 }
else if ((Name.starts_with(
"avx512.mask.max.p") ||
3832 Name.starts_with(
"avx512.mask.min.p")) &&
3833 Name.drop_front(18) ==
".512") {
3834 bool IsDouble = Name[17] ==
'd';
3835 bool IsMin = Name[13] ==
'i';
3837 {Intrinsic::x86_avx512_max_ps_512, Intrinsic::x86_avx512_max_pd_512},
3838 {Intrinsic::x86_avx512_min_ps_512, Intrinsic::x86_avx512_min_pd_512}};
3841 Rep = Builder.CreateIntrinsic(
3846 }
else if (Name.starts_with(
"avx512.mask.lzcnt.")) {
3848 Builder.CreateIntrinsic(Intrinsic::ctlz, CI->
getType(),
3849 {CI->getArgOperand(0), Builder.getInt1(false)});
3852 }
else if (Name.starts_with(
"avx512.mask.psll")) {
3853 bool IsImmediate = Name[16] ==
'i' || (Name.size() > 18 && Name[18] ==
'i');
3854 bool IsVariable = Name[16] ==
'v';
3855 char Size = Name[16] ==
'.' ? Name[17]
3856 : Name[17] ==
'.' ? Name[18]
3857 : Name[18] ==
'.' ? Name[19]
3861 if (IsVariable && Name[17] !=
'.') {
3862 if (
Size ==
'd' && Name[17] ==
'2')
3863 IID = Intrinsic::x86_avx2_psllv_q;
3864 else if (
Size ==
'd' && Name[17] ==
'4')
3865 IID = Intrinsic::x86_avx2_psllv_q_256;
3866 else if (
Size ==
's' && Name[17] ==
'4')
3867 IID = Intrinsic::x86_avx2_psllv_d;
3868 else if (
Size ==
's' && Name[17] ==
'8')
3869 IID = Intrinsic::x86_avx2_psllv_d_256;
3870 else if (
Size ==
'h' && Name[17] ==
'8')
3871 IID = Intrinsic::x86_avx512_psllv_w_128;
3872 else if (
Size ==
'h' && Name[17] ==
'1')
3873 IID = Intrinsic::x86_avx512_psllv_w_256;
3874 else if (Name[17] ==
'3' && Name[18] ==
'2')
3875 IID = Intrinsic::x86_avx512_psllv_w_512;
3878 }
else if (Name.ends_with(
".128")) {
3880 IID = IsImmediate ? Intrinsic::x86_sse2_pslli_d
3881 : Intrinsic::x86_sse2_psll_d;
3882 else if (
Size ==
'q')
3883 IID = IsImmediate ? Intrinsic::x86_sse2_pslli_q
3884 : Intrinsic::x86_sse2_psll_q;
3885 else if (
Size ==
'w')
3886 IID = IsImmediate ? Intrinsic::x86_sse2_pslli_w
3887 : Intrinsic::x86_sse2_psll_w;
3890 }
else if (Name.ends_with(
".256")) {
3892 IID = IsImmediate ? Intrinsic::x86_avx2_pslli_d
3893 : Intrinsic::x86_avx2_psll_d;
3894 else if (
Size ==
'q')
3895 IID = IsImmediate ? Intrinsic::x86_avx2_pslli_q
3896 : Intrinsic::x86_avx2_psll_q;
3897 else if (
Size ==
'w')
3898 IID = IsImmediate ? Intrinsic::x86_avx2_pslli_w
3899 : Intrinsic::x86_avx2_psll_w;
3904 IID = IsImmediate ? Intrinsic::x86_avx512_pslli_d_512
3905 : IsVariable ? Intrinsic::x86_avx512_psllv_d_512
3906 : Intrinsic::x86_avx512_psll_d_512;
3907 else if (
Size ==
'q')
3908 IID = IsImmediate ? Intrinsic::x86_avx512_pslli_q_512
3909 : IsVariable ? Intrinsic::x86_avx512_psllv_q_512
3910 : Intrinsic::x86_avx512_psll_q_512;
3911 else if (
Size ==
'w')
3912 IID = IsImmediate ? Intrinsic::x86_avx512_pslli_w_512
3913 : Intrinsic::x86_avx512_psll_w_512;
3919 }
else if (Name.starts_with(
"avx512.mask.psrl")) {
3920 bool IsImmediate = Name[16] ==
'i' || (Name.size() > 18 && Name[18] ==
'i');
3921 bool IsVariable = Name[16] ==
'v';
3922 char Size = Name[16] ==
'.' ? Name[17]
3923 : Name[17] ==
'.' ? Name[18]
3924 : Name[18] ==
'.' ? Name[19]
3928 if (IsVariable && Name[17] !=
'.') {
3929 if (
Size ==
'd' && Name[17] ==
'2')
3930 IID = Intrinsic::x86_avx2_psrlv_q;
3931 else if (
Size ==
'd' && Name[17] ==
'4')
3932 IID = Intrinsic::x86_avx2_psrlv_q_256;
3933 else if (
Size ==
's' && Name[17] ==
'4')
3934 IID = Intrinsic::x86_avx2_psrlv_d;
3935 else if (
Size ==
's' && Name[17] ==
'8')
3936 IID = Intrinsic::x86_avx2_psrlv_d_256;
3937 else if (
Size ==
'h' && Name[17] ==
'8')
3938 IID = Intrinsic::x86_avx512_psrlv_w_128;
3939 else if (
Size ==
'h' && Name[17] ==
'1')
3940 IID = Intrinsic::x86_avx512_psrlv_w_256;
3941 else if (Name[17] ==
'3' && Name[18] ==
'2')
3942 IID = Intrinsic::x86_avx512_psrlv_w_512;
3945 }
else if (Name.ends_with(
".128")) {
3947 IID = IsImmediate ? Intrinsic::x86_sse2_psrli_d
3948 : Intrinsic::x86_sse2_psrl_d;
3949 else if (
Size ==
'q')
3950 IID = IsImmediate ? Intrinsic::x86_sse2_psrli_q
3951 : Intrinsic::x86_sse2_psrl_q;
3952 else if (
Size ==
'w')
3953 IID = IsImmediate ? Intrinsic::x86_sse2_psrli_w
3954 : Intrinsic::x86_sse2_psrl_w;
3957 }
else if (Name.ends_with(
".256")) {
3959 IID = IsImmediate ? Intrinsic::x86_avx2_psrli_d
3960 : Intrinsic::x86_avx2_psrl_d;
3961 else if (
Size ==
'q')
3962 IID = IsImmediate ? Intrinsic::x86_avx2_psrli_q
3963 : Intrinsic::x86_avx2_psrl_q;
3964 else if (
Size ==
'w')
3965 IID = IsImmediate ? Intrinsic::x86_avx2_psrli_w
3966 : Intrinsic::x86_avx2_psrl_w;
3971 IID = IsImmediate ? Intrinsic::x86_avx512_psrli_d_512
3972 : IsVariable ? Intrinsic::x86_avx512_psrlv_d_512
3973 : Intrinsic::x86_avx512_psrl_d_512;
3974 else if (
Size ==
'q')
3975 IID = IsImmediate ? Intrinsic::x86_avx512_psrli_q_512
3976 : IsVariable ? Intrinsic::x86_avx512_psrlv_q_512
3977 : Intrinsic::x86_avx512_psrl_q_512;
3978 else if (
Size ==
'w')
3979 IID = IsImmediate ? Intrinsic::x86_avx512_psrli_w_512
3980 : Intrinsic::x86_avx512_psrl_w_512;
3986 }
else if (Name.starts_with(
"avx512.mask.psra")) {
3987 bool IsImmediate = Name[16] ==
'i' || (Name.size() > 18 && Name[18] ==
'i');
3988 bool IsVariable = Name[16] ==
'v';
3989 char Size = Name[16] ==
'.' ? Name[17]
3990 : Name[17] ==
'.' ? Name[18]
3991 : Name[18] ==
'.' ? Name[19]
3995 if (IsVariable && Name[17] !=
'.') {
3996 if (
Size ==
's' && Name[17] ==
'4')
3997 IID = Intrinsic::x86_avx2_psrav_d;
3998 else if (
Size ==
's' && Name[17] ==
'8')
3999 IID = Intrinsic::x86_avx2_psrav_d_256;
4000 else if (
Size ==
'h' && Name[17] ==
'8')
4001 IID = Intrinsic::x86_avx512_psrav_w_128;
4002 else if (
Size ==
'h' && Name[17] ==
'1')
4003 IID = Intrinsic::x86_avx512_psrav_w_256;
4004 else if (Name[17] ==
'3' && Name[18] ==
'2')
4005 IID = Intrinsic::x86_avx512_psrav_w_512;
4008 }
else if (Name.ends_with(
".128")) {
4010 IID = IsImmediate ? Intrinsic::x86_sse2_psrai_d
4011 : Intrinsic::x86_sse2_psra_d;
4012 else if (
Size ==
'q')
4013 IID = IsImmediate ? Intrinsic::x86_avx512_psrai_q_128
4014 : IsVariable ? Intrinsic::x86_avx512_psrav_q_128
4015 : Intrinsic::x86_avx512_psra_q_128;
4016 else if (
Size ==
'w')
4017 IID = IsImmediate ? Intrinsic::x86_sse2_psrai_w
4018 : Intrinsic::x86_sse2_psra_w;
4021 }
else if (Name.ends_with(
".256")) {
4023 IID = IsImmediate ? Intrinsic::x86_avx2_psrai_d
4024 : Intrinsic::x86_avx2_psra_d;
4025 else if (
Size ==
'q')
4026 IID = IsImmediate ? Intrinsic::x86_avx512_psrai_q_256
4027 : IsVariable ? Intrinsic::x86_avx512_psrav_q_256
4028 : Intrinsic::x86_avx512_psra_q_256;
4029 else if (
Size ==
'w')
4030 IID = IsImmediate ? Intrinsic::x86_avx2_psrai_w
4031 : Intrinsic::x86_avx2_psra_w;
4036 IID = IsImmediate ? Intrinsic::x86_avx512_psrai_d_512
4037 : IsVariable ? Intrinsic::x86_avx512_psrav_d_512
4038 : Intrinsic::x86_avx512_psra_d_512;
4039 else if (
Size ==
'q')
4040 IID = IsImmediate ? Intrinsic::x86_avx512_psrai_q_512
4041 : IsVariable ? Intrinsic::x86_avx512_psrav_q_512
4042 : Intrinsic::x86_avx512_psra_q_512;
4043 else if (
Size ==
'w')
4044 IID = IsImmediate ? Intrinsic::x86_avx512_psrai_w_512
4045 : Intrinsic::x86_avx512_psra_w_512;
4051 }
else if (Name.starts_with(
"avx512.mask.move.s")) {
4053 }
else if (Name.starts_with(
"avx512.cvtmask2")) {
4055 }
else if (Name.ends_with(
".movntdqa")) {
4059 LoadInst *LI = Builder.CreateAlignedLoad(
4064 }
else if (Name.starts_with(
"fma.vfmadd.") ||
4065 Name.starts_with(
"fma.vfmsub.") ||
4066 Name.starts_with(
"fma.vfnmadd.") ||
4067 Name.starts_with(
"fma.vfnmsub.")) {
4068 bool NegMul = Name[6] ==
'n';
4069 bool NegAcc = NegMul ? Name[8] ==
's' : Name[7] ==
's';
4070 bool IsScalar = NegMul ? Name[12] ==
's' : Name[11] ==
's';
4081 if (NegMul && !IsScalar)
4082 Ops[0] = Builder.CreateFNeg(
Ops[0]);
4083 if (NegMul && IsScalar)
4084 Ops[1] = Builder.CreateFNeg(
Ops[1]);
4086 Ops[2] = Builder.CreateFNeg(
Ops[2]);
4088 Rep = Builder.CreateIntrinsic(Intrinsic::fma,
Ops[0]->
getType(),
Ops);
4092 }
else if (Name.starts_with(
"fma4.vfmadd.s")) {
4100 Rep = Builder.CreateIntrinsic(Intrinsic::fma,
Ops[0]->
getType(),
Ops);
4104 }
else if (Name.starts_with(
"avx512.mask.vfmadd.s") ||
4105 Name.starts_with(
"avx512.maskz.vfmadd.s") ||
4106 Name.starts_with(
"avx512.mask3.vfmadd.s") ||
4107 Name.starts_with(
"avx512.mask3.vfmsub.s") ||
4108 Name.starts_with(
"avx512.mask3.vfnmsub.s")) {
4109 bool IsMask3 = Name[11] ==
'3';
4110 bool IsMaskZ = Name[11] ==
'z';
4112 Name = Name.drop_front(IsMask3 || IsMaskZ ? 13 : 12);
4113 bool NegMul = Name[2] ==
'n';
4114 bool NegAcc = NegMul ? Name[4] ==
's' : Name[3] ==
's';
4120 if (NegMul && (IsMask3 || IsMaskZ))
4121 A = Builder.CreateFNeg(
A);
4122 if (NegMul && !(IsMask3 || IsMaskZ))
4123 B = Builder.CreateFNeg(
B);
4125 C = Builder.CreateFNeg(
C);
4127 A = Builder.CreateExtractElement(
A, (
uint64_t)0);
4128 B = Builder.CreateExtractElement(
B, (
uint64_t)0);
4129 C = Builder.CreateExtractElement(
C, (
uint64_t)0);
4136 if (Name.back() ==
'd')
4137 IID = Intrinsic::x86_avx512_vfmadd_f64;
4139 IID = Intrinsic::x86_avx512_vfmadd_f32;
4140 Rep = Builder.CreateIntrinsic(IID,
Ops);
4142 Rep = Builder.CreateFMA(
A,
B,
C);
4151 if (NegAcc && IsMask3)
4156 Rep = Builder.CreateInsertElement(CI->
getArgOperand(IsMask3 ? 2 : 0), Rep,
4158 }
else if (Name.starts_with(
"avx512.mask.vfmadd.p") ||
4159 Name.starts_with(
"avx512.mask.vfnmadd.p") ||
4160 Name.starts_with(
"avx512.mask.vfnmsub.p") ||
4161 Name.starts_with(
"avx512.mask3.vfmadd.p") ||
4162 Name.starts_with(
"avx512.mask3.vfmsub.p") ||
4163 Name.starts_with(
"avx512.mask3.vfnmsub.p") ||
4164 Name.starts_with(
"avx512.maskz.vfmadd.p")) {
4165 bool IsMask3 = Name[11] ==
'3';
4166 bool IsMaskZ = Name[11] ==
'z';
4168 Name = Name.drop_front(IsMask3 || IsMaskZ ? 13 : 12);
4169 bool NegMul = Name[2] ==
'n';
4170 bool NegAcc = NegMul ? Name[4] ==
's' : Name[3] ==
's';
4176 if (NegMul && (IsMask3 || IsMaskZ))
4177 A = Builder.CreateFNeg(
A);
4178 if (NegMul && !(IsMask3 || IsMaskZ))
4179 B = Builder.CreateFNeg(
B);
4181 C = Builder.CreateFNeg(
C);
4188 if (Name[Name.size() - 5] ==
's')
4189 IID = Intrinsic::x86_avx512_vfmadd_ps_512;
4191 IID = Intrinsic::x86_avx512_vfmadd_pd_512;
4195 Rep = Builder.CreateFMA(
A,
B,
C);
4203 }
else if (Name.starts_with(
"fma.vfmsubadd.p")) {
4207 if (VecWidth == 128 && EltWidth == 32)
4208 IID = Intrinsic::x86_fma_vfmaddsub_ps;
4209 else if (VecWidth == 256 && EltWidth == 32)
4210 IID = Intrinsic::x86_fma_vfmaddsub_ps_256;
4211 else if (VecWidth == 128 && EltWidth == 64)
4212 IID = Intrinsic::x86_fma_vfmaddsub_pd;
4213 else if (VecWidth == 256 && EltWidth == 64)
4214 IID = Intrinsic::x86_fma_vfmaddsub_pd_256;
4220 Ops[2] = Builder.CreateFNeg(
Ops[2]);
4221 Rep = Builder.CreateIntrinsic(IID,
Ops);
4222 }
else if (Name.starts_with(
"avx512.mask.vfmaddsub.p") ||
4223 Name.starts_with(
"avx512.mask3.vfmaddsub.p") ||
4224 Name.starts_with(
"avx512.maskz.vfmaddsub.p") ||
4225 Name.starts_with(
"avx512.mask3.vfmsubadd.p")) {
4226 bool IsMask3 = Name[11] ==
'3';
4227 bool IsMaskZ = Name[11] ==
'z';
4229 Name = Name.drop_front(IsMask3 || IsMaskZ ? 13 : 12);
4230 bool IsSubAdd = Name[3] ==
's';
4234 if (Name[Name.size() - 5] ==
's')
4235 IID = Intrinsic::x86_avx512_vfmaddsub_ps_512;
4237 IID = Intrinsic::x86_avx512_vfmaddsub_pd_512;
4242 Ops[2] = Builder.CreateFNeg(
Ops[2]);
4244 Rep = Builder.CreateIntrinsic(IID,
Ops);
4253 Value *Odd = Builder.CreateCall(FMA,
Ops);
4254 Ops[2] = Builder.CreateFNeg(
Ops[2]);
4255 Value *Even = Builder.CreateCall(FMA,
Ops);
4261 for (
int i = 0; i != NumElts; ++i)
4262 Idxs[i] = i + (i % 2) * NumElts;
4264 Rep = Builder.CreateShuffleVector(Even, Odd, Idxs);
4272 }
else if (Name.starts_with(
"avx512.mask.pternlog.") ||
4273 Name.starts_with(
"avx512.maskz.pternlog.")) {
4274 bool ZeroMask = Name[11] ==
'z';
4278 if (VecWidth == 128 && EltWidth == 32)
4279 IID = Intrinsic::x86_avx512_pternlog_d_128;
4280 else if (VecWidth == 256 && EltWidth == 32)
4281 IID = Intrinsic::x86_avx512_pternlog_d_256;
4282 else if (VecWidth == 512 && EltWidth == 32)
4283 IID = Intrinsic::x86_avx512_pternlog_d_512;
4284 else if (VecWidth == 128 && EltWidth == 64)
4285 IID = Intrinsic::x86_avx512_pternlog_q_128;
4286 else if (VecWidth == 256 && EltWidth == 64)
4287 IID = Intrinsic::x86_avx512_pternlog_q_256;
4288 else if (VecWidth == 512 && EltWidth == 64)
4289 IID = Intrinsic::x86_avx512_pternlog_q_512;
4295 Rep = Builder.CreateIntrinsic(IID, Args);
4299 }
else if (Name.starts_with(
"avx512.mask.vpmadd52") ||
4300 Name.starts_with(
"avx512.maskz.vpmadd52")) {
4301 bool ZeroMask = Name[11] ==
'z';
4302 bool High = Name[20] ==
'h' || Name[21] ==
'h';
4305 if (VecWidth == 128 && !
High)
4306 IID = Intrinsic::x86_avx512_vpmadd52l_uq_128;
4307 else if (VecWidth == 256 && !
High)
4308 IID = Intrinsic::x86_avx512_vpmadd52l_uq_256;
4309 else if (VecWidth == 512 && !
High)
4310 IID = Intrinsic::x86_avx512_vpmadd52l_uq_512;
4311 else if (VecWidth == 128 &&
High)
4312 IID = Intrinsic::x86_avx512_vpmadd52h_uq_128;
4313 else if (VecWidth == 256 &&
High)
4314 IID = Intrinsic::x86_avx512_vpmadd52h_uq_256;
4315 else if (VecWidth == 512 &&
High)
4316 IID = Intrinsic::x86_avx512_vpmadd52h_uq_512;
4322 Rep = Builder.CreateIntrinsic(IID, Args);
4326 }
else if (Name.starts_with(
"avx512.mask.vpermi2var.") ||
4327 Name.starts_with(
"avx512.mask.vpermt2var.") ||
4328 Name.starts_with(
"avx512.maskz.vpermt2var.")) {
4329 bool ZeroMask = Name[11] ==
'z';
4330 bool IndexForm = Name[17] ==
'i';
4332 }
else if (Name.starts_with(
"avx512.mask.vpdpbusd.") ||
4333 Name.starts_with(
"avx512.maskz.vpdpbusd.") ||
4334 Name.starts_with(
"avx512.mask.vpdpbusds.") ||
4335 Name.starts_with(
"avx512.maskz.vpdpbusds.")) {
4336 bool ZeroMask = Name[11] ==
'z';
4337 bool IsSaturating = Name[ZeroMask ? 21 : 20] ==
's';
4340 if (VecWidth == 128 && !IsSaturating)
4341 IID = Intrinsic::x86_avx512_vpdpbusd_128;
4342 else if (VecWidth == 256 && !IsSaturating)
4343 IID = Intrinsic::x86_avx512_vpdpbusd_256;
4344 else if (VecWidth == 512 && !IsSaturating)
4345 IID = Intrinsic::x86_avx512_vpdpbusd_512;
4346 else if (VecWidth == 128 && IsSaturating)
4347 IID = Intrinsic::x86_avx512_vpdpbusds_128;
4348 else if (VecWidth == 256 && IsSaturating)
4349 IID = Intrinsic::x86_avx512_vpdpbusds_256;
4350 else if (VecWidth == 512 && IsSaturating)
4351 IID = Intrinsic::x86_avx512_vpdpbusds_512;
4361 if (Args[1]->
getType()->isVectorTy() &&
4364 ->isIntegerTy(32) &&
4365 Args[2]->
getType()->isVectorTy() &&
4368 ->isIntegerTy(32)) {
4369 Type *NewArgType =
nullptr;
4370 if (VecWidth == 128)
4372 else if (VecWidth == 256)
4374 else if (VecWidth == 512)
4379 Args[1] = Builder.CreateBitCast(Args[1], NewArgType);
4380 Args[2] = Builder.CreateBitCast(Args[2], NewArgType);
4383 Rep = Builder.CreateIntrinsic(IID, Args);
4387 }
else if (Name.starts_with(
"avx512.mask.vpdpwssd.") ||
4388 Name.starts_with(
"avx512.maskz.vpdpwssd.") ||
4389 Name.starts_with(
"avx512.mask.vpdpwssds.") ||
4390 Name.starts_with(
"avx512.maskz.vpdpwssds.")) {
4391 bool ZeroMask = Name[11] ==
'z';
4392 bool IsSaturating = Name[ZeroMask ? 21 : 20] ==
's';
4395 if (VecWidth == 128 && !IsSaturating)
4396 IID = Intrinsic::x86_avx512_vpdpwssd_128;
4397 else if (VecWidth == 256 && !IsSaturating)
4398 IID = Intrinsic::x86_avx512_vpdpwssd_256;
4399 else if (VecWidth == 512 && !IsSaturating)
4400 IID = Intrinsic::x86_avx512_vpdpwssd_512;
4401 else if (VecWidth == 128 && IsSaturating)
4402 IID = Intrinsic::x86_avx512_vpdpwssds_128;
4403 else if (VecWidth == 256 && IsSaturating)
4404 IID = Intrinsic::x86_avx512_vpdpwssds_256;
4405 else if (VecWidth == 512 && IsSaturating)
4406 IID = Intrinsic::x86_avx512_vpdpwssds_512;
4416 if (Args[1]->
getType()->isVectorTy() &&
4419 ->isIntegerTy(32) &&
4420 Args[2]->
getType()->isVectorTy() &&
4423 ->isIntegerTy(32)) {
4424 Type *NewArgType =
nullptr;
4425 if (VecWidth == 128)
4427 else if (VecWidth == 256)
4429 else if (VecWidth == 512)
4434 Args[1] = Builder.CreateBitCast(Args[1], NewArgType);
4435 Args[2] = Builder.CreateBitCast(Args[2], NewArgType);
4438 Rep = Builder.CreateIntrinsic(IID, Args);
4442 }
else if (Name ==
"addcarryx.u32" || Name ==
"addcarryx.u64" ||
4443 Name ==
"addcarry.u32" || Name ==
"addcarry.u64" ||
4444 Name ==
"subborrow.u32" || Name ==
"subborrow.u64") {
4446 if (Name[0] ==
'a' && Name.back() ==
'2')
4447 IID = Intrinsic::x86_addcarry_32;
4448 else if (Name[0] ==
'a' && Name.back() ==
'4')
4449 IID = Intrinsic::x86_addcarry_64;
4450 else if (Name[0] ==
's' && Name.back() ==
'2')
4451 IID = Intrinsic::x86_subborrow_32;
4452 else if (Name[0] ==
's' && Name.back() ==
'4')
4453 IID = Intrinsic::x86_subborrow_64;
4460 Value *NewCall = Builder.CreateIntrinsic(IID, Args);
4463 Value *
Data = Builder.CreateExtractValue(NewCall, 1);
4466 Value *CF = Builder.CreateExtractValue(NewCall, 0);
4470 }
else if (Name.starts_with(
"avx512.mask.") &&
4480 if (Name.starts_with(
"neon.bfcvt")) {
4481 if (Name.starts_with(
"neon.bfcvtn2")) {
4483 std::iota(LoMask.
begin(), LoMask.
end(), 0);
4485 std::iota(ConcatMask.
begin(), ConcatMask.
end(), 0);
4486 Value *Inactive = Builder.CreateShuffleVector(CI->
getOperand(0), LoMask);
4489 return Builder.CreateShuffleVector(Inactive, Trunc, ConcatMask);
4490 }
else if (Name.starts_with(
"neon.bfcvtn")) {
4492 std::iota(ConcatMask.
begin(), ConcatMask.
end(), 0);
4496 dbgs() <<
"Trunc: " << *Trunc <<
"\n";
4497 return Builder.CreateShuffleVector(
4500 return Builder.CreateFPTrunc(CI->
getOperand(0),
4503 }
else if (Name.starts_with(
"sve.fcvt")) {
4506 .
Case(
"sve.fcvt.bf16f32", Intrinsic::aarch64_sve_fcvt_bf16f32_v2)
4507 .
Case(
"sve.fcvtnt.bf16f32",
4508 Intrinsic::aarch64_sve_fcvtnt_bf16f32_v2)
4520 if (Args[1]->
getType() != BadPredTy)
4523 Args[1] = Builder.CreateIntrinsic(Intrinsic::aarch64_sve_convert_to_svbool,
4524 BadPredTy, Args[1]);
4525 Args[1] = Builder.CreateIntrinsic(
4526 Intrinsic::aarch64_sve_convert_from_svbool, GoodPredTy, Args[1]);
4528 return Builder.CreateIntrinsic(NewID, Args,
nullptr,
4537 if (Name ==
"mve.vctp64.old") {
4540 Value *VCTP = Builder.CreateIntrinsic(Intrinsic::arm_mve_vctp64, {},
4543 Value *C1 = Builder.CreateIntrinsic(
4544 Intrinsic::arm_mve_pred_v2i,
4546 return Builder.CreateIntrinsic(
4547 Intrinsic::arm_mve_pred_i2v,
4549 }
else if (Name ==
"mve.mull.int.predicated.v2i64.v4i32.v4i1" ||
4550 Name ==
"mve.vqdmull.predicated.v2i64.v4i32.v4i1" ||
4551 Name ==
"mve.vldr.gather.base.predicated.v2i64.v2i64.v4i1" ||
4552 Name ==
"mve.vldr.gather.base.wb.predicated.v2i64.v2i64.v4i1" ||
4554 "mve.vldr.gather.offset.predicated.v2i64.p0i64.v2i64.v4i1" ||
4555 Name ==
"mve.vldr.gather.offset.predicated.v2i64.p0.v2i64.v4i1" ||
4556 Name ==
"mve.vstr.scatter.base.predicated.v2i64.v2i64.v4i1" ||
4557 Name ==
"mve.vstr.scatter.base.wb.predicated.v2i64.v2i64.v4i1" ||
4559 "mve.vstr.scatter.offset.predicated.p0i64.v2i64.v2i64.v4i1" ||
4560 Name ==
"mve.vstr.scatter.offset.predicated.p0.v2i64.v2i64.v4i1" ||
4561 Name ==
"cde.vcx1q.predicated.v2i64.v4i1" ||
4562 Name ==
"cde.vcx1qa.predicated.v2i64.v4i1" ||
4563 Name ==
"cde.vcx2q.predicated.v2i64.v4i1" ||
4564 Name ==
"cde.vcx2qa.predicated.v2i64.v4i1" ||
4565 Name ==
"cde.vcx3q.predicated.v2i64.v4i1" ||
4566 Name ==
"cde.vcx3qa.predicated.v2i64.v4i1") {
4567 std::vector<Type *> Tys;
4571 case Intrinsic::arm_mve_mull_int_predicated:
4572 case Intrinsic::arm_mve_vqdmull_predicated:
4573 case Intrinsic::arm_mve_vldr_gather_base_predicated:
4576 case Intrinsic::arm_mve_vldr_gather_base_wb_predicated:
4577 case Intrinsic::arm_mve_vstr_scatter_base_predicated:
4578 case Intrinsic::arm_mve_vstr_scatter_base_wb_predicated:
4582 case Intrinsic::arm_mve_vldr_gather_offset_predicated:
4586 case Intrinsic::arm_mve_vstr_scatter_offset_predicated:
4590 case Intrinsic::arm_cde_vcx1q_predicated:
4591 case Intrinsic::arm_cde_vcx1qa_predicated:
4592 case Intrinsic::arm_cde_vcx2q_predicated:
4593 case Intrinsic::arm_cde_vcx2qa_predicated:
4594 case Intrinsic::arm_cde_vcx3q_predicated:
4595 case Intrinsic::arm_cde_vcx3qa_predicated:
4602 std::vector<Value *>
Ops;
4604 Type *Ty =
Op->getType();
4605 if (Ty->getScalarSizeInBits() == 1) {
4606 Value *C1 = Builder.CreateIntrinsic(
4607 Intrinsic::arm_mve_pred_v2i,
4609 Op = Builder.CreateIntrinsic(Intrinsic::arm_mve_pred_i2v, {V2I1Ty}, C1);
4614 return Builder.CreateIntrinsic(
ID, Tys,
Ops,
nullptr,
4629 auto UpgradeLegacyWMMAIUIntrinsicCall =
4634 Args.push_back(Builder.getFalse());
4638 F->getParent(),
F->getIntrinsicID(), OverloadTys);
4645 auto *NewCall =
cast<CallInst>(Builder.CreateCall(NewDecl, Args, Bundles));
4650 NewCall->copyMetadata(*CI);
4654 if (
F->getIntrinsicID() == Intrinsic::amdgcn_wmma_i32_16x16x64_iu8) {
4655 assert(CI->
arg_size() == 7 &&
"Legacy int_amdgcn_wmma_i32_16x16x64_iu8 "
4656 "intrinsic should have 7 arguments");
4659 return UpgradeLegacyWMMAIUIntrinsicCall(
F, CI, Builder, {
T1, T2});
4661 if (
F->getIntrinsicID() == Intrinsic::amdgcn_swmmac_i32_16x16x128_iu8) {
4662 assert(CI->
arg_size() == 8 &&
"Legacy int_amdgcn_swmmac_i32_16x16x128_iu8 "
4663 "intrinsic should have 8 arguments");
4668 return UpgradeLegacyWMMAIUIntrinsicCall(
F, CI, Builder, {
T1, T2, T3, T4});
4688 if (NumOperands < 3)
4701 bool IsVolatile =
false;
4705 if (NumOperands > 3)
4710 if (NumOperands > 5) {
4712 IsVolatile = !VolatileArg || !VolatileArg->
isZero();
4726 if (VT->getElementType()->isIntegerTy(16)) {
4729 Val = Builder.CreateBitCast(Val, AsBF16);
4737 Builder.CreateAtomicRMW(RMWOp, Ptr, Val, std::nullopt, Order, SSID);
4739 unsigned AddrSpace = PtrTy->getAddressSpace();
4742 RMW->
setMetadata(
"amdgpu.no.fine.grained.memory", EmptyMD);
4744 RMW->
setMetadata(
"amdgpu.ignore.denormal.mode", EmptyMD);
4749 MDNode *RangeNotPrivate =
4752 RMW->
setMetadata(LLVMContext::MD_noalias_addrspace, RangeNotPrivate);
4758 return Builder.CreateBitCast(RMW, RetTy);
4779 return MAV->getMetadata();
4786 return I->getDebugLoc().getAsMDNode();
4794 if (Name ==
"label") {
4797 }
else if (Name ==
"assign") {
4804 }
else if (Name ==
"declare") {
4809 }
else if (Name ==
"addr") {
4819 unwrapMAVOp(CI, 1), ExprNode,
nullptr,
nullptr,
nullptr,
4821 }
else if (Name ==
"value") {
4824 unsigned ExprOp = 2;
4838 assert(DR &&
"Unhandled intrinsic kind in upgrade to DbgRecord");
4846 int64_t OffsetVal =
Offset->getSExtValue();
4847 return Builder.CreateIntrinsic(OffsetVal >= 0
4848 ? Intrinsic::vector_splice_left
4849 : Intrinsic::vector_splice_right,
4851 {CI->getArgOperand(0), CI->getArgOperand(1),
4852 Builder.getInt32(std::abs(OffsetVal))});
4873 assert(Name.starts_with(
"llvm.") &&
"Intrinsic doesn't start with 'llvm.'");
4874 Name = Name.substr(5);
4876 bool IsX86 = Name.consume_front(
"x86.");
4877 bool IsNVVM = Name.consume_front(
"nvvm.");
4878 bool IsAArch64 = Name.consume_front(
"aarch64.");
4879 bool IsARM = Name.consume_front(
"arm.");
4880 bool IsAMDGCN = Name.consume_front(
"amdgcn.");
4881 bool IsDbg = Name.consume_front(
"dbg.");
4883 (Name.consume_front(
"experimental.vector.splice") ||
4884 Name.consume_front(
"vector.splice")) &&
4885 !(Name.starts_with(
".left") || Name.starts_with(
".right"));
4886 Value *Rep =
nullptr;
4888 if (!IsX86 && Name ==
"stackprotectorcheck") {
4890 }
else if (IsNVVM) {
4894 }
else if (IsAArch64) {
4898 }
else if (IsAMDGCN) {
4902 }
else if (IsOldSplice) {
4914 const auto &DefaultCase = [&]() ->
void {
4922 "Unknown function for CallBase upgrade and isn't just a name change");
4930 "Return type must have changed");
4931 assert(OldST->getNumElements() ==
4933 "Must have same number of elements");
4936 CallInst *NewCI = Builder.CreateCall(NewFn, Args);
4939 for (
unsigned Idx = 0; Idx < OldST->getNumElements(); ++Idx) {
4940 Value *Elem = Builder.CreateExtractValue(NewCI, Idx);
4941 Res = Builder.CreateInsertValue(Res, Elem, Idx);
4960 case Intrinsic::arm_neon_vst1:
4961 case Intrinsic::arm_neon_vst2:
4962 case Intrinsic::arm_neon_vst3:
4963 case Intrinsic::arm_neon_vst4:
4964 case Intrinsic::arm_neon_vst2lane:
4965 case Intrinsic::arm_neon_vst3lane:
4966 case Intrinsic::arm_neon_vst4lane: {
4968 NewCall = Builder.CreateCall(NewFn, Args);
4971 case Intrinsic::aarch64_sve_bfmlalb_lane_v2:
4972 case Intrinsic::aarch64_sve_bfmlalt_lane_v2:
4973 case Intrinsic::aarch64_sve_bfdot_lane_v2: {
4978 NewCall = Builder.CreateCall(NewFn, Args);
4981 case Intrinsic::aarch64_sve_ld3_sret:
4982 case Intrinsic::aarch64_sve_ld4_sret:
4983 case Intrinsic::aarch64_sve_ld2_sret: {
4985 Name = Name.substr(5);
4992 unsigned MinElts = RetTy->getMinNumElements() /
N;
4994 Value *NewLdCall = Builder.CreateCall(NewFn, Args);
4996 for (
unsigned I = 0;
I <
N;
I++) {
4997 Value *SRet = Builder.CreateExtractValue(NewLdCall,
I);
4998 Ret = Builder.CreateInsertVector(RetTy, Ret, SRet,
I * MinElts);
5004 case Intrinsic::coro_end: {
5007 NewCall = Builder.CreateCall(NewFn, Args);
5011 case Intrinsic::vector_extract: {
5013 Name = Name.substr(5);
5014 if (!Name.starts_with(
"aarch64.sve.tuple.get")) {
5019 unsigned MinElts = RetTy->getMinNumElements();
5022 NewCall = Builder.CreateCall(NewFn, {CI->
getArgOperand(0), NewIdx});
5026 case Intrinsic::vector_insert: {
5028 Name = Name.substr(5);
5029 if (!Name.starts_with(
"aarch64.sve.tuple")) {
5033 if (Name.starts_with(
"aarch64.sve.tuple.set")) {
5038 NewCall = Builder.CreateCall(
5042 if (Name.starts_with(
"aarch64.sve.tuple.create")) {
5048 assert(
N > 1 &&
"Create is expected to be between 2-4");
5051 unsigned MinElts = RetTy->getMinNumElements() /
N;
5052 for (
unsigned I = 0;
I <
N;
I++) {
5054 Ret = Builder.CreateInsertVector(RetTy, Ret, V,
I * MinElts);
5061 case Intrinsic::arm_neon_bfdot:
5062 case Intrinsic::arm_neon_bfmmla:
5063 case Intrinsic::arm_neon_bfmlalb:
5064 case Intrinsic::arm_neon_bfmlalt:
5065 case Intrinsic::aarch64_neon_bfdot:
5066 case Intrinsic::aarch64_neon_bfmmla:
5067 case Intrinsic::aarch64_neon_bfmlalb:
5068 case Intrinsic::aarch64_neon_bfmlalt: {
5071 "Mismatch between function args and call args");
5072 size_t OperandWidth =
5074 assert((OperandWidth == 64 || OperandWidth == 128) &&
5075 "Unexpected operand width");
5077 auto Iter = CI->
args().begin();
5078 Args.push_back(*Iter++);
5079 Args.push_back(Builder.CreateBitCast(*Iter++, NewTy));
5080 Args.push_back(Builder.CreateBitCast(*Iter++, NewTy));
5081 NewCall = Builder.CreateCall(NewFn, Args);
5085 case Intrinsic::bitreverse:
5086 NewCall = Builder.CreateCall(NewFn, {CI->
getArgOperand(0)});
5089 case Intrinsic::ctlz:
5090 case Intrinsic::cttz: {
5097 Builder.CreateCall(NewFn, {CI->
getArgOperand(0), Builder.getFalse()});
5101 case Intrinsic::objectsize: {
5102 Value *NullIsUnknownSize =
5106 NewCall = Builder.CreateCall(
5111 case Intrinsic::ctpop:
5112 NewCall = Builder.CreateCall(NewFn, {CI->
getArgOperand(0)});
5115 case Intrinsic::convert_from_fp16:
5116 NewCall = Builder.CreateCall(NewFn, {CI->
getArgOperand(0)});
5119 case Intrinsic::dbg_value: {
5121 Name = Name.substr(5);
5123 if (Name.starts_with(
"dbg.addr")) {
5137 if (
Offset->isZeroValue()) {
5138 NewCall = Builder.CreateCall(
5147 case Intrinsic::ptr_annotation:
5155 NewCall = Builder.CreateCall(
5164 case Intrinsic::var_annotation:
5171 NewCall = Builder.CreateCall(
5180 case Intrinsic::riscv_aes32dsi:
5181 case Intrinsic::riscv_aes32dsmi:
5182 case Intrinsic::riscv_aes32esi:
5183 case Intrinsic::riscv_aes32esmi:
5184 case Intrinsic::riscv_sm4ks:
5185 case Intrinsic::riscv_sm4ed: {
5195 Arg0 = Builder.CreateTrunc(Arg0, Builder.getInt32Ty());
5196 Arg1 = Builder.CreateTrunc(Arg1, Builder.getInt32Ty());
5202 NewCall = Builder.CreateCall(NewFn, {Arg0, Arg1, Arg2});
5203 Value *Res = NewCall;
5205 Res = Builder.CreateIntCast(NewCall, CI->
getType(),
true);
5211 case Intrinsic::nvvm_mapa_shared_cluster: {
5215 Value *Res = NewCall;
5216 Res = Builder.CreateAddrSpaceCast(
5223 case Intrinsic::nvvm_cp_async_bulk_global_to_shared_cluster:
5224 case Intrinsic::nvvm_cp_async_bulk_shared_cta_to_cluster: {
5227 Args[0] = Builder.CreateAddrSpaceCast(
5230 NewCall = Builder.CreateCall(NewFn, Args);
5236 case Intrinsic::nvvm_cp_async_bulk_tensor_g2s_im2col_3d:
5237 case Intrinsic::nvvm_cp_async_bulk_tensor_g2s_im2col_4d:
5238 case Intrinsic::nvvm_cp_async_bulk_tensor_g2s_im2col_5d:
5239 case Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_1d:
5240 case Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_2d:
5241 case Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_3d:
5242 case Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_4d:
5243 case Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_5d: {
5250 Args[0] = Builder.CreateAddrSpaceCast(
5259 Args.push_back(ConstantInt::get(Builder.getInt32Ty(), 0));
5261 NewCall = Builder.CreateCall(NewFn, Args);
5267 case Intrinsic::riscv_sha256sig0:
5268 case Intrinsic::riscv_sha256sig1:
5269 case Intrinsic::riscv_sha256sum0:
5270 case Intrinsic::riscv_sha256sum1:
5271 case Intrinsic::riscv_sm3p0:
5272 case Intrinsic::riscv_sm3p1: {
5279 Builder.CreateTrunc(CI->
getArgOperand(0), Builder.getInt32Ty());
5281 NewCall = Builder.CreateCall(NewFn, Arg);
5283 Builder.CreateIntCast(NewCall, CI->
getType(),
true);
5290 case Intrinsic::x86_xop_vfrcz_ss:
5291 case Intrinsic::x86_xop_vfrcz_sd:
5292 NewCall = Builder.CreateCall(NewFn, {CI->
getArgOperand(1)});
5295 case Intrinsic::x86_xop_vpermil2pd:
5296 case Intrinsic::x86_xop_vpermil2ps:
5297 case Intrinsic::x86_xop_vpermil2pd_256:
5298 case Intrinsic::x86_xop_vpermil2ps_256: {
5302 Args[2] = Builder.CreateBitCast(Args[2], IntIdxTy);
5303 NewCall = Builder.CreateCall(NewFn, Args);
5307 case Intrinsic::x86_sse41_ptestc:
5308 case Intrinsic::x86_sse41_ptestz:
5309 case Intrinsic::x86_sse41_ptestnzc: {
5323 Value *BC0 = Builder.CreateBitCast(Arg0, NewVecTy,
"cast");
5324 Value *BC1 = Builder.CreateBitCast(Arg1, NewVecTy,
"cast");
5326 NewCall = Builder.CreateCall(NewFn, {BC0, BC1});
5330 case Intrinsic::x86_rdtscp: {
5336 NewCall = Builder.CreateCall(NewFn);
5338 Value *
Data = Builder.CreateExtractValue(NewCall, 1);
5341 Value *TSC = Builder.CreateExtractValue(NewCall, 0);
5349 case Intrinsic::x86_sse41_insertps:
5350 case Intrinsic::x86_sse41_dppd:
5351 case Intrinsic::x86_sse41_dpps:
5352 case Intrinsic::x86_sse41_mpsadbw:
5353 case Intrinsic::x86_avx_dp_ps_256:
5354 case Intrinsic::x86_avx2_mpsadbw: {
5360 Args.back() = Builder.CreateTrunc(Args.back(),
Type::getInt8Ty(
C),
"trunc");
5361 NewCall = Builder.CreateCall(NewFn, Args);
5365 case Intrinsic::x86_avx512_mask_cmp_pd_128:
5366 case Intrinsic::x86_avx512_mask_cmp_pd_256:
5367 case Intrinsic::x86_avx512_mask_cmp_pd_512:
5368 case Intrinsic::x86_avx512_mask_cmp_ps_128:
5369 case Intrinsic::x86_avx512_mask_cmp_ps_256:
5370 case Intrinsic::x86_avx512_mask_cmp_ps_512: {
5376 NewCall = Builder.CreateCall(NewFn, Args);
5385 case Intrinsic::x86_avx512bf16_cvtne2ps2bf16_128:
5386 case Intrinsic::x86_avx512bf16_cvtne2ps2bf16_256:
5387 case Intrinsic::x86_avx512bf16_cvtne2ps2bf16_512:
5388 case Intrinsic::x86_avx512bf16_mask_cvtneps2bf16_128:
5389 case Intrinsic::x86_avx512bf16_cvtneps2bf16_256:
5390 case Intrinsic::x86_avx512bf16_cvtneps2bf16_512: {
5394 Intrinsic::x86_avx512bf16_mask_cvtneps2bf16_128)
5395 Args[1] = Builder.CreateBitCast(
5398 NewCall = Builder.CreateCall(NewFn, Args);
5399 Value *Res = Builder.CreateBitCast(
5407 case Intrinsic::x86_avx512bf16_dpbf16ps_128:
5408 case Intrinsic::x86_avx512bf16_dpbf16ps_256:
5409 case Intrinsic::x86_avx512bf16_dpbf16ps_512:{
5413 Args[1] = Builder.CreateBitCast(
5415 Args[2] = Builder.CreateBitCast(
5418 NewCall = Builder.CreateCall(NewFn, Args);
5422 case Intrinsic::thread_pointer: {
5423 NewCall = Builder.CreateCall(NewFn, {});
5427 case Intrinsic::memcpy:
5428 case Intrinsic::memmove:
5429 case Intrinsic::memset: {
5445 NewCall = Builder.CreateCall(NewFn, Args);
5447 AttributeList NewAttrs = AttributeList::get(
5448 C, OldAttrs.getFnAttrs(), OldAttrs.getRetAttrs(),
5449 {OldAttrs.getParamAttrs(0), OldAttrs.getParamAttrs(1),
5450 OldAttrs.getParamAttrs(2), OldAttrs.getParamAttrs(4)});
5455 MemCI->setDestAlignment(
Align->getMaybeAlignValue());
5458 MTI->setSourceAlignment(
Align->getMaybeAlignValue());
5462 case Intrinsic::masked_load:
5463 case Intrinsic::masked_gather:
5464 case Intrinsic::masked_store:
5465 case Intrinsic::masked_scatter: {
5471 auto GetMaybeAlign = [](
Value *
Op) {
5481 auto GetAlign = [&](
Value *
Op) {
5490 case Intrinsic::masked_load:
5491 NewCall = Builder.CreateMaskedLoad(
5495 case Intrinsic::masked_gather:
5496 NewCall = Builder.CreateMaskedGather(
5502 case Intrinsic::masked_store:
5503 NewCall = Builder.CreateMaskedStore(
5507 case Intrinsic::masked_scatter:
5508 NewCall = Builder.CreateMaskedScatter(
5510 DL.getValueOrABITypeAlignment(
5524 case Intrinsic::lifetime_start:
5525 case Intrinsic::lifetime_end: {
5537 NewCall = Builder.CreateLifetimeStart(Ptr);
5539 NewCall = Builder.CreateLifetimeEnd(Ptr);
5548 case Intrinsic::x86_avx512_vpdpbusd_128:
5549 case Intrinsic::x86_avx512_vpdpbusd_256:
5550 case Intrinsic::x86_avx512_vpdpbusd_512:
5551 case Intrinsic::x86_avx512_vpdpbusds_128:
5552 case Intrinsic::x86_avx512_vpdpbusds_256:
5553 case Intrinsic::x86_avx512_vpdpbusds_512:
5554 case Intrinsic::x86_avx2_vpdpbssd_128:
5555 case Intrinsic::x86_avx2_vpdpbssd_256:
5556 case Intrinsic::x86_avx10_vpdpbssd_512:
5557 case Intrinsic::x86_avx2_vpdpbssds_128:
5558 case Intrinsic::x86_avx2_vpdpbssds_256:
5559 case Intrinsic::x86_avx10_vpdpbssds_512:
5560 case Intrinsic::x86_avx2_vpdpbsud_128:
5561 case Intrinsic::x86_avx2_vpdpbsud_256:
5562 case Intrinsic::x86_avx10_vpdpbsud_512:
5563 case Intrinsic::x86_avx2_vpdpbsuds_128:
5564 case Intrinsic::x86_avx2_vpdpbsuds_256:
5565 case Intrinsic::x86_avx10_vpdpbsuds_512:
5566 case Intrinsic::x86_avx2_vpdpbuud_128:
5567 case Intrinsic::x86_avx2_vpdpbuud_256:
5568 case Intrinsic::x86_avx10_vpdpbuud_512:
5569 case Intrinsic::x86_avx2_vpdpbuuds_128:
5570 case Intrinsic::x86_avx2_vpdpbuuds_256:
5571 case Intrinsic::x86_avx10_vpdpbuuds_512: {
5576 Args[1] = Builder.CreateBitCast(Args[1], NewArgType);
5577 Args[2] = Builder.CreateBitCast(Args[2], NewArgType);
5579 NewCall = Builder.CreateCall(NewFn, Args);
5582 case Intrinsic::x86_avx512_vpdpwssd_128:
5583 case Intrinsic::x86_avx512_vpdpwssd_256:
5584 case Intrinsic::x86_avx512_vpdpwssd_512:
5585 case Intrinsic::x86_avx512_vpdpwssds_128:
5586 case Intrinsic::x86_avx512_vpdpwssds_256:
5587 case Intrinsic::x86_avx512_vpdpwssds_512:
5588 case Intrinsic::x86_avx2_vpdpwsud_128:
5589 case Intrinsic::x86_avx2_vpdpwsud_256:
5590 case Intrinsic::x86_avx10_vpdpwsud_512:
5591 case Intrinsic::x86_avx2_vpdpwsuds_128:
5592 case Intrinsic::x86_avx2_vpdpwsuds_256:
5593 case Intrinsic::x86_avx10_vpdpwsuds_512:
5594 case Intrinsic::x86_avx2_vpdpwusd_128:
5595 case Intrinsic::x86_avx2_vpdpwusd_256:
5596 case Intrinsic::x86_avx10_vpdpwusd_512:
5597 case Intrinsic::x86_avx2_vpdpwusds_128:
5598 case Intrinsic::x86_avx2_vpdpwusds_256:
5599 case Intrinsic::x86_avx10_vpdpwusds_512:
5600 case Intrinsic::x86_avx2_vpdpwuud_128:
5601 case Intrinsic::x86_avx2_vpdpwuud_256:
5602 case Intrinsic::x86_avx10_vpdpwuud_512:
5603 case Intrinsic::x86_avx2_vpdpwuuds_128:
5604 case Intrinsic::x86_avx2_vpdpwuuds_256:
5605 case Intrinsic::x86_avx10_vpdpwuuds_512:
5610 Args[1] = Builder.CreateBitCast(Args[1], NewArgType);
5611 Args[2] = Builder.CreateBitCast(Args[2], NewArgType);
5613 NewCall = Builder.CreateCall(NewFn, Args);
5616 assert(NewCall &&
"Should have either set this variable or returned through "
5617 "the default case");
5624 assert(
F &&
"Illegal attempt to upgrade a non-existent intrinsic.");
5638 F->eraseFromParent();
5644 if (NumOperands == 0)
5652 if (NumOperands == 3) {
5656 Metadata *Elts2[] = {ScalarType, ScalarType,
5670 if (
Opc != Instruction::BitCast)
5674 Type *SrcTy = V->getType();
5691 if (
Opc != Instruction::BitCast)
5694 Type *SrcTy =
C->getType();
5721 if (
NamedMDNode *ModFlags = M.getModuleFlagsMetadata()) {
5722 auto OpIt =
find_if(ModFlags->operands(), [](
const MDNode *Flag) {
5723 if (Flag->getNumOperands() < 3)
5725 if (MDString *K = dyn_cast_or_null<MDString>(Flag->getOperand(1)))
5726 return K->getString() ==
"Debug Info Version";
5729 if (OpIt != ModFlags->op_end()) {
5730 const MDOperand &ValOp = (*OpIt)->getOperand(2);
5737 bool BrokenDebugInfo =
false;
5740 if (!BrokenDebugInfo)
5746 M.getContext().diagnose(Diag);
5753 M.getContext().diagnose(DiagVersion);
5763 StringRef Vect3[3] = {DefaultValue, DefaultValue, DefaultValue};
5766 if (
F->hasFnAttribute(Attr)) {
5769 StringRef S =
F->getFnAttribute(Attr).getValueAsString();
5771 auto [Part, Rest] = S.
split(
',');
5777 const unsigned Dim = DimC -
'x';
5778 assert(Dim < 3 &&
"Unexpected dim char");
5788 F->addFnAttr(Attr, NewAttr);
5792 return S ==
"x" || S ==
"y" || S ==
"z";
5797 if (K ==
"kernel") {
5809 const unsigned Idx = (AlignIdxValuePair >> 16);
5810 const Align StackAlign =
Align(AlignIdxValuePair & 0xFFFF);
5815 if (K ==
"maxclusterrank" || K ==
"cluster_max_blocks") {
5820 if (K ==
"minctasm") {
5825 if (K ==
"maxnreg") {
5830 if (K.consume_front(
"maxntid") &&
isXYZ(K)) {
5834 if (K.consume_front(
"reqntid") &&
isXYZ(K)) {
5838 if (K.consume_front(
"cluster_dim_") &&
isXYZ(K)) {
5842 if (K ==
"grid_constant") {
5857 NamedMDNode *NamedMD = M.getNamedMetadata(
"nvvm.annotations");
5864 if (!SeenNodes.
insert(MD).second)
5871 assert((MD->getNumOperands() % 2) == 1 &&
"Invalid number of operands");
5878 for (
unsigned j = 1, je = MD->getNumOperands(); j < je; j += 2) {
5880 const MDOperand &V = MD->getOperand(j + 1);
5883 NewOperands.
append({K, V});
5886 if (NewOperands.
size() > 1)
5899 const char *MarkerKey =
"clang.arc.retainAutoreleasedReturnValueMarker";
5900 NamedMDNode *ModRetainReleaseMarker = M.getNamedMetadata(MarkerKey);
5901 if (ModRetainReleaseMarker) {
5907 ID->getString().split(ValueComp,
"#");
5908 if (ValueComp.
size() == 2) {
5909 std::string NewValue = ValueComp[0].str() +
";" + ValueComp[1].str();
5913 M.eraseNamedMetadata(ModRetainReleaseMarker);
5924 auto UpgradeToIntrinsic = [&](
const char *OldFunc,
5950 bool InvalidCast =
false;
5952 for (
unsigned I = 0, E = CI->
arg_size();
I != E; ++
I) {
5965 Arg = Builder.CreateBitCast(Arg, NewFuncTy->
getParamType(
I));
5967 Args.push_back(Arg);
5974 CallInst *NewCall = Builder.CreateCall(NewFuncTy, NewFn, Args);
5979 Value *NewRetVal = Builder.CreateBitCast(NewCall, CI->
getType());
5992 UpgradeToIntrinsic(
"clang.arc.use", llvm::Intrinsic::objc_clang_arc_use);
6000 std::pair<const char *, llvm::Intrinsic::ID> RuntimeFuncs[] = {
6001 {
"objc_autorelease", llvm::Intrinsic::objc_autorelease},
6002 {
"objc_autoreleasePoolPop", llvm::Intrinsic::objc_autoreleasePoolPop},
6003 {
"objc_autoreleasePoolPush", llvm::Intrinsic::objc_autoreleasePoolPush},
6004 {
"objc_autoreleaseReturnValue",
6005 llvm::Intrinsic::objc_autoreleaseReturnValue},
6006 {
"objc_copyWeak", llvm::Intrinsic::objc_copyWeak},
6007 {
"objc_destroyWeak", llvm::Intrinsic::objc_destroyWeak},
6008 {
"objc_initWeak", llvm::Intrinsic::objc_initWeak},
6009 {
"objc_loadWeak", llvm::Intrinsic::objc_loadWeak},
6010 {
"objc_loadWeakRetained", llvm::Intrinsic::objc_loadWeakRetained},
6011 {
"objc_moveWeak", llvm::Intrinsic::objc_moveWeak},
6012 {
"objc_release", llvm::Intrinsic::objc_release},
6013 {
"objc_retain", llvm::Intrinsic::objc_retain},
6014 {
"objc_retainAutorelease", llvm::Intrinsic::objc_retainAutorelease},
6015 {
"objc_retainAutoreleaseReturnValue",
6016 llvm::Intrinsic::objc_retainAutoreleaseReturnValue},
6017 {
"objc_retainAutoreleasedReturnValue",
6018 llvm::Intrinsic::objc_retainAutoreleasedReturnValue},
6019 {
"objc_retainBlock", llvm::Intrinsic::objc_retainBlock},
6020 {
"objc_storeStrong", llvm::Intrinsic::objc_storeStrong},
6021 {
"objc_storeWeak", llvm::Intrinsic::objc_storeWeak},
6022 {
"objc_unsafeClaimAutoreleasedReturnValue",
6023 llvm::Intrinsic::objc_unsafeClaimAutoreleasedReturnValue},
6024 {
"objc_retainedObject", llvm::Intrinsic::objc_retainedObject},
6025 {
"objc_unretainedObject", llvm::Intrinsic::objc_unretainedObject},
6026 {
"objc_unretainedPointer", llvm::Intrinsic::objc_unretainedPointer},
6027 {
"objc_retain_autorelease", llvm::Intrinsic::objc_retain_autorelease},
6028 {
"objc_sync_enter", llvm::Intrinsic::objc_sync_enter},
6029 {
"objc_sync_exit", llvm::Intrinsic::objc_sync_exit},
6030 {
"objc_arc_annotation_topdown_bbstart",
6031 llvm::Intrinsic::objc_arc_annotation_topdown_bbstart},
6032 {
"objc_arc_annotation_topdown_bbend",
6033 llvm::Intrinsic::objc_arc_annotation_topdown_bbend},
6034 {
"objc_arc_annotation_bottomup_bbstart",
6035 llvm::Intrinsic::objc_arc_annotation_bottomup_bbstart},
6036 {
"objc_arc_annotation_bottomup_bbend",
6037 llvm::Intrinsic::objc_arc_annotation_bottomup_bbend}};
6039 for (
auto &
I : RuntimeFuncs)
6040 UpgradeToIntrinsic(
I.first,
I.second);
6044 NamedMDNode *ModFlags = M.getModuleFlagsMetadata();
6048 bool HasObjCFlag =
false, HasClassProperties =
false,
Changed =
false;
6049 bool HasSwiftVersionFlag =
false;
6050 uint8_t SwiftMajorVersion, SwiftMinorVersion;
6057 if (
Op->getNumOperands() != 3)
6071 if (
ID->getString() ==
"Objective-C Image Info Version")
6073 if (
ID->getString() ==
"Objective-C Class Properties")
6074 HasClassProperties =
true;
6076 if (
ID->getString() ==
"PIC Level") {
6077 if (
auto *Behavior =
6079 uint64_t V = Behavior->getLimitedValue();
6085 if (
ID->getString() ==
"PIE Level")
6086 if (
auto *Behavior =
6093 if (
ID->getString() ==
"branch-target-enforcement" ||
6094 ID->getString().starts_with(
"sign-return-address")) {
6095 if (
auto *Behavior =
6101 Op->getOperand(1),
Op->getOperand(2)};
6111 if (
ID->getString() ==
"Objective-C Image Info Section") {
6114 Value->getString().split(ValueComp,
" ");
6115 if (ValueComp.
size() != 1) {
6116 std::string NewValue;
6117 for (
auto &S : ValueComp)
6118 NewValue += S.str();
6129 if (
ID->getString() ==
"Objective-C Garbage Collection") {
6132 assert(Md->getValue() &&
"Expected non-empty metadata");
6133 auto Type = Md->getValue()->getType();
6136 unsigned Val = Md->getValue()->getUniqueInteger().getZExtValue();
6137 if ((Val & 0xff) != Val) {
6138 HasSwiftVersionFlag =
true;
6139 SwiftABIVersion = (Val & 0xff00) >> 8;
6140 SwiftMajorVersion = (Val & 0xff000000) >> 24;
6141 SwiftMinorVersion = (Val & 0xff0000) >> 16;
6152 if (
ID->getString() ==
"amdgpu_code_object_version") {
6155 MDString::get(M.getContext(),
"amdhsa_code_object_version"),
6167 if (HasObjCFlag && !HasClassProperties) {
6173 if (HasSwiftVersionFlag) {
6177 ConstantInt::get(Int8Ty, SwiftMajorVersion));
6179 ConstantInt::get(Int8Ty, SwiftMinorVersion));
6187 auto TrimSpaces = [](
StringRef Section) -> std::string {
6189 Section.split(Components,
',');
6194 for (
auto Component : Components)
6195 OS <<
',' << Component.trim();
6200 for (
auto &GV : M.globals()) {
6201 if (!GV.hasSection())
6206 if (!Section.starts_with(
"__DATA, __objc_catlist"))
6211 GV.setSection(TrimSpaces(Section));
6227struct StrictFPUpgradeVisitor :
public InstVisitor<StrictFPUpgradeVisitor> {
6228 StrictFPUpgradeVisitor() =
default;
6231 if (!
Call.isStrictFP())
6237 Call.removeFnAttr(Attribute::StrictFP);
6238 Call.addFnAttr(Attribute::NoBuiltin);
6243struct AMDGPUUnsafeFPAtomicsUpgradeVisitor
6244 :
public InstVisitor<AMDGPUUnsafeFPAtomicsUpgradeVisitor> {
6245 AMDGPUUnsafeFPAtomicsUpgradeVisitor() =
default;
6247 void visitAtomicRMWInst(AtomicRMWInst &RMW) {
6262 if (!
F.isDeclaration() && !
F.hasFnAttribute(Attribute::StrictFP)) {
6263 StrictFPUpgradeVisitor SFPV;
6268 F.removeRetAttrs(AttributeFuncs::typeIncompatible(
6269 F.getReturnType(),
F.getAttributes().getRetAttrs()));
6270 for (
auto &Arg :
F.args())
6272 AttributeFuncs::typeIncompatible(Arg.getType(), Arg.getAttributes()));
6276 if (
Attribute A =
F.getFnAttribute(
"implicit-section-name");
6277 A.isValid() &&
A.isStringAttribute()) {
6278 F.setSection(
A.getValueAsString());
6279 F.removeFnAttr(
"implicit-section-name");
6286 if (
Attribute A =
F.getFnAttribute(
"amdgpu-unsafe-fp-atomics");
6289 if (
A.getValueAsBool()) {
6290 AMDGPUUnsafeFPAtomicsUpgradeVisitor Visitor;
6296 F.removeFnAttr(
"amdgpu-unsafe-fp-atomics");
6304 if (!
F.hasFnAttribute(FnAttrName))
6305 F.addFnAttr(FnAttrName,
Value);
6312 if (!
F.hasFnAttribute(FnAttrName)) {
6314 F.addFnAttr(FnAttrName);
6316 auto A =
F.getFnAttribute(FnAttrName);
6317 if (
"false" ==
A.getValueAsString())
6318 F.removeFnAttr(FnAttrName);
6319 else if (
"true" ==
A.getValueAsString()) {
6320 F.removeFnAttr(FnAttrName);
6321 F.addFnAttr(FnAttrName);
6327 Triple T(M.getTargetTriple());
6328 if (!
T.isThumb() && !
T.isARM() && !
T.isAArch64())
6338 NamedMDNode *ModFlags = M.getModuleFlagsMetadata();
6342 if (
Op->getNumOperands() != 3)
6351 uint64_t *ValPtr = IDStr ==
"branch-target-enforcement" ? &BTEValue
6352 : IDStr ==
"branch-protection-pauth-lr" ? &BPPLRValue
6353 : IDStr ==
"guarded-control-stack" ? &GCSValue
6354 : IDStr ==
"sign-return-address" ? &SRAValue
6355 : IDStr ==
"sign-return-address-all" ? &SRAALLValue
6356 : IDStr ==
"sign-return-address-with-bkey"
6362 *ValPtr = CI->getZExtValue();
6368 bool BTE = BTEValue == 1;
6369 bool BPPLR = BPPLRValue == 1;
6370 bool GCS = GCSValue == 1;
6371 bool SRA = SRAValue == 1;
6374 if (SRA && SRAALLValue == 1)
6375 SignTypeValue =
"all";
6378 if (SRA && SRABKeyValue == 1)
6379 SignKeyValue =
"b_key";
6381 for (
Function &
F : M.getFunctionList()) {
6382 if (
F.isDeclaration())
6389 if (
auto A =
F.getFnAttribute(
"sign-return-address");
6390 A.isValid() &&
"none" ==
A.getValueAsString()) {
6391 F.removeFnAttr(
"sign-return-address");
6392 F.removeFnAttr(
"sign-return-address-key");
6408 if (SRAALLValue == 1)
6410 if (SRABKeyValue == 1)
6419 if (
T->getNumOperands() < 1)
6424 return S->getString().starts_with(
"llvm.vectorizer.");
6428 StringRef OldPrefix =
"llvm.vectorizer.";
6431 if (OldTag ==
"llvm.vectorizer.unroll")
6443 if (
T->getNumOperands() < 1)
6448 if (!OldTag->getString().starts_with(
"llvm.vectorizer."))
6453 Ops.reserve(
T->getNumOperands());
6455 for (
unsigned I = 1,
E =
T->getNumOperands();
I !=
E; ++
I)
6456 Ops.push_back(
T->getOperand(
I));
6470 Ops.reserve(
T->getNumOperands());
6481 if ((
T.isSPIR() || (
T.isSPIRV() && !
T.isSPIRVLogical())) &&
6482 !
DL.contains(
"-G") && !
DL.starts_with(
"G")) {
6483 return DL.empty() ? std::string(
"G1") : (
DL +
"-G1").str();
6486 if (
T.isLoongArch64() ||
T.isRISCV64()) {
6488 auto I =
DL.find(
"-n64-");
6490 return (
DL.take_front(
I) +
"-n32:64-" +
DL.drop_front(
I + 5)).str();
6495 std::string Res =
DL.str();
6498 if (!
DL.contains(
"-G") && !
DL.starts_with(
"G"))
6499 Res.append(Res.empty() ?
"G1" :
"-G1");
6507 if (!
DL.contains(
"-ni") && !
DL.starts_with(
"ni"))
6508 Res.append(
"-ni:7:8:9");
6510 if (
DL.ends_with(
"ni:7"))
6512 if (
DL.ends_with(
"ni:7:8"))
6517 if (!
DL.contains(
"-p7") && !
DL.starts_with(
"p7"))
6518 Res.append(
"-p7:160:256:256:32");
6519 if (!
DL.contains(
"-p8") && !
DL.starts_with(
"p8"))
6520 Res.append(
"-p8:128:128:128:48");
6521 constexpr StringRef OldP8(
"-p8:128:128-");
6522 if (
DL.contains(OldP8))
6523 Res.replace(Res.find(OldP8), OldP8.
size(),
"-p8:128:128:128:48-");
6524 if (!
DL.contains(
"-p9") && !
DL.starts_with(
"p9"))
6525 Res.append(
"-p9:192:256:256:32");
6529 if (!
DL.contains(
"m:e"))
6530 Res = Res.empty() ?
"m:e" :
"m:e-" + Res;
6535 auto AddPtr32Ptr64AddrSpaces = [&
DL, &Res]() {
6538 StringRef AddrSpaces{
"-p270:32:32-p271:32:32-p272:64:64"};
6539 if (!
DL.contains(AddrSpaces)) {
6541 Regex R(
"^([Ee]-m:[a-z](-p:32:32)?)(-.*)$");
6542 if (R.match(Res, &
Groups))
6548 if (
T.isAArch64()) {
6550 if (!
DL.empty() && !
DL.contains(
"-Fn32"))
6551 Res.append(
"-Fn32");
6552 AddPtr32Ptr64AddrSpaces();
6556 if (
T.isSPARC() || (
T.isMIPS64() && !
DL.contains(
"m:m")) ||
T.isPPC64() ||
6560 std::string I64 =
"-i64:64";
6561 std::string I128 =
"-i128:128";
6563 size_t Pos = Res.find(I64);
6564 if (Pos !=
size_t(-1))
6565 Res.insert(Pos + I64.size(), I128);
6569 if (
T.isPPC() &&
T.isOSAIX() && !
DL.contains(
"f64:32:64") && !
DL.empty()) {
6570 size_t Pos = Res.find(
"-S128");
6573 Res.insert(Pos,
"-f64:32:64");
6579 AddPtr32Ptr64AddrSpaces();
6587 if (!
T.isOSIAMCU()) {
6588 std::string I128 =
"-i128:128";
6591 Regex R(
"^(e(-[mpi][^-]*)*)((-[^mpi][^-]*)*)$");
6592 if (R.match(Res, &
Groups))
6600 if (
T.isWindowsMSVCEnvironment() && !
T.isArch64Bit()) {
6602 auto I =
Ref.find(
"-f80:32-");
6604 Res = (
Ref.take_front(
I) +
"-f80:128-" +
Ref.drop_front(
I + 8)).str();
6612 Attribute A =
B.getAttribute(
"no-frame-pointer-elim");
6615 FramePointer =
A.getValueAsString() ==
"true" ?
"all" :
"none";
6616 B.removeAttribute(
"no-frame-pointer-elim");
6618 if (
B.contains(
"no-frame-pointer-elim-non-leaf")) {
6620 if (FramePointer !=
"all")
6621 FramePointer =
"non-leaf";
6622 B.removeAttribute(
"no-frame-pointer-elim-non-leaf");
6624 if (!FramePointer.
empty())
6625 B.addAttribute(
"frame-pointer", FramePointer);
6627 A =
B.getAttribute(
"null-pointer-is-valid");
6630 bool NullPointerIsValid =
A.getValueAsString() ==
"true";
6631 B.removeAttribute(
"null-pointer-is-valid");
6632 if (NullPointerIsValid)
6633 B.addAttribute(Attribute::NullPointerIsValid);
6643 return OBD.
getTag() ==
"clang.arc.attachedcall" &&
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)
static Metadata * upgradeLoopArgument(Metadata *MD)
static bool isXYZ(StringRef S)
static bool upgradeIntrinsicFunction1(Function *F, Function *&NewFn, bool CanUpgradeDebugIntrinsicsToRecords)
static Value * upgradeX86PSLLDQIntrinsics(IRBuilder<> &Builder, Value *Op, unsigned Shift)
static Intrinsic::ID shouldUpgradeNVPTXSharedClusterIntrinsic(Function *F, StringRef Name)
static bool upgradeRetainReleaseMarker(Module &M)
This checks for objc retain release marker which should be upgraded.
static Value * upgradeX86vpcom(IRBuilder<> &Builder, CallBase &CI, unsigned Imm, bool IsSigned)
static Value * upgradeMaskToInt(IRBuilder<> &Builder, CallBase &CI)
static Value * upgradeX86Rotate(IRBuilder<> &Builder, CallBase &CI, bool IsRotateRight)
static bool upgradeX86MultiplyAddBytes(Function *F, Intrinsic::ID IID, Function *&NewFn)
static void setFunctionAttrIfNotSet(Function &F, StringRef FnAttrName, StringRef Value)
static Intrinsic::ID shouldUpgradeNVPTXBF16Intrinsic(StringRef Name)
static bool upgradeSingleNVVMAnnotation(GlobalValue *GV, StringRef K, const Metadata *V)
static MDNode * unwrapMAVOp(CallBase *CI, unsigned Op)
Helper to unwrap intrinsic call MetadataAsValue operands.
static MDString * upgradeLoopTag(LLVMContext &C, StringRef OldTag)
static void upgradeNVVMFnVectorAttr(const StringRef Attr, const char DimC, GlobalValue *GV, const Metadata *V)
static bool upgradeX86MaskedFPCompare(Function *F, Intrinsic::ID IID, Function *&NewFn)
static Value * upgradeX86ALIGNIntrinsics(IRBuilder<> &Builder, Value *Op0, Value *Op1, Value *Shift, Value *Passthru, Value *Mask, bool IsVALIGN)
static Value * upgradeAbs(IRBuilder<> &Builder, CallBase &CI)
static Value * emitX86Select(IRBuilder<> &Builder, Value *Mask, Value *Op0, Value *Op1)
static Value * upgradeAArch64IntrinsicCall(StringRef Name, CallBase *CI, Function *F, IRBuilder<> &Builder)
static Value * upgradeMaskedMove(IRBuilder<> &Builder, CallBase &CI)
static bool upgradeX86IntrinsicFunction(Function *F, StringRef Name, Function *&NewFn)
static Value * applyX86MaskOn1BitsVec(IRBuilder<> &Builder, Value *Vec, Value *Mask)
static bool consumeNVVMPtrAddrSpace(StringRef &Name)
static bool shouldUpgradeX86Intrinsic(Function *F, StringRef Name)
static Value * upgradeX86PSRLDQIntrinsics(IRBuilder<> &Builder, Value *Op, unsigned Shift)
static Intrinsic::ID shouldUpgradeNVPTXTMAG2SIntrinsics(Function *F, StringRef Name)
static bool isOldLoopArgument(Metadata *MD)
static Value * upgradeARMIntrinsicCall(StringRef Name, CallBase *CI, Function *F, IRBuilder<> &Builder)
static bool upgradeX86IntrinsicsWith8BitMask(Function *F, Intrinsic::ID IID, Function *&NewFn)
static Value * upgradeVectorSplice(CallBase *CI, IRBuilder<> &Builder)
static Value * upgradeAMDGCNIntrinsicCall(StringRef Name, CallBase *CI, Function *F, IRBuilder<> &Builder)
static Value * upgradeMaskedLoad(IRBuilder<> &Builder, Value *Ptr, Value *Passthru, Value *Mask, bool Aligned)
static Metadata * unwrapMAVMetadataOp(CallBase *CI, unsigned Op)
Helper to unwrap Metadata MetadataAsValue operands, such as the Value field.
static bool upgradeX86BF16Intrinsic(Function *F, Intrinsic::ID IID, Function *&NewFn)
static bool upgradeArmOrAarch64IntrinsicFunction(bool IsArm, Function *F, StringRef Name, Function *&NewFn)
static Value * getX86MaskVec(IRBuilder<> &Builder, Value *Mask, unsigned NumElts)
static Value * emitX86ScalarSelect(IRBuilder<> &Builder, Value *Mask, Value *Op0, Value *Op1)
static Value * upgradeX86ConcatShift(IRBuilder<> &Builder, CallBase &CI, bool IsShiftRight, bool ZeroMask)
static void rename(GlobalValue *GV)
static bool upgradePTESTIntrinsic(Function *F, Intrinsic::ID IID, Function *&NewFn)
static bool upgradeX86BF16DPIntrinsic(Function *F, Intrinsic::ID IID, Function *&NewFn)
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)
static Value * upgradeX86BinaryIntrinsics(IRBuilder<> &Builder, CallBase &CI, Intrinsic::ID IID)
static Value * upgradeNVVMIntrinsicCall(StringRef Name, CallBase *CI, Function *F, IRBuilder<> &Builder)
static Value * upgradeX86MaskedShift(IRBuilder<> &Builder, CallBase &CI, Intrinsic::ID IID)
static bool upgradeAVX512MaskToSelect(StringRef Name, IRBuilder<> &Builder, CallBase &CI, Value *&Rep)
static void upgradeDbgIntrinsicToDbgRecord(StringRef Name, CallBase *CI)
Convert debug intrinsic calls to non-instruction debug records.
static void ConvertFunctionAttr(Function &F, bool Set, StringRef FnAttrName)
static Value * upgradePMULDQ(IRBuilder<> &Builder, CallBase &CI, bool IsSigned)
static Value * upgradeMaskedStore(IRBuilder<> &Builder, Value *Ptr, Value *Data, Value *Mask, bool Aligned)
static bool upgradeX86MultiplyAddWords(Function *F, Intrinsic::ID IID, Function *&NewFn)
static MDNode * getDebugLocSafe(const Instruction *I)
static Value * upgradeX86IntrinsicCall(StringRef Name, CallBase *CI, Function *F, IRBuilder<> &Builder)
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.
@ USubCond
Subtract only if no unsigned overflow.
@ USubSat
*p = usub.sat(old, v) usub.sat matches the behavior of llvm.usub.sat.
@ 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...
LLVM_ABI void getOperandBundlesAsDefs(SmallVectorImpl< OperandBundleDef > &Defs) const
Return the list of operand bundles attached to this instruction as a vector of OperandBundleDefs.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
CallingConv::ID getCallingConv() const
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...
LLVM_ABI void UpgradeSectionAttributes(Module &M)
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.
bool isValidAtomicOrdering(Int I)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - 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,...
LLVM_ABI MDNode * upgradeInstructionLoopAttachment(MDNode &N)
Upgrade the loop attachment metadata node.
auto dyn_cast_if_present(const Y &Val)
dyn_cast_if_present<X> - 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.
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...
LLVM_ABI void UpgradeNVVMAnnotations(Module &M)
Convert legacy nvvm.annotations metadata to appropriate function attributes.
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.
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.
LLVM_ABI void UpgradeOperandBundles(std::vector< OperandBundleDef > &OperandBundles)
Upgrade operand bundles (without knowing about their user instruction).
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...
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.
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<X> - 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.
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...
DWARFExpression::Operation Op
@ Dynamic
Denotes mode unknown at compile time.
ArrayRef(const T &OneElt) -> ArrayRef< T >
decltype(auto) cast(const From &Val)
cast<X> - 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.
LLVM_ABI void UpgradeFunctionAttributes(Function &F)
Correct any IR that is relying on old function attribute behavior.
@ 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 ...
LLVM_ABI void UpgradeARCRuntime(Module &M)
Convert calls to ARC runtime functions to intrinsic calls and upgrade the old retain release marker t...
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.