34#include "llvm/IR/IntrinsicsAArch64.h"
35#include "llvm/IR/IntrinsicsARM.h"
36#include "llvm/IR/IntrinsicsNVPTX.h"
37#include "llvm/IR/IntrinsicsRISCV.h"
38#include "llvm/IR/IntrinsicsWebAssembly.h"
39#include "llvm/IR/IntrinsicsX86.h"
61 cl::desc(
"Disable autoupgrade of debug info"));
71 Type *Arg0Type =
F->getFunctionType()->getParamType(0);
86 Type *LastArgType =
F->getFunctionType()->getParamType(
87 F->getFunctionType()->getNumParams() - 1);
102 if (
F->getReturnType()->isVectorTy())
115 Type *Arg1Type =
F->getFunctionType()->getParamType(1);
116 Type *Arg2Type =
F->getFunctionType()->getParamType(2);
133 Type *Arg1Type =
F->getFunctionType()->getParamType(1);
134 Type *Arg2Type =
F->getFunctionType()->getParamType(2);
148 if (
F->getReturnType()->getScalarType()->isBFloatTy())
158 if (
F->getFunctionType()->getParamType(1)->getScalarType()->isBFloatTy())
172 if (Name.consume_front(
"avx."))
173 return (Name.starts_with(
"blend.p") ||
174 Name ==
"cvt.ps2.pd.256" ||
175 Name ==
"cvtdq2.pd.256" ||
176 Name ==
"cvtdq2.ps.256" ||
177 Name.starts_with(
"movnt.") ||
178 Name.starts_with(
"sqrt.p") ||
179 Name.starts_with(
"storeu.") ||
180 Name.starts_with(
"vbroadcast.s") ||
181 Name.starts_with(
"vbroadcastf128") ||
182 Name.starts_with(
"vextractf128.") ||
183 Name.starts_with(
"vinsertf128.") ||
184 Name.starts_with(
"vperm2f128.") ||
185 Name.starts_with(
"vpermil."));
187 if (Name.consume_front(
"avx2."))
188 return (Name ==
"movntdqa" ||
189 Name.starts_with(
"pabs.") ||
190 Name.starts_with(
"padds.") ||
191 Name.starts_with(
"paddus.") ||
192 Name.starts_with(
"pblendd.") ||
194 Name.starts_with(
"pbroadcast") ||
195 Name.starts_with(
"pcmpeq.") ||
196 Name.starts_with(
"pcmpgt.") ||
197 Name.starts_with(
"pmax") ||
198 Name.starts_with(
"pmin") ||
199 Name.starts_with(
"pmovsx") ||
200 Name.starts_with(
"pmovzx") ||
202 Name ==
"pmulu.dq" ||
203 Name.starts_with(
"psll.dq") ||
204 Name.starts_with(
"psrl.dq") ||
205 Name.starts_with(
"psubs.") ||
206 Name.starts_with(
"psubus.") ||
207 Name.starts_with(
"vbroadcast") ||
208 Name ==
"vbroadcasti128" ||
209 Name ==
"vextracti128" ||
210 Name ==
"vinserti128" ||
211 Name ==
"vperm2i128");
213 if (Name.consume_front(
"avx512.")) {
214 if (Name.consume_front(
"mask."))
216 return (Name.starts_with(
"add.p") ||
217 Name.starts_with(
"and.") ||
218 Name.starts_with(
"andn.") ||
219 Name.starts_with(
"broadcast.s") ||
220 Name.starts_with(
"broadcastf32x4.") ||
221 Name.starts_with(
"broadcastf32x8.") ||
222 Name.starts_with(
"broadcastf64x2.") ||
223 Name.starts_with(
"broadcastf64x4.") ||
224 Name.starts_with(
"broadcasti32x4.") ||
225 Name.starts_with(
"broadcasti32x8.") ||
226 Name.starts_with(
"broadcasti64x2.") ||
227 Name.starts_with(
"broadcasti64x4.") ||
228 Name.starts_with(
"cmp.b") ||
229 Name.starts_with(
"cmp.d") ||
230 Name.starts_with(
"cmp.q") ||
231 Name.starts_with(
"cmp.w") ||
232 Name.starts_with(
"compress.b") ||
233 Name.starts_with(
"compress.d") ||
234 Name.starts_with(
"compress.p") ||
235 Name.starts_with(
"compress.q") ||
236 Name.starts_with(
"compress.store.") ||
237 Name.starts_with(
"compress.w") ||
238 Name.starts_with(
"conflict.") ||
239 Name.starts_with(
"cvtdq2pd.") ||
240 Name.starts_with(
"cvtdq2ps.") ||
241 Name ==
"cvtpd2dq.256" ||
242 Name ==
"cvtpd2ps.256" ||
243 Name ==
"cvtps2pd.128" ||
244 Name ==
"cvtps2pd.256" ||
245 Name.starts_with(
"cvtqq2pd.") ||
246 Name ==
"cvtqq2ps.256" ||
247 Name ==
"cvtqq2ps.512" ||
248 Name ==
"cvttpd2dq.256" ||
249 Name ==
"cvttps2dq.128" ||
250 Name ==
"cvttps2dq.256" ||
251 Name.starts_with(
"cvtudq2pd.") ||
252 Name.starts_with(
"cvtudq2ps.") ||
253 Name.starts_with(
"cvtuqq2pd.") ||
254 Name ==
"cvtuqq2ps.256" ||
255 Name ==
"cvtuqq2ps.512" ||
256 Name.starts_with(
"dbpsadbw.") ||
257 Name.starts_with(
"div.p") ||
258 Name.starts_with(
"expand.b") ||
259 Name.starts_with(
"expand.d") ||
260 Name.starts_with(
"expand.load.") ||
261 Name.starts_with(
"expand.p") ||
262 Name.starts_with(
"expand.q") ||
263 Name.starts_with(
"expand.w") ||
264 Name.starts_with(
"fpclass.p") ||
265 Name.starts_with(
"insert") ||
266 Name.starts_with(
"load.") ||
267 Name.starts_with(
"loadu.") ||
268 Name.starts_with(
"lzcnt.") ||
269 Name.starts_with(
"max.p") ||
270 Name.starts_with(
"min.p") ||
271 Name.starts_with(
"movddup") ||
272 Name.starts_with(
"move.s") ||
273 Name.starts_with(
"movshdup") ||
274 Name.starts_with(
"movsldup") ||
275 Name.starts_with(
"mul.p") ||
276 Name.starts_with(
"or.") ||
277 Name.starts_with(
"pabs.") ||
278 Name.starts_with(
"packssdw.") ||
279 Name.starts_with(
"packsswb.") ||
280 Name.starts_with(
"packusdw.") ||
281 Name.starts_with(
"packuswb.") ||
282 Name.starts_with(
"padd.") ||
283 Name.starts_with(
"padds.") ||
284 Name.starts_with(
"paddus.") ||
285 Name.starts_with(
"palignr.") ||
286 Name.starts_with(
"pand.") ||
287 Name.starts_with(
"pandn.") ||
288 Name.starts_with(
"pavg") ||
289 Name.starts_with(
"pbroadcast") ||
290 Name.starts_with(
"pcmpeq.") ||
291 Name.starts_with(
"pcmpgt.") ||
292 Name.starts_with(
"perm.df.") ||
293 Name.starts_with(
"perm.di.") ||
294 Name.starts_with(
"permvar.") ||
295 Name.starts_with(
"pmaddubs.w.") ||
296 Name.starts_with(
"pmaddw.d.") ||
297 Name.starts_with(
"pmax") ||
298 Name.starts_with(
"pmin") ||
299 Name ==
"pmov.qd.256" ||
300 Name ==
"pmov.qd.512" ||
301 Name ==
"pmov.wb.256" ||
302 Name ==
"pmov.wb.512" ||
303 Name.starts_with(
"pmovsx") ||
304 Name.starts_with(
"pmovzx") ||
305 Name.starts_with(
"pmul.dq.") ||
306 Name.starts_with(
"pmul.hr.sw.") ||
307 Name.starts_with(
"pmulh.w.") ||
308 Name.starts_with(
"pmulhu.w.") ||
309 Name.starts_with(
"pmull.") ||
310 Name.starts_with(
"pmultishift.qb.") ||
311 Name.starts_with(
"pmulu.dq.") ||
312 Name.starts_with(
"por.") ||
313 Name.starts_with(
"prol.") ||
314 Name.starts_with(
"prolv.") ||
315 Name.starts_with(
"pror.") ||
316 Name.starts_with(
"prorv.") ||
317 Name.starts_with(
"pshuf.b.") ||
318 Name.starts_with(
"pshuf.d.") ||
319 Name.starts_with(
"pshufh.w.") ||
320 Name.starts_with(
"pshufl.w.") ||
321 Name.starts_with(
"psll.d") ||
322 Name.starts_with(
"psll.q") ||
323 Name.starts_with(
"psll.w") ||
324 Name.starts_with(
"pslli") ||
325 Name.starts_with(
"psllv") ||
326 Name.starts_with(
"psra.d") ||
327 Name.starts_with(
"psra.q") ||
328 Name.starts_with(
"psra.w") ||
329 Name.starts_with(
"psrai") ||
330 Name.starts_with(
"psrav") ||
331 Name.starts_with(
"psrl.d") ||
332 Name.starts_with(
"psrl.q") ||
333 Name.starts_with(
"psrl.w") ||
334 Name.starts_with(
"psrli") ||
335 Name.starts_with(
"psrlv") ||
336 Name.starts_with(
"psub.") ||
337 Name.starts_with(
"psubs.") ||
338 Name.starts_with(
"psubus.") ||
339 Name.starts_with(
"pternlog.") ||
340 Name.starts_with(
"punpckh") ||
341 Name.starts_with(
"punpckl") ||
342 Name.starts_with(
"pxor.") ||
343 Name.starts_with(
"shuf.f") ||
344 Name.starts_with(
"shuf.i") ||
345 Name.starts_with(
"shuf.p") ||
346 Name.starts_with(
"sqrt.p") ||
347 Name.starts_with(
"store.b.") ||
348 Name.starts_with(
"store.d.") ||
349 Name.starts_with(
"store.p") ||
350 Name.starts_with(
"store.q.") ||
351 Name.starts_with(
"store.w.") ||
352 Name ==
"store.ss" ||
353 Name.starts_with(
"storeu.") ||
354 Name.starts_with(
"sub.p") ||
355 Name.starts_with(
"ucmp.") ||
356 Name.starts_with(
"unpckh.") ||
357 Name.starts_with(
"unpckl.") ||
358 Name.starts_with(
"valign.") ||
359 Name ==
"vcvtph2ps.128" ||
360 Name ==
"vcvtph2ps.256" ||
361 Name.starts_with(
"vextract") ||
362 Name.starts_with(
"vfmadd.") ||
363 Name.starts_with(
"vfmaddsub.") ||
364 Name.starts_with(
"vfnmadd.") ||
365 Name.starts_with(
"vfnmsub.") ||
366 Name.starts_with(
"vpdpbusd.") ||
367 Name.starts_with(
"vpdpbusds.") ||
368 Name.starts_with(
"vpdpwssd.") ||
369 Name.starts_with(
"vpdpwssds.") ||
370 Name.starts_with(
"vpermi2var.") ||
371 Name.starts_with(
"vpermil.p") ||
372 Name.starts_with(
"vpermilvar.") ||
373 Name.starts_with(
"vpermt2var.") ||
374 Name.starts_with(
"vpmadd52") ||
375 Name.starts_with(
"vpshld.") ||
376 Name.starts_with(
"vpshldv.") ||
377 Name.starts_with(
"vpshrd.") ||
378 Name.starts_with(
"vpshrdv.") ||
379 Name.starts_with(
"vpshufbitqmb.") ||
380 Name.starts_with(
"xor."));
382 if (Name.consume_front(
"mask3."))
384 return (Name.starts_with(
"vfmadd.") ||
385 Name.starts_with(
"vfmaddsub.") ||
386 Name.starts_with(
"vfmsub.") ||
387 Name.starts_with(
"vfmsubadd.") ||
388 Name.starts_with(
"vfnmsub."));
390 if (Name.consume_front(
"maskz."))
392 return (Name.starts_with(
"pternlog.") ||
393 Name.starts_with(
"vfmadd.") ||
394 Name.starts_with(
"vfmaddsub.") ||
395 Name.starts_with(
"vpdpbusd.") ||
396 Name.starts_with(
"vpdpbusds.") ||
397 Name.starts_with(
"vpdpwssd.") ||
398 Name.starts_with(
"vpdpwssds.") ||
399 Name.starts_with(
"vpermt2var.") ||
400 Name.starts_with(
"vpmadd52") ||
401 Name.starts_with(
"vpshldv.") ||
402 Name.starts_with(
"vpshrdv."));
405 return (Name ==
"movntdqa" ||
406 Name ==
"pmul.dq.512" ||
407 Name ==
"pmulu.dq.512" ||
408 Name.starts_with(
"broadcastm") ||
409 Name.starts_with(
"cmp.p") ||
410 Name.starts_with(
"cvtb2mask.") ||
411 Name.starts_with(
"cvtd2mask.") ||
412 Name.starts_with(
"cvtmask2") ||
413 Name.starts_with(
"cvtq2mask.") ||
414 Name ==
"cvtusi2sd" ||
415 Name.starts_with(
"cvtw2mask.") ||
420 Name ==
"kortestc.w" ||
421 Name ==
"kortestz.w" ||
422 Name.starts_with(
"kunpck") ||
425 Name.starts_with(
"padds.") ||
426 Name.starts_with(
"pbroadcast") ||
427 Name.starts_with(
"prol") ||
428 Name.starts_with(
"pror") ||
429 Name.starts_with(
"psll.dq") ||
430 Name.starts_with(
"psrl.dq") ||
431 Name.starts_with(
"psubs.") ||
432 Name.starts_with(
"ptestm") ||
433 Name.starts_with(
"ptestnm") ||
434 Name.starts_with(
"storent.") ||
435 Name.starts_with(
"vbroadcast.s") ||
436 Name.starts_with(
"vpshld.") ||
437 Name.starts_with(
"vpshrd."));
440 if (Name.consume_front(
"fma."))
441 return (Name.starts_with(
"vfmadd.") ||
442 Name.starts_with(
"vfmsub.") ||
443 Name.starts_with(
"vfmsubadd.") ||
444 Name.starts_with(
"vfnmadd.") ||
445 Name.starts_with(
"vfnmsub."));
447 if (Name.consume_front(
"fma4."))
448 return Name.starts_with(
"vfmadd.s");
450 if (Name.consume_front(
"sse."))
451 return (Name ==
"add.ss" ||
452 Name ==
"cvtsi2ss" ||
453 Name ==
"cvtsi642ss" ||
456 Name.starts_with(
"sqrt.p") ||
458 Name.starts_with(
"storeu.") ||
461 if (Name.consume_front(
"sse2."))
462 return (Name ==
"add.sd" ||
463 Name ==
"cvtdq2pd" ||
464 Name ==
"cvtdq2ps" ||
465 Name ==
"cvtps2pd" ||
466 Name ==
"cvtsi2sd" ||
467 Name ==
"cvtsi642sd" ||
468 Name ==
"cvtss2sd" ||
471 Name.starts_with(
"padds.") ||
472 Name.starts_with(
"paddus.") ||
473 Name.starts_with(
"pcmpeq.") ||
474 Name.starts_with(
"pcmpgt.") ||
479 Name ==
"pmulu.dq" ||
480 Name.starts_with(
"pshuf") ||
481 Name.starts_with(
"psll.dq") ||
482 Name.starts_with(
"psrl.dq") ||
483 Name.starts_with(
"psubs.") ||
484 Name.starts_with(
"psubus.") ||
485 Name.starts_with(
"sqrt.p") ||
487 Name ==
"storel.dq" ||
488 Name.starts_with(
"storeu.") ||
491 if (Name.consume_front(
"sse41."))
492 return (Name.starts_with(
"blendp") ||
493 Name ==
"movntdqa" ||
503 Name.starts_with(
"pmovsx") ||
504 Name.starts_with(
"pmovzx") ||
507 if (Name.consume_front(
"sse42."))
508 return Name ==
"crc32.64.8";
510 if (Name.consume_front(
"sse4a."))
511 return Name.starts_with(
"movnt.");
513 if (Name.consume_front(
"ssse3."))
514 return (Name ==
"pabs.b.128" ||
515 Name ==
"pabs.d.128" ||
516 Name ==
"pabs.w.128");
518 if (Name.consume_front(
"xop."))
519 return (Name ==
"vpcmov" ||
520 Name ==
"vpcmov.256" ||
521 Name.starts_with(
"vpcom") ||
522 Name.starts_with(
"vprot"));
524 return (Name ==
"addcarry.u32" ||
525 Name ==
"addcarry.u64" ||
526 Name ==
"addcarryx.u32" ||
527 Name ==
"addcarryx.u64" ||
528 Name ==
"subborrow.u32" ||
529 Name ==
"subborrow.u64" ||
530 Name.starts_with(
"vcvtph2ps."));
536 if (!Name.consume_front(
"x86."))
544 if (Name ==
"rdtscp") {
546 if (
F->getFunctionType()->getNumParams() == 0)
551 Intrinsic::x86_rdtscp);
558 if (Name.consume_front(
"sse41.ptest")) {
560 .
Case(
"c", Intrinsic::x86_sse41_ptestc)
561 .
Case(
"z", Intrinsic::x86_sse41_ptestz)
562 .
Case(
"nzc", Intrinsic::x86_sse41_ptestnzc)
575 .
Case(
"sse41.insertps", Intrinsic::x86_sse41_insertps)
576 .
Case(
"sse41.dppd", Intrinsic::x86_sse41_dppd)
577 .
Case(
"sse41.dpps", Intrinsic::x86_sse41_dpps)
578 .
Case(
"sse41.mpsadbw", Intrinsic::x86_sse41_mpsadbw)
579 .
Case(
"avx.dp.ps.256", Intrinsic::x86_avx_dp_ps_256)
580 .
Case(
"avx2.mpsadbw", Intrinsic::x86_avx2_mpsadbw)
585 if (Name.consume_front(
"avx512.")) {
586 if (Name.consume_front(
"mask.cmp.")) {
589 .
Case(
"pd.128", Intrinsic::x86_avx512_mask_cmp_pd_128)
590 .
Case(
"pd.256", Intrinsic::x86_avx512_mask_cmp_pd_256)
591 .
Case(
"pd.512", Intrinsic::x86_avx512_mask_cmp_pd_512)
592 .
Case(
"ps.128", Intrinsic::x86_avx512_mask_cmp_ps_128)
593 .
Case(
"ps.256", Intrinsic::x86_avx512_mask_cmp_ps_256)
594 .
Case(
"ps.512", Intrinsic::x86_avx512_mask_cmp_ps_512)
598 }
else if (Name.starts_with(
"vpdpbusd.") ||
599 Name.starts_with(
"vpdpbusds.")) {
602 .
Case(
"vpdpbusd.128", Intrinsic::x86_avx512_vpdpbusd_128)
603 .
Case(
"vpdpbusd.256", Intrinsic::x86_avx512_vpdpbusd_256)
604 .
Case(
"vpdpbusd.512", Intrinsic::x86_avx512_vpdpbusd_512)
605 .
Case(
"vpdpbusds.128", Intrinsic::x86_avx512_vpdpbusds_128)
606 .
Case(
"vpdpbusds.256", Intrinsic::x86_avx512_vpdpbusds_256)
607 .
Case(
"vpdpbusds.512", Intrinsic::x86_avx512_vpdpbusds_512)
611 }
else if (Name.starts_with(
"vpdpwssd.") ||
612 Name.starts_with(
"vpdpwssds.")) {
615 .
Case(
"vpdpwssd.128", Intrinsic::x86_avx512_vpdpwssd_128)
616 .
Case(
"vpdpwssd.256", Intrinsic::x86_avx512_vpdpwssd_256)
617 .
Case(
"vpdpwssd.512", Intrinsic::x86_avx512_vpdpwssd_512)
618 .
Case(
"vpdpwssds.128", Intrinsic::x86_avx512_vpdpwssds_128)
619 .
Case(
"vpdpwssds.256", Intrinsic::x86_avx512_vpdpwssds_256)
620 .
Case(
"vpdpwssds.512", Intrinsic::x86_avx512_vpdpwssds_512)
628 if (Name.consume_front(
"avx2.")) {
629 if (Name.consume_front(
"vpdpb")) {
632 .
Case(
"ssd.128", Intrinsic::x86_avx2_vpdpbssd_128)
633 .
Case(
"ssd.256", Intrinsic::x86_avx2_vpdpbssd_256)
634 .
Case(
"ssds.128", Intrinsic::x86_avx2_vpdpbssds_128)
635 .
Case(
"ssds.256", Intrinsic::x86_avx2_vpdpbssds_256)
636 .
Case(
"sud.128", Intrinsic::x86_avx2_vpdpbsud_128)
637 .
Case(
"sud.256", Intrinsic::x86_avx2_vpdpbsud_256)
638 .
Case(
"suds.128", Intrinsic::x86_avx2_vpdpbsuds_128)
639 .
Case(
"suds.256", Intrinsic::x86_avx2_vpdpbsuds_256)
640 .
Case(
"uud.128", Intrinsic::x86_avx2_vpdpbuud_128)
641 .
Case(
"uud.256", Intrinsic::x86_avx2_vpdpbuud_256)
642 .
Case(
"uuds.128", Intrinsic::x86_avx2_vpdpbuuds_128)
643 .
Case(
"uuds.256", Intrinsic::x86_avx2_vpdpbuuds_256)
647 }
else if (Name.consume_front(
"vpdpw")) {
650 .
Case(
"sud.128", Intrinsic::x86_avx2_vpdpwsud_128)
651 .
Case(
"sud.256", Intrinsic::x86_avx2_vpdpwsud_256)
652 .
Case(
"suds.128", Intrinsic::x86_avx2_vpdpwsuds_128)
653 .
Case(
"suds.256", Intrinsic::x86_avx2_vpdpwsuds_256)
654 .
Case(
"usd.128", Intrinsic::x86_avx2_vpdpwusd_128)
655 .
Case(
"usd.256", Intrinsic::x86_avx2_vpdpwusd_256)
656 .
Case(
"usds.128", Intrinsic::x86_avx2_vpdpwusds_128)
657 .
Case(
"usds.256", Intrinsic::x86_avx2_vpdpwusds_256)
658 .
Case(
"uud.128", Intrinsic::x86_avx2_vpdpwuud_128)
659 .
Case(
"uud.256", Intrinsic::x86_avx2_vpdpwuud_256)
660 .
Case(
"uuds.128", Intrinsic::x86_avx2_vpdpwuuds_128)
661 .
Case(
"uuds.256", Intrinsic::x86_avx2_vpdpwuuds_256)
669 if (Name.consume_front(
"avx10.")) {
670 if (Name.consume_front(
"vpdpb")) {
673 .
Case(
"ssd.512", Intrinsic::x86_avx10_vpdpbssd_512)
674 .
Case(
"ssds.512", Intrinsic::x86_avx10_vpdpbssds_512)
675 .
Case(
"sud.512", Intrinsic::x86_avx10_vpdpbsud_512)
676 .
Case(
"suds.512", Intrinsic::x86_avx10_vpdpbsuds_512)
677 .
Case(
"uud.512", Intrinsic::x86_avx10_vpdpbuud_512)
678 .
Case(
"uuds.512", Intrinsic::x86_avx10_vpdpbuuds_512)
682 }
else if (Name.consume_front(
"vpdpw")) {
684 .
Case(
"sud.512", Intrinsic::x86_avx10_vpdpwsud_512)
685 .
Case(
"suds.512", Intrinsic::x86_avx10_vpdpwsuds_512)
686 .
Case(
"usd.512", Intrinsic::x86_avx10_vpdpwusd_512)
687 .
Case(
"usds.512", Intrinsic::x86_avx10_vpdpwusds_512)
688 .
Case(
"uud.512", Intrinsic::x86_avx10_vpdpwuud_512)
689 .
Case(
"uuds.512", Intrinsic::x86_avx10_vpdpwuuds_512)
697 if (Name.consume_front(
"avx512bf16.")) {
700 .
Case(
"cvtne2ps2bf16.128",
701 Intrinsic::x86_avx512bf16_cvtne2ps2bf16_128)
702 .
Case(
"cvtne2ps2bf16.256",
703 Intrinsic::x86_avx512bf16_cvtne2ps2bf16_256)
704 .
Case(
"cvtne2ps2bf16.512",
705 Intrinsic::x86_avx512bf16_cvtne2ps2bf16_512)
706 .
Case(
"mask.cvtneps2bf16.128",
707 Intrinsic::x86_avx512bf16_mask_cvtneps2bf16_128)
708 .
Case(
"cvtneps2bf16.256",
709 Intrinsic::x86_avx512bf16_cvtneps2bf16_256)
710 .
Case(
"cvtneps2bf16.512",
711 Intrinsic::x86_avx512bf16_cvtneps2bf16_512)
718 .
Case(
"dpbf16ps.128", Intrinsic::x86_avx512bf16_dpbf16ps_128)
719 .
Case(
"dpbf16ps.256", Intrinsic::x86_avx512bf16_dpbf16ps_256)
720 .
Case(
"dpbf16ps.512", Intrinsic::x86_avx512bf16_dpbf16ps_512)
727 if (Name.consume_front(
"xop.")) {
729 if (Name.starts_with(
"vpermil2")) {
732 auto Idx =
F->getFunctionType()->getParamType(2);
733 if (Idx->isFPOrFPVectorTy()) {
734 unsigned IdxSize = Idx->getPrimitiveSizeInBits();
735 unsigned EltSize = Idx->getScalarSizeInBits();
736 if (EltSize == 64 && IdxSize == 128)
737 ID = Intrinsic::x86_xop_vpermil2pd;
738 else if (EltSize == 32 && IdxSize == 128)
739 ID = Intrinsic::x86_xop_vpermil2ps;
740 else if (EltSize == 64 && IdxSize == 256)
741 ID = Intrinsic::x86_xop_vpermil2pd_256;
743 ID = Intrinsic::x86_xop_vpermil2ps_256;
745 }
else if (
F->arg_size() == 2)
748 .
Case(
"vfrcz.ss", Intrinsic::x86_xop_vfrcz_ss)
749 .
Case(
"vfrcz.sd", Intrinsic::x86_xop_vfrcz_sd)
760 if (Name ==
"seh.recoverfp") {
762 Intrinsic::eh_recoverfp);
774 if (Name.starts_with(
"rbit")) {
777 F->getParent(), Intrinsic::bitreverse,
F->arg_begin()->getType());
781 if (Name ==
"thread.pointer") {
784 F->getParent(), Intrinsic::thread_pointer,
F->getReturnType());
788 bool Neon = Name.consume_front(
"neon.");
793 if (Name.consume_front(
"bfdot.")) {
797 .
Cases({
"v2f32.v8i8",
"v4f32.v16i8"},
802 size_t OperandWidth =
F->getReturnType()->getPrimitiveSizeInBits();
803 assert((OperandWidth == 64 || OperandWidth == 128) &&
804 "Unexpected operand width");
806 std::array<Type *, 2> Tys{
817 if (Name.consume_front(
"bfm")) {
819 if (Name.consume_back(
".v4f32.v16i8")) {
865 F->arg_begin()->getType());
869 if (Name.consume_front(
"vst")) {
871 static const Regex vstRegex(
"^([1234]|[234]lane)\\.v[a-z0-9]*$");
875 Intrinsic::arm_neon_vst1, Intrinsic::arm_neon_vst2,
876 Intrinsic::arm_neon_vst3, Intrinsic::arm_neon_vst4};
879 Intrinsic::arm_neon_vst2lane, Intrinsic::arm_neon_vst3lane,
880 Intrinsic::arm_neon_vst4lane};
882 auto fArgs =
F->getFunctionType()->params();
883 Type *Tys[] = {fArgs[0], fArgs[1]};
886 F->getParent(), StoreInts[fArgs.size() - 3], Tys);
889 F->getParent(), StoreLaneInts[fArgs.size() - 5], Tys);
898 if (Name.consume_front(
"mve.")) {
900 if (Name ==
"vctp64") {
910 if (Name.starts_with(
"vrintn.v")) {
912 F->getParent(), Intrinsic::roundeven,
F->arg_begin()->getType());
917 if (Name.consume_back(
".v4i1")) {
919 if (Name.consume_back(
".predicated.v2i64.v4i32"))
921 return Name ==
"mull.int" || Name ==
"vqdmull";
923 if (Name.consume_back(
".v2i64")) {
925 bool IsGather = Name.consume_front(
"vldr.gather.");
926 if (IsGather || Name.consume_front(
"vstr.scatter.")) {
927 if (Name.consume_front(
"base.")) {
929 Name.consume_front(
"wb.");
932 return Name ==
"predicated.v2i64";
935 if (Name.consume_front(
"offset.predicated."))
936 return Name == (IsGather ?
"v2i64.p0i64" :
"p0i64.v2i64") ||
937 Name == (IsGather ?
"v2i64.p0" :
"p0.v2i64");
950 if (Name.consume_front(
"cde.vcx")) {
952 if (Name.consume_back(
".predicated.v2i64.v4i1"))
954 return Name ==
"1q" || Name ==
"1qa" || Name ==
"2q" || Name ==
"2qa" ||
955 Name ==
"3q" || Name ==
"3qa";
969 F->arg_begin()->getType());
973 if (Name.starts_with(
"addp")) {
975 if (
F->arg_size() != 2)
978 if (Ty && Ty->getElementType()->isFloatingPointTy()) {
980 F->getParent(), Intrinsic::aarch64_neon_faddp, Ty);
986 if (Name.starts_with(
"bfcvt")) {
993 if (Name.consume_front(
"sve.")) {
995 if (Name.consume_front(
"bf")) {
996 if (Name.consume_back(
".lane")) {
1000 .
Case(
"dot", Intrinsic::aarch64_sve_bfdot_lane_v2)
1001 .
Case(
"mlalb", Intrinsic::aarch64_sve_bfmlalb_lane_v2)
1002 .
Case(
"mlalt", Intrinsic::aarch64_sve_bfmlalt_lane_v2)
1014 if (Name ==
"fcvt.bf16f32" || Name ==
"fcvtnt.bf16f32") {
1019 if (Name.consume_front(
"addqv")) {
1021 if (!
F->getReturnType()->isFPOrFPVectorTy())
1024 auto Args =
F->getFunctionType()->params();
1025 Type *Tys[] = {
F->getReturnType(), Args[1]};
1027 F->getParent(), Intrinsic::aarch64_sve_faddqv, Tys);
1031 if (Name.consume_front(
"ld")) {
1033 static const Regex LdRegex(
"^[234](.nxv[a-z0-9]+|$)");
1034 if (LdRegex.
match(Name)) {
1041 Intrinsic::aarch64_sve_ld2_sret,
1042 Intrinsic::aarch64_sve_ld3_sret,
1043 Intrinsic::aarch64_sve_ld4_sret,
1046 LoadIDs[Name[0] -
'2'], Ty);
1052 if (Name.consume_front(
"tuple.")) {
1054 if (Name.starts_with(
"get")) {
1056 Type *Tys[] = {
F->getReturnType(),
F->arg_begin()->getType()};
1058 F->getParent(), Intrinsic::vector_extract, Tys);
1062 if (Name.starts_with(
"set")) {
1064 auto Args =
F->getFunctionType()->params();
1065 Type *Tys[] = {Args[0], Args[2], Args[1]};
1067 F->getParent(), Intrinsic::vector_insert, Tys);
1071 static const Regex CreateTupleRegex(
"^create[234](.nxv[a-z0-9]+|$)");
1072 if (CreateTupleRegex.
match(Name)) {
1074 auto Args =
F->getFunctionType()->params();
1075 Type *Tys[] = {
F->getReturnType(), Args[1]};
1077 F->getParent(), Intrinsic::vector_insert, Tys);
1083 if (Name.starts_with(
"rev.nxv")) {
1086 F->getParent(), Intrinsic::vector_reverse,
F->getReturnType());
1098 if (Name.consume_front(
"cp.async.bulk.tensor.g2s.")) {
1102 Intrinsic::nvvm_cp_async_bulk_tensor_g2s_im2col_3d)
1104 Intrinsic::nvvm_cp_async_bulk_tensor_g2s_im2col_4d)
1106 Intrinsic::nvvm_cp_async_bulk_tensor_g2s_im2col_5d)
1107 .
Case(
"tile.1d", Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_1d)
1108 .
Case(
"tile.2d", Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_2d)
1109 .
Case(
"tile.3d", Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_3d)
1110 .
Case(
"tile.4d", Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_4d)
1111 .
Case(
"tile.5d", Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_5d)
1120 if (
F->getArg(0)->getType()->getPointerAddressSpace() ==
1134 size_t FlagStartIndex =
F->getFunctionType()->getNumParams() - 3;
1135 Type *ArgType =
F->getFunctionType()->getParamType(FlagStartIndex);
1145 if (Name.consume_front(
"mapa.shared.cluster"))
1146 if (
F->getReturnType()->getPointerAddressSpace() ==
1148 return Intrinsic::nvvm_mapa_shared_cluster;
1150 if (Name.consume_front(
"cp.async.bulk.")) {
1153 .
Case(
"global.to.shared.cluster",
1154 Intrinsic::nvvm_cp_async_bulk_global_to_shared_cluster)
1155 .
Case(
"shared.cta.to.cluster",
1156 Intrinsic::nvvm_cp_async_bulk_shared_cta_to_cluster)
1160 if (
F->getArg(0)->getType()->getPointerAddressSpace() ==
1169 if (Name.consume_front(
"fma.rn."))
1171 .
Case(
"bf16", Intrinsic::nvvm_fma_rn_bf16)
1172 .
Case(
"bf16x2", Intrinsic::nvvm_fma_rn_bf16x2)
1173 .
Case(
"ftz.bf16", Intrinsic::nvvm_fma_rn_ftz_bf16)
1174 .
Case(
"ftz.bf16x2", Intrinsic::nvvm_fma_rn_ftz_bf16x2)
1175 .
Case(
"ftz.relu.bf16", Intrinsic::nvvm_fma_rn_ftz_relu_bf16)
1176 .
Case(
"ftz.relu.bf16x2", Intrinsic::nvvm_fma_rn_ftz_relu_bf16x2)
1177 .
Case(
"ftz.sat.bf16", Intrinsic::nvvm_fma_rn_ftz_sat_bf16)
1178 .
Case(
"ftz.sat.bf16x2", Intrinsic::nvvm_fma_rn_ftz_sat_bf16x2)
1179 .
Case(
"relu.bf16", Intrinsic::nvvm_fma_rn_relu_bf16)
1180 .
Case(
"relu.bf16x2", Intrinsic::nvvm_fma_rn_relu_bf16x2)
1181 .
Case(
"sat.bf16", Intrinsic::nvvm_fma_rn_sat_bf16)
1182 .
Case(
"sat.bf16x2", Intrinsic::nvvm_fma_rn_sat_bf16x2)
1185 if (Name.consume_front(
"fmax."))
1187 .
Case(
"bf16", Intrinsic::nvvm_fmax_bf16)
1188 .
Case(
"bf16x2", Intrinsic::nvvm_fmax_bf16x2)
1189 .
Case(
"ftz.bf16", Intrinsic::nvvm_fmax_ftz_bf16)
1190 .
Case(
"ftz.bf16x2", Intrinsic::nvvm_fmax_ftz_bf16x2)
1191 .
Case(
"ftz.nan.bf16", Intrinsic::nvvm_fmax_ftz_nan_bf16)
1192 .
Case(
"ftz.nan.bf16x2", Intrinsic::nvvm_fmax_ftz_nan_bf16x2)
1193 .
Case(
"ftz.nan.xorsign.abs.bf16",
1194 Intrinsic::nvvm_fmax_ftz_nan_xorsign_abs_bf16)
1195 .
Case(
"ftz.nan.xorsign.abs.bf16x2",
1196 Intrinsic::nvvm_fmax_ftz_nan_xorsign_abs_bf16x2)
1197 .
Case(
"ftz.xorsign.abs.bf16", Intrinsic::nvvm_fmax_ftz_xorsign_abs_bf16)
1198 .
Case(
"ftz.xorsign.abs.bf16x2",
1199 Intrinsic::nvvm_fmax_ftz_xorsign_abs_bf16x2)
1200 .
Case(
"nan.bf16", Intrinsic::nvvm_fmax_nan_bf16)
1201 .
Case(
"nan.bf16x2", Intrinsic::nvvm_fmax_nan_bf16x2)
1202 .
Case(
"nan.xorsign.abs.bf16", Intrinsic::nvvm_fmax_nan_xorsign_abs_bf16)
1203 .
Case(
"nan.xorsign.abs.bf16x2",
1204 Intrinsic::nvvm_fmax_nan_xorsign_abs_bf16x2)
1205 .
Case(
"xorsign.abs.bf16", Intrinsic::nvvm_fmax_xorsign_abs_bf16)
1206 .
Case(
"xorsign.abs.bf16x2", Intrinsic::nvvm_fmax_xorsign_abs_bf16x2)
1209 if (Name.consume_front(
"fmin."))
1211 .
Case(
"bf16", Intrinsic::nvvm_fmin_bf16)
1212 .
Case(
"bf16x2", Intrinsic::nvvm_fmin_bf16x2)
1213 .
Case(
"ftz.bf16", Intrinsic::nvvm_fmin_ftz_bf16)
1214 .
Case(
"ftz.bf16x2", Intrinsic::nvvm_fmin_ftz_bf16x2)
1215 .
Case(
"ftz.nan.bf16", Intrinsic::nvvm_fmin_ftz_nan_bf16)
1216 .
Case(
"ftz.nan.bf16x2", Intrinsic::nvvm_fmin_ftz_nan_bf16x2)
1217 .
Case(
"ftz.nan.xorsign.abs.bf16",
1218 Intrinsic::nvvm_fmin_ftz_nan_xorsign_abs_bf16)
1219 .
Case(
"ftz.nan.xorsign.abs.bf16x2",
1220 Intrinsic::nvvm_fmin_ftz_nan_xorsign_abs_bf16x2)
1221 .
Case(
"ftz.xorsign.abs.bf16", Intrinsic::nvvm_fmin_ftz_xorsign_abs_bf16)
1222 .
Case(
"ftz.xorsign.abs.bf16x2",
1223 Intrinsic::nvvm_fmin_ftz_xorsign_abs_bf16x2)
1224 .
Case(
"nan.bf16", Intrinsic::nvvm_fmin_nan_bf16)
1225 .
Case(
"nan.bf16x2", Intrinsic::nvvm_fmin_nan_bf16x2)
1226 .
Case(
"nan.xorsign.abs.bf16", Intrinsic::nvvm_fmin_nan_xorsign_abs_bf16)
1227 .
Case(
"nan.xorsign.abs.bf16x2",
1228 Intrinsic::nvvm_fmin_nan_xorsign_abs_bf16x2)
1229 .
Case(
"xorsign.abs.bf16", Intrinsic::nvvm_fmin_xorsign_abs_bf16)
1230 .
Case(
"xorsign.abs.bf16x2", Intrinsic::nvvm_fmin_xorsign_abs_bf16x2)
1233 if (Name.consume_front(
"neg."))
1235 .
Case(
"bf16", Intrinsic::nvvm_neg_bf16)
1236 .
Case(
"bf16x2", Intrinsic::nvvm_neg_bf16x2)
1243 return Name.consume_front(
"local") || Name.consume_front(
"shared") ||
1244 Name.consume_front(
"global") || Name.consume_front(
"constant") ||
1245 Name.consume_front(
"param");
1249 bool CanUpgradeDebugIntrinsicsToRecords) {
1250 assert(
F &&
"Illegal to upgrade a non-existent Function.");
1255 if (!Name.consume_front(
"llvm.") || Name.empty())
1261 bool IsArm = Name.consume_front(
"arm.");
1262 if (IsArm || Name.consume_front(
"aarch64.")) {
1268 if (Name.consume_front(
"amdgcn.")) {
1269 if (Name ==
"alignbit") {
1272 F->getParent(), Intrinsic::fshr, {F->getReturnType()});
1276 if (Name.consume_front(
"atomic.")) {
1277 if (Name.starts_with(
"inc") || Name.starts_with(
"dec") ||
1278 Name.starts_with(
"cond.sub") || Name.starts_with(
"csub")) {
1287 if (Name.consume_front(
"ds.") || Name.consume_front(
"global.atomic.") ||
1288 Name.consume_front(
"flat.atomic.")) {
1289 if (Name.starts_with(
"fadd") ||
1291 (Name.starts_with(
"fmin") && !Name.starts_with(
"fmin.num")) ||
1292 (Name.starts_with(
"fmax") && !Name.starts_with(
"fmax.num"))) {
1300 if (Name.starts_with(
"ldexp.")) {
1303 F->getParent(), Intrinsic::ldexp,
1304 {F->getReturnType(), F->getArg(1)->getType()});
1313 if (
F->arg_size() == 1) {
1321 F->arg_begin()->getType());
1326 if (
F->arg_size() == 2 && Name ==
"coro.end") {
1329 Intrinsic::coro_end);
1336 if (Name.consume_front(
"dbg.")) {
1338 if (CanUpgradeDebugIntrinsicsToRecords) {
1339 if (Name ==
"addr" || Name ==
"value" || Name ==
"assign" ||
1340 Name ==
"declare" || Name ==
"label") {
1349 if (Name ==
"addr" || (Name ==
"value" &&
F->arg_size() == 4)) {
1352 Intrinsic::dbg_value);
1359 if (Name.consume_front(
"experimental.vector.")) {
1365 .
StartsWith(
"extract.", Intrinsic::vector_extract)
1366 .
StartsWith(
"insert.", Intrinsic::vector_insert)
1367 .
StartsWith(
"splice.", Intrinsic::vector_splice)
1368 .
StartsWith(
"reverse.", Intrinsic::vector_reverse)
1369 .
StartsWith(
"interleave2.", Intrinsic::vector_interleave2)
1370 .
StartsWith(
"deinterleave2.", Intrinsic::vector_deinterleave2)
1372 Intrinsic::vector_partial_reduce_add)
1375 const auto *FT =
F->getFunctionType();
1377 if (
ID == Intrinsic::vector_extract ||
1378 ID == Intrinsic::vector_interleave2)
1381 if (
ID != Intrinsic::vector_interleave2)
1383 if (
ID == Intrinsic::vector_insert ||
1384 ID == Intrinsic::vector_partial_reduce_add)
1392 if (Name.consume_front(
"reduce.")) {
1394 static const Regex R(
"^([a-z]+)\\.[a-z][0-9]+");
1395 if (R.match(Name, &
Groups))
1397 .
Case(
"add", Intrinsic::vector_reduce_add)
1398 .
Case(
"mul", Intrinsic::vector_reduce_mul)
1399 .
Case(
"and", Intrinsic::vector_reduce_and)
1400 .
Case(
"or", Intrinsic::vector_reduce_or)
1401 .
Case(
"xor", Intrinsic::vector_reduce_xor)
1402 .
Case(
"smax", Intrinsic::vector_reduce_smax)
1403 .
Case(
"smin", Intrinsic::vector_reduce_smin)
1404 .
Case(
"umax", Intrinsic::vector_reduce_umax)
1405 .
Case(
"umin", Intrinsic::vector_reduce_umin)
1406 .
Case(
"fmax", Intrinsic::vector_reduce_fmax)
1407 .
Case(
"fmin", Intrinsic::vector_reduce_fmin)
1412 static const Regex R2(
"^v2\\.([a-z]+)\\.[fi][0-9]+");
1417 .
Case(
"fadd", Intrinsic::vector_reduce_fadd)
1418 .
Case(
"fmul", Intrinsic::vector_reduce_fmul)
1423 auto Args =
F->getFunctionType()->params();
1425 {Args[V2 ? 1 : 0]});
1432 if (Name.consume_front(
"experimental.stepvector.")) {
1436 F->getParent(),
ID,
F->getFunctionType()->getReturnType());
1441 if (Name.starts_with(
"flt.rounds")) {
1444 Intrinsic::get_rounding);
1449 if (Name.starts_with(
"invariant.group.barrier")) {
1451 auto Args =
F->getFunctionType()->params();
1452 Type* ObjectPtr[1] = {Args[0]};
1455 F->getParent(), Intrinsic::launder_invariant_group, ObjectPtr);
1460 if ((Name.starts_with(
"lifetime.start") ||
1461 Name.starts_with(
"lifetime.end")) &&
1462 F->arg_size() == 2) {
1464 ? Intrinsic::lifetime_start
1465 : Intrinsic::lifetime_end;
1468 F->getArg(0)->getType());
1477 .StartsWith(
"memcpy.", Intrinsic::memcpy)
1478 .StartsWith(
"memmove.", Intrinsic::memmove)
1480 if (
F->arg_size() == 5) {
1484 F->getFunctionType()->params().slice(0, 3);
1490 if (Name.starts_with(
"memset.") &&
F->arg_size() == 5) {
1493 const auto *FT =
F->getFunctionType();
1494 Type *ParamTypes[2] = {
1495 FT->getParamType(0),
1499 Intrinsic::memset, ParamTypes);
1505 .
StartsWith(
"masked.load", Intrinsic::masked_load)
1506 .
StartsWith(
"masked.gather", Intrinsic::masked_gather)
1507 .
StartsWith(
"masked.store", Intrinsic::masked_store)
1508 .
StartsWith(
"masked.scatter", Intrinsic::masked_scatter)
1510 if (MaskedID &&
F->arg_size() == 4) {
1512 if (MaskedID == Intrinsic::masked_load ||
1513 MaskedID == Intrinsic::masked_gather) {
1515 F->getParent(), MaskedID,
1516 {F->getReturnType(), F->getArg(0)->getType()});
1520 F->getParent(), MaskedID,
1521 {F->getArg(0)->getType(), F->getArg(1)->getType()});
1527 if (Name.consume_front(
"nvvm.")) {
1529 if (
F->arg_size() == 1) {
1532 .
Cases({
"brev32",
"brev64"}, Intrinsic::bitreverse)
1533 .Case(
"clz.i", Intrinsic::ctlz)
1534 .
Case(
"popc.i", Intrinsic::ctpop)
1538 {F->getReturnType()});
1544 if (!
F->getReturnType()->getScalarType()->isBFloatTy()) {
1572 bool Expand =
false;
1573 if (Name.consume_front(
"abs."))
1576 Name ==
"i" || Name ==
"ll" || Name ==
"bf16" || Name ==
"bf16x2";
1577 else if (Name.consume_front(
"fabs."))
1579 Expand = Name ==
"f" || Name ==
"ftz.f" || Name ==
"d";
1580 else if (Name.consume_front(
"ex2.approx."))
1583 Name ==
"f" || Name ==
"ftz.f" || Name ==
"d" || Name ==
"f16x2";
1584 else if (Name.consume_front(
"max.") || Name.consume_front(
"min."))
1586 Expand = Name ==
"s" || Name ==
"i" || Name ==
"ll" || Name ==
"us" ||
1587 Name ==
"ui" || Name ==
"ull";
1588 else if (Name.consume_front(
"atomic.load."))
1597 else if (Name.consume_front(
"bitcast."))
1600 Name ==
"f2i" || Name ==
"i2f" || Name ==
"ll2d" || Name ==
"d2ll";
1601 else if (Name.consume_front(
"rotate."))
1603 Expand = Name ==
"b32" || Name ==
"b64" || Name ==
"right.b64";
1604 else if (Name.consume_front(
"ptr.gen.to."))
1607 else if (Name.consume_front(
"ptr."))
1610 else if (Name.consume_front(
"ldg.global."))
1612 Expand = (Name.starts_with(
"i.") || Name.starts_with(
"f.") ||
1613 Name.starts_with(
"p."));
1616 .
Case(
"barrier0",
true)
1617 .
Case(
"barrier.n",
true)
1618 .
Case(
"barrier.sync.cnt",
true)
1619 .
Case(
"barrier.sync",
true)
1620 .
Case(
"barrier",
true)
1621 .
Case(
"bar.sync",
true)
1622 .
Case(
"clz.ll",
true)
1623 .
Case(
"popc.ll",
true)
1625 .
Case(
"swap.lo.hi.b64",
true)
1626 .
Case(
"tanh.approx.f32",
true)
1638 if (Name.starts_with(
"objectsize.")) {
1639 Type *Tys[2] = {
F->getReturnType(),
F->arg_begin()->getType() };
1640 if (
F->arg_size() == 2 ||
F->arg_size() == 3) {
1643 Intrinsic::objectsize, Tys);
1650 if (Name.starts_with(
"ptr.annotation.") &&
F->arg_size() == 4) {
1653 F->getParent(), Intrinsic::ptr_annotation,
1654 {F->arg_begin()->getType(), F->getArg(1)->getType()});
1660 if (Name.consume_front(
"riscv.")) {
1663 .
Case(
"aes32dsi", Intrinsic::riscv_aes32dsi)
1664 .
Case(
"aes32dsmi", Intrinsic::riscv_aes32dsmi)
1665 .
Case(
"aes32esi", Intrinsic::riscv_aes32esi)
1666 .
Case(
"aes32esmi", Intrinsic::riscv_aes32esmi)
1669 if (!
F->getFunctionType()->getParamType(2)->isIntegerTy(32)) {
1682 if (!
F->getFunctionType()->getParamType(2)->isIntegerTy(32) ||
1683 F->getFunctionType()->getReturnType()->isIntegerTy(64)) {
1692 .
StartsWith(
"sha256sig0", Intrinsic::riscv_sha256sig0)
1693 .
StartsWith(
"sha256sig1", Intrinsic::riscv_sha256sig1)
1694 .
StartsWith(
"sha256sum0", Intrinsic::riscv_sha256sum0)
1695 .
StartsWith(
"sha256sum1", Intrinsic::riscv_sha256sum1)
1700 if (
F->getFunctionType()->getReturnType()->isIntegerTy(64)) {
1712 if (Name ==
"stackprotectorcheck") {
1719 if (Name ==
"thread.pointer") {
1721 F->getParent(), Intrinsic::thread_pointer,
F->getReturnType());
1727 if (Name ==
"var.annotation" &&
F->arg_size() == 4) {
1730 F->getParent(), Intrinsic::var_annotation,
1731 {{F->arg_begin()->getType(), F->getArg(1)->getType()}});
1738 if (Name.consume_front(
"wasm.")) {
1741 .
StartsWith(
"fma.", Intrinsic::wasm_relaxed_madd)
1742 .
StartsWith(
"fms.", Intrinsic::wasm_relaxed_nmadd)
1743 .
StartsWith(
"laneselect.", Intrinsic::wasm_relaxed_laneselect)
1748 F->getReturnType());
1752 if (Name.consume_front(
"dot.i8x16.i7x16.")) {
1754 .
Case(
"signed", Intrinsic::wasm_relaxed_dot_i8x16_i7x16_signed)
1756 Intrinsic::wasm_relaxed_dot_i8x16_i7x16_add_signed)
1775 if (ST && (!
ST->isLiteral() ||
ST->isPacked()) &&
1784 auto *FT =
F->getFunctionType();
1787 std::string
Name =
F->getName().str();
1790 Name,
F->getParent());
1801 if (Result != std::nullopt) {
1814 bool CanUpgradeDebugIntrinsicsToRecords) {
1834 GV->
getName() ==
"llvm.global_dtors")) ||
1849 unsigned N =
Init->getNumOperands();
1850 std::vector<Constant *> NewCtors(
N);
1851 for (
unsigned i = 0; i !=
N; ++i) {
1854 Ctor->getAggregateElement(1),
1868 unsigned NumElts = ResultTy->getNumElements() * 8;
1872 Op = Builder.CreateBitCast(
Op, VecTy,
"cast");
1882 for (
unsigned l = 0; l != NumElts; l += 16)
1883 for (
unsigned i = 0; i != 16; ++i) {
1884 unsigned Idx = NumElts + i - Shift;
1886 Idx -= NumElts - 16;
1887 Idxs[l + i] = Idx + l;
1890 Res = Builder.CreateShuffleVector(Res,
Op,
ArrayRef(Idxs, NumElts));
1894 return Builder.CreateBitCast(Res, ResultTy,
"cast");
1902 unsigned NumElts = ResultTy->getNumElements() * 8;
1906 Op = Builder.CreateBitCast(
Op, VecTy,
"cast");
1916 for (
unsigned l = 0; l != NumElts; l += 16)
1917 for (
unsigned i = 0; i != 16; ++i) {
1918 unsigned Idx = i + Shift;
1920 Idx += NumElts - 16;
1921 Idxs[l + i] = Idx + l;
1924 Res = Builder.CreateShuffleVector(
Op, Res,
ArrayRef(Idxs, NumElts));
1928 return Builder.CreateBitCast(Res, ResultTy,
"cast");
1936 Mask = Builder.CreateBitCast(Mask, MaskTy);
1942 for (
unsigned i = 0; i != NumElts; ++i)
1944 Mask = Builder.CreateShuffleVector(Mask, Mask,
ArrayRef(Indices, NumElts),
1955 if (
C->isAllOnesValue())
1960 return Builder.CreateSelect(Mask, Op0, Op1);
1967 if (
C->isAllOnesValue())
1971 Mask->getType()->getIntegerBitWidth());
1972 Mask = Builder.CreateBitCast(Mask, MaskTy);
1973 Mask = Builder.CreateExtractElement(Mask, (
uint64_t)0);
1974 return Builder.CreateSelect(Mask, Op0, Op1);
1987 assert((IsVALIGN || NumElts % 16 == 0) &&
"Illegal NumElts for PALIGNR!");
1988 assert((!IsVALIGN || NumElts <= 16) &&
"NumElts too large for VALIGN!");
1993 ShiftVal &= (NumElts - 1);
2002 if (ShiftVal > 16) {
2010 for (
unsigned l = 0; l < NumElts; l += 16) {
2011 for (
unsigned i = 0; i != 16; ++i) {
2012 unsigned Idx = ShiftVal + i;
2013 if (!IsVALIGN && Idx >= 16)
2014 Idx += NumElts - 16;
2015 Indices[l + i] = Idx + l;
2020 Op1, Op0,
ArrayRef(Indices, NumElts),
"palignr");
2026 bool ZeroMask,
bool IndexForm) {
2029 unsigned EltWidth = Ty->getScalarSizeInBits();
2030 bool IsFloat = Ty->isFPOrFPVectorTy();
2032 if (VecWidth == 128 && EltWidth == 32 && IsFloat)
2033 IID = Intrinsic::x86_avx512_vpermi2var_ps_128;
2034 else if (VecWidth == 128 && EltWidth == 32 && !IsFloat)
2035 IID = Intrinsic::x86_avx512_vpermi2var_d_128;
2036 else if (VecWidth == 128 && EltWidth == 64 && IsFloat)
2037 IID = Intrinsic::x86_avx512_vpermi2var_pd_128;
2038 else if (VecWidth == 128 && EltWidth == 64 && !IsFloat)
2039 IID = Intrinsic::x86_avx512_vpermi2var_q_128;
2040 else if (VecWidth == 256 && EltWidth == 32 && IsFloat)
2041 IID = Intrinsic::x86_avx512_vpermi2var_ps_256;
2042 else if (VecWidth == 256 && EltWidth == 32 && !IsFloat)
2043 IID = Intrinsic::x86_avx512_vpermi2var_d_256;
2044 else if (VecWidth == 256 && EltWidth == 64 && IsFloat)
2045 IID = Intrinsic::x86_avx512_vpermi2var_pd_256;
2046 else if (VecWidth == 256 && EltWidth == 64 && !IsFloat)
2047 IID = Intrinsic::x86_avx512_vpermi2var_q_256;
2048 else if (VecWidth == 512 && EltWidth == 32 && IsFloat)
2049 IID = Intrinsic::x86_avx512_vpermi2var_ps_512;
2050 else if (VecWidth == 512 && EltWidth == 32 && !IsFloat)
2051 IID = Intrinsic::x86_avx512_vpermi2var_d_512;
2052 else if (VecWidth == 512 && EltWidth == 64 && IsFloat)
2053 IID = Intrinsic::x86_avx512_vpermi2var_pd_512;
2054 else if (VecWidth == 512 && EltWidth == 64 && !IsFloat)
2055 IID = Intrinsic::x86_avx512_vpermi2var_q_512;
2056 else if (VecWidth == 128 && EltWidth == 16)
2057 IID = Intrinsic::x86_avx512_vpermi2var_hi_128;
2058 else if (VecWidth == 256 && EltWidth == 16)
2059 IID = Intrinsic::x86_avx512_vpermi2var_hi_256;
2060 else if (VecWidth == 512 && EltWidth == 16)
2061 IID = Intrinsic::x86_avx512_vpermi2var_hi_512;
2062 else if (VecWidth == 128 && EltWidth == 8)
2063 IID = Intrinsic::x86_avx512_vpermi2var_qi_128;
2064 else if (VecWidth == 256 && EltWidth == 8)
2065 IID = Intrinsic::x86_avx512_vpermi2var_qi_256;
2066 else if (VecWidth == 512 && EltWidth == 8)
2067 IID = Intrinsic::x86_avx512_vpermi2var_qi_512;
2078 Value *V = Builder.CreateIntrinsic(IID, Args);
2090 Value *Res = Builder.CreateIntrinsic(IID, Ty, {Op0, Op1});
2101 bool IsRotateRight) {
2111 Amt = Builder.CreateIntCast(Amt, Ty->getScalarType(),
false);
2112 Amt = Builder.CreateVectorSplat(NumElts, Amt);
2115 Intrinsic::ID IID = IsRotateRight ? Intrinsic::fshr : Intrinsic::fshl;
2116 Value *Res = Builder.CreateIntrinsic(IID, Ty, {Src, Src, Amt});
2161 Value *Ext = Builder.CreateSExt(Cmp, Ty);
2166 bool IsShiftRight,
bool ZeroMask) {
2180 Amt = Builder.CreateIntCast(Amt, Ty->getScalarType(),
false);
2181 Amt = Builder.CreateVectorSplat(NumElts, Amt);
2184 Intrinsic::ID IID = IsShiftRight ? Intrinsic::fshr : Intrinsic::fshl;
2185 Value *Res = Builder.CreateIntrinsic(IID, Ty, {Op0, Op1, Amt});
2200 const Align Alignment =
2202 ?
Align(
Data->getType()->getPrimitiveSizeInBits().getFixedValue() / 8)
2207 if (
C->isAllOnesValue())
2208 return Builder.CreateAlignedStore(
Data, Ptr, Alignment);
2213 return Builder.CreateMaskedStore(
Data, Ptr, Alignment, Mask);
2219 const Align Alignment =
2228 if (
C->isAllOnesValue())
2229 return Builder.CreateAlignedLoad(ValTy, Ptr, Alignment);
2234 return Builder.CreateMaskedLoad(ValTy, Ptr, Alignment, Mask, Passthru);
2240 Value *Res = Builder.CreateIntrinsic(Intrinsic::abs, Ty,
2241 {Op0, Builder.getInt1(
false)});
2256 Constant *ShiftAmt = ConstantInt::get(Ty, 32);
2257 LHS = Builder.CreateShl(
LHS, ShiftAmt);
2258 LHS = Builder.CreateAShr(
LHS, ShiftAmt);
2259 RHS = Builder.CreateShl(
RHS, ShiftAmt);
2260 RHS = Builder.CreateAShr(
RHS, ShiftAmt);
2263 Constant *Mask = ConstantInt::get(Ty, 0xffffffff);
2264 LHS = Builder.CreateAnd(
LHS, Mask);
2265 RHS = Builder.CreateAnd(
RHS, Mask);
2282 if (!
C || !
C->isAllOnesValue())
2283 Vec = Builder.CreateAnd(Vec,
getX86MaskVec(Builder, Mask, NumElts));
2288 for (
unsigned i = 0; i != NumElts; ++i)
2290 for (
unsigned i = NumElts; i != 8; ++i)
2291 Indices[i] = NumElts + i % NumElts;
2292 Vec = Builder.CreateShuffleVector(Vec,
2296 return Builder.CreateBitCast(Vec, Builder.getIntNTy(std::max(NumElts, 8U)));
2300 unsigned CC,
bool Signed) {
2308 }
else if (CC == 7) {
2344 Value* AndNode = Builder.CreateAnd(Mask,
APInt(8, 1));
2345 Value* Cmp = Builder.CreateIsNotNull(AndNode);
2347 Value* Extract2 = Builder.CreateExtractElement(Src, (
uint64_t)0);
2348 Value*
Select = Builder.CreateSelect(Cmp, Extract1, Extract2);
2357 return Builder.CreateSExt(Mask, ReturnOp,
"vpmovm2");
2363 Name = Name.substr(12);
2368 if (Name.starts_with(
"max.p")) {
2369 if (VecWidth == 128 && EltWidth == 32)
2370 IID = Intrinsic::x86_sse_max_ps;
2371 else if (VecWidth == 128 && EltWidth == 64)
2372 IID = Intrinsic::x86_sse2_max_pd;
2373 else if (VecWidth == 256 && EltWidth == 32)
2374 IID = Intrinsic::x86_avx_max_ps_256;
2375 else if (VecWidth == 256 && EltWidth == 64)
2376 IID = Intrinsic::x86_avx_max_pd_256;
2379 }
else if (Name.starts_with(
"min.p")) {
2380 if (VecWidth == 128 && EltWidth == 32)
2381 IID = Intrinsic::x86_sse_min_ps;
2382 else if (VecWidth == 128 && EltWidth == 64)
2383 IID = Intrinsic::x86_sse2_min_pd;
2384 else if (VecWidth == 256 && EltWidth == 32)
2385 IID = Intrinsic::x86_avx_min_ps_256;
2386 else if (VecWidth == 256 && EltWidth == 64)
2387 IID = Intrinsic::x86_avx_min_pd_256;
2390 }
else if (Name.starts_with(
"pshuf.b.")) {
2391 if (VecWidth == 128)
2392 IID = Intrinsic::x86_ssse3_pshuf_b_128;
2393 else if (VecWidth == 256)
2394 IID = Intrinsic::x86_avx2_pshuf_b;
2395 else if (VecWidth == 512)
2396 IID = Intrinsic::x86_avx512_pshuf_b_512;
2399 }
else if (Name.starts_with(
"pmul.hr.sw.")) {
2400 if (VecWidth == 128)
2401 IID = Intrinsic::x86_ssse3_pmul_hr_sw_128;
2402 else if (VecWidth == 256)
2403 IID = Intrinsic::x86_avx2_pmul_hr_sw;
2404 else if (VecWidth == 512)
2405 IID = Intrinsic::x86_avx512_pmul_hr_sw_512;
2408 }
else if (Name.starts_with(
"pmulh.w.")) {
2409 if (VecWidth == 128)
2410 IID = Intrinsic::x86_sse2_pmulh_w;
2411 else if (VecWidth == 256)
2412 IID = Intrinsic::x86_avx2_pmulh_w;
2413 else if (VecWidth == 512)
2414 IID = Intrinsic::x86_avx512_pmulh_w_512;
2417 }
else if (Name.starts_with(
"pmulhu.w.")) {
2418 if (VecWidth == 128)
2419 IID = Intrinsic::x86_sse2_pmulhu_w;
2420 else if (VecWidth == 256)
2421 IID = Intrinsic::x86_avx2_pmulhu_w;
2422 else if (VecWidth == 512)
2423 IID = Intrinsic::x86_avx512_pmulhu_w_512;
2426 }
else if (Name.starts_with(
"pmaddw.d.")) {
2427 if (VecWidth == 128)
2428 IID = Intrinsic::x86_sse2_pmadd_wd;
2429 else if (VecWidth == 256)
2430 IID = Intrinsic::x86_avx2_pmadd_wd;
2431 else if (VecWidth == 512)
2432 IID = Intrinsic::x86_avx512_pmaddw_d_512;
2435 }
else if (Name.starts_with(
"pmaddubs.w.")) {
2436 if (VecWidth == 128)
2437 IID = Intrinsic::x86_ssse3_pmadd_ub_sw_128;
2438 else if (VecWidth == 256)
2439 IID = Intrinsic::x86_avx2_pmadd_ub_sw;
2440 else if (VecWidth == 512)
2441 IID = Intrinsic::x86_avx512_pmaddubs_w_512;
2444 }
else if (Name.starts_with(
"packsswb.")) {
2445 if (VecWidth == 128)
2446 IID = Intrinsic::x86_sse2_packsswb_128;
2447 else if (VecWidth == 256)
2448 IID = Intrinsic::x86_avx2_packsswb;
2449 else if (VecWidth == 512)
2450 IID = Intrinsic::x86_avx512_packsswb_512;
2453 }
else if (Name.starts_with(
"packssdw.")) {
2454 if (VecWidth == 128)
2455 IID = Intrinsic::x86_sse2_packssdw_128;
2456 else if (VecWidth == 256)
2457 IID = Intrinsic::x86_avx2_packssdw;
2458 else if (VecWidth == 512)
2459 IID = Intrinsic::x86_avx512_packssdw_512;
2462 }
else if (Name.starts_with(
"packuswb.")) {
2463 if (VecWidth == 128)
2464 IID = Intrinsic::x86_sse2_packuswb_128;
2465 else if (VecWidth == 256)
2466 IID = Intrinsic::x86_avx2_packuswb;
2467 else if (VecWidth == 512)
2468 IID = Intrinsic::x86_avx512_packuswb_512;
2471 }
else if (Name.starts_with(
"packusdw.")) {
2472 if (VecWidth == 128)
2473 IID = Intrinsic::x86_sse41_packusdw;
2474 else if (VecWidth == 256)
2475 IID = Intrinsic::x86_avx2_packusdw;
2476 else if (VecWidth == 512)
2477 IID = Intrinsic::x86_avx512_packusdw_512;
2480 }
else if (Name.starts_with(
"vpermilvar.")) {
2481 if (VecWidth == 128 && EltWidth == 32)
2482 IID = Intrinsic::x86_avx_vpermilvar_ps;
2483 else if (VecWidth == 128 && EltWidth == 64)
2484 IID = Intrinsic::x86_avx_vpermilvar_pd;
2485 else if (VecWidth == 256 && EltWidth == 32)
2486 IID = Intrinsic::x86_avx_vpermilvar_ps_256;
2487 else if (VecWidth == 256 && EltWidth == 64)
2488 IID = Intrinsic::x86_avx_vpermilvar_pd_256;
2489 else if (VecWidth == 512 && EltWidth == 32)
2490 IID = Intrinsic::x86_avx512_vpermilvar_ps_512;
2491 else if (VecWidth == 512 && EltWidth == 64)
2492 IID = Intrinsic::x86_avx512_vpermilvar_pd_512;
2495 }
else if (Name ==
"cvtpd2dq.256") {
2496 IID = Intrinsic::x86_avx_cvt_pd2dq_256;
2497 }
else if (Name ==
"cvtpd2ps.256") {
2498 IID = Intrinsic::x86_avx_cvt_pd2_ps_256;
2499 }
else if (Name ==
"cvttpd2dq.256") {
2500 IID = Intrinsic::x86_avx_cvtt_pd2dq_256;
2501 }
else if (Name ==
"cvttps2dq.128") {
2502 IID = Intrinsic::x86_sse2_cvttps2dq;
2503 }
else if (Name ==
"cvttps2dq.256") {
2504 IID = Intrinsic::x86_avx_cvtt_ps2dq_256;
2505 }
else if (Name.starts_with(
"permvar.")) {
2507 if (VecWidth == 256 && EltWidth == 32 && IsFloat)
2508 IID = Intrinsic::x86_avx2_permps;
2509 else if (VecWidth == 256 && EltWidth == 32 && !IsFloat)
2510 IID = Intrinsic::x86_avx2_permd;
2511 else if (VecWidth == 256 && EltWidth == 64 && IsFloat)
2512 IID = Intrinsic::x86_avx512_permvar_df_256;
2513 else if (VecWidth == 256 && EltWidth == 64 && !IsFloat)
2514 IID = Intrinsic::x86_avx512_permvar_di_256;
2515 else if (VecWidth == 512 && EltWidth == 32 && IsFloat)
2516 IID = Intrinsic::x86_avx512_permvar_sf_512;
2517 else if (VecWidth == 512 && EltWidth == 32 && !IsFloat)
2518 IID = Intrinsic::x86_avx512_permvar_si_512;
2519 else if (VecWidth == 512 && EltWidth == 64 && IsFloat)
2520 IID = Intrinsic::x86_avx512_permvar_df_512;
2521 else if (VecWidth == 512 && EltWidth == 64 && !IsFloat)
2522 IID = Intrinsic::x86_avx512_permvar_di_512;
2523 else if (VecWidth == 128 && EltWidth == 16)
2524 IID = Intrinsic::x86_avx512_permvar_hi_128;
2525 else if (VecWidth == 256 && EltWidth == 16)
2526 IID = Intrinsic::x86_avx512_permvar_hi_256;
2527 else if (VecWidth == 512 && EltWidth == 16)
2528 IID = Intrinsic::x86_avx512_permvar_hi_512;
2529 else if (VecWidth == 128 && EltWidth == 8)
2530 IID = Intrinsic::x86_avx512_permvar_qi_128;
2531 else if (VecWidth == 256 && EltWidth == 8)
2532 IID = Intrinsic::x86_avx512_permvar_qi_256;
2533 else if (VecWidth == 512 && EltWidth == 8)
2534 IID = Intrinsic::x86_avx512_permvar_qi_512;
2537 }
else if (Name.starts_with(
"dbpsadbw.")) {
2538 if (VecWidth == 128)
2539 IID = Intrinsic::x86_avx512_dbpsadbw_128;
2540 else if (VecWidth == 256)
2541 IID = Intrinsic::x86_avx512_dbpsadbw_256;
2542 else if (VecWidth == 512)
2543 IID = Intrinsic::x86_avx512_dbpsadbw_512;
2546 }
else if (Name.starts_with(
"pmultishift.qb.")) {
2547 if (VecWidth == 128)
2548 IID = Intrinsic::x86_avx512_pmultishift_qb_128;
2549 else if (VecWidth == 256)
2550 IID = Intrinsic::x86_avx512_pmultishift_qb_256;
2551 else if (VecWidth == 512)
2552 IID = Intrinsic::x86_avx512_pmultishift_qb_512;
2555 }
else if (Name.starts_with(
"conflict.")) {
2556 if (Name[9] ==
'd' && VecWidth == 128)
2557 IID = Intrinsic::x86_avx512_conflict_d_128;
2558 else if (Name[9] ==
'd' && VecWidth == 256)
2559 IID = Intrinsic::x86_avx512_conflict_d_256;
2560 else if (Name[9] ==
'd' && VecWidth == 512)
2561 IID = Intrinsic::x86_avx512_conflict_d_512;
2562 else if (Name[9] ==
'q' && VecWidth == 128)
2563 IID = Intrinsic::x86_avx512_conflict_q_128;
2564 else if (Name[9] ==
'q' && VecWidth == 256)
2565 IID = Intrinsic::x86_avx512_conflict_q_256;
2566 else if (Name[9] ==
'q' && VecWidth == 512)
2567 IID = Intrinsic::x86_avx512_conflict_q_512;
2570 }
else if (Name.starts_with(
"pavg.")) {
2571 if (Name[5] ==
'b' && VecWidth == 128)
2572 IID = Intrinsic::x86_sse2_pavg_b;
2573 else if (Name[5] ==
'b' && VecWidth == 256)
2574 IID = Intrinsic::x86_avx2_pavg_b;
2575 else if (Name[5] ==
'b' && VecWidth == 512)
2576 IID = Intrinsic::x86_avx512_pavg_b_512;
2577 else if (Name[5] ==
'w' && VecWidth == 128)
2578 IID = Intrinsic::x86_sse2_pavg_w;
2579 else if (Name[5] ==
'w' && VecWidth == 256)
2580 IID = Intrinsic::x86_avx2_pavg_w;
2581 else if (Name[5] ==
'w' && VecWidth == 512)
2582 IID = Intrinsic::x86_avx512_pavg_w_512;
2591 Rep = Builder.CreateIntrinsic(IID, Args);
2602 if (AsmStr->find(
"mov\tfp") == 0 &&
2603 AsmStr->find(
"objc_retainAutoreleaseReturnValue") != std::string::npos &&
2604 (Pos = AsmStr->find(
"# marker")) != std::string::npos) {
2605 AsmStr->replace(Pos, 1,
";");
2611 Value *Rep =
nullptr;
2613 if (Name ==
"abs.i" || Name ==
"abs.ll") {
2615 Value *Neg = Builder.CreateNeg(Arg,
"neg");
2616 Value *Cmp = Builder.CreateICmpSGE(
2618 Rep = Builder.CreateSelect(Cmp, Arg, Neg,
"abs");
2619 }
else if (Name ==
"abs.bf16" || Name ==
"abs.bf16x2") {
2620 Type *Ty = (Name ==
"abs.bf16")
2624 Value *Abs = Builder.CreateUnaryIntrinsic(Intrinsic::nvvm_fabs, Arg);
2625 Rep = Builder.CreateBitCast(Abs, CI->
getType());
2626 }
else if (Name ==
"fabs.f" || Name ==
"fabs.ftz.f" || Name ==
"fabs.d") {
2627 Intrinsic::ID IID = (Name ==
"fabs.ftz.f") ? Intrinsic::nvvm_fabs_ftz
2628 : Intrinsic::nvvm_fabs;
2629 Rep = Builder.CreateUnaryIntrinsic(IID, CI->
getArgOperand(0));
2630 }
else if (Name.consume_front(
"ex2.approx.")) {
2632 Intrinsic::ID IID = Name.starts_with(
"ftz") ? Intrinsic::nvvm_ex2_approx_ftz
2633 : Intrinsic::nvvm_ex2_approx;
2634 Rep = Builder.CreateUnaryIntrinsic(IID, CI->
getArgOperand(0));
2635 }
else if (Name.starts_with(
"atomic.load.add.f32.p") ||
2636 Name.starts_with(
"atomic.load.add.f64.p")) {
2641 }
else if (Name.starts_with(
"atomic.load.inc.32.p") ||
2642 Name.starts_with(
"atomic.load.dec.32.p")) {
2647 Rep = Builder.CreateAtomicRMW(
Op, Ptr, Val,
MaybeAlign(),
2649 }
else if (Name.consume_front(
"max.") &&
2650 (Name ==
"s" || Name ==
"i" || Name ==
"ll" || Name ==
"us" ||
2651 Name ==
"ui" || Name ==
"ull")) {
2654 Value *Cmp = Name.starts_with(
"u")
2655 ? Builder.CreateICmpUGE(Arg0, Arg1,
"max.cond")
2656 : Builder.CreateICmpSGE(Arg0, Arg1,
"max.cond");
2657 Rep = Builder.CreateSelect(Cmp, Arg0, Arg1,
"max");
2658 }
else if (Name.consume_front(
"min.") &&
2659 (Name ==
"s" || Name ==
"i" || Name ==
"ll" || Name ==
"us" ||
2660 Name ==
"ui" || Name ==
"ull")) {
2663 Value *Cmp = Name.starts_with(
"u")
2664 ? Builder.CreateICmpULE(Arg0, Arg1,
"min.cond")
2665 : Builder.CreateICmpSLE(Arg0, Arg1,
"min.cond");
2666 Rep = Builder.CreateSelect(Cmp, Arg0, Arg1,
"min");
2667 }
else if (Name ==
"clz.ll") {
2670 Value *Ctlz = Builder.CreateIntrinsic(Intrinsic::ctlz, {Arg->
getType()},
2671 {Arg, Builder.getFalse()},
2673 Rep = Builder.CreateTrunc(Ctlz, Builder.getInt32Ty(),
"ctlz.trunc");
2674 }
else if (Name ==
"popc.ll") {
2678 Value *Popc = Builder.CreateIntrinsic(Intrinsic::ctpop, {Arg->
getType()},
2679 Arg,
nullptr,
"ctpop");
2680 Rep = Builder.CreateTrunc(Popc, Builder.getInt32Ty(),
"ctpop.trunc");
2681 }
else if (Name ==
"h2f") {
2682 Rep = Builder.CreateIntrinsic(Intrinsic::convert_from_fp16,
2685 }
else if (Name.consume_front(
"bitcast.") &&
2686 (Name ==
"f2i" || Name ==
"i2f" || Name ==
"ll2d" ||
2689 }
else if (Name ==
"rotate.b32") {
2692 Rep = Builder.CreateIntrinsic(Builder.getInt32Ty(), Intrinsic::fshl,
2693 {Arg, Arg, ShiftAmt});
2694 }
else if (Name ==
"rotate.b64") {
2698 Rep = Builder.CreateIntrinsic(Int64Ty, Intrinsic::fshl,
2699 {Arg, Arg, ZExtShiftAmt});
2700 }
else if (Name ==
"rotate.right.b64") {
2704 Rep = Builder.CreateIntrinsic(Int64Ty, Intrinsic::fshr,
2705 {Arg, Arg, ZExtShiftAmt});
2706 }
else if (Name ==
"swap.lo.hi.b64") {
2709 Rep = Builder.CreateIntrinsic(Int64Ty, Intrinsic::fshl,
2710 {Arg, Arg, Builder.getInt64(32)});
2711 }
else if ((Name.consume_front(
"ptr.gen.to.") &&
2714 Name.starts_with(
".to.gen"))) {
2716 }
else if (Name.consume_front(
"ldg.global")) {
2720 Value *ASC = Builder.CreateAddrSpaceCast(Ptr, Builder.getPtrTy(1));
2723 LD->setMetadata(LLVMContext::MD_invariant_load, MD);
2725 }
else if (Name ==
"tanh.approx.f32") {
2729 Rep = Builder.CreateUnaryIntrinsic(Intrinsic::tanh, CI->
getArgOperand(0),
2731 }
else if (Name ==
"barrier0" || Name ==
"barrier.n" || Name ==
"bar.sync") {
2733 Name.ends_with(
'0') ? Builder.getInt32(0) : CI->
getArgOperand(0);
2734 Rep = Builder.CreateIntrinsic(Intrinsic::nvvm_barrier_cta_sync_aligned_all,
2736 }
else if (Name ==
"barrier") {
2737 Rep = Builder.CreateIntrinsic(
2738 Intrinsic::nvvm_barrier_cta_sync_aligned_count, {},
2740 }
else if (Name ==
"barrier.sync") {
2741 Rep = Builder.CreateIntrinsic(Intrinsic::nvvm_barrier_cta_sync_all, {},
2743 }
else if (Name ==
"barrier.sync.cnt") {
2744 Rep = Builder.CreateIntrinsic(Intrinsic::nvvm_barrier_cta_sync_count, {},
2749 !
F->getReturnType()->getScalarType()->isBFloatTy()) {
2759 ? Builder.CreateBitCast(Arg, NewType)
2762 Rep = Builder.CreateCall(NewFn, Args);
2763 if (
F->getReturnType()->isIntegerTy())
2764 Rep = Builder.CreateBitCast(Rep,
F->getReturnType());
2774 Value *Rep =
nullptr;
2776 if (Name.starts_with(
"sse4a.movnt.")) {
2788 Builder.CreateExtractElement(Arg1, (
uint64_t)0,
"extractelement");
2791 SI->setMetadata(LLVMContext::MD_nontemporal,
Node);
2792 }
else if (Name.starts_with(
"avx.movnt.") ||
2793 Name.starts_with(
"avx512.storent.")) {
2805 SI->setMetadata(LLVMContext::MD_nontemporal,
Node);
2806 }
else if (Name ==
"sse2.storel.dq") {
2811 Value *BC0 = Builder.CreateBitCast(Arg1, NewVecTy,
"cast");
2812 Value *Elt = Builder.CreateExtractElement(BC0, (
uint64_t)0);
2813 Builder.CreateAlignedStore(Elt, Arg0,
Align(1));
2814 }
else if (Name.starts_with(
"sse.storeu.") ||
2815 Name.starts_with(
"sse2.storeu.") ||
2816 Name.starts_with(
"avx.storeu.")) {
2819 Builder.CreateAlignedStore(Arg1, Arg0,
Align(1));
2820 }
else if (Name ==
"avx512.mask.store.ss") {
2824 }
else if (Name.starts_with(
"avx512.mask.store")) {
2826 bool Aligned = Name[17] !=
'u';
2829 }
else if (Name.starts_with(
"sse2.pcmp") || Name.starts_with(
"avx2.pcmp")) {
2832 bool CmpEq = Name[9] ==
'e';
2835 Rep = Builder.CreateSExt(Rep, CI->
getType(),
"");
2836 }
else if (Name.starts_with(
"avx512.broadcastm")) {
2843 Rep = Builder.CreateVectorSplat(NumElts, Rep);
2844 }
else if (Name ==
"sse.sqrt.ss" || Name ==
"sse2.sqrt.sd") {
2846 Value *Elt0 = Builder.CreateExtractElement(Vec, (
uint64_t)0);
2847 Elt0 = Builder.CreateIntrinsic(Intrinsic::sqrt, Elt0->
getType(), Elt0);
2848 Rep = Builder.CreateInsertElement(Vec, Elt0, (
uint64_t)0);
2849 }
else if (Name.starts_with(
"avx.sqrt.p") ||
2850 Name.starts_with(
"sse2.sqrt.p") ||
2851 Name.starts_with(
"sse.sqrt.p")) {
2852 Rep = Builder.CreateIntrinsic(Intrinsic::sqrt, CI->
getType(),
2853 {CI->getArgOperand(0)});
2854 }
else if (Name.starts_with(
"avx512.mask.sqrt.p")) {
2858 Intrinsic::ID IID = Name[18] ==
's' ? Intrinsic::x86_avx512_sqrt_ps_512
2859 : Intrinsic::x86_avx512_sqrt_pd_512;
2862 Rep = Builder.CreateIntrinsic(IID, Args);
2864 Rep = Builder.CreateIntrinsic(Intrinsic::sqrt, CI->
getType(),
2865 {CI->getArgOperand(0)});
2869 }
else if (Name.starts_with(
"avx512.ptestm") ||
2870 Name.starts_with(
"avx512.ptestnm")) {
2874 Rep = Builder.CreateAnd(Op0, Op1);
2880 Rep = Builder.CreateICmp(Pred, Rep, Zero);
2882 }
else if (Name.starts_with(
"avx512.mask.pbroadcast")) {
2885 Rep = Builder.CreateVectorSplat(NumElts, CI->
getArgOperand(0));
2888 }
else if (Name.starts_with(
"avx512.kunpck")) {
2893 for (
unsigned i = 0; i != NumElts; ++i)
2902 Rep = Builder.CreateShuffleVector(
RHS,
LHS,
ArrayRef(Indices, NumElts));
2903 Rep = Builder.CreateBitCast(Rep, CI->
getType());
2904 }
else if (Name ==
"avx512.kand.w") {
2907 Rep = Builder.CreateAnd(
LHS,
RHS);
2908 Rep = Builder.CreateBitCast(Rep, CI->
getType());
2909 }
else if (Name ==
"avx512.kandn.w") {
2912 LHS = Builder.CreateNot(
LHS);
2913 Rep = Builder.CreateAnd(
LHS,
RHS);
2914 Rep = Builder.CreateBitCast(Rep, CI->
getType());
2915 }
else if (Name ==
"avx512.kor.w") {
2918 Rep = Builder.CreateOr(
LHS,
RHS);
2919 Rep = Builder.CreateBitCast(Rep, CI->
getType());
2920 }
else if (Name ==
"avx512.kxor.w") {
2923 Rep = Builder.CreateXor(
LHS,
RHS);
2924 Rep = Builder.CreateBitCast(Rep, CI->
getType());
2925 }
else if (Name ==
"avx512.kxnor.w") {
2928 LHS = Builder.CreateNot(
LHS);
2929 Rep = Builder.CreateXor(
LHS,
RHS);
2930 Rep = Builder.CreateBitCast(Rep, CI->
getType());
2931 }
else if (Name ==
"avx512.knot.w") {
2933 Rep = Builder.CreateNot(Rep);
2934 Rep = Builder.CreateBitCast(Rep, CI->
getType());
2935 }
else if (Name ==
"avx512.kortestz.w" || Name ==
"avx512.kortestc.w") {
2938 Rep = Builder.CreateOr(
LHS,
RHS);
2939 Rep = Builder.CreateBitCast(Rep, Builder.getInt16Ty());
2941 if (Name[14] ==
'c')
2945 Rep = Builder.CreateICmpEQ(Rep,
C);
2946 Rep = Builder.CreateZExt(Rep, Builder.getInt32Ty());
2947 }
else if (Name ==
"sse.add.ss" || Name ==
"sse2.add.sd" ||
2948 Name ==
"sse.sub.ss" || Name ==
"sse2.sub.sd" ||
2949 Name ==
"sse.mul.ss" || Name ==
"sse2.mul.sd" ||
2950 Name ==
"sse.div.ss" || Name ==
"sse2.div.sd") {
2953 ConstantInt::get(I32Ty, 0));
2955 ConstantInt::get(I32Ty, 0));
2957 if (Name.contains(
".add."))
2958 EltOp = Builder.CreateFAdd(Elt0, Elt1);
2959 else if (Name.contains(
".sub."))
2960 EltOp = Builder.CreateFSub(Elt0, Elt1);
2961 else if (Name.contains(
".mul."))
2962 EltOp = Builder.CreateFMul(Elt0, Elt1);
2964 EltOp = Builder.CreateFDiv(Elt0, Elt1);
2965 Rep = Builder.CreateInsertElement(CI->
getArgOperand(0), EltOp,
2966 ConstantInt::get(I32Ty, 0));
2967 }
else if (Name.starts_with(
"avx512.mask.pcmp")) {
2969 bool CmpEq = Name[16] ==
'e';
2971 }
else if (Name.starts_with(
"avx512.mask.vpshufbitqmb.")) {
2979 IID = Intrinsic::x86_avx512_vpshufbitqmb_128;
2982 IID = Intrinsic::x86_avx512_vpshufbitqmb_256;
2985 IID = Intrinsic::x86_avx512_vpshufbitqmb_512;
2992 }
else if (Name.starts_with(
"avx512.mask.fpclass.p")) {
2997 if (VecWidth == 128 && EltWidth == 32)
2998 IID = Intrinsic::x86_avx512_fpclass_ps_128;
2999 else if (VecWidth == 256 && EltWidth == 32)
3000 IID = Intrinsic::x86_avx512_fpclass_ps_256;
3001 else if (VecWidth == 512 && EltWidth == 32)
3002 IID = Intrinsic::x86_avx512_fpclass_ps_512;
3003 else if (VecWidth == 128 && EltWidth == 64)
3004 IID = Intrinsic::x86_avx512_fpclass_pd_128;
3005 else if (VecWidth == 256 && EltWidth == 64)
3006 IID = Intrinsic::x86_avx512_fpclass_pd_256;
3007 else if (VecWidth == 512 && EltWidth == 64)
3008 IID = Intrinsic::x86_avx512_fpclass_pd_512;
3015 }
else if (Name.starts_with(
"avx512.cmp.p")) {
3017 Type *OpTy = Args[0]->getType();
3021 if (VecWidth == 128 && EltWidth == 32)
3022 IID = Intrinsic::x86_avx512_mask_cmp_ps_128;
3023 else if (VecWidth == 256 && EltWidth == 32)
3024 IID = Intrinsic::x86_avx512_mask_cmp_ps_256;
3025 else if (VecWidth == 512 && EltWidth == 32)
3026 IID = Intrinsic::x86_avx512_mask_cmp_ps_512;
3027 else if (VecWidth == 128 && EltWidth == 64)
3028 IID = Intrinsic::x86_avx512_mask_cmp_pd_128;
3029 else if (VecWidth == 256 && EltWidth == 64)
3030 IID = Intrinsic::x86_avx512_mask_cmp_pd_256;
3031 else if (VecWidth == 512 && EltWidth == 64)
3032 IID = Intrinsic::x86_avx512_mask_cmp_pd_512;
3037 if (VecWidth == 512)
3039 Args.push_back(Mask);
3041 Rep = Builder.CreateIntrinsic(IID, Args);
3042 }
else if (Name.starts_with(
"avx512.mask.cmp.")) {
3046 }
else if (Name.starts_with(
"avx512.mask.ucmp.")) {
3049 }
else if (Name.starts_with(
"avx512.cvtb2mask.") ||
3050 Name.starts_with(
"avx512.cvtw2mask.") ||
3051 Name.starts_with(
"avx512.cvtd2mask.") ||
3052 Name.starts_with(
"avx512.cvtq2mask.")) {
3057 }
else if (Name ==
"ssse3.pabs.b.128" || Name ==
"ssse3.pabs.w.128" ||
3058 Name ==
"ssse3.pabs.d.128" || Name.starts_with(
"avx2.pabs") ||
3059 Name.starts_with(
"avx512.mask.pabs")) {
3061 }
else if (Name ==
"sse41.pmaxsb" || Name ==
"sse2.pmaxs.w" ||
3062 Name ==
"sse41.pmaxsd" || Name.starts_with(
"avx2.pmaxs") ||
3063 Name.starts_with(
"avx512.mask.pmaxs")) {
3065 }
else if (Name ==
"sse2.pmaxu.b" || Name ==
"sse41.pmaxuw" ||
3066 Name ==
"sse41.pmaxud" || Name.starts_with(
"avx2.pmaxu") ||
3067 Name.starts_with(
"avx512.mask.pmaxu")) {
3069 }
else if (Name ==
"sse41.pminsb" || Name ==
"sse2.pmins.w" ||
3070 Name ==
"sse41.pminsd" || Name.starts_with(
"avx2.pmins") ||
3071 Name.starts_with(
"avx512.mask.pmins")) {
3073 }
else if (Name ==
"sse2.pminu.b" || Name ==
"sse41.pminuw" ||
3074 Name ==
"sse41.pminud" || Name.starts_with(
"avx2.pminu") ||
3075 Name.starts_with(
"avx512.mask.pminu")) {
3077 }
else if (Name ==
"sse2.pmulu.dq" || Name ==
"avx2.pmulu.dq" ||
3078 Name ==
"avx512.pmulu.dq.512" ||
3079 Name.starts_with(
"avx512.mask.pmulu.dq.")) {
3081 }
else if (Name ==
"sse41.pmuldq" || Name ==
"avx2.pmul.dq" ||
3082 Name ==
"avx512.pmul.dq.512" ||
3083 Name.starts_with(
"avx512.mask.pmul.dq.")) {
3085 }
else if (Name ==
"sse.cvtsi2ss" || Name ==
"sse2.cvtsi2sd" ||
3086 Name ==
"sse.cvtsi642ss" || Name ==
"sse2.cvtsi642sd") {
3091 }
else if (Name ==
"avx512.cvtusi2sd") {
3096 }
else if (Name ==
"sse2.cvtss2sd") {
3098 Rep = Builder.CreateFPExt(
3101 }
else if (Name ==
"sse2.cvtdq2pd" || Name ==
"sse2.cvtdq2ps" ||
3102 Name ==
"avx.cvtdq2.pd.256" || Name ==
"avx.cvtdq2.ps.256" ||
3103 Name.starts_with(
"avx512.mask.cvtdq2pd.") ||
3104 Name.starts_with(
"avx512.mask.cvtudq2pd.") ||
3105 Name.starts_with(
"avx512.mask.cvtdq2ps.") ||
3106 Name.starts_with(
"avx512.mask.cvtudq2ps.") ||
3107 Name.starts_with(
"avx512.mask.cvtqq2pd.") ||
3108 Name.starts_with(
"avx512.mask.cvtuqq2pd.") ||
3109 Name ==
"avx512.mask.cvtqq2ps.256" ||
3110 Name ==
"avx512.mask.cvtqq2ps.512" ||
3111 Name ==
"avx512.mask.cvtuqq2ps.256" ||
3112 Name ==
"avx512.mask.cvtuqq2ps.512" || Name ==
"sse2.cvtps2pd" ||
3113 Name ==
"avx.cvt.ps2.pd.256" ||
3114 Name ==
"avx512.mask.cvtps2pd.128" ||
3115 Name ==
"avx512.mask.cvtps2pd.256") {
3120 unsigned NumDstElts = DstTy->getNumElements();
3122 assert(NumDstElts == 2 &&
"Unexpected vector size");
3123 Rep = Builder.CreateShuffleVector(Rep, Rep,
ArrayRef<int>{0, 1});
3126 bool IsPS2PD = SrcTy->getElementType()->isFloatTy();
3127 bool IsUnsigned = Name.contains(
"cvtu");
3129 Rep = Builder.CreateFPExt(Rep, DstTy,
"cvtps2pd");
3133 Intrinsic::ID IID = IsUnsigned ? Intrinsic::x86_avx512_uitofp_round
3134 : Intrinsic::x86_avx512_sitofp_round;
3135 Rep = Builder.CreateIntrinsic(IID, {DstTy, SrcTy},
3138 Rep = IsUnsigned ? Builder.CreateUIToFP(Rep, DstTy,
"cvt")
3139 : Builder.CreateSIToFP(Rep, DstTy,
"cvt");
3145 }
else if (Name.starts_with(
"avx512.mask.vcvtph2ps.") ||
3146 Name.starts_with(
"vcvtph2ps.")) {
3150 unsigned NumDstElts = DstTy->getNumElements();
3151 if (NumDstElts != SrcTy->getNumElements()) {
3152 assert(NumDstElts == 4 &&
"Unexpected vector size");
3153 Rep = Builder.CreateShuffleVector(Rep, Rep,
ArrayRef<int>{0, 1, 2, 3});
3155 Rep = Builder.CreateBitCast(
3157 Rep = Builder.CreateFPExt(Rep, DstTy,
"cvtph2ps");
3161 }
else if (Name.starts_with(
"avx512.mask.load")) {
3163 bool Aligned = Name[16] !=
'u';
3166 }
else if (Name.starts_with(
"avx512.mask.expand.load.")) {
3169 ResultTy->getNumElements());
3171 Rep = Builder.CreateIntrinsic(
3172 Intrinsic::masked_expandload, ResultTy,
3174 }
else if (Name.starts_with(
"avx512.mask.compress.store.")) {
3180 Rep = Builder.CreateIntrinsic(
3181 Intrinsic::masked_compressstore, ResultTy,
3183 }
else if (Name.starts_with(
"avx512.mask.compress.") ||
3184 Name.starts_with(
"avx512.mask.expand.")) {
3188 ResultTy->getNumElements());
3190 bool IsCompress = Name[12] ==
'c';
3191 Intrinsic::ID IID = IsCompress ? Intrinsic::x86_avx512_mask_compress
3192 : Intrinsic::x86_avx512_mask_expand;
3193 Rep = Builder.CreateIntrinsic(
3195 }
else if (Name.starts_with(
"xop.vpcom")) {
3197 if (Name.ends_with(
"ub") || Name.ends_with(
"uw") || Name.ends_with(
"ud") ||
3198 Name.ends_with(
"uq"))
3200 else if (Name.ends_with(
"b") || Name.ends_with(
"w") ||
3201 Name.ends_with(
"d") || Name.ends_with(
"q"))
3210 Name = Name.substr(9);
3211 if (Name.starts_with(
"lt"))
3213 else if (Name.starts_with(
"le"))
3215 else if (Name.starts_with(
"gt"))
3217 else if (Name.starts_with(
"ge"))
3219 else if (Name.starts_with(
"eq"))
3221 else if (Name.starts_with(
"ne"))
3223 else if (Name.starts_with(
"false"))
3225 else if (Name.starts_with(
"true"))
3232 }
else if (Name.starts_with(
"xop.vpcmov")) {
3234 Value *NotSel = Builder.CreateNot(Sel);
3237 Rep = Builder.CreateOr(Sel0, Sel1);
3238 }
else if (Name.starts_with(
"xop.vprot") || Name.starts_with(
"avx512.prol") ||
3239 Name.starts_with(
"avx512.mask.prol")) {
3241 }
else if (Name.starts_with(
"avx512.pror") ||
3242 Name.starts_with(
"avx512.mask.pror")) {
3244 }
else if (Name.starts_with(
"avx512.vpshld.") ||
3245 Name.starts_with(
"avx512.mask.vpshld") ||
3246 Name.starts_with(
"avx512.maskz.vpshld")) {
3247 bool ZeroMask = Name[11] ==
'z';
3249 }
else if (Name.starts_with(
"avx512.vpshrd.") ||
3250 Name.starts_with(
"avx512.mask.vpshrd") ||
3251 Name.starts_with(
"avx512.maskz.vpshrd")) {
3252 bool ZeroMask = Name[11] ==
'z';
3254 }
else if (Name ==
"sse42.crc32.64.8") {
3257 Rep = Builder.CreateIntrinsic(Intrinsic::x86_sse42_crc32_32_8,
3259 Rep = Builder.CreateZExt(Rep, CI->
getType(),
"");
3260 }
else if (Name.starts_with(
"avx.vbroadcast.s") ||
3261 Name.starts_with(
"avx512.vbroadcast.s")) {
3264 Type *EltTy = VecTy->getElementType();
3265 unsigned EltNum = VecTy->getNumElements();
3269 for (
unsigned I = 0;
I < EltNum; ++
I)
3270 Rep = Builder.CreateInsertElement(Rep, Load, ConstantInt::get(I32Ty,
I));
3271 }
else if (Name.starts_with(
"sse41.pmovsx") ||
3272 Name.starts_with(
"sse41.pmovzx") ||
3273 Name.starts_with(
"avx2.pmovsx") ||
3274 Name.starts_with(
"avx2.pmovzx") ||
3275 Name.starts_with(
"avx512.mask.pmovsx") ||
3276 Name.starts_with(
"avx512.mask.pmovzx")) {
3278 unsigned NumDstElts = DstTy->getNumElements();
3282 for (
unsigned i = 0; i != NumDstElts; ++i)
3287 bool DoSext = Name.contains(
"pmovsx");
3289 DoSext ? Builder.CreateSExt(SV, DstTy) : Builder.CreateZExt(SV, DstTy);
3294 }
else if (Name ==
"avx512.mask.pmov.qd.256" ||
3295 Name ==
"avx512.mask.pmov.qd.512" ||
3296 Name ==
"avx512.mask.pmov.wb.256" ||
3297 Name ==
"avx512.mask.pmov.wb.512") {
3302 }
else if (Name.starts_with(
"avx.vbroadcastf128") ||
3303 Name ==
"avx2.vbroadcasti128") {
3309 if (NumSrcElts == 2)
3310 Rep = Builder.CreateShuffleVector(Load,
ArrayRef<int>{0, 1, 0, 1});
3312 Rep = Builder.CreateShuffleVector(Load,
3314 }
else if (Name.starts_with(
"avx512.mask.shuf.i") ||
3315 Name.starts_with(
"avx512.mask.shuf.f")) {
3320 unsigned ControlBitsMask = NumLanes - 1;
3321 unsigned NumControlBits = NumLanes / 2;
3324 for (
unsigned l = 0; l != NumLanes; ++l) {
3325 unsigned LaneMask = (Imm >> (l * NumControlBits)) & ControlBitsMask;
3327 if (l >= NumLanes / 2)
3328 LaneMask += NumLanes;
3329 for (
unsigned i = 0; i != NumElementsInLane; ++i)
3330 ShuffleMask.push_back(LaneMask * NumElementsInLane + i);
3336 }
else if (Name.starts_with(
"avx512.mask.broadcastf") ||
3337 Name.starts_with(
"avx512.mask.broadcasti")) {
3340 unsigned NumDstElts =
3344 for (
unsigned i = 0; i != NumDstElts; ++i)
3345 ShuffleMask[i] = i % NumSrcElts;
3351 }
else if (Name.starts_with(
"avx2.pbroadcast") ||
3352 Name.starts_with(
"avx2.vbroadcast") ||
3353 Name.starts_with(
"avx512.pbroadcast") ||
3354 Name.starts_with(
"avx512.mask.broadcast.s")) {
3361 Rep = Builder.CreateShuffleVector(
Op, M);
3366 }
else if (Name.starts_with(
"sse2.padds.") ||
3367 Name.starts_with(
"avx2.padds.") ||
3368 Name.starts_with(
"avx512.padds.") ||
3369 Name.starts_with(
"avx512.mask.padds.")) {
3371 }
else if (Name.starts_with(
"sse2.psubs.") ||
3372 Name.starts_with(
"avx2.psubs.") ||
3373 Name.starts_with(
"avx512.psubs.") ||
3374 Name.starts_with(
"avx512.mask.psubs.")) {
3376 }
else if (Name.starts_with(
"sse2.paddus.") ||
3377 Name.starts_with(
"avx2.paddus.") ||
3378 Name.starts_with(
"avx512.mask.paddus.")) {
3380 }
else if (Name.starts_with(
"sse2.psubus.") ||
3381 Name.starts_with(
"avx2.psubus.") ||
3382 Name.starts_with(
"avx512.mask.psubus.")) {
3384 }
else if (Name.starts_with(
"avx512.mask.palignr.")) {
3389 }
else if (Name.starts_with(
"avx512.mask.valign.")) {
3393 }
else if (Name ==
"sse2.psll.dq" || Name ==
"avx2.psll.dq") {
3398 }
else if (Name ==
"sse2.psrl.dq" || Name ==
"avx2.psrl.dq") {
3403 }
else if (Name ==
"sse2.psll.dq.bs" || Name ==
"avx2.psll.dq.bs" ||
3404 Name ==
"avx512.psll.dq.512") {
3408 }
else if (Name ==
"sse2.psrl.dq.bs" || Name ==
"avx2.psrl.dq.bs" ||
3409 Name ==
"avx512.psrl.dq.512") {
3413 }
else if (Name ==
"sse41.pblendw" || Name.starts_with(
"sse41.blendp") ||
3414 Name.starts_with(
"avx.blend.p") || Name ==
"avx2.pblendw" ||
3415 Name.starts_with(
"avx2.pblendd.")) {
3420 unsigned NumElts = VecTy->getNumElements();
3423 for (
unsigned i = 0; i != NumElts; ++i)
3424 Idxs[i] = ((Imm >> (i % 8)) & 1) ? i + NumElts : i;
3426 Rep = Builder.CreateShuffleVector(Op0, Op1, Idxs);
3427 }
else if (Name.starts_with(
"avx.vinsertf128.") ||
3428 Name ==
"avx2.vinserti128" ||
3429 Name.starts_with(
"avx512.mask.insert")) {
3433 unsigned DstNumElts =
3435 unsigned SrcNumElts =
3437 unsigned Scale = DstNumElts / SrcNumElts;
3444 for (
unsigned i = 0; i != SrcNumElts; ++i)
3446 for (
unsigned i = SrcNumElts; i != DstNumElts; ++i)
3447 Idxs[i] = SrcNumElts;
3448 Rep = Builder.CreateShuffleVector(Op1, Idxs);
3462 for (
unsigned i = 0; i != DstNumElts; ++i)
3465 for (
unsigned i = 0; i != SrcNumElts; ++i)
3466 Idxs[i + Imm * SrcNumElts] = i + DstNumElts;
3467 Rep = Builder.CreateShuffleVector(Op0, Rep, Idxs);
3473 }
else if (Name.starts_with(
"avx.vextractf128.") ||
3474 Name ==
"avx2.vextracti128" ||
3475 Name.starts_with(
"avx512.mask.vextract")) {
3478 unsigned DstNumElts =
3480 unsigned SrcNumElts =
3482 unsigned Scale = SrcNumElts / DstNumElts;
3489 for (
unsigned i = 0; i != DstNumElts; ++i) {
3490 Idxs[i] = i + (Imm * DstNumElts);
3492 Rep = Builder.CreateShuffleVector(Op0, Op0, Idxs);
3498 }
else if (Name.starts_with(
"avx512.mask.perm.df.") ||
3499 Name.starts_with(
"avx512.mask.perm.di.")) {
3503 unsigned NumElts = VecTy->getNumElements();
3506 for (
unsigned i = 0; i != NumElts; ++i)
3507 Idxs[i] = (i & ~0x3) + ((Imm >> (2 * (i & 0x3))) & 3);
3509 Rep = Builder.CreateShuffleVector(Op0, Op0, Idxs);
3514 }
else if (Name.starts_with(
"avx.vperm2f128.") || Name ==
"avx2.vperm2i128") {
3526 unsigned HalfSize = NumElts / 2;
3538 unsigned StartIndex = (Imm & 0x01) ? HalfSize : 0;
3539 for (
unsigned i = 0; i < HalfSize; ++i)
3540 ShuffleMask[i] = StartIndex + i;
3543 StartIndex = (Imm & 0x10) ? HalfSize : 0;
3544 for (
unsigned i = 0; i < HalfSize; ++i)
3545 ShuffleMask[i + HalfSize] = NumElts + StartIndex + i;
3547 Rep = Builder.CreateShuffleVector(V0, V1, ShuffleMask);
3549 }
else if (Name.starts_with(
"avx.vpermil.") || Name ==
"sse2.pshuf.d" ||
3550 Name.starts_with(
"avx512.mask.vpermil.p") ||
3551 Name.starts_with(
"avx512.mask.pshuf.d.")) {
3555 unsigned NumElts = VecTy->getNumElements();
3557 unsigned IdxSize = 64 / VecTy->getScalarSizeInBits();
3558 unsigned IdxMask = ((1 << IdxSize) - 1);
3564 for (
unsigned i = 0; i != NumElts; ++i)
3565 Idxs[i] = ((Imm >> ((i * IdxSize) % 8)) & IdxMask) | (i & ~IdxMask);
3567 Rep = Builder.CreateShuffleVector(Op0, Op0, Idxs);
3572 }
else if (Name ==
"sse2.pshufl.w" ||
3573 Name.starts_with(
"avx512.mask.pshufl.w.")) {
3579 for (
unsigned l = 0; l != NumElts; l += 8) {
3580 for (
unsigned i = 0; i != 4; ++i)
3581 Idxs[i + l] = ((Imm >> (2 * i)) & 0x3) + l;
3582 for (
unsigned i = 4; i != 8; ++i)
3583 Idxs[i + l] = i + l;
3586 Rep = Builder.CreateShuffleVector(Op0, Op0, Idxs);
3591 }
else if (Name ==
"sse2.pshufh.w" ||
3592 Name.starts_with(
"avx512.mask.pshufh.w.")) {
3598 for (
unsigned l = 0; l != NumElts; l += 8) {
3599 for (
unsigned i = 0; i != 4; ++i)
3600 Idxs[i + l] = i + l;
3601 for (
unsigned i = 0; i != 4; ++i)
3602 Idxs[i + l + 4] = ((Imm >> (2 * i)) & 0x3) + 4 + l;
3605 Rep = Builder.CreateShuffleVector(Op0, Op0, Idxs);
3610 }
else if (Name.starts_with(
"avx512.mask.shuf.p")) {
3617 unsigned HalfLaneElts = NumLaneElts / 2;
3620 for (
unsigned i = 0; i != NumElts; ++i) {
3622 Idxs[i] = i - (i % NumLaneElts);
3624 if ((i % NumLaneElts) >= HalfLaneElts)
3628 Idxs[i] += (Imm >> ((i * HalfLaneElts) % 8)) & ((1 << HalfLaneElts) - 1);
3631 Rep = Builder.CreateShuffleVector(Op0, Op1, Idxs);
3635 }
else if (Name.starts_with(
"avx512.mask.movddup") ||
3636 Name.starts_with(
"avx512.mask.movshdup") ||
3637 Name.starts_with(
"avx512.mask.movsldup")) {
3643 if (Name.starts_with(
"avx512.mask.movshdup."))
3647 for (
unsigned l = 0; l != NumElts; l += NumLaneElts)
3648 for (
unsigned i = 0; i != NumLaneElts; i += 2) {
3649 Idxs[i + l + 0] = i + l +
Offset;
3650 Idxs[i + l + 1] = i + l +
Offset;
3653 Rep = Builder.CreateShuffleVector(Op0, Op0, Idxs);
3657 }
else if (Name.starts_with(
"avx512.mask.punpckl") ||
3658 Name.starts_with(
"avx512.mask.unpckl.")) {
3665 for (
int l = 0; l != NumElts; l += NumLaneElts)
3666 for (
int i = 0; i != NumLaneElts; ++i)
3667 Idxs[i + l] = l + (i / 2) + NumElts * (i % 2);
3669 Rep = Builder.CreateShuffleVector(Op0, Op1, Idxs);
3673 }
else if (Name.starts_with(
"avx512.mask.punpckh") ||
3674 Name.starts_with(
"avx512.mask.unpckh.")) {
3681 for (
int l = 0; l != NumElts; l += NumLaneElts)
3682 for (
int i = 0; i != NumLaneElts; ++i)
3683 Idxs[i + l] = (NumLaneElts / 2) + l + (i / 2) + NumElts * (i % 2);
3685 Rep = Builder.CreateShuffleVector(Op0, Op1, Idxs);
3689 }
else if (Name.starts_with(
"avx512.mask.and.") ||
3690 Name.starts_with(
"avx512.mask.pand.")) {
3693 Rep = Builder.CreateAnd(Builder.CreateBitCast(CI->
getArgOperand(0), ITy),
3695 Rep = Builder.CreateBitCast(Rep, FTy);
3698 }
else if (Name.starts_with(
"avx512.mask.andn.") ||
3699 Name.starts_with(
"avx512.mask.pandn.")) {
3702 Rep = Builder.CreateNot(Builder.CreateBitCast(CI->
getArgOperand(0), ITy));
3703 Rep = Builder.CreateAnd(Rep,
3705 Rep = Builder.CreateBitCast(Rep, FTy);
3708 }
else if (Name.starts_with(
"avx512.mask.or.") ||
3709 Name.starts_with(
"avx512.mask.por.")) {
3712 Rep = Builder.CreateOr(Builder.CreateBitCast(CI->
getArgOperand(0), ITy),
3714 Rep = Builder.CreateBitCast(Rep, FTy);
3717 }
else if (Name.starts_with(
"avx512.mask.xor.") ||
3718 Name.starts_with(
"avx512.mask.pxor.")) {
3721 Rep = Builder.CreateXor(Builder.CreateBitCast(CI->
getArgOperand(0), ITy),
3723 Rep = Builder.CreateBitCast(Rep, FTy);
3726 }
else if (Name.starts_with(
"avx512.mask.padd.")) {
3730 }
else if (Name.starts_with(
"avx512.mask.psub.")) {
3734 }
else if (Name.starts_with(
"avx512.mask.pmull.")) {
3738 }
else if (Name.starts_with(
"avx512.mask.add.p")) {
3739 if (Name.ends_with(
".512")) {
3741 if (Name[17] ==
's')
3742 IID = Intrinsic::x86_avx512_add_ps_512;
3744 IID = Intrinsic::x86_avx512_add_pd_512;
3746 Rep = Builder.CreateIntrinsic(
3754 }
else if (Name.starts_with(
"avx512.mask.div.p")) {
3755 if (Name.ends_with(
".512")) {
3757 if (Name[17] ==
's')
3758 IID = Intrinsic::x86_avx512_div_ps_512;
3760 IID = Intrinsic::x86_avx512_div_pd_512;
3762 Rep = Builder.CreateIntrinsic(
3770 }
else if (Name.starts_with(
"avx512.mask.mul.p")) {
3771 if (Name.ends_with(
".512")) {
3773 if (Name[17] ==
's')
3774 IID = Intrinsic::x86_avx512_mul_ps_512;
3776 IID = Intrinsic::x86_avx512_mul_pd_512;
3778 Rep = Builder.CreateIntrinsic(
3786 }
else if (Name.starts_with(
"avx512.mask.sub.p")) {
3787 if (Name.ends_with(
".512")) {
3789 if (Name[17] ==
's')
3790 IID = Intrinsic::x86_avx512_sub_ps_512;
3792 IID = Intrinsic::x86_avx512_sub_pd_512;
3794 Rep = Builder.CreateIntrinsic(
3802 }
else if ((Name.starts_with(
"avx512.mask.max.p") ||
3803 Name.starts_with(
"avx512.mask.min.p")) &&
3804 Name.drop_front(18) ==
".512") {
3805 bool IsDouble = Name[17] ==
'd';
3806 bool IsMin = Name[13] ==
'i';
3808 {Intrinsic::x86_avx512_max_ps_512, Intrinsic::x86_avx512_max_pd_512},
3809 {Intrinsic::x86_avx512_min_ps_512, Intrinsic::x86_avx512_min_pd_512}};
3812 Rep = Builder.CreateIntrinsic(
3817 }
else if (Name.starts_with(
"avx512.mask.lzcnt.")) {
3819 Builder.CreateIntrinsic(Intrinsic::ctlz, CI->
getType(),
3820 {CI->getArgOperand(0), Builder.getInt1(false)});
3823 }
else if (Name.starts_with(
"avx512.mask.psll")) {
3824 bool IsImmediate = Name[16] ==
'i' || (Name.size() > 18 && Name[18] ==
'i');
3825 bool IsVariable = Name[16] ==
'v';
3826 char Size = Name[16] ==
'.' ? Name[17]
3827 : Name[17] ==
'.' ? Name[18]
3828 : Name[18] ==
'.' ? Name[19]
3832 if (IsVariable && Name[17] !=
'.') {
3833 if (
Size ==
'd' && Name[17] ==
'2')
3834 IID = Intrinsic::x86_avx2_psllv_q;
3835 else if (
Size ==
'd' && Name[17] ==
'4')
3836 IID = Intrinsic::x86_avx2_psllv_q_256;
3837 else if (
Size ==
's' && Name[17] ==
'4')
3838 IID = Intrinsic::x86_avx2_psllv_d;
3839 else if (
Size ==
's' && Name[17] ==
'8')
3840 IID = Intrinsic::x86_avx2_psllv_d_256;
3841 else if (
Size ==
'h' && Name[17] ==
'8')
3842 IID = Intrinsic::x86_avx512_psllv_w_128;
3843 else if (
Size ==
'h' && Name[17] ==
'1')
3844 IID = Intrinsic::x86_avx512_psllv_w_256;
3845 else if (Name[17] ==
'3' && Name[18] ==
'2')
3846 IID = Intrinsic::x86_avx512_psllv_w_512;
3849 }
else if (Name.ends_with(
".128")) {
3851 IID = IsImmediate ? Intrinsic::x86_sse2_pslli_d
3852 : Intrinsic::x86_sse2_psll_d;
3853 else if (
Size ==
'q')
3854 IID = IsImmediate ? Intrinsic::x86_sse2_pslli_q
3855 : Intrinsic::x86_sse2_psll_q;
3856 else if (
Size ==
'w')
3857 IID = IsImmediate ? Intrinsic::x86_sse2_pslli_w
3858 : Intrinsic::x86_sse2_psll_w;
3861 }
else if (Name.ends_with(
".256")) {
3863 IID = IsImmediate ? Intrinsic::x86_avx2_pslli_d
3864 : Intrinsic::x86_avx2_psll_d;
3865 else if (
Size ==
'q')
3866 IID = IsImmediate ? Intrinsic::x86_avx2_pslli_q
3867 : Intrinsic::x86_avx2_psll_q;
3868 else if (
Size ==
'w')
3869 IID = IsImmediate ? Intrinsic::x86_avx2_pslli_w
3870 : Intrinsic::x86_avx2_psll_w;
3875 IID = IsImmediate ? Intrinsic::x86_avx512_pslli_d_512
3876 : IsVariable ? Intrinsic::x86_avx512_psllv_d_512
3877 : Intrinsic::x86_avx512_psll_d_512;
3878 else if (
Size ==
'q')
3879 IID = IsImmediate ? Intrinsic::x86_avx512_pslli_q_512
3880 : IsVariable ? Intrinsic::x86_avx512_psllv_q_512
3881 : Intrinsic::x86_avx512_psll_q_512;
3882 else if (
Size ==
'w')
3883 IID = IsImmediate ? Intrinsic::x86_avx512_pslli_w_512
3884 : Intrinsic::x86_avx512_psll_w_512;
3890 }
else if (Name.starts_with(
"avx512.mask.psrl")) {
3891 bool IsImmediate = Name[16] ==
'i' || (Name.size() > 18 && Name[18] ==
'i');
3892 bool IsVariable = Name[16] ==
'v';
3893 char Size = Name[16] ==
'.' ? Name[17]
3894 : Name[17] ==
'.' ? Name[18]
3895 : Name[18] ==
'.' ? Name[19]
3899 if (IsVariable && Name[17] !=
'.') {
3900 if (
Size ==
'd' && Name[17] ==
'2')
3901 IID = Intrinsic::x86_avx2_psrlv_q;
3902 else if (
Size ==
'd' && Name[17] ==
'4')
3903 IID = Intrinsic::x86_avx2_psrlv_q_256;
3904 else if (
Size ==
's' && Name[17] ==
'4')
3905 IID = Intrinsic::x86_avx2_psrlv_d;
3906 else if (
Size ==
's' && Name[17] ==
'8')
3907 IID = Intrinsic::x86_avx2_psrlv_d_256;
3908 else if (
Size ==
'h' && Name[17] ==
'8')
3909 IID = Intrinsic::x86_avx512_psrlv_w_128;
3910 else if (
Size ==
'h' && Name[17] ==
'1')
3911 IID = Intrinsic::x86_avx512_psrlv_w_256;
3912 else if (Name[17] ==
'3' && Name[18] ==
'2')
3913 IID = Intrinsic::x86_avx512_psrlv_w_512;
3916 }
else if (Name.ends_with(
".128")) {
3918 IID = IsImmediate ? Intrinsic::x86_sse2_psrli_d
3919 : Intrinsic::x86_sse2_psrl_d;
3920 else if (
Size ==
'q')
3921 IID = IsImmediate ? Intrinsic::x86_sse2_psrli_q
3922 : Intrinsic::x86_sse2_psrl_q;
3923 else if (
Size ==
'w')
3924 IID = IsImmediate ? Intrinsic::x86_sse2_psrli_w
3925 : Intrinsic::x86_sse2_psrl_w;
3928 }
else if (Name.ends_with(
".256")) {
3930 IID = IsImmediate ? Intrinsic::x86_avx2_psrli_d
3931 : Intrinsic::x86_avx2_psrl_d;
3932 else if (
Size ==
'q')
3933 IID = IsImmediate ? Intrinsic::x86_avx2_psrli_q
3934 : Intrinsic::x86_avx2_psrl_q;
3935 else if (
Size ==
'w')
3936 IID = IsImmediate ? Intrinsic::x86_avx2_psrli_w
3937 : Intrinsic::x86_avx2_psrl_w;
3942 IID = IsImmediate ? Intrinsic::x86_avx512_psrli_d_512
3943 : IsVariable ? Intrinsic::x86_avx512_psrlv_d_512
3944 : Intrinsic::x86_avx512_psrl_d_512;
3945 else if (
Size ==
'q')
3946 IID = IsImmediate ? Intrinsic::x86_avx512_psrli_q_512
3947 : IsVariable ? Intrinsic::x86_avx512_psrlv_q_512
3948 : Intrinsic::x86_avx512_psrl_q_512;
3949 else if (
Size ==
'w')
3950 IID = IsImmediate ? Intrinsic::x86_avx512_psrli_w_512
3951 : Intrinsic::x86_avx512_psrl_w_512;
3957 }
else if (Name.starts_with(
"avx512.mask.psra")) {
3958 bool IsImmediate = Name[16] ==
'i' || (Name.size() > 18 && Name[18] ==
'i');
3959 bool IsVariable = Name[16] ==
'v';
3960 char Size = Name[16] ==
'.' ? Name[17]
3961 : Name[17] ==
'.' ? Name[18]
3962 : Name[18] ==
'.' ? Name[19]
3966 if (IsVariable && Name[17] !=
'.') {
3967 if (
Size ==
's' && Name[17] ==
'4')
3968 IID = Intrinsic::x86_avx2_psrav_d;
3969 else if (
Size ==
's' && Name[17] ==
'8')
3970 IID = Intrinsic::x86_avx2_psrav_d_256;
3971 else if (
Size ==
'h' && Name[17] ==
'8')
3972 IID = Intrinsic::x86_avx512_psrav_w_128;
3973 else if (
Size ==
'h' && Name[17] ==
'1')
3974 IID = Intrinsic::x86_avx512_psrav_w_256;
3975 else if (Name[17] ==
'3' && Name[18] ==
'2')
3976 IID = Intrinsic::x86_avx512_psrav_w_512;
3979 }
else if (Name.ends_with(
".128")) {
3981 IID = IsImmediate ? Intrinsic::x86_sse2_psrai_d
3982 : Intrinsic::x86_sse2_psra_d;
3983 else if (
Size ==
'q')
3984 IID = IsImmediate ? Intrinsic::x86_avx512_psrai_q_128
3985 : IsVariable ? Intrinsic::x86_avx512_psrav_q_128
3986 : Intrinsic::x86_avx512_psra_q_128;
3987 else if (
Size ==
'w')
3988 IID = IsImmediate ? Intrinsic::x86_sse2_psrai_w
3989 : Intrinsic::x86_sse2_psra_w;
3992 }
else if (Name.ends_with(
".256")) {
3994 IID = IsImmediate ? Intrinsic::x86_avx2_psrai_d
3995 : Intrinsic::x86_avx2_psra_d;
3996 else if (
Size ==
'q')
3997 IID = IsImmediate ? Intrinsic::x86_avx512_psrai_q_256
3998 : IsVariable ? Intrinsic::x86_avx512_psrav_q_256
3999 : Intrinsic::x86_avx512_psra_q_256;
4000 else if (
Size ==
'w')
4001 IID = IsImmediate ? Intrinsic::x86_avx2_psrai_w
4002 : Intrinsic::x86_avx2_psra_w;
4007 IID = IsImmediate ? Intrinsic::x86_avx512_psrai_d_512
4008 : IsVariable ? Intrinsic::x86_avx512_psrav_d_512
4009 : Intrinsic::x86_avx512_psra_d_512;
4010 else if (
Size ==
'q')
4011 IID = IsImmediate ? Intrinsic::x86_avx512_psrai_q_512
4012 : IsVariable ? Intrinsic::x86_avx512_psrav_q_512
4013 : Intrinsic::x86_avx512_psra_q_512;
4014 else if (
Size ==
'w')
4015 IID = IsImmediate ? Intrinsic::x86_avx512_psrai_w_512
4016 : Intrinsic::x86_avx512_psra_w_512;
4022 }
else if (Name.starts_with(
"avx512.mask.move.s")) {
4024 }
else if (Name.starts_with(
"avx512.cvtmask2")) {
4026 }
else if (Name.ends_with(
".movntdqa")) {
4030 LoadInst *LI = Builder.CreateAlignedLoad(
4035 }
else if (Name.starts_with(
"fma.vfmadd.") ||
4036 Name.starts_with(
"fma.vfmsub.") ||
4037 Name.starts_with(
"fma.vfnmadd.") ||
4038 Name.starts_with(
"fma.vfnmsub.")) {
4039 bool NegMul = Name[6] ==
'n';
4040 bool NegAcc = NegMul ? Name[8] ==
's' : Name[7] ==
's';
4041 bool IsScalar = NegMul ? Name[12] ==
's' : Name[11] ==
's';
4052 if (NegMul && !IsScalar)
4053 Ops[0] = Builder.CreateFNeg(
Ops[0]);
4054 if (NegMul && IsScalar)
4055 Ops[1] = Builder.CreateFNeg(
Ops[1]);
4057 Ops[2] = Builder.CreateFNeg(
Ops[2]);
4059 Rep = Builder.CreateIntrinsic(Intrinsic::fma,
Ops[0]->
getType(),
Ops);
4063 }
else if (Name.starts_with(
"fma4.vfmadd.s")) {
4071 Rep = Builder.CreateIntrinsic(Intrinsic::fma,
Ops[0]->
getType(),
Ops);
4075 }
else if (Name.starts_with(
"avx512.mask.vfmadd.s") ||
4076 Name.starts_with(
"avx512.maskz.vfmadd.s") ||
4077 Name.starts_with(
"avx512.mask3.vfmadd.s") ||
4078 Name.starts_with(
"avx512.mask3.vfmsub.s") ||
4079 Name.starts_with(
"avx512.mask3.vfnmsub.s")) {
4080 bool IsMask3 = Name[11] ==
'3';
4081 bool IsMaskZ = Name[11] ==
'z';
4083 Name = Name.drop_front(IsMask3 || IsMaskZ ? 13 : 12);
4084 bool NegMul = Name[2] ==
'n';
4085 bool NegAcc = NegMul ? Name[4] ==
's' : Name[3] ==
's';
4091 if (NegMul && (IsMask3 || IsMaskZ))
4092 A = Builder.CreateFNeg(
A);
4093 if (NegMul && !(IsMask3 || IsMaskZ))
4094 B = Builder.CreateFNeg(
B);
4096 C = Builder.CreateFNeg(
C);
4098 A = Builder.CreateExtractElement(
A, (
uint64_t)0);
4099 B = Builder.CreateExtractElement(
B, (
uint64_t)0);
4100 C = Builder.CreateExtractElement(
C, (
uint64_t)0);
4107 if (Name.back() ==
'd')
4108 IID = Intrinsic::x86_avx512_vfmadd_f64;
4110 IID = Intrinsic::x86_avx512_vfmadd_f32;
4111 Rep = Builder.CreateIntrinsic(IID,
Ops);
4113 Rep = Builder.CreateFMA(
A,
B,
C);
4122 if (NegAcc && IsMask3)
4127 Rep = Builder.CreateInsertElement(CI->
getArgOperand(IsMask3 ? 2 : 0), Rep,
4129 }
else if (Name.starts_with(
"avx512.mask.vfmadd.p") ||
4130 Name.starts_with(
"avx512.mask.vfnmadd.p") ||
4131 Name.starts_with(
"avx512.mask.vfnmsub.p") ||
4132 Name.starts_with(
"avx512.mask3.vfmadd.p") ||
4133 Name.starts_with(
"avx512.mask3.vfmsub.p") ||
4134 Name.starts_with(
"avx512.mask3.vfnmsub.p") ||
4135 Name.starts_with(
"avx512.maskz.vfmadd.p")) {
4136 bool IsMask3 = Name[11] ==
'3';
4137 bool IsMaskZ = Name[11] ==
'z';
4139 Name = Name.drop_front(IsMask3 || IsMaskZ ? 13 : 12);
4140 bool NegMul = Name[2] ==
'n';
4141 bool NegAcc = NegMul ? Name[4] ==
's' : Name[3] ==
's';
4147 if (NegMul && (IsMask3 || IsMaskZ))
4148 A = Builder.CreateFNeg(
A);
4149 if (NegMul && !(IsMask3 || IsMaskZ))
4150 B = Builder.CreateFNeg(
B);
4152 C = Builder.CreateFNeg(
C);
4159 if (Name[Name.size() - 5] ==
's')
4160 IID = Intrinsic::x86_avx512_vfmadd_ps_512;
4162 IID = Intrinsic::x86_avx512_vfmadd_pd_512;
4166 Rep = Builder.CreateFMA(
A,
B,
C);
4174 }
else if (Name.starts_with(
"fma.vfmsubadd.p")) {
4178 if (VecWidth == 128 && EltWidth == 32)
4179 IID = Intrinsic::x86_fma_vfmaddsub_ps;
4180 else if (VecWidth == 256 && EltWidth == 32)
4181 IID = Intrinsic::x86_fma_vfmaddsub_ps_256;
4182 else if (VecWidth == 128 && EltWidth == 64)
4183 IID = Intrinsic::x86_fma_vfmaddsub_pd;
4184 else if (VecWidth == 256 && EltWidth == 64)
4185 IID = Intrinsic::x86_fma_vfmaddsub_pd_256;
4191 Ops[2] = Builder.CreateFNeg(
Ops[2]);
4192 Rep = Builder.CreateIntrinsic(IID,
Ops);
4193 }
else if (Name.starts_with(
"avx512.mask.vfmaddsub.p") ||
4194 Name.starts_with(
"avx512.mask3.vfmaddsub.p") ||
4195 Name.starts_with(
"avx512.maskz.vfmaddsub.p") ||
4196 Name.starts_with(
"avx512.mask3.vfmsubadd.p")) {
4197 bool IsMask3 = Name[11] ==
'3';
4198 bool IsMaskZ = Name[11] ==
'z';
4200 Name = Name.drop_front(IsMask3 || IsMaskZ ? 13 : 12);
4201 bool IsSubAdd = Name[3] ==
's';
4205 if (Name[Name.size() - 5] ==
's')
4206 IID = Intrinsic::x86_avx512_vfmaddsub_ps_512;
4208 IID = Intrinsic::x86_avx512_vfmaddsub_pd_512;
4213 Ops[2] = Builder.CreateFNeg(
Ops[2]);
4215 Rep = Builder.CreateIntrinsic(IID,
Ops);
4224 Value *Odd = Builder.CreateCall(FMA,
Ops);
4225 Ops[2] = Builder.CreateFNeg(
Ops[2]);
4226 Value *Even = Builder.CreateCall(FMA,
Ops);
4232 for (
int i = 0; i != NumElts; ++i)
4233 Idxs[i] = i + (i % 2) * NumElts;
4235 Rep = Builder.CreateShuffleVector(Even, Odd, Idxs);
4243 }
else if (Name.starts_with(
"avx512.mask.pternlog.") ||
4244 Name.starts_with(
"avx512.maskz.pternlog.")) {
4245 bool ZeroMask = Name[11] ==
'z';
4249 if (VecWidth == 128 && EltWidth == 32)
4250 IID = Intrinsic::x86_avx512_pternlog_d_128;
4251 else if (VecWidth == 256 && EltWidth == 32)
4252 IID = Intrinsic::x86_avx512_pternlog_d_256;
4253 else if (VecWidth == 512 && EltWidth == 32)
4254 IID = Intrinsic::x86_avx512_pternlog_d_512;
4255 else if (VecWidth == 128 && EltWidth == 64)
4256 IID = Intrinsic::x86_avx512_pternlog_q_128;
4257 else if (VecWidth == 256 && EltWidth == 64)
4258 IID = Intrinsic::x86_avx512_pternlog_q_256;
4259 else if (VecWidth == 512 && EltWidth == 64)
4260 IID = Intrinsic::x86_avx512_pternlog_q_512;
4266 Rep = Builder.CreateIntrinsic(IID, Args);
4270 }
else if (Name.starts_with(
"avx512.mask.vpmadd52") ||
4271 Name.starts_with(
"avx512.maskz.vpmadd52")) {
4272 bool ZeroMask = Name[11] ==
'z';
4273 bool High = Name[20] ==
'h' || Name[21] ==
'h';
4276 if (VecWidth == 128 && !
High)
4277 IID = Intrinsic::x86_avx512_vpmadd52l_uq_128;
4278 else if (VecWidth == 256 && !
High)
4279 IID = Intrinsic::x86_avx512_vpmadd52l_uq_256;
4280 else if (VecWidth == 512 && !
High)
4281 IID = Intrinsic::x86_avx512_vpmadd52l_uq_512;
4282 else if (VecWidth == 128 &&
High)
4283 IID = Intrinsic::x86_avx512_vpmadd52h_uq_128;
4284 else if (VecWidth == 256 &&
High)
4285 IID = Intrinsic::x86_avx512_vpmadd52h_uq_256;
4286 else if (VecWidth == 512 &&
High)
4287 IID = Intrinsic::x86_avx512_vpmadd52h_uq_512;
4293 Rep = Builder.CreateIntrinsic(IID, Args);
4297 }
else if (Name.starts_with(
"avx512.mask.vpermi2var.") ||
4298 Name.starts_with(
"avx512.mask.vpermt2var.") ||
4299 Name.starts_with(
"avx512.maskz.vpermt2var.")) {
4300 bool ZeroMask = Name[11] ==
'z';
4301 bool IndexForm = Name[17] ==
'i';
4303 }
else if (Name.starts_with(
"avx512.mask.vpdpbusd.") ||
4304 Name.starts_with(
"avx512.maskz.vpdpbusd.") ||
4305 Name.starts_with(
"avx512.mask.vpdpbusds.") ||
4306 Name.starts_with(
"avx512.maskz.vpdpbusds.")) {
4307 bool ZeroMask = Name[11] ==
'z';
4308 bool IsSaturating = Name[ZeroMask ? 21 : 20] ==
's';
4311 if (VecWidth == 128 && !IsSaturating)
4312 IID = Intrinsic::x86_avx512_vpdpbusd_128;
4313 else if (VecWidth == 256 && !IsSaturating)
4314 IID = Intrinsic::x86_avx512_vpdpbusd_256;
4315 else if (VecWidth == 512 && !IsSaturating)
4316 IID = Intrinsic::x86_avx512_vpdpbusd_512;
4317 else if (VecWidth == 128 && IsSaturating)
4318 IID = Intrinsic::x86_avx512_vpdpbusds_128;
4319 else if (VecWidth == 256 && IsSaturating)
4320 IID = Intrinsic::x86_avx512_vpdpbusds_256;
4321 else if (VecWidth == 512 && IsSaturating)
4322 IID = Intrinsic::x86_avx512_vpdpbusds_512;
4332 if (Args[1]->
getType()->isVectorTy() &&
4335 ->isIntegerTy(32) &&
4336 Args[2]->
getType()->isVectorTy() &&
4339 ->isIntegerTy(32)) {
4340 Type *NewArgType =
nullptr;
4341 if (VecWidth == 128)
4343 else if (VecWidth == 256)
4345 else if (VecWidth == 512)
4350 Args[1] = Builder.CreateBitCast(Args[1], NewArgType);
4351 Args[2] = Builder.CreateBitCast(Args[2], NewArgType);
4354 Rep = Builder.CreateIntrinsic(IID, Args);
4358 }
else if (Name.starts_with(
"avx512.mask.vpdpwssd.") ||
4359 Name.starts_with(
"avx512.maskz.vpdpwssd.") ||
4360 Name.starts_with(
"avx512.mask.vpdpwssds.") ||
4361 Name.starts_with(
"avx512.maskz.vpdpwssds.")) {
4362 bool ZeroMask = Name[11] ==
'z';
4363 bool IsSaturating = Name[ZeroMask ? 21 : 20] ==
's';
4366 if (VecWidth == 128 && !IsSaturating)
4367 IID = Intrinsic::x86_avx512_vpdpwssd_128;
4368 else if (VecWidth == 256 && !IsSaturating)
4369 IID = Intrinsic::x86_avx512_vpdpwssd_256;
4370 else if (VecWidth == 512 && !IsSaturating)
4371 IID = Intrinsic::x86_avx512_vpdpwssd_512;
4372 else if (VecWidth == 128 && IsSaturating)
4373 IID = Intrinsic::x86_avx512_vpdpwssds_128;
4374 else if (VecWidth == 256 && IsSaturating)
4375 IID = Intrinsic::x86_avx512_vpdpwssds_256;
4376 else if (VecWidth == 512 && IsSaturating)
4377 IID = Intrinsic::x86_avx512_vpdpwssds_512;
4387 if (Args[1]->
getType()->isVectorTy() &&
4390 ->isIntegerTy(32) &&
4391 Args[2]->
getType()->isVectorTy() &&
4394 ->isIntegerTy(32)) {
4395 Type *NewArgType =
nullptr;
4396 if (VecWidth == 128)
4398 else if (VecWidth == 256)
4400 else if (VecWidth == 512)
4405 Args[1] = Builder.CreateBitCast(Args[1], NewArgType);
4406 Args[2] = Builder.CreateBitCast(Args[2], NewArgType);
4409 Rep = Builder.CreateIntrinsic(IID, Args);
4413 }
else if (Name ==
"addcarryx.u32" || Name ==
"addcarryx.u64" ||
4414 Name ==
"addcarry.u32" || Name ==
"addcarry.u64" ||
4415 Name ==
"subborrow.u32" || Name ==
"subborrow.u64") {
4417 if (Name[0] ==
'a' && Name.back() ==
'2')
4418 IID = Intrinsic::x86_addcarry_32;
4419 else if (Name[0] ==
'a' && Name.back() ==
'4')
4420 IID = Intrinsic::x86_addcarry_64;
4421 else if (Name[0] ==
's' && Name.back() ==
'2')
4422 IID = Intrinsic::x86_subborrow_32;
4423 else if (Name[0] ==
's' && Name.back() ==
'4')
4424 IID = Intrinsic::x86_subborrow_64;
4431 Value *NewCall = Builder.CreateIntrinsic(IID, Args);
4434 Value *
Data = Builder.CreateExtractValue(NewCall, 1);
4437 Value *CF = Builder.CreateExtractValue(NewCall, 0);
4441 }
else if (Name.starts_with(
"avx512.mask.") &&
4451 if (Name.starts_with(
"neon.bfcvt")) {
4452 if (Name.starts_with(
"neon.bfcvtn2")) {
4454 std::iota(LoMask.
begin(), LoMask.
end(), 0);
4456 std::iota(ConcatMask.
begin(), ConcatMask.
end(), 0);
4457 Value *Inactive = Builder.CreateShuffleVector(CI->
getOperand(0), LoMask);
4460 return Builder.CreateShuffleVector(Inactive, Trunc, ConcatMask);
4461 }
else if (Name.starts_with(
"neon.bfcvtn")) {
4463 std::iota(ConcatMask.
begin(), ConcatMask.
end(), 0);
4467 dbgs() <<
"Trunc: " << *Trunc <<
"\n";
4468 return Builder.CreateShuffleVector(
4471 return Builder.CreateFPTrunc(CI->
getOperand(0),
4474 }
else if (Name.starts_with(
"sve.fcvt")) {
4477 .
Case(
"sve.fcvt.bf16f32", Intrinsic::aarch64_sve_fcvt_bf16f32_v2)
4478 .
Case(
"sve.fcvtnt.bf16f32",
4479 Intrinsic::aarch64_sve_fcvtnt_bf16f32_v2)
4491 if (Args[1]->
getType() != BadPredTy)
4494 Args[1] = Builder.CreateIntrinsic(Intrinsic::aarch64_sve_convert_to_svbool,
4495 BadPredTy, Args[1]);
4496 Args[1] = Builder.CreateIntrinsic(
4497 Intrinsic::aarch64_sve_convert_from_svbool, GoodPredTy, Args[1]);
4499 return Builder.CreateIntrinsic(NewID, Args,
nullptr,
4508 if (Name ==
"mve.vctp64.old") {
4511 Value *VCTP = Builder.CreateIntrinsic(Intrinsic::arm_mve_vctp64, {},
4514 Value *C1 = Builder.CreateIntrinsic(
4515 Intrinsic::arm_mve_pred_v2i,
4517 return Builder.CreateIntrinsic(
4518 Intrinsic::arm_mve_pred_i2v,
4520 }
else if (Name ==
"mve.mull.int.predicated.v2i64.v4i32.v4i1" ||
4521 Name ==
"mve.vqdmull.predicated.v2i64.v4i32.v4i1" ||
4522 Name ==
"mve.vldr.gather.base.predicated.v2i64.v2i64.v4i1" ||
4523 Name ==
"mve.vldr.gather.base.wb.predicated.v2i64.v2i64.v4i1" ||
4525 "mve.vldr.gather.offset.predicated.v2i64.p0i64.v2i64.v4i1" ||
4526 Name ==
"mve.vldr.gather.offset.predicated.v2i64.p0.v2i64.v4i1" ||
4527 Name ==
"mve.vstr.scatter.base.predicated.v2i64.v2i64.v4i1" ||
4528 Name ==
"mve.vstr.scatter.base.wb.predicated.v2i64.v2i64.v4i1" ||
4530 "mve.vstr.scatter.offset.predicated.p0i64.v2i64.v2i64.v4i1" ||
4531 Name ==
"mve.vstr.scatter.offset.predicated.p0.v2i64.v2i64.v4i1" ||
4532 Name ==
"cde.vcx1q.predicated.v2i64.v4i1" ||
4533 Name ==
"cde.vcx1qa.predicated.v2i64.v4i1" ||
4534 Name ==
"cde.vcx2q.predicated.v2i64.v4i1" ||
4535 Name ==
"cde.vcx2qa.predicated.v2i64.v4i1" ||
4536 Name ==
"cde.vcx3q.predicated.v2i64.v4i1" ||
4537 Name ==
"cde.vcx3qa.predicated.v2i64.v4i1") {
4538 std::vector<Type *> Tys;
4542 case Intrinsic::arm_mve_mull_int_predicated:
4543 case Intrinsic::arm_mve_vqdmull_predicated:
4544 case Intrinsic::arm_mve_vldr_gather_base_predicated:
4547 case Intrinsic::arm_mve_vldr_gather_base_wb_predicated:
4548 case Intrinsic::arm_mve_vstr_scatter_base_predicated:
4549 case Intrinsic::arm_mve_vstr_scatter_base_wb_predicated:
4553 case Intrinsic::arm_mve_vldr_gather_offset_predicated:
4557 case Intrinsic::arm_mve_vstr_scatter_offset_predicated:
4561 case Intrinsic::arm_cde_vcx1q_predicated:
4562 case Intrinsic::arm_cde_vcx1qa_predicated:
4563 case Intrinsic::arm_cde_vcx2q_predicated:
4564 case Intrinsic::arm_cde_vcx2qa_predicated:
4565 case Intrinsic::arm_cde_vcx3q_predicated:
4566 case Intrinsic::arm_cde_vcx3qa_predicated:
4573 std::vector<Value *>
Ops;
4575 Type *Ty =
Op->getType();
4576 if (Ty->getScalarSizeInBits() == 1) {
4577 Value *C1 = Builder.CreateIntrinsic(
4578 Intrinsic::arm_mve_pred_v2i,
4580 Op = Builder.CreateIntrinsic(Intrinsic::arm_mve_pred_i2v, {V2I1Ty}, C1);
4585 return Builder.CreateIntrinsic(
ID, Tys,
Ops,
nullptr,
4615 if (NumOperands < 3)
4628 bool IsVolatile =
false;
4632 if (NumOperands > 3)
4637 if (NumOperands > 5) {
4639 IsVolatile = !VolatileArg || !VolatileArg->
isZero();
4653 if (VT->getElementType()->isIntegerTy(16)) {
4656 Val = Builder.CreateBitCast(Val, AsBF16);
4664 Builder.CreateAtomicRMW(RMWOp, Ptr, Val, std::nullopt, Order, SSID);
4666 unsigned AddrSpace = PtrTy->getAddressSpace();
4669 RMW->
setMetadata(
"amdgpu.no.fine.grained.memory", EmptyMD);
4671 RMW->
setMetadata(
"amdgpu.ignore.denormal.mode", EmptyMD);
4676 MDNode *RangeNotPrivate =
4679 RMW->
setMetadata(LLVMContext::MD_noalias_addrspace, RangeNotPrivate);
4685 return Builder.CreateBitCast(RMW, RetTy);
4706 return MAV->getMetadata();
4713 return I->getDebugLoc().getAsMDNode();
4721 if (Name ==
"label") {
4724 }
else if (Name ==
"assign") {
4731 }
else if (Name ==
"declare") {
4736 }
else if (Name ==
"addr") {
4746 unwrapMAVOp(CI, 1), ExprNode,
nullptr,
nullptr,
nullptr,
4748 }
else if (Name ==
"value") {
4751 unsigned ExprOp = 2;
4765 assert(DR &&
"Unhandled intrinsic kind in upgrade to DbgRecord");
4787 assert(Name.starts_with(
"llvm.") &&
"Intrinsic doesn't start with 'llvm.'");
4788 Name = Name.substr(5);
4790 bool IsX86 = Name.consume_front(
"x86.");
4791 bool IsNVVM = Name.consume_front(
"nvvm.");
4792 bool IsAArch64 = Name.consume_front(
"aarch64.");
4793 bool IsARM = Name.consume_front(
"arm.");
4794 bool IsAMDGCN = Name.consume_front(
"amdgcn.");
4795 bool IsDbg = Name.consume_front(
"dbg.");
4796 Value *Rep =
nullptr;
4798 if (!IsX86 && Name ==
"stackprotectorcheck") {
4800 }
else if (IsNVVM) {
4804 }
else if (IsAArch64) {
4808 }
else if (IsAMDGCN) {
4822 const auto &DefaultCase = [&]() ->
void {
4830 "Unknown function for CallBase upgrade and isn't just a name change");
4838 "Return type must have changed");
4839 assert(OldST->getNumElements() ==
4841 "Must have same number of elements");
4844 CallInst *NewCI = Builder.CreateCall(NewFn, Args);
4847 for (
unsigned Idx = 0; Idx < OldST->getNumElements(); ++Idx) {
4848 Value *Elem = Builder.CreateExtractValue(NewCI, Idx);
4849 Res = Builder.CreateInsertValue(Res, Elem, Idx);
4868 case Intrinsic::arm_neon_vst1:
4869 case Intrinsic::arm_neon_vst2:
4870 case Intrinsic::arm_neon_vst3:
4871 case Intrinsic::arm_neon_vst4:
4872 case Intrinsic::arm_neon_vst2lane:
4873 case Intrinsic::arm_neon_vst3lane:
4874 case Intrinsic::arm_neon_vst4lane: {
4876 NewCall = Builder.CreateCall(NewFn, Args);
4879 case Intrinsic::aarch64_sve_bfmlalb_lane_v2:
4880 case Intrinsic::aarch64_sve_bfmlalt_lane_v2:
4881 case Intrinsic::aarch64_sve_bfdot_lane_v2: {
4886 NewCall = Builder.CreateCall(NewFn, Args);
4889 case Intrinsic::aarch64_sve_ld3_sret:
4890 case Intrinsic::aarch64_sve_ld4_sret:
4891 case Intrinsic::aarch64_sve_ld2_sret: {
4893 Name = Name.substr(5);
4900 unsigned MinElts = RetTy->getMinNumElements() /
N;
4902 Value *NewLdCall = Builder.CreateCall(NewFn, Args);
4904 for (
unsigned I = 0;
I <
N;
I++) {
4905 Value *SRet = Builder.CreateExtractValue(NewLdCall,
I);
4906 Ret = Builder.CreateInsertVector(RetTy, Ret, SRet,
I * MinElts);
4912 case Intrinsic::coro_end: {
4915 NewCall = Builder.CreateCall(NewFn, Args);
4919 case Intrinsic::vector_extract: {
4921 Name = Name.substr(5);
4922 if (!Name.starts_with(
"aarch64.sve.tuple.get")) {
4927 unsigned MinElts = RetTy->getMinNumElements();
4930 NewCall = Builder.CreateCall(NewFn, {CI->
getArgOperand(0), NewIdx});
4934 case Intrinsic::vector_insert: {
4936 Name = Name.substr(5);
4937 if (!Name.starts_with(
"aarch64.sve.tuple")) {
4941 if (Name.starts_with(
"aarch64.sve.tuple.set")) {
4946 NewCall = Builder.CreateCall(
4950 if (Name.starts_with(
"aarch64.sve.tuple.create")) {
4956 assert(
N > 1 &&
"Create is expected to be between 2-4");
4959 unsigned MinElts = RetTy->getMinNumElements() /
N;
4960 for (
unsigned I = 0;
I <
N;
I++) {
4962 Ret = Builder.CreateInsertVector(RetTy, Ret, V,
I * MinElts);
4969 case Intrinsic::arm_neon_bfdot:
4970 case Intrinsic::arm_neon_bfmmla:
4971 case Intrinsic::arm_neon_bfmlalb:
4972 case Intrinsic::arm_neon_bfmlalt:
4973 case Intrinsic::aarch64_neon_bfdot:
4974 case Intrinsic::aarch64_neon_bfmmla:
4975 case Intrinsic::aarch64_neon_bfmlalb:
4976 case Intrinsic::aarch64_neon_bfmlalt: {
4979 "Mismatch between function args and call args");
4980 size_t OperandWidth =
4982 assert((OperandWidth == 64 || OperandWidth == 128) &&
4983 "Unexpected operand width");
4985 auto Iter = CI->
args().begin();
4986 Args.push_back(*Iter++);
4987 Args.push_back(Builder.CreateBitCast(*Iter++, NewTy));
4988 Args.push_back(Builder.CreateBitCast(*Iter++, NewTy));
4989 NewCall = Builder.CreateCall(NewFn, Args);
4993 case Intrinsic::bitreverse:
4994 NewCall = Builder.CreateCall(NewFn, {CI->
getArgOperand(0)});
4997 case Intrinsic::ctlz:
4998 case Intrinsic::cttz:
5000 "Mismatch between function args and call args");
5002 Builder.CreateCall(NewFn, {CI->
getArgOperand(0), Builder.getFalse()});
5005 case Intrinsic::objectsize: {
5006 Value *NullIsUnknownSize =
5010 NewCall = Builder.CreateCall(
5015 case Intrinsic::ctpop:
5016 NewCall = Builder.CreateCall(NewFn, {CI->
getArgOperand(0)});
5019 case Intrinsic::convert_from_fp16:
5020 NewCall = Builder.CreateCall(NewFn, {CI->
getArgOperand(0)});
5023 case Intrinsic::dbg_value: {
5025 Name = Name.substr(5);
5027 if (Name.starts_with(
"dbg.addr")) {
5041 if (
Offset->isZeroValue()) {
5042 NewCall = Builder.CreateCall(
5051 case Intrinsic::ptr_annotation:
5059 NewCall = Builder.CreateCall(
5068 case Intrinsic::var_annotation:
5075 NewCall = Builder.CreateCall(
5084 case Intrinsic::riscv_aes32dsi:
5085 case Intrinsic::riscv_aes32dsmi:
5086 case Intrinsic::riscv_aes32esi:
5087 case Intrinsic::riscv_aes32esmi:
5088 case Intrinsic::riscv_sm4ks:
5089 case Intrinsic::riscv_sm4ed: {
5099 Arg0 = Builder.CreateTrunc(Arg0, Builder.getInt32Ty());
5100 Arg1 = Builder.CreateTrunc(Arg1, Builder.getInt32Ty());
5106 NewCall = Builder.CreateCall(NewFn, {Arg0, Arg1, Arg2});
5107 Value *Res = NewCall;
5109 Res = Builder.CreateIntCast(NewCall, CI->
getType(),
true);
5115 case Intrinsic::nvvm_mapa_shared_cluster: {
5119 Value *Res = NewCall;
5120 Res = Builder.CreateAddrSpaceCast(
5127 case Intrinsic::nvvm_cp_async_bulk_global_to_shared_cluster:
5128 case Intrinsic::nvvm_cp_async_bulk_shared_cta_to_cluster: {
5131 Args[0] = Builder.CreateAddrSpaceCast(
5134 NewCall = Builder.CreateCall(NewFn, Args);
5140 case Intrinsic::nvvm_cp_async_bulk_tensor_g2s_im2col_3d:
5141 case Intrinsic::nvvm_cp_async_bulk_tensor_g2s_im2col_4d:
5142 case Intrinsic::nvvm_cp_async_bulk_tensor_g2s_im2col_5d:
5143 case Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_1d:
5144 case Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_2d:
5145 case Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_3d:
5146 case Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_4d:
5147 case Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_5d: {
5154 Args[0] = Builder.CreateAddrSpaceCast(
5163 Args.push_back(ConstantInt::get(Builder.getInt32Ty(), 0));
5165 NewCall = Builder.CreateCall(NewFn, Args);
5171 case Intrinsic::riscv_sha256sig0:
5172 case Intrinsic::riscv_sha256sig1:
5173 case Intrinsic::riscv_sha256sum0:
5174 case Intrinsic::riscv_sha256sum1:
5175 case Intrinsic::riscv_sm3p0:
5176 case Intrinsic::riscv_sm3p1: {
5183 Builder.CreateTrunc(CI->
getArgOperand(0), Builder.getInt32Ty());
5185 NewCall = Builder.CreateCall(NewFn, Arg);
5187 Builder.CreateIntCast(NewCall, CI->
getType(),
true);
5194 case Intrinsic::x86_xop_vfrcz_ss:
5195 case Intrinsic::x86_xop_vfrcz_sd:
5196 NewCall = Builder.CreateCall(NewFn, {CI->
getArgOperand(1)});
5199 case Intrinsic::x86_xop_vpermil2pd:
5200 case Intrinsic::x86_xop_vpermil2ps:
5201 case Intrinsic::x86_xop_vpermil2pd_256:
5202 case Intrinsic::x86_xop_vpermil2ps_256: {
5206 Args[2] = Builder.CreateBitCast(Args[2], IntIdxTy);
5207 NewCall = Builder.CreateCall(NewFn, Args);
5211 case Intrinsic::x86_sse41_ptestc:
5212 case Intrinsic::x86_sse41_ptestz:
5213 case Intrinsic::x86_sse41_ptestnzc: {
5227 Value *BC0 = Builder.CreateBitCast(Arg0, NewVecTy,
"cast");
5228 Value *BC1 = Builder.CreateBitCast(Arg1, NewVecTy,
"cast");
5230 NewCall = Builder.CreateCall(NewFn, {BC0, BC1});
5234 case Intrinsic::x86_rdtscp: {
5240 NewCall = Builder.CreateCall(NewFn);
5242 Value *
Data = Builder.CreateExtractValue(NewCall, 1);
5245 Value *TSC = Builder.CreateExtractValue(NewCall, 0);
5253 case Intrinsic::x86_sse41_insertps:
5254 case Intrinsic::x86_sse41_dppd:
5255 case Intrinsic::x86_sse41_dpps:
5256 case Intrinsic::x86_sse41_mpsadbw:
5257 case Intrinsic::x86_avx_dp_ps_256:
5258 case Intrinsic::x86_avx2_mpsadbw: {
5264 Args.back() = Builder.CreateTrunc(Args.back(),
Type::getInt8Ty(
C),
"trunc");
5265 NewCall = Builder.CreateCall(NewFn, Args);
5269 case Intrinsic::x86_avx512_mask_cmp_pd_128:
5270 case Intrinsic::x86_avx512_mask_cmp_pd_256:
5271 case Intrinsic::x86_avx512_mask_cmp_pd_512:
5272 case Intrinsic::x86_avx512_mask_cmp_ps_128:
5273 case Intrinsic::x86_avx512_mask_cmp_ps_256:
5274 case Intrinsic::x86_avx512_mask_cmp_ps_512: {
5280 NewCall = Builder.CreateCall(NewFn, Args);
5289 case Intrinsic::x86_avx512bf16_cvtne2ps2bf16_128:
5290 case Intrinsic::x86_avx512bf16_cvtne2ps2bf16_256:
5291 case Intrinsic::x86_avx512bf16_cvtne2ps2bf16_512:
5292 case Intrinsic::x86_avx512bf16_mask_cvtneps2bf16_128:
5293 case Intrinsic::x86_avx512bf16_cvtneps2bf16_256:
5294 case Intrinsic::x86_avx512bf16_cvtneps2bf16_512: {
5298 Intrinsic::x86_avx512bf16_mask_cvtneps2bf16_128)
5299 Args[1] = Builder.CreateBitCast(
5302 NewCall = Builder.CreateCall(NewFn, Args);
5303 Value *Res = Builder.CreateBitCast(
5311 case Intrinsic::x86_avx512bf16_dpbf16ps_128:
5312 case Intrinsic::x86_avx512bf16_dpbf16ps_256:
5313 case Intrinsic::x86_avx512bf16_dpbf16ps_512:{
5317 Args[1] = Builder.CreateBitCast(
5319 Args[2] = Builder.CreateBitCast(
5322 NewCall = Builder.CreateCall(NewFn, Args);
5326 case Intrinsic::thread_pointer: {
5327 NewCall = Builder.CreateCall(NewFn, {});
5331 case Intrinsic::memcpy:
5332 case Intrinsic::memmove:
5333 case Intrinsic::memset: {
5349 NewCall = Builder.CreateCall(NewFn, Args);
5351 AttributeList NewAttrs = AttributeList::get(
5352 C, OldAttrs.getFnAttrs(), OldAttrs.getRetAttrs(),
5353 {OldAttrs.getParamAttrs(0), OldAttrs.getParamAttrs(1),
5354 OldAttrs.getParamAttrs(2), OldAttrs.getParamAttrs(4)});
5359 MemCI->setDestAlignment(
Align->getMaybeAlignValue());
5362 MTI->setSourceAlignment(
Align->getMaybeAlignValue());
5366 case Intrinsic::masked_load:
5367 case Intrinsic::masked_gather:
5368 case Intrinsic::masked_store:
5369 case Intrinsic::masked_scatter: {
5375 auto GetMaybeAlign = [](
Value *
Op) {
5385 auto GetAlign = [&](
Value *
Op) {
5394 case Intrinsic::masked_load:
5395 NewCall = Builder.CreateMaskedLoad(
5399 case Intrinsic::masked_gather:
5400 NewCall = Builder.CreateMaskedGather(
5406 case Intrinsic::masked_store:
5407 NewCall = Builder.CreateMaskedStore(
5411 case Intrinsic::masked_scatter:
5412 NewCall = Builder.CreateMaskedScatter(
5414 DL.getValueOrABITypeAlignment(
5428 case Intrinsic::lifetime_start:
5429 case Intrinsic::lifetime_end: {
5441 NewCall = Builder.CreateLifetimeStart(Ptr);
5443 NewCall = Builder.CreateLifetimeEnd(Ptr);
5452 case Intrinsic::x86_avx512_vpdpbusd_128:
5453 case Intrinsic::x86_avx512_vpdpbusd_256:
5454 case Intrinsic::x86_avx512_vpdpbusd_512:
5455 case Intrinsic::x86_avx512_vpdpbusds_128:
5456 case Intrinsic::x86_avx512_vpdpbusds_256:
5457 case Intrinsic::x86_avx512_vpdpbusds_512:
5458 case Intrinsic::x86_avx2_vpdpbssd_128:
5459 case Intrinsic::x86_avx2_vpdpbssd_256:
5460 case Intrinsic::x86_avx10_vpdpbssd_512:
5461 case Intrinsic::x86_avx2_vpdpbssds_128:
5462 case Intrinsic::x86_avx2_vpdpbssds_256:
5463 case Intrinsic::x86_avx10_vpdpbssds_512:
5464 case Intrinsic::x86_avx2_vpdpbsud_128:
5465 case Intrinsic::x86_avx2_vpdpbsud_256:
5466 case Intrinsic::x86_avx10_vpdpbsud_512:
5467 case Intrinsic::x86_avx2_vpdpbsuds_128:
5468 case Intrinsic::x86_avx2_vpdpbsuds_256:
5469 case Intrinsic::x86_avx10_vpdpbsuds_512:
5470 case Intrinsic::x86_avx2_vpdpbuud_128:
5471 case Intrinsic::x86_avx2_vpdpbuud_256:
5472 case Intrinsic::x86_avx10_vpdpbuud_512:
5473 case Intrinsic::x86_avx2_vpdpbuuds_128:
5474 case Intrinsic::x86_avx2_vpdpbuuds_256:
5475 case Intrinsic::x86_avx10_vpdpbuuds_512: {
5480 Args[1] = Builder.CreateBitCast(Args[1], NewArgType);
5481 Args[2] = Builder.CreateBitCast(Args[2], NewArgType);
5483 NewCall = Builder.CreateCall(NewFn, Args);
5486 case Intrinsic::x86_avx512_vpdpwssd_128:
5487 case Intrinsic::x86_avx512_vpdpwssd_256:
5488 case Intrinsic::x86_avx512_vpdpwssd_512:
5489 case Intrinsic::x86_avx512_vpdpwssds_128:
5490 case Intrinsic::x86_avx512_vpdpwssds_256:
5491 case Intrinsic::x86_avx512_vpdpwssds_512:
5492 case Intrinsic::x86_avx2_vpdpwsud_128:
5493 case Intrinsic::x86_avx2_vpdpwsud_256:
5494 case Intrinsic::x86_avx10_vpdpwsud_512:
5495 case Intrinsic::x86_avx2_vpdpwsuds_128:
5496 case Intrinsic::x86_avx2_vpdpwsuds_256:
5497 case Intrinsic::x86_avx10_vpdpwsuds_512:
5498 case Intrinsic::x86_avx2_vpdpwusd_128:
5499 case Intrinsic::x86_avx2_vpdpwusd_256:
5500 case Intrinsic::x86_avx10_vpdpwusd_512:
5501 case Intrinsic::x86_avx2_vpdpwusds_128:
5502 case Intrinsic::x86_avx2_vpdpwusds_256:
5503 case Intrinsic::x86_avx10_vpdpwusds_512:
5504 case Intrinsic::x86_avx2_vpdpwuud_128:
5505 case Intrinsic::x86_avx2_vpdpwuud_256:
5506 case Intrinsic::x86_avx10_vpdpwuud_512:
5507 case Intrinsic::x86_avx2_vpdpwuuds_128:
5508 case Intrinsic::x86_avx2_vpdpwuuds_256:
5509 case Intrinsic::x86_avx10_vpdpwuuds_512:
5514 Args[1] = Builder.CreateBitCast(Args[1], NewArgType);
5515 Args[2] = Builder.CreateBitCast(Args[2], NewArgType);
5517 NewCall = Builder.CreateCall(NewFn, Args);
5520 assert(NewCall &&
"Should have either set this variable or returned through "
5521 "the default case");
5528 assert(
F &&
"Illegal attempt to upgrade a non-existent intrinsic.");
5542 F->eraseFromParent();
5548 if (NumOperands == 0)
5556 if (NumOperands == 3) {
5560 Metadata *Elts2[] = {ScalarType, ScalarType,
5574 if (
Opc != Instruction::BitCast)
5578 Type *SrcTy = V->getType();
5595 if (
Opc != Instruction::BitCast)
5598 Type *SrcTy =
C->getType();
5625 if (
NamedMDNode *ModFlags = M.getModuleFlagsMetadata()) {
5626 auto OpIt =
find_if(ModFlags->operands(), [](
const MDNode *Flag) {
5627 if (Flag->getNumOperands() < 3)
5629 if (MDString *K = dyn_cast_or_null<MDString>(Flag->getOperand(1)))
5630 return K->getString() ==
"Debug Info Version";
5633 if (OpIt != ModFlags->op_end()) {
5634 const MDOperand &ValOp = (*OpIt)->getOperand(2);
5641 bool BrokenDebugInfo =
false;
5644 if (!BrokenDebugInfo)
5650 M.getContext().diagnose(Diag);
5657 M.getContext().diagnose(DiagVersion);
5667 StringRef Vect3[3] = {DefaultValue, DefaultValue, DefaultValue};
5670 if (
F->hasFnAttribute(Attr)) {
5673 StringRef S =
F->getFnAttribute(Attr).getValueAsString();
5675 auto [Part, Rest] = S.
split(
',');
5681 const unsigned Dim = DimC -
'x';
5682 assert(Dim < 3 &&
"Unexpected dim char");
5692 F->addFnAttr(Attr, NewAttr);
5696 return S ==
"x" || S ==
"y" || S ==
"z";
5701 if (K ==
"kernel") {
5713 const unsigned Idx = (AlignIdxValuePair >> 16);
5714 const Align StackAlign =
Align(AlignIdxValuePair & 0xFFFF);
5719 if (K ==
"maxclusterrank" || K ==
"cluster_max_blocks") {
5724 if (K ==
"minctasm") {
5729 if (K ==
"maxnreg") {
5734 if (K.consume_front(
"maxntid") &&
isXYZ(K)) {
5738 if (K.consume_front(
"reqntid") &&
isXYZ(K)) {
5742 if (K.consume_front(
"cluster_dim_") &&
isXYZ(K)) {
5746 if (K ==
"grid_constant") {
5761 NamedMDNode *NamedMD = M.getNamedMetadata(
"nvvm.annotations");
5768 if (!SeenNodes.
insert(MD).second)
5775 assert((MD->getNumOperands() % 2) == 1 &&
"Invalid number of operands");
5782 for (
unsigned j = 1, je = MD->getNumOperands(); j < je; j += 2) {
5784 const MDOperand &V = MD->getOperand(j + 1);
5787 NewOperands.
append({K, V});
5790 if (NewOperands.
size() > 1)
5803 const char *MarkerKey =
"clang.arc.retainAutoreleasedReturnValueMarker";
5804 NamedMDNode *ModRetainReleaseMarker = M.getNamedMetadata(MarkerKey);
5805 if (ModRetainReleaseMarker) {
5811 ID->getString().split(ValueComp,
"#");
5812 if (ValueComp.
size() == 2) {
5813 std::string NewValue = ValueComp[0].str() +
";" + ValueComp[1].str();
5817 M.eraseNamedMetadata(ModRetainReleaseMarker);
5828 auto UpgradeToIntrinsic = [&](
const char *OldFunc,
5854 bool InvalidCast =
false;
5856 for (
unsigned I = 0, E = CI->
arg_size();
I != E; ++
I) {
5869 Arg = Builder.CreateBitCast(Arg, NewFuncTy->
getParamType(
I));
5871 Args.push_back(Arg);
5878 CallInst *NewCall = Builder.CreateCall(NewFuncTy, NewFn, Args);
5883 Value *NewRetVal = Builder.CreateBitCast(NewCall, CI->
getType());
5896 UpgradeToIntrinsic(
"clang.arc.use", llvm::Intrinsic::objc_clang_arc_use);
5904 std::pair<const char *, llvm::Intrinsic::ID> RuntimeFuncs[] = {
5905 {
"objc_autorelease", llvm::Intrinsic::objc_autorelease},
5906 {
"objc_autoreleasePoolPop", llvm::Intrinsic::objc_autoreleasePoolPop},
5907 {
"objc_autoreleasePoolPush", llvm::Intrinsic::objc_autoreleasePoolPush},
5908 {
"objc_autoreleaseReturnValue",
5909 llvm::Intrinsic::objc_autoreleaseReturnValue},
5910 {
"objc_copyWeak", llvm::Intrinsic::objc_copyWeak},
5911 {
"objc_destroyWeak", llvm::Intrinsic::objc_destroyWeak},
5912 {
"objc_initWeak", llvm::Intrinsic::objc_initWeak},
5913 {
"objc_loadWeak", llvm::Intrinsic::objc_loadWeak},
5914 {
"objc_loadWeakRetained", llvm::Intrinsic::objc_loadWeakRetained},
5915 {
"objc_moveWeak", llvm::Intrinsic::objc_moveWeak},
5916 {
"objc_release", llvm::Intrinsic::objc_release},
5917 {
"objc_retain", llvm::Intrinsic::objc_retain},
5918 {
"objc_retainAutorelease", llvm::Intrinsic::objc_retainAutorelease},
5919 {
"objc_retainAutoreleaseReturnValue",
5920 llvm::Intrinsic::objc_retainAutoreleaseReturnValue},
5921 {
"objc_retainAutoreleasedReturnValue",
5922 llvm::Intrinsic::objc_retainAutoreleasedReturnValue},
5923 {
"objc_retainBlock", llvm::Intrinsic::objc_retainBlock},
5924 {
"objc_storeStrong", llvm::Intrinsic::objc_storeStrong},
5925 {
"objc_storeWeak", llvm::Intrinsic::objc_storeWeak},
5926 {
"objc_unsafeClaimAutoreleasedReturnValue",
5927 llvm::Intrinsic::objc_unsafeClaimAutoreleasedReturnValue},
5928 {
"objc_retainedObject", llvm::Intrinsic::objc_retainedObject},
5929 {
"objc_unretainedObject", llvm::Intrinsic::objc_unretainedObject},
5930 {
"objc_unretainedPointer", llvm::Intrinsic::objc_unretainedPointer},
5931 {
"objc_retain_autorelease", llvm::Intrinsic::objc_retain_autorelease},
5932 {
"objc_sync_enter", llvm::Intrinsic::objc_sync_enter},
5933 {
"objc_sync_exit", llvm::Intrinsic::objc_sync_exit},
5934 {
"objc_arc_annotation_topdown_bbstart",
5935 llvm::Intrinsic::objc_arc_annotation_topdown_bbstart},
5936 {
"objc_arc_annotation_topdown_bbend",
5937 llvm::Intrinsic::objc_arc_annotation_topdown_bbend},
5938 {
"objc_arc_annotation_bottomup_bbstart",
5939 llvm::Intrinsic::objc_arc_annotation_bottomup_bbstart},
5940 {
"objc_arc_annotation_bottomup_bbend",
5941 llvm::Intrinsic::objc_arc_annotation_bottomup_bbend}};
5943 for (
auto &
I : RuntimeFuncs)
5944 UpgradeToIntrinsic(
I.first,
I.second);
5948 NamedMDNode *ModFlags = M.getModuleFlagsMetadata();
5952 bool HasObjCFlag =
false, HasClassProperties =
false,
Changed =
false;
5953 bool HasSwiftVersionFlag =
false;
5954 uint8_t SwiftMajorVersion, SwiftMinorVersion;
5961 if (
Op->getNumOperands() != 3)
5975 if (
ID->getString() ==
"Objective-C Image Info Version")
5977 if (
ID->getString() ==
"Objective-C Class Properties")
5978 HasClassProperties =
true;
5980 if (
ID->getString() ==
"PIC Level") {
5981 if (
auto *Behavior =
5983 uint64_t V = Behavior->getLimitedValue();
5989 if (
ID->getString() ==
"PIE Level")
5990 if (
auto *Behavior =
5997 if (
ID->getString() ==
"branch-target-enforcement" ||
5998 ID->getString().starts_with(
"sign-return-address")) {
5999 if (
auto *Behavior =
6005 Op->getOperand(1),
Op->getOperand(2)};
6015 if (
ID->getString() ==
"Objective-C Image Info Section") {
6018 Value->getString().split(ValueComp,
" ");
6019 if (ValueComp.
size() != 1) {
6020 std::string NewValue;
6021 for (
auto &S : ValueComp)
6022 NewValue += S.str();
6033 if (
ID->getString() ==
"Objective-C Garbage Collection") {
6036 assert(Md->getValue() &&
"Expected non-empty metadata");
6037 auto Type = Md->getValue()->getType();
6040 unsigned Val = Md->getValue()->getUniqueInteger().getZExtValue();
6041 if ((Val & 0xff) != Val) {
6042 HasSwiftVersionFlag =
true;
6043 SwiftABIVersion = (Val & 0xff00) >> 8;
6044 SwiftMajorVersion = (Val & 0xff000000) >> 24;
6045 SwiftMinorVersion = (Val & 0xff0000) >> 16;
6056 if (
ID->getString() ==
"amdgpu_code_object_version") {
6059 MDString::get(M.getContext(),
"amdhsa_code_object_version"),
6071 if (HasObjCFlag && !HasClassProperties) {
6077 if (HasSwiftVersionFlag) {
6081 ConstantInt::get(Int8Ty, SwiftMajorVersion));
6083 ConstantInt::get(Int8Ty, SwiftMinorVersion));
6091 auto TrimSpaces = [](
StringRef Section) -> std::string {
6093 Section.split(Components,
',');
6098 for (
auto Component : Components)
6099 OS <<
',' << Component.trim();
6104 for (
auto &GV : M.globals()) {
6105 if (!GV.hasSection())
6110 if (!Section.starts_with(
"__DATA, __objc_catlist"))
6115 GV.setSection(TrimSpaces(Section));
6131struct StrictFPUpgradeVisitor :
public InstVisitor<StrictFPUpgradeVisitor> {
6132 StrictFPUpgradeVisitor() =
default;
6135 if (!
Call.isStrictFP())
6141 Call.removeFnAttr(Attribute::StrictFP);
6142 Call.addFnAttr(Attribute::NoBuiltin);
6147struct AMDGPUUnsafeFPAtomicsUpgradeVisitor
6148 :
public InstVisitor<AMDGPUUnsafeFPAtomicsUpgradeVisitor> {
6149 AMDGPUUnsafeFPAtomicsUpgradeVisitor() =
default;
6151 void visitAtomicRMWInst(AtomicRMWInst &RMW) {
6166 if (!
F.isDeclaration() && !
F.hasFnAttribute(Attribute::StrictFP)) {
6167 StrictFPUpgradeVisitor SFPV;
6172 F.removeRetAttrs(AttributeFuncs::typeIncompatible(
6173 F.getReturnType(),
F.getAttributes().getRetAttrs()));
6174 for (
auto &Arg :
F.args())
6176 AttributeFuncs::typeIncompatible(Arg.getType(), Arg.getAttributes()));
6180 if (
Attribute A =
F.getFnAttribute(
"implicit-section-name");
6181 A.isValid() &&
A.isStringAttribute()) {
6182 F.setSection(
A.getValueAsString());
6183 F.removeFnAttr(
"implicit-section-name");
6190 if (
Attribute A =
F.getFnAttribute(
"amdgpu-unsafe-fp-atomics");
6193 if (
A.getValueAsBool()) {
6194 AMDGPUUnsafeFPAtomicsUpgradeVisitor Visitor;
6200 F.removeFnAttr(
"amdgpu-unsafe-fp-atomics");
6208 if (!
F.hasFnAttribute(FnAttrName))
6209 F.addFnAttr(FnAttrName,
Value);
6216 if (!
F.hasFnAttribute(FnAttrName)) {
6218 F.addFnAttr(FnAttrName);
6220 auto A =
F.getFnAttribute(FnAttrName);
6221 if (
"false" ==
A.getValueAsString())
6222 F.removeFnAttr(FnAttrName);
6223 else if (
"true" ==
A.getValueAsString()) {
6224 F.removeFnAttr(FnAttrName);
6225 F.addFnAttr(FnAttrName);
6231 Triple T(M.getTargetTriple());
6232 if (!
T.isThumb() && !
T.isARM() && !
T.isAArch64())
6242 NamedMDNode *ModFlags = M.getModuleFlagsMetadata();
6246 if (
Op->getNumOperands() != 3)
6255 uint64_t *ValPtr = IDStr ==
"branch-target-enforcement" ? &BTEValue
6256 : IDStr ==
"branch-protection-pauth-lr" ? &BPPLRValue
6257 : IDStr ==
"guarded-control-stack" ? &GCSValue
6258 : IDStr ==
"sign-return-address" ? &SRAValue
6259 : IDStr ==
"sign-return-address-all" ? &SRAALLValue
6260 : IDStr ==
"sign-return-address-with-bkey"
6266 *ValPtr = CI->getZExtValue();
6272 bool BTE = BTEValue == 1;
6273 bool BPPLR = BPPLRValue == 1;
6274 bool GCS = GCSValue == 1;
6275 bool SRA = SRAValue == 1;
6278 if (SRA && SRAALLValue == 1)
6279 SignTypeValue =
"all";
6282 if (SRA && SRABKeyValue == 1)
6283 SignKeyValue =
"b_key";
6285 for (
Function &
F : M.getFunctionList()) {
6286 if (
F.isDeclaration())
6293 if (
auto A =
F.getFnAttribute(
"sign-return-address");
6294 A.isValid() &&
"none" ==
A.getValueAsString()) {
6295 F.removeFnAttr(
"sign-return-address");
6296 F.removeFnAttr(
"sign-return-address-key");
6312 if (SRAALLValue == 1)
6314 if (SRABKeyValue == 1)
6323 if (
T->getNumOperands() < 1)
6328 return S->getString().starts_with(
"llvm.vectorizer.");
6332 StringRef OldPrefix =
"llvm.vectorizer.";
6335 if (OldTag ==
"llvm.vectorizer.unroll")
6347 if (
T->getNumOperands() < 1)
6352 if (!OldTag->getString().starts_with(
"llvm.vectorizer."))
6357 Ops.reserve(
T->getNumOperands());
6359 for (
unsigned I = 1,
E =
T->getNumOperands();
I !=
E; ++
I)
6360 Ops.push_back(
T->getOperand(
I));
6374 Ops.reserve(
T->getNumOperands());
6385 if ((
T.isSPIR() || (
T.isSPIRV() && !
T.isSPIRVLogical())) &&
6386 !
DL.contains(
"-G") && !
DL.starts_with(
"G")) {
6387 return DL.empty() ? std::string(
"G1") : (
DL +
"-G1").str();
6390 if (
T.isLoongArch64() ||
T.isRISCV64()) {
6392 auto I =
DL.find(
"-n64-");
6394 return (
DL.take_front(
I) +
"-n32:64-" +
DL.drop_front(
I + 5)).str();
6399 std::string Res =
DL.str();
6402 if (!
DL.contains(
"-G") && !
DL.starts_with(
"G"))
6403 Res.append(Res.empty() ?
"G1" :
"-G1");
6411 if (!
DL.contains(
"-ni") && !
DL.starts_with(
"ni"))
6412 Res.append(
"-ni:7:8:9");
6414 if (
DL.ends_with(
"ni:7"))
6416 if (
DL.ends_with(
"ni:7:8"))
6421 if (!
DL.contains(
"-p7") && !
DL.starts_with(
"p7"))
6422 Res.append(
"-p7:160:256:256:32");
6423 if (!
DL.contains(
"-p8") && !
DL.starts_with(
"p8"))
6424 Res.append(
"-p8:128:128:128:48");
6425 constexpr StringRef OldP8(
"-p8:128:128-");
6426 if (
DL.contains(OldP8))
6427 Res.replace(Res.find(OldP8), OldP8.
size(),
"-p8:128:128:128:48-");
6428 if (!
DL.contains(
"-p9") && !
DL.starts_with(
"p9"))
6429 Res.append(
"-p9:192:256:256:32");
6433 if (!
DL.contains(
"m:e"))
6434 Res = Res.empty() ?
"m:e" :
"m:e-" + Res;
6439 auto AddPtr32Ptr64AddrSpaces = [&
DL, &Res]() {
6442 StringRef AddrSpaces{
"-p270:32:32-p271:32:32-p272:64:64"};
6443 if (!
DL.contains(AddrSpaces)) {
6445 Regex R(
"^([Ee]-m:[a-z](-p:32:32)?)(-.*)$");
6446 if (R.match(Res, &
Groups))
6452 if (
T.isAArch64()) {
6454 if (!
DL.empty() && !
DL.contains(
"-Fn32"))
6455 Res.append(
"-Fn32");
6456 AddPtr32Ptr64AddrSpaces();
6460 if (
T.isSPARC() || (
T.isMIPS64() && !
DL.contains(
"m:m")) ||
T.isPPC64() ||
6464 std::string I64 =
"-i64:64";
6465 std::string I128 =
"-i128:128";
6467 size_t Pos = Res.find(I64);
6468 if (Pos !=
size_t(-1))
6469 Res.insert(Pos + I64.size(), I128);
6477 AddPtr32Ptr64AddrSpaces();
6485 if (!
T.isOSIAMCU()) {
6486 std::string I128 =
"-i128:128";
6489 Regex R(
"^(e(-[mpi][^-]*)*)((-[^mpi][^-]*)*)$");
6490 if (R.match(Res, &
Groups))
6498 if (
T.isWindowsMSVCEnvironment() && !
T.isArch64Bit()) {
6500 auto I =
Ref.find(
"-f80:32-");
6502 Res = (
Ref.take_front(
I) +
"-f80:128-" +
Ref.drop_front(
I + 8)).str();
6510 Attribute A =
B.getAttribute(
"no-frame-pointer-elim");
6513 FramePointer =
A.getValueAsString() ==
"true" ?
"all" :
"none";
6514 B.removeAttribute(
"no-frame-pointer-elim");
6516 if (
B.contains(
"no-frame-pointer-elim-non-leaf")) {
6518 if (FramePointer !=
"all")
6519 FramePointer =
"non-leaf";
6520 B.removeAttribute(
"no-frame-pointer-elim-non-leaf");
6522 if (!FramePointer.
empty())
6523 B.addAttribute(
"frame-pointer", FramePointer);
6525 A =
B.getAttribute(
"null-pointer-is-valid");
6528 bool NullPointerIsValid =
A.getValueAsString() ==
"true";
6529 B.removeAttribute(
"null-pointer-is-valid");
6530 if (NullPointerIsValid)
6531 B.addAttribute(Attribute::NullPointerIsValid);
6541 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 * 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...
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
Value * getCalledOperand() const
void setAttributes(AttributeList A)
Set the attributes for this call.
Value * getArgOperand(unsigned i) const
FunctionType * getFunctionType() const
LLVM_ABI Intrinsic::ID getIntrinsicID() const
Returns the intrinsic ID of the intrinsic called or Intrinsic::not_intrinsic if the called function i...
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
void setCalledOperand(Value *V)
unsigned arg_size() const
AttributeList getAttributes() const
Return the attributes for this call.
void setCalledFunction(Function *Fn)
Sets the function called, including updating the function type.
This class represents a function call, abstracting a target machine's calling convention.
void setTailCallKind(TailCallKind TCK)
static LLVM_ABI CastInst * Create(Instruction::CastOps, Value *S, Type *Ty, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Provides a way to construct any of the CastInst subclasses using an opcode instead of the subclass's ...
static LLVM_ABI bool castIsValid(Instruction::CastOps op, Type *SrcTy, Type *DstTy)
This method can be used to determine if a cast from SrcTy to DstTy using Opcode op is valid or not.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ ICMP_SLT
signed less than
@ ICMP_SLE
signed less or equal
@ ICMP_UGE
unsigned greater or equal
@ ICMP_UGT
unsigned greater than
@ ICMP_SGT
signed greater than
@ ICMP_ULT
unsigned less than
@ ICMP_SGE
signed greater or equal
@ ICMP_ULE
unsigned less or equal
static LLVM_ABI ConstantAggregateZero * get(Type *Ty)
static LLVM_ABI Constant * get(ArrayType *T, ArrayRef< Constant * > V)
static LLVM_ABI Constant * getIntToPtr(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static LLVM_ABI Constant * getPointerCast(Constant *C, Type *Ty)
Create a BitCast, AddrSpaceCast, or a PtrToInt cast constant expression.
static LLVM_ABI Constant * getPtrToInt(Constant *C, Type *Ty, bool OnlyIfReduced=false)
This is the shared class of boolean and integer constants.
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
static LLVM_ABI ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
static LLVM_ABI Constant * get(StructType *T, ArrayRef< Constant * > V)
static LLVM_ABI ConstantTokenNone * get(LLVMContext &Context)
Return the ConstantTokenNone.
This is an important base class in LLVM.
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
static LLVM_ABI DIExpression * append(const DIExpression *Expr, ArrayRef< uint64_t > Ops)
Append the opcodes Ops to DIExpr.
A parsed version of the target data layout string in and methods for querying it.
static LLVM_ABI DbgLabelRecord * createUnresolvedDbgLabelRecord(MDNode *Label, MDNode *DL)
For use during parsing; creates a DbgLabelRecord from as-of-yet unresolved MDNodes.
Base class for non-instruction debug metadata records that have positions within IR.
static LLVM_ABI DbgVariableRecord * createUnresolvedDbgVariableRecord(LocationType Type, Metadata *Val, MDNode *Variable, MDNode *Expression, MDNode *AssignID, Metadata *Address, MDNode *AddressExpression, MDNode *DI)
Used to create DbgVariableRecords during parsing, where some metadata references may still be unresol...
Convenience struct for specifying and reasoning about fast-math flags.
void setApproxFunc(bool B=true)
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
Class to represent function types.
Type * getParamType(unsigned i) const
Parameter type accessors.
Type * getReturnType() const
static LLVM_ABI FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
FunctionType * getFunctionType() const
Returns the FunctionType for me.
Intrinsic::ID getIntrinsicID() const LLVM_READONLY
getIntrinsicID - This method returns the ID number of the specified function, or Intrinsic::not_intri...
const Function & getFunction() const
void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it.
Type * getReturnType() const
Returns the type of the ret val.
Argument * getArg(unsigned i) const
LinkageTypes getLinkage() const
Type * getValueType() const
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
bool hasInitializer() const
Definitions have initializers, declarations don't.
PointerType * getPtrTy(unsigned AddrSpace=0)
Fetch the type representing a pointer.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Base class for instruction visitors.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
LLVM_ABI void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
LLVM_ABI void copyMetadata(const Instruction &SrcInst, ArrayRef< unsigned > WL=ArrayRef< unsigned >())
Copy metadata from SrcInst to this instruction.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
This is an important class for using LLVM in a threaded context.
An instruction for reading from memory.
LLVM_ABI MDNode * createRange(const APInt &Lo, const APInt &Hi)
Return metadata describing the range [Lo, Hi).
const MDOperand & getOperand(unsigned I) const
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
unsigned getNumOperands() const
Return number of MDNode operands.
LLVMContext & getContext() const
Tracking metadata reference owned by Metadata.
static LLVM_ABI MDString * get(LLVMContext &Context, StringRef Str)
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
A Module instance is used to store all the information related to an LLVM module.
ModFlagBehavior
This enumeration defines the supported behaviors of module flags.
@ Override
Uses the specified value, regardless of the behavior or value of the other module.
@ Error
Emits an error if two values disagree, otherwise the resulting value is that of the operands.
@ Min
Takes the min of the two values, which are required to be integers.
@ Max
Takes the max of the two values, which are required to be integers.
LLVM_ABI void setOperand(unsigned I, MDNode *New)
LLVM_ABI MDNode * getOperand(unsigned i) const
LLVM_ABI unsigned getNumOperands() const
LLVM_ABI void clearOperands()
Drop all references to this node's operands.
iterator_range< op_iterator > operands()
LLVM_ABI void addOperand(MDNode *M)
ArrayRef< InputTy > inputs() const
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
LLVM_ABI bool match(StringRef String, SmallVectorImpl< StringRef > *Matches=nullptr, std::string *Error=nullptr) const
matches - Match the regex against a given String.
static LLVM_ABI ScalableVectorType * get(Type *ElementType, unsigned MinNumElts)
ArrayRef< int > getShuffleMask() const
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
StringRef - Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
static constexpr size_t npos
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
empty - Check if the string is empty.
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
constexpr size_t size() const
size - Get the string size.
StringRef trim(char Char) const
Return string with consecutive Char characters starting from the left and right removed.
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
StringSwitch & StartsWith(StringLiteral S, T Value)
StringSwitch & Cases(std::initializer_list< StringLiteral > CaseStrings, T Value)
Class to represent struct types.
static LLVM_ABI StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
unsigned getNumElements() const
Random access to the elements.
Type * getElementType(unsigned N) const
The TimeTraceScope is a helper class to call the begin and end functions of the time trace profiler.
Triple - Helper class for working with autoconf configuration names.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
bool isVectorTy() const
True if this is an instance of VectorType.
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
bool isBFloatTy() const
Return true if this is 'bfloat', a 16-bit bfloat type.
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isPtrOrPtrVectorTy() const
Return true if this is a pointer type or a vector of pointer types.
bool isIntegerTy() const
True if this is an instance of IntegerType.
bool isFPOrFPVectorTy() const
Return true if this is a FP type or a vector of FP.
static LLVM_ABI Type * getFloatTy(LLVMContext &C)
static LLVM_ABI Type * getBFloatTy(LLVMContext &C)
static LLVM_ABI Type * getHalfTy(LLVMContext &C)
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI void setName(const Twine &Name)
Change the name of the value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
iterator_range< user_iterator > users()
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
LLVM_ABI LLVMContext & getContext() const
All values hold a context through their type.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
Base class of all SIMD vector types.
static VectorType * getInteger(VectorType *VTy)
This static method gets a VectorType with the same number of elements as the input type,...
static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
constexpr ScalarTy getFixedValue() const
const ParentTy * getParent() const
self_iterator getIterator()
A raw_ostream that writes to an SmallVector or SmallString.
StringRef str() const
Return a StringRef for the vector contents.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ LOCAL_ADDRESS
Address space for local memory.
@ FLAT_ADDRESS
Address space for flat memory.
@ PRIVATE_ADDRESS
Address space for private memory.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ PTX_Kernel
Call to a PTX kernel. Passes all arguments in parameter space.
@ C
The default llvm calling convention, compatible with C.
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > Tys={})
Look up the Function declaration of the intrinsic id in the Module M.
LLVM_ABI void getIntrinsicInfoTableEntries(ID id, SmallVectorImpl< IITDescriptor > &T)
Return the IIT table descriptor for the specified intrinsic into an array of IITDescriptors.
LLVM_ABI std::optional< Function * > remangleIntrinsicFunction(Function *F)
LLVM_ABI AttributeList getAttributes(LLVMContext &C, ID id, FunctionType *FT)
Return the attributes for an intrinsic.
LLVM_ABI bool getIntrinsicSignature(Intrinsic::ID, FunctionType *FT, SmallVectorImpl< Type * > &ArgTys)
Gets the type arguments of an intrinsic call by matching type contraints specified by the ....
@ ADDRESS_SPACE_SHARED_CLUSTER
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > dyn_extract_or_null(Y &&MD)
Extract a Value from Metadata, if any, allowing null.
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > dyn_extract(Y &&MD)
Extract a Value from Metadata, if any.
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract(Y &&MD)
Extract a Value from Metadata.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI void UpgradeIntrinsicCall(CallBase *CB, Function *NewFn)
This is the complement to the above, replacing a specific call to an intrinsic function with a call t...
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.