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);
130 if (
F->getReturnType()->getScalarType()->isBFloatTy())
140 if (
F->getFunctionType()->getParamType(1)->getScalarType()->isBFloatTy())
154 if (Name.consume_front(
"avx."))
155 return (Name.starts_with(
"blend.p") ||
156 Name ==
"cvt.ps2.pd.256" ||
157 Name ==
"cvtdq2.pd.256" ||
158 Name ==
"cvtdq2.ps.256" ||
159 Name.starts_with(
"movnt.") ||
160 Name.starts_with(
"sqrt.p") ||
161 Name.starts_with(
"storeu.") ||
162 Name.starts_with(
"vbroadcast.s") ||
163 Name.starts_with(
"vbroadcastf128") ||
164 Name.starts_with(
"vextractf128.") ||
165 Name.starts_with(
"vinsertf128.") ||
166 Name.starts_with(
"vperm2f128.") ||
167 Name.starts_with(
"vpermil."));
169 if (Name.consume_front(
"avx2."))
170 return (Name ==
"movntdqa" ||
171 Name.starts_with(
"pabs.") ||
172 Name.starts_with(
"padds.") ||
173 Name.starts_with(
"paddus.") ||
174 Name.starts_with(
"pblendd.") ||
176 Name.starts_with(
"pbroadcast") ||
177 Name.starts_with(
"pcmpeq.") ||
178 Name.starts_with(
"pcmpgt.") ||
179 Name.starts_with(
"pmax") ||
180 Name.starts_with(
"pmin") ||
181 Name.starts_with(
"pmovsx") ||
182 Name.starts_with(
"pmovzx") ||
184 Name ==
"pmulu.dq" ||
185 Name.starts_with(
"psll.dq") ||
186 Name.starts_with(
"psrl.dq") ||
187 Name.starts_with(
"psubs.") ||
188 Name.starts_with(
"psubus.") ||
189 Name.starts_with(
"vbroadcast") ||
190 Name ==
"vbroadcasti128" ||
191 Name ==
"vextracti128" ||
192 Name ==
"vinserti128" ||
193 Name ==
"vperm2i128");
195 if (Name.consume_front(
"avx512.")) {
196 if (Name.consume_front(
"mask."))
198 return (Name.starts_with(
"add.p") ||
199 Name.starts_with(
"and.") ||
200 Name.starts_with(
"andn.") ||
201 Name.starts_with(
"broadcast.s") ||
202 Name.starts_with(
"broadcastf32x4.") ||
203 Name.starts_with(
"broadcastf32x8.") ||
204 Name.starts_with(
"broadcastf64x2.") ||
205 Name.starts_with(
"broadcastf64x4.") ||
206 Name.starts_with(
"broadcasti32x4.") ||
207 Name.starts_with(
"broadcasti32x8.") ||
208 Name.starts_with(
"broadcasti64x2.") ||
209 Name.starts_with(
"broadcasti64x4.") ||
210 Name.starts_with(
"cmp.b") ||
211 Name.starts_with(
"cmp.d") ||
212 Name.starts_with(
"cmp.q") ||
213 Name.starts_with(
"cmp.w") ||
214 Name.starts_with(
"compress.b") ||
215 Name.starts_with(
"compress.d") ||
216 Name.starts_with(
"compress.p") ||
217 Name.starts_with(
"compress.q") ||
218 Name.starts_with(
"compress.store.") ||
219 Name.starts_with(
"compress.w") ||
220 Name.starts_with(
"conflict.") ||
221 Name.starts_with(
"cvtdq2pd.") ||
222 Name.starts_with(
"cvtdq2ps.") ||
223 Name ==
"cvtpd2dq.256" ||
224 Name ==
"cvtpd2ps.256" ||
225 Name ==
"cvtps2pd.128" ||
226 Name ==
"cvtps2pd.256" ||
227 Name.starts_with(
"cvtqq2pd.") ||
228 Name ==
"cvtqq2ps.256" ||
229 Name ==
"cvtqq2ps.512" ||
230 Name ==
"cvttpd2dq.256" ||
231 Name ==
"cvttps2dq.128" ||
232 Name ==
"cvttps2dq.256" ||
233 Name.starts_with(
"cvtudq2pd.") ||
234 Name.starts_with(
"cvtudq2ps.") ||
235 Name.starts_with(
"cvtuqq2pd.") ||
236 Name ==
"cvtuqq2ps.256" ||
237 Name ==
"cvtuqq2ps.512" ||
238 Name.starts_with(
"dbpsadbw.") ||
239 Name.starts_with(
"div.p") ||
240 Name.starts_with(
"expand.b") ||
241 Name.starts_with(
"expand.d") ||
242 Name.starts_with(
"expand.load.") ||
243 Name.starts_with(
"expand.p") ||
244 Name.starts_with(
"expand.q") ||
245 Name.starts_with(
"expand.w") ||
246 Name.starts_with(
"fpclass.p") ||
247 Name.starts_with(
"insert") ||
248 Name.starts_with(
"load.") ||
249 Name.starts_with(
"loadu.") ||
250 Name.starts_with(
"lzcnt.") ||
251 Name.starts_with(
"max.p") ||
252 Name.starts_with(
"min.p") ||
253 Name.starts_with(
"movddup") ||
254 Name.starts_with(
"move.s") ||
255 Name.starts_with(
"movshdup") ||
256 Name.starts_with(
"movsldup") ||
257 Name.starts_with(
"mul.p") ||
258 Name.starts_with(
"or.") ||
259 Name.starts_with(
"pabs.") ||
260 Name.starts_with(
"packssdw.") ||
261 Name.starts_with(
"packsswb.") ||
262 Name.starts_with(
"packusdw.") ||
263 Name.starts_with(
"packuswb.") ||
264 Name.starts_with(
"padd.") ||
265 Name.starts_with(
"padds.") ||
266 Name.starts_with(
"paddus.") ||
267 Name.starts_with(
"palignr.") ||
268 Name.starts_with(
"pand.") ||
269 Name.starts_with(
"pandn.") ||
270 Name.starts_with(
"pavg") ||
271 Name.starts_with(
"pbroadcast") ||
272 Name.starts_with(
"pcmpeq.") ||
273 Name.starts_with(
"pcmpgt.") ||
274 Name.starts_with(
"perm.df.") ||
275 Name.starts_with(
"perm.di.") ||
276 Name.starts_with(
"permvar.") ||
277 Name.starts_with(
"pmaddubs.w.") ||
278 Name.starts_with(
"pmaddw.d.") ||
279 Name.starts_with(
"pmax") ||
280 Name.starts_with(
"pmin") ||
281 Name ==
"pmov.qd.256" ||
282 Name ==
"pmov.qd.512" ||
283 Name ==
"pmov.wb.256" ||
284 Name ==
"pmov.wb.512" ||
285 Name.starts_with(
"pmovsx") ||
286 Name.starts_with(
"pmovzx") ||
287 Name.starts_with(
"pmul.dq.") ||
288 Name.starts_with(
"pmul.hr.sw.") ||
289 Name.starts_with(
"pmulh.w.") ||
290 Name.starts_with(
"pmulhu.w.") ||
291 Name.starts_with(
"pmull.") ||
292 Name.starts_with(
"pmultishift.qb.") ||
293 Name.starts_with(
"pmulu.dq.") ||
294 Name.starts_with(
"por.") ||
295 Name.starts_with(
"prol.") ||
296 Name.starts_with(
"prolv.") ||
297 Name.starts_with(
"pror.") ||
298 Name.starts_with(
"prorv.") ||
299 Name.starts_with(
"pshuf.b.") ||
300 Name.starts_with(
"pshuf.d.") ||
301 Name.starts_with(
"pshufh.w.") ||
302 Name.starts_with(
"pshufl.w.") ||
303 Name.starts_with(
"psll.d") ||
304 Name.starts_with(
"psll.q") ||
305 Name.starts_with(
"psll.w") ||
306 Name.starts_with(
"pslli") ||
307 Name.starts_with(
"psllv") ||
308 Name.starts_with(
"psra.d") ||
309 Name.starts_with(
"psra.q") ||
310 Name.starts_with(
"psra.w") ||
311 Name.starts_with(
"psrai") ||
312 Name.starts_with(
"psrav") ||
313 Name.starts_with(
"psrl.d") ||
314 Name.starts_with(
"psrl.q") ||
315 Name.starts_with(
"psrl.w") ||
316 Name.starts_with(
"psrli") ||
317 Name.starts_with(
"psrlv") ||
318 Name.starts_with(
"psub.") ||
319 Name.starts_with(
"psubs.") ||
320 Name.starts_with(
"psubus.") ||
321 Name.starts_with(
"pternlog.") ||
322 Name.starts_with(
"punpckh") ||
323 Name.starts_with(
"punpckl") ||
324 Name.starts_with(
"pxor.") ||
325 Name.starts_with(
"shuf.f") ||
326 Name.starts_with(
"shuf.i") ||
327 Name.starts_with(
"shuf.p") ||
328 Name.starts_with(
"sqrt.p") ||
329 Name.starts_with(
"store.b.") ||
330 Name.starts_with(
"store.d.") ||
331 Name.starts_with(
"store.p") ||
332 Name.starts_with(
"store.q.") ||
333 Name.starts_with(
"store.w.") ||
334 Name ==
"store.ss" ||
335 Name.starts_with(
"storeu.") ||
336 Name.starts_with(
"sub.p") ||
337 Name.starts_with(
"ucmp.") ||
338 Name.starts_with(
"unpckh.") ||
339 Name.starts_with(
"unpckl.") ||
340 Name.starts_with(
"valign.") ||
341 Name ==
"vcvtph2ps.128" ||
342 Name ==
"vcvtph2ps.256" ||
343 Name.starts_with(
"vextract") ||
344 Name.starts_with(
"vfmadd.") ||
345 Name.starts_with(
"vfmaddsub.") ||
346 Name.starts_with(
"vfnmadd.") ||
347 Name.starts_with(
"vfnmsub.") ||
348 Name.starts_with(
"vpdpbusd.") ||
349 Name.starts_with(
"vpdpbusds.") ||
350 Name.starts_with(
"vpdpwssd.") ||
351 Name.starts_with(
"vpdpwssds.") ||
352 Name.starts_with(
"vpermi2var.") ||
353 Name.starts_with(
"vpermil.p") ||
354 Name.starts_with(
"vpermilvar.") ||
355 Name.starts_with(
"vpermt2var.") ||
356 Name.starts_with(
"vpmadd52") ||
357 Name.starts_with(
"vpshld.") ||
358 Name.starts_with(
"vpshldv.") ||
359 Name.starts_with(
"vpshrd.") ||
360 Name.starts_with(
"vpshrdv.") ||
361 Name.starts_with(
"vpshufbitqmb.") ||
362 Name.starts_with(
"xor."));
364 if (Name.consume_front(
"mask3."))
366 return (Name.starts_with(
"vfmadd.") ||
367 Name.starts_with(
"vfmaddsub.") ||
368 Name.starts_with(
"vfmsub.") ||
369 Name.starts_with(
"vfmsubadd.") ||
370 Name.starts_with(
"vfnmsub."));
372 if (Name.consume_front(
"maskz."))
374 return (Name.starts_with(
"pternlog.") ||
375 Name.starts_with(
"vfmadd.") ||
376 Name.starts_with(
"vfmaddsub.") ||
377 Name.starts_with(
"vpdpbusd.") ||
378 Name.starts_with(
"vpdpbusds.") ||
379 Name.starts_with(
"vpdpwssd.") ||
380 Name.starts_with(
"vpdpwssds.") ||
381 Name.starts_with(
"vpermt2var.") ||
382 Name.starts_with(
"vpmadd52") ||
383 Name.starts_with(
"vpshldv.") ||
384 Name.starts_with(
"vpshrdv."));
387 return (Name ==
"movntdqa" ||
388 Name ==
"pmul.dq.512" ||
389 Name ==
"pmulu.dq.512" ||
390 Name.starts_with(
"broadcastm") ||
391 Name.starts_with(
"cmp.p") ||
392 Name.starts_with(
"cvtb2mask.") ||
393 Name.starts_with(
"cvtd2mask.") ||
394 Name.starts_with(
"cvtmask2") ||
395 Name.starts_with(
"cvtq2mask.") ||
396 Name ==
"cvtusi2sd" ||
397 Name.starts_with(
"cvtw2mask.") ||
402 Name ==
"kortestc.w" ||
403 Name ==
"kortestz.w" ||
404 Name.starts_with(
"kunpck") ||
407 Name.starts_with(
"padds.") ||
408 Name.starts_with(
"pbroadcast") ||
409 Name.starts_with(
"prol") ||
410 Name.starts_with(
"pror") ||
411 Name.starts_with(
"psll.dq") ||
412 Name.starts_with(
"psrl.dq") ||
413 Name.starts_with(
"psubs.") ||
414 Name.starts_with(
"ptestm") ||
415 Name.starts_with(
"ptestnm") ||
416 Name.starts_with(
"storent.") ||
417 Name.starts_with(
"vbroadcast.s") ||
418 Name.starts_with(
"vpshld.") ||
419 Name.starts_with(
"vpshrd."));
422 if (Name.consume_front(
"fma."))
423 return (Name.starts_with(
"vfmadd.") ||
424 Name.starts_with(
"vfmsub.") ||
425 Name.starts_with(
"vfmsubadd.") ||
426 Name.starts_with(
"vfnmadd.") ||
427 Name.starts_with(
"vfnmsub."));
429 if (Name.consume_front(
"fma4."))
430 return Name.starts_with(
"vfmadd.s");
432 if (Name.consume_front(
"sse."))
433 return (Name ==
"add.ss" ||
434 Name ==
"cvtsi2ss" ||
435 Name ==
"cvtsi642ss" ||
438 Name.starts_with(
"sqrt.p") ||
440 Name.starts_with(
"storeu.") ||
443 if (Name.consume_front(
"sse2."))
444 return (Name ==
"add.sd" ||
445 Name ==
"cvtdq2pd" ||
446 Name ==
"cvtdq2ps" ||
447 Name ==
"cvtps2pd" ||
448 Name ==
"cvtsi2sd" ||
449 Name ==
"cvtsi642sd" ||
450 Name ==
"cvtss2sd" ||
453 Name.starts_with(
"padds.") ||
454 Name.starts_with(
"paddus.") ||
455 Name.starts_with(
"pcmpeq.") ||
456 Name.starts_with(
"pcmpgt.") ||
461 Name ==
"pmulu.dq" ||
462 Name.starts_with(
"pshuf") ||
463 Name.starts_with(
"psll.dq") ||
464 Name.starts_with(
"psrl.dq") ||
465 Name.starts_with(
"psubs.") ||
466 Name.starts_with(
"psubus.") ||
467 Name.starts_with(
"sqrt.p") ||
469 Name ==
"storel.dq" ||
470 Name.starts_with(
"storeu.") ||
473 if (Name.consume_front(
"sse41."))
474 return (Name.starts_with(
"blendp") ||
475 Name ==
"movntdqa" ||
485 Name.starts_with(
"pmovsx") ||
486 Name.starts_with(
"pmovzx") ||
489 if (Name.consume_front(
"sse42."))
490 return Name ==
"crc32.64.8";
492 if (Name.consume_front(
"sse4a."))
493 return Name.starts_with(
"movnt.");
495 if (Name.consume_front(
"ssse3."))
496 return (Name ==
"pabs.b.128" ||
497 Name ==
"pabs.d.128" ||
498 Name ==
"pabs.w.128");
500 if (Name.consume_front(
"xop."))
501 return (Name ==
"vpcmov" ||
502 Name ==
"vpcmov.256" ||
503 Name.starts_with(
"vpcom") ||
504 Name.starts_with(
"vprot"));
506 return (Name ==
"addcarry.u32" ||
507 Name ==
"addcarry.u64" ||
508 Name ==
"addcarryx.u32" ||
509 Name ==
"addcarryx.u64" ||
510 Name ==
"subborrow.u32" ||
511 Name ==
"subborrow.u64" ||
512 Name.starts_with(
"vcvtph2ps."));
518 if (!Name.consume_front(
"x86."))
526 if (Name ==
"rdtscp") {
528 if (
F->getFunctionType()->getNumParams() == 0)
533 Intrinsic::x86_rdtscp);
540 if (Name.consume_front(
"sse41.ptest")) {
542 .
Case(
"c", Intrinsic::x86_sse41_ptestc)
543 .
Case(
"z", Intrinsic::x86_sse41_ptestz)
544 .
Case(
"nzc", Intrinsic::x86_sse41_ptestnzc)
557 .
Case(
"sse41.insertps", Intrinsic::x86_sse41_insertps)
558 .
Case(
"sse41.dppd", Intrinsic::x86_sse41_dppd)
559 .
Case(
"sse41.dpps", Intrinsic::x86_sse41_dpps)
560 .
Case(
"sse41.mpsadbw", Intrinsic::x86_sse41_mpsadbw)
561 .
Case(
"avx.dp.ps.256", Intrinsic::x86_avx_dp_ps_256)
562 .
Case(
"avx2.mpsadbw", Intrinsic::x86_avx2_mpsadbw)
567 if (Name.consume_front(
"avx512.")) {
568 if (Name.consume_front(
"mask.cmp.")) {
571 .
Case(
"pd.128", Intrinsic::x86_avx512_mask_cmp_pd_128)
572 .
Case(
"pd.256", Intrinsic::x86_avx512_mask_cmp_pd_256)
573 .
Case(
"pd.512", Intrinsic::x86_avx512_mask_cmp_pd_512)
574 .
Case(
"ps.128", Intrinsic::x86_avx512_mask_cmp_ps_128)
575 .
Case(
"ps.256", Intrinsic::x86_avx512_mask_cmp_ps_256)
576 .
Case(
"ps.512", Intrinsic::x86_avx512_mask_cmp_ps_512)
580 }
else if (Name.starts_with(
"vpdpbusd.") ||
581 Name.starts_with(
"vpdpbusds.")) {
584 .
Case(
"vpdpbusd.128", Intrinsic::x86_avx512_vpdpbusd_128)
585 .
Case(
"vpdpbusd.256", Intrinsic::x86_avx512_vpdpbusd_256)
586 .
Case(
"vpdpbusd.512", Intrinsic::x86_avx512_vpdpbusd_512)
587 .
Case(
"vpdpbusds.128", Intrinsic::x86_avx512_vpdpbusds_128)
588 .
Case(
"vpdpbusds.256", Intrinsic::x86_avx512_vpdpbusds_256)
589 .
Case(
"vpdpbusds.512", Intrinsic::x86_avx512_vpdpbusds_512)
597 if (Name.consume_front(
"avx2.vpdpb")) {
600 .
Case(
"ssd.128", Intrinsic::x86_avx2_vpdpbssd_128)
601 .
Case(
"ssd.256", Intrinsic::x86_avx2_vpdpbssd_256)
602 .
Case(
"ssds.128", Intrinsic::x86_avx2_vpdpbssds_128)
603 .
Case(
"ssds.256", Intrinsic::x86_avx2_vpdpbssds_256)
604 .
Case(
"sud.128", Intrinsic::x86_avx2_vpdpbsud_128)
605 .
Case(
"sud.256", Intrinsic::x86_avx2_vpdpbsud_256)
606 .
Case(
"suds.128", Intrinsic::x86_avx2_vpdpbsuds_128)
607 .
Case(
"suds.256", Intrinsic::x86_avx2_vpdpbsuds_256)
608 .
Case(
"uud.128", Intrinsic::x86_avx2_vpdpbuud_128)
609 .
Case(
"uud.256", Intrinsic::x86_avx2_vpdpbuud_256)
610 .
Case(
"uuds.128", Intrinsic::x86_avx2_vpdpbuuds_128)
611 .
Case(
"uuds.256", Intrinsic::x86_avx2_vpdpbuuds_256)
618 if (Name.consume_front(
"avx10.vpdpb")) {
621 .
Case(
"ssd.512", Intrinsic::x86_avx10_vpdpbssd_512)
622 .
Case(
"ssds.512", Intrinsic::x86_avx10_vpdpbssds_512)
623 .
Case(
"sud.512", Intrinsic::x86_avx10_vpdpbsud_512)
624 .
Case(
"suds.512", Intrinsic::x86_avx10_vpdpbsuds_512)
625 .
Case(
"uud.512", Intrinsic::x86_avx10_vpdpbuud_512)
626 .
Case(
"uuds.512", Intrinsic::x86_avx10_vpdpbuuds_512)
633 if (Name.consume_front(
"avx512bf16.")) {
636 .
Case(
"cvtne2ps2bf16.128",
637 Intrinsic::x86_avx512bf16_cvtne2ps2bf16_128)
638 .
Case(
"cvtne2ps2bf16.256",
639 Intrinsic::x86_avx512bf16_cvtne2ps2bf16_256)
640 .
Case(
"cvtne2ps2bf16.512",
641 Intrinsic::x86_avx512bf16_cvtne2ps2bf16_512)
642 .
Case(
"mask.cvtneps2bf16.128",
643 Intrinsic::x86_avx512bf16_mask_cvtneps2bf16_128)
644 .
Case(
"cvtneps2bf16.256",
645 Intrinsic::x86_avx512bf16_cvtneps2bf16_256)
646 .
Case(
"cvtneps2bf16.512",
647 Intrinsic::x86_avx512bf16_cvtneps2bf16_512)
654 .
Case(
"dpbf16ps.128", Intrinsic::x86_avx512bf16_dpbf16ps_128)
655 .
Case(
"dpbf16ps.256", Intrinsic::x86_avx512bf16_dpbf16ps_256)
656 .
Case(
"dpbf16ps.512", Intrinsic::x86_avx512bf16_dpbf16ps_512)
663 if (Name.consume_front(
"xop.")) {
665 if (Name.starts_with(
"vpermil2")) {
668 auto Idx =
F->getFunctionType()->getParamType(2);
669 if (Idx->isFPOrFPVectorTy()) {
670 unsigned IdxSize = Idx->getPrimitiveSizeInBits();
671 unsigned EltSize = Idx->getScalarSizeInBits();
672 if (EltSize == 64 && IdxSize == 128)
673 ID = Intrinsic::x86_xop_vpermil2pd;
674 else if (EltSize == 32 && IdxSize == 128)
675 ID = Intrinsic::x86_xop_vpermil2ps;
676 else if (EltSize == 64 && IdxSize == 256)
677 ID = Intrinsic::x86_xop_vpermil2pd_256;
679 ID = Intrinsic::x86_xop_vpermil2ps_256;
681 }
else if (
F->arg_size() == 2)
684 .
Case(
"vfrcz.ss", Intrinsic::x86_xop_vfrcz_ss)
685 .
Case(
"vfrcz.sd", Intrinsic::x86_xop_vfrcz_sd)
696 if (Name ==
"seh.recoverfp") {
698 Intrinsic::eh_recoverfp);
710 if (Name.starts_with(
"rbit")) {
713 F->getParent(), Intrinsic::bitreverse,
F->arg_begin()->getType());
717 if (Name ==
"thread.pointer") {
720 F->getParent(), Intrinsic::thread_pointer,
F->getReturnType());
724 bool Neon = Name.consume_front(
"neon.");
729 if (Name.consume_front(
"bfdot.")) {
733 .
Cases({
"v2f32.v8i8",
"v4f32.v16i8"},
738 size_t OperandWidth =
F->getReturnType()->getPrimitiveSizeInBits();
739 assert((OperandWidth == 64 || OperandWidth == 128) &&
740 "Unexpected operand width");
742 std::array<Type *, 2> Tys{
753 if (Name.consume_front(
"bfm")) {
755 if (Name.consume_back(
".v4f32.v16i8")) {
801 F->arg_begin()->getType());
805 if (Name.consume_front(
"vst")) {
807 static const Regex vstRegex(
"^([1234]|[234]lane)\\.v[a-z0-9]*$");
811 Intrinsic::arm_neon_vst1, Intrinsic::arm_neon_vst2,
812 Intrinsic::arm_neon_vst3, Intrinsic::arm_neon_vst4};
815 Intrinsic::arm_neon_vst2lane, Intrinsic::arm_neon_vst3lane,
816 Intrinsic::arm_neon_vst4lane};
818 auto fArgs =
F->getFunctionType()->params();
819 Type *Tys[] = {fArgs[0], fArgs[1]};
822 F->getParent(), StoreInts[fArgs.size() - 3], Tys);
825 F->getParent(), StoreLaneInts[fArgs.size() - 5], Tys);
834 if (Name.consume_front(
"mve.")) {
836 if (Name ==
"vctp64") {
846 if (Name.starts_with(
"vrintn.v")) {
848 F->getParent(), Intrinsic::roundeven,
F->arg_begin()->getType());
853 if (Name.consume_back(
".v4i1")) {
855 if (Name.consume_back(
".predicated.v2i64.v4i32"))
857 return Name ==
"mull.int" || Name ==
"vqdmull";
859 if (Name.consume_back(
".v2i64")) {
861 bool IsGather = Name.consume_front(
"vldr.gather.");
862 if (IsGather || Name.consume_front(
"vstr.scatter.")) {
863 if (Name.consume_front(
"base.")) {
865 Name.consume_front(
"wb.");
868 return Name ==
"predicated.v2i64";
871 if (Name.consume_front(
"offset.predicated."))
872 return Name == (IsGather ?
"v2i64.p0i64" :
"p0i64.v2i64") ||
873 Name == (IsGather ?
"v2i64.p0" :
"p0.v2i64");
886 if (Name.consume_front(
"cde.vcx")) {
888 if (Name.consume_back(
".predicated.v2i64.v4i1"))
890 return Name ==
"1q" || Name ==
"1qa" || Name ==
"2q" || Name ==
"2qa" ||
891 Name ==
"3q" || Name ==
"3qa";
905 F->arg_begin()->getType());
909 if (Name.starts_with(
"addp")) {
911 if (
F->arg_size() != 2)
914 if (Ty && Ty->getElementType()->isFloatingPointTy()) {
916 F->getParent(), Intrinsic::aarch64_neon_faddp, Ty);
922 if (Name.starts_with(
"bfcvt")) {
929 if (Name.consume_front(
"sve.")) {
931 if (Name.consume_front(
"bf")) {
932 if (Name.consume_back(
".lane")) {
936 .
Case(
"dot", Intrinsic::aarch64_sve_bfdot_lane_v2)
937 .
Case(
"mlalb", Intrinsic::aarch64_sve_bfmlalb_lane_v2)
938 .
Case(
"mlalt", Intrinsic::aarch64_sve_bfmlalt_lane_v2)
950 if (Name ==
"fcvt.bf16f32" || Name ==
"fcvtnt.bf16f32") {
955 if (Name.consume_front(
"addqv")) {
957 if (!
F->getReturnType()->isFPOrFPVectorTy())
960 auto Args =
F->getFunctionType()->params();
961 Type *Tys[] = {
F->getReturnType(), Args[1]};
963 F->getParent(), Intrinsic::aarch64_sve_faddqv, Tys);
967 if (Name.consume_front(
"ld")) {
969 static const Regex LdRegex(
"^[234](.nxv[a-z0-9]+|$)");
970 if (LdRegex.
match(Name)) {
977 Intrinsic::aarch64_sve_ld2_sret,
978 Intrinsic::aarch64_sve_ld3_sret,
979 Intrinsic::aarch64_sve_ld4_sret,
982 LoadIDs[Name[0] -
'2'], Ty);
988 if (Name.consume_front(
"tuple.")) {
990 if (Name.starts_with(
"get")) {
992 Type *Tys[] = {
F->getReturnType(),
F->arg_begin()->getType()};
994 F->getParent(), Intrinsic::vector_extract, Tys);
998 if (Name.starts_with(
"set")) {
1000 auto Args =
F->getFunctionType()->params();
1001 Type *Tys[] = {Args[0], Args[2], Args[1]};
1003 F->getParent(), Intrinsic::vector_insert, Tys);
1007 static const Regex CreateTupleRegex(
"^create[234](.nxv[a-z0-9]+|$)");
1008 if (CreateTupleRegex.
match(Name)) {
1010 auto Args =
F->getFunctionType()->params();
1011 Type *Tys[] = {
F->getReturnType(), Args[1]};
1013 F->getParent(), Intrinsic::vector_insert, Tys);
1026 if (Name.consume_front(
"cp.async.bulk.tensor.g2s.")) {
1030 Intrinsic::nvvm_cp_async_bulk_tensor_g2s_im2col_3d)
1032 Intrinsic::nvvm_cp_async_bulk_tensor_g2s_im2col_4d)
1034 Intrinsic::nvvm_cp_async_bulk_tensor_g2s_im2col_5d)
1035 .
Case(
"tile.1d", Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_1d)
1036 .
Case(
"tile.2d", Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_2d)
1037 .
Case(
"tile.3d", Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_3d)
1038 .
Case(
"tile.4d", Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_4d)
1039 .
Case(
"tile.5d", Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_5d)
1048 if (
F->getArg(0)->getType()->getPointerAddressSpace() ==
1062 size_t FlagStartIndex =
F->getFunctionType()->getNumParams() - 3;
1063 Type *ArgType =
F->getFunctionType()->getParamType(FlagStartIndex);
1073 if (Name.consume_front(
"mapa.shared.cluster"))
1074 if (
F->getReturnType()->getPointerAddressSpace() ==
1076 return Intrinsic::nvvm_mapa_shared_cluster;
1078 if (Name.consume_front(
"cp.async.bulk.")) {
1081 .
Case(
"global.to.shared.cluster",
1082 Intrinsic::nvvm_cp_async_bulk_global_to_shared_cluster)
1083 .
Case(
"shared.cta.to.cluster",
1084 Intrinsic::nvvm_cp_async_bulk_shared_cta_to_cluster)
1088 if (
F->getArg(0)->getType()->getPointerAddressSpace() ==
1097 if (Name.consume_front(
"fma.rn."))
1099 .
Case(
"bf16", Intrinsic::nvvm_fma_rn_bf16)
1100 .
Case(
"bf16x2", Intrinsic::nvvm_fma_rn_bf16x2)
1101 .
Case(
"ftz.bf16", Intrinsic::nvvm_fma_rn_ftz_bf16)
1102 .
Case(
"ftz.bf16x2", Intrinsic::nvvm_fma_rn_ftz_bf16x2)
1103 .
Case(
"ftz.relu.bf16", Intrinsic::nvvm_fma_rn_ftz_relu_bf16)
1104 .
Case(
"ftz.relu.bf16x2", Intrinsic::nvvm_fma_rn_ftz_relu_bf16x2)
1105 .
Case(
"ftz.sat.bf16", Intrinsic::nvvm_fma_rn_ftz_sat_bf16)
1106 .
Case(
"ftz.sat.bf16x2", Intrinsic::nvvm_fma_rn_ftz_sat_bf16x2)
1107 .
Case(
"relu.bf16", Intrinsic::nvvm_fma_rn_relu_bf16)
1108 .
Case(
"relu.bf16x2", Intrinsic::nvvm_fma_rn_relu_bf16x2)
1109 .
Case(
"sat.bf16", Intrinsic::nvvm_fma_rn_sat_bf16)
1110 .
Case(
"sat.bf16x2", Intrinsic::nvvm_fma_rn_sat_bf16x2)
1113 if (Name.consume_front(
"fmax."))
1115 .
Case(
"bf16", Intrinsic::nvvm_fmax_bf16)
1116 .
Case(
"bf16x2", Intrinsic::nvvm_fmax_bf16x2)
1117 .
Case(
"ftz.bf16", Intrinsic::nvvm_fmax_ftz_bf16)
1118 .
Case(
"ftz.bf16x2", Intrinsic::nvvm_fmax_ftz_bf16x2)
1119 .
Case(
"ftz.nan.bf16", Intrinsic::nvvm_fmax_ftz_nan_bf16)
1120 .
Case(
"ftz.nan.bf16x2", Intrinsic::nvvm_fmax_ftz_nan_bf16x2)
1121 .
Case(
"ftz.nan.xorsign.abs.bf16",
1122 Intrinsic::nvvm_fmax_ftz_nan_xorsign_abs_bf16)
1123 .
Case(
"ftz.nan.xorsign.abs.bf16x2",
1124 Intrinsic::nvvm_fmax_ftz_nan_xorsign_abs_bf16x2)
1125 .
Case(
"ftz.xorsign.abs.bf16", Intrinsic::nvvm_fmax_ftz_xorsign_abs_bf16)
1126 .
Case(
"ftz.xorsign.abs.bf16x2",
1127 Intrinsic::nvvm_fmax_ftz_xorsign_abs_bf16x2)
1128 .
Case(
"nan.bf16", Intrinsic::nvvm_fmax_nan_bf16)
1129 .
Case(
"nan.bf16x2", Intrinsic::nvvm_fmax_nan_bf16x2)
1130 .
Case(
"nan.xorsign.abs.bf16", Intrinsic::nvvm_fmax_nan_xorsign_abs_bf16)
1131 .
Case(
"nan.xorsign.abs.bf16x2",
1132 Intrinsic::nvvm_fmax_nan_xorsign_abs_bf16x2)
1133 .
Case(
"xorsign.abs.bf16", Intrinsic::nvvm_fmax_xorsign_abs_bf16)
1134 .
Case(
"xorsign.abs.bf16x2", Intrinsic::nvvm_fmax_xorsign_abs_bf16x2)
1137 if (Name.consume_front(
"fmin."))
1139 .
Case(
"bf16", Intrinsic::nvvm_fmin_bf16)
1140 .
Case(
"bf16x2", Intrinsic::nvvm_fmin_bf16x2)
1141 .
Case(
"ftz.bf16", Intrinsic::nvvm_fmin_ftz_bf16)
1142 .
Case(
"ftz.bf16x2", Intrinsic::nvvm_fmin_ftz_bf16x2)
1143 .
Case(
"ftz.nan.bf16", Intrinsic::nvvm_fmin_ftz_nan_bf16)
1144 .
Case(
"ftz.nan.bf16x2", Intrinsic::nvvm_fmin_ftz_nan_bf16x2)
1145 .
Case(
"ftz.nan.xorsign.abs.bf16",
1146 Intrinsic::nvvm_fmin_ftz_nan_xorsign_abs_bf16)
1147 .
Case(
"ftz.nan.xorsign.abs.bf16x2",
1148 Intrinsic::nvvm_fmin_ftz_nan_xorsign_abs_bf16x2)
1149 .
Case(
"ftz.xorsign.abs.bf16", Intrinsic::nvvm_fmin_ftz_xorsign_abs_bf16)
1150 .
Case(
"ftz.xorsign.abs.bf16x2",
1151 Intrinsic::nvvm_fmin_ftz_xorsign_abs_bf16x2)
1152 .
Case(
"nan.bf16", Intrinsic::nvvm_fmin_nan_bf16)
1153 .
Case(
"nan.bf16x2", Intrinsic::nvvm_fmin_nan_bf16x2)
1154 .
Case(
"nan.xorsign.abs.bf16", Intrinsic::nvvm_fmin_nan_xorsign_abs_bf16)
1155 .
Case(
"nan.xorsign.abs.bf16x2",
1156 Intrinsic::nvvm_fmin_nan_xorsign_abs_bf16x2)
1157 .
Case(
"xorsign.abs.bf16", Intrinsic::nvvm_fmin_xorsign_abs_bf16)
1158 .
Case(
"xorsign.abs.bf16x2", Intrinsic::nvvm_fmin_xorsign_abs_bf16x2)
1161 if (Name.consume_front(
"neg."))
1163 .
Case(
"bf16", Intrinsic::nvvm_neg_bf16)
1164 .
Case(
"bf16x2", Intrinsic::nvvm_neg_bf16x2)
1171 return Name.consume_front(
"local") || Name.consume_front(
"shared") ||
1172 Name.consume_front(
"global") || Name.consume_front(
"constant") ||
1173 Name.consume_front(
"param");
1177 bool CanUpgradeDebugIntrinsicsToRecords) {
1178 assert(
F &&
"Illegal to upgrade a non-existent Function.");
1183 if (!Name.consume_front(
"llvm.") || Name.empty())
1189 bool IsArm = Name.consume_front(
"arm.");
1190 if (IsArm || Name.consume_front(
"aarch64.")) {
1196 if (Name.consume_front(
"amdgcn.")) {
1197 if (Name ==
"alignbit") {
1200 F->getParent(), Intrinsic::fshr, {F->getReturnType()});
1204 if (Name.consume_front(
"atomic.")) {
1205 if (Name.starts_with(
"inc") || Name.starts_with(
"dec")) {
1214 if (Name.consume_front(
"ds.") || Name.consume_front(
"global.atomic.") ||
1215 Name.consume_front(
"flat.atomic.")) {
1216 if (Name.starts_with(
"fadd") ||
1218 (Name.starts_with(
"fmin") && !Name.starts_with(
"fmin.num")) ||
1219 (Name.starts_with(
"fmax") && !Name.starts_with(
"fmax.num"))) {
1227 if (Name.starts_with(
"ldexp.")) {
1230 F->getParent(), Intrinsic::ldexp,
1231 {F->getReturnType(), F->getArg(1)->getType()});
1240 if (
F->arg_size() == 1) {
1248 F->arg_begin()->getType());
1253 if (
F->arg_size() == 2 && Name ==
"coro.end") {
1256 Intrinsic::coro_end);
1263 if (Name.consume_front(
"dbg.")) {
1265 if (CanUpgradeDebugIntrinsicsToRecords) {
1266 if (Name ==
"addr" || Name ==
"value" || Name ==
"assign" ||
1267 Name ==
"declare" || Name ==
"label") {
1276 if (Name ==
"addr" || (Name ==
"value" &&
F->arg_size() == 4)) {
1279 Intrinsic::dbg_value);
1286 if (Name.consume_front(
"experimental.vector.")) {
1292 .
StartsWith(
"extract.", Intrinsic::vector_extract)
1293 .
StartsWith(
"insert.", Intrinsic::vector_insert)
1294 .
StartsWith(
"splice.", Intrinsic::vector_splice)
1295 .
StartsWith(
"reverse.", Intrinsic::vector_reverse)
1296 .
StartsWith(
"interleave2.", Intrinsic::vector_interleave2)
1297 .
StartsWith(
"deinterleave2.", Intrinsic::vector_deinterleave2)
1299 Intrinsic::vector_partial_reduce_add)
1302 const auto *FT =
F->getFunctionType();
1304 if (
ID == Intrinsic::vector_extract ||
1305 ID == Intrinsic::vector_interleave2)
1308 if (
ID != Intrinsic::vector_interleave2)
1310 if (
ID == Intrinsic::vector_insert ||
1311 ID == Intrinsic::vector_partial_reduce_add)
1319 if (Name.consume_front(
"reduce.")) {
1321 static const Regex R(
"^([a-z]+)\\.[a-z][0-9]+");
1322 if (R.match(Name, &
Groups))
1324 .
Case(
"add", Intrinsic::vector_reduce_add)
1325 .
Case(
"mul", Intrinsic::vector_reduce_mul)
1326 .
Case(
"and", Intrinsic::vector_reduce_and)
1327 .
Case(
"or", Intrinsic::vector_reduce_or)
1328 .
Case(
"xor", Intrinsic::vector_reduce_xor)
1329 .
Case(
"smax", Intrinsic::vector_reduce_smax)
1330 .
Case(
"smin", Intrinsic::vector_reduce_smin)
1331 .
Case(
"umax", Intrinsic::vector_reduce_umax)
1332 .
Case(
"umin", Intrinsic::vector_reduce_umin)
1333 .
Case(
"fmax", Intrinsic::vector_reduce_fmax)
1334 .
Case(
"fmin", Intrinsic::vector_reduce_fmin)
1339 static const Regex R2(
"^v2\\.([a-z]+)\\.[fi][0-9]+");
1344 .
Case(
"fadd", Intrinsic::vector_reduce_fadd)
1345 .
Case(
"fmul", Intrinsic::vector_reduce_fmul)
1350 auto Args =
F->getFunctionType()->params();
1352 {Args[V2 ? 1 : 0]});
1359 if (Name.consume_front(
"experimental.stepvector.")) {
1363 F->getParent(),
ID,
F->getFunctionType()->getReturnType());
1368 if (Name.starts_with(
"flt.rounds")) {
1371 Intrinsic::get_rounding);
1376 if (Name.starts_with(
"invariant.group.barrier")) {
1378 auto Args =
F->getFunctionType()->params();
1379 Type* ObjectPtr[1] = {Args[0]};
1382 F->getParent(), Intrinsic::launder_invariant_group, ObjectPtr);
1387 if ((Name.starts_with(
"lifetime.start") ||
1388 Name.starts_with(
"lifetime.end")) &&
1389 F->arg_size() == 2) {
1391 ? Intrinsic::lifetime_start
1392 : Intrinsic::lifetime_end;
1395 F->getArg(0)->getType());
1404 .StartsWith(
"memcpy.", Intrinsic::memcpy)
1405 .StartsWith(
"memmove.", Intrinsic::memmove)
1407 if (
F->arg_size() == 5) {
1411 F->getFunctionType()->params().slice(0, 3);
1417 if (Name.starts_with(
"memset.") &&
F->arg_size() == 5) {
1420 const auto *FT =
F->getFunctionType();
1421 Type *ParamTypes[2] = {
1422 FT->getParamType(0),
1426 Intrinsic::memset, ParamTypes);
1432 .
StartsWith(
"masked.load", Intrinsic::masked_load)
1433 .
StartsWith(
"masked.gather", Intrinsic::masked_gather)
1434 .
StartsWith(
"masked.store", Intrinsic::masked_store)
1435 .
StartsWith(
"masked.scatter", Intrinsic::masked_scatter)
1437 if (MaskedID &&
F->arg_size() == 4) {
1439 if (MaskedID == Intrinsic::masked_load ||
1440 MaskedID == Intrinsic::masked_gather) {
1442 F->getParent(), MaskedID,
1443 {F->getReturnType(), F->getArg(0)->getType()});
1447 F->getParent(), MaskedID,
1448 {F->getArg(0)->getType(), F->getArg(1)->getType()});
1454 if (Name.consume_front(
"nvvm.")) {
1456 if (
F->arg_size() == 1) {
1459 .
Cases({
"brev32",
"brev64"}, Intrinsic::bitreverse)
1460 .Case(
"clz.i", Intrinsic::ctlz)
1461 .
Case(
"popc.i", Intrinsic::ctpop)
1465 {F->getReturnType()});
1471 if (!
F->getReturnType()->getScalarType()->isBFloatTy()) {
1499 bool Expand =
false;
1500 if (Name.consume_front(
"abs."))
1503 Name ==
"i" || Name ==
"ll" || Name ==
"bf16" || Name ==
"bf16x2";
1504 else if (Name.consume_front(
"fabs."))
1506 Expand = Name ==
"f" || Name ==
"ftz.f" || Name ==
"d";
1507 else if (Name.consume_front(
"ex2.approx."))
1510 Name ==
"f" || Name ==
"ftz.f" || Name ==
"d" || Name ==
"f16x2";
1511 else if (Name.consume_front(
"max.") || Name.consume_front(
"min."))
1513 Expand = Name ==
"s" || Name ==
"i" || Name ==
"ll" || Name ==
"us" ||
1514 Name ==
"ui" || Name ==
"ull";
1515 else if (Name.consume_front(
"atomic.load."))
1524 else if (Name.consume_front(
"bitcast."))
1527 Name ==
"f2i" || Name ==
"i2f" || Name ==
"ll2d" || Name ==
"d2ll";
1528 else if (Name.consume_front(
"rotate."))
1530 Expand = Name ==
"b32" || Name ==
"b64" || Name ==
"right.b64";
1531 else if (Name.consume_front(
"ptr.gen.to."))
1534 else if (Name.consume_front(
"ptr."))
1537 else if (Name.consume_front(
"ldg.global."))
1539 Expand = (Name.starts_with(
"i.") || Name.starts_with(
"f.") ||
1540 Name.starts_with(
"p."));
1543 .
Case(
"barrier0",
true)
1544 .
Case(
"barrier.n",
true)
1545 .
Case(
"barrier.sync.cnt",
true)
1546 .
Case(
"barrier.sync",
true)
1547 .
Case(
"barrier",
true)
1548 .
Case(
"bar.sync",
true)
1549 .
Case(
"clz.ll",
true)
1550 .
Case(
"popc.ll",
true)
1552 .
Case(
"swap.lo.hi.b64",
true)
1553 .
Case(
"tanh.approx.f32",
true)
1565 if (Name.starts_with(
"objectsize.")) {
1566 Type *Tys[2] = {
F->getReturnType(),
F->arg_begin()->getType() };
1567 if (
F->arg_size() == 2 ||
F->arg_size() == 3) {
1570 Intrinsic::objectsize, Tys);
1577 if (Name.starts_with(
"ptr.annotation.") &&
F->arg_size() == 4) {
1580 F->getParent(), Intrinsic::ptr_annotation,
1581 {F->arg_begin()->getType(), F->getArg(1)->getType()});
1587 if (Name.consume_front(
"riscv.")) {
1590 .
Case(
"aes32dsi", Intrinsic::riscv_aes32dsi)
1591 .
Case(
"aes32dsmi", Intrinsic::riscv_aes32dsmi)
1592 .
Case(
"aes32esi", Intrinsic::riscv_aes32esi)
1593 .
Case(
"aes32esmi", Intrinsic::riscv_aes32esmi)
1596 if (!
F->getFunctionType()->getParamType(2)->isIntegerTy(32)) {
1609 if (!
F->getFunctionType()->getParamType(2)->isIntegerTy(32) ||
1610 F->getFunctionType()->getReturnType()->isIntegerTy(64)) {
1619 .
StartsWith(
"sha256sig0", Intrinsic::riscv_sha256sig0)
1620 .
StartsWith(
"sha256sig1", Intrinsic::riscv_sha256sig1)
1621 .
StartsWith(
"sha256sum0", Intrinsic::riscv_sha256sum0)
1622 .
StartsWith(
"sha256sum1", Intrinsic::riscv_sha256sum1)
1627 if (
F->getFunctionType()->getReturnType()->isIntegerTy(64)) {
1639 if (Name ==
"stackprotectorcheck") {
1646 if (Name ==
"thread.pointer") {
1648 F->getParent(), Intrinsic::thread_pointer,
F->getReturnType());
1654 if (Name ==
"var.annotation" &&
F->arg_size() == 4) {
1657 F->getParent(), Intrinsic::var_annotation,
1658 {{F->arg_begin()->getType(), F->getArg(1)->getType()}});
1665 if (Name.consume_front(
"wasm.")) {
1668 .
StartsWith(
"fma.", Intrinsic::wasm_relaxed_madd)
1669 .
StartsWith(
"fms.", Intrinsic::wasm_relaxed_nmadd)
1670 .
StartsWith(
"laneselect.", Intrinsic::wasm_relaxed_laneselect)
1675 F->getReturnType());
1679 if (Name.consume_front(
"dot.i8x16.i7x16.")) {
1681 .
Case(
"signed", Intrinsic::wasm_relaxed_dot_i8x16_i7x16_signed)
1683 Intrinsic::wasm_relaxed_dot_i8x16_i7x16_add_signed)
1702 if (ST && (!
ST->isLiteral() ||
ST->isPacked()) &&
1711 auto *FT =
F->getFunctionType();
1714 std::string
Name =
F->getName().str();
1717 Name,
F->getParent());
1728 if (Result != std::nullopt) {
1741 bool CanUpgradeDebugIntrinsicsToRecords) {
1761 GV->
getName() ==
"llvm.global_dtors")) ||
1776 unsigned N =
Init->getNumOperands();
1777 std::vector<Constant *> NewCtors(
N);
1778 for (
unsigned i = 0; i !=
N; ++i) {
1781 Ctor->getAggregateElement(1),
1795 unsigned NumElts = ResultTy->getNumElements() * 8;
1799 Op = Builder.CreateBitCast(
Op, VecTy,
"cast");
1809 for (
unsigned l = 0; l != NumElts; l += 16)
1810 for (
unsigned i = 0; i != 16; ++i) {
1811 unsigned Idx = NumElts + i - Shift;
1813 Idx -= NumElts - 16;
1814 Idxs[l + i] = Idx + l;
1817 Res = Builder.CreateShuffleVector(Res,
Op,
ArrayRef(Idxs, NumElts));
1821 return Builder.CreateBitCast(Res, ResultTy,
"cast");
1829 unsigned NumElts = ResultTy->getNumElements() * 8;
1833 Op = Builder.CreateBitCast(
Op, VecTy,
"cast");
1843 for (
unsigned l = 0; l != NumElts; l += 16)
1844 for (
unsigned i = 0; i != 16; ++i) {
1845 unsigned Idx = i + Shift;
1847 Idx += NumElts - 16;
1848 Idxs[l + i] = Idx + l;
1851 Res = Builder.CreateShuffleVector(
Op, Res,
ArrayRef(Idxs, NumElts));
1855 return Builder.CreateBitCast(Res, ResultTy,
"cast");
1863 Mask = Builder.CreateBitCast(Mask, MaskTy);
1869 for (
unsigned i = 0; i != NumElts; ++i)
1871 Mask = Builder.CreateShuffleVector(Mask, Mask,
ArrayRef(Indices, NumElts),
1882 if (
C->isAllOnesValue())
1887 return Builder.CreateSelect(Mask, Op0, Op1);
1894 if (
C->isAllOnesValue())
1898 Mask->getType()->getIntegerBitWidth());
1899 Mask = Builder.CreateBitCast(Mask, MaskTy);
1900 Mask = Builder.CreateExtractElement(Mask, (
uint64_t)0);
1901 return Builder.CreateSelect(Mask, Op0, Op1);
1914 assert((IsVALIGN || NumElts % 16 == 0) &&
"Illegal NumElts for PALIGNR!");
1915 assert((!IsVALIGN || NumElts <= 16) &&
"NumElts too large for VALIGN!");
1920 ShiftVal &= (NumElts - 1);
1929 if (ShiftVal > 16) {
1937 for (
unsigned l = 0; l < NumElts; l += 16) {
1938 for (
unsigned i = 0; i != 16; ++i) {
1939 unsigned Idx = ShiftVal + i;
1940 if (!IsVALIGN && Idx >= 16)
1941 Idx += NumElts - 16;
1942 Indices[l + i] = Idx + l;
1947 Op1, Op0,
ArrayRef(Indices, NumElts),
"palignr");
1953 bool ZeroMask,
bool IndexForm) {
1956 unsigned EltWidth = Ty->getScalarSizeInBits();
1957 bool IsFloat = Ty->isFPOrFPVectorTy();
1959 if (VecWidth == 128 && EltWidth == 32 && IsFloat)
1960 IID = Intrinsic::x86_avx512_vpermi2var_ps_128;
1961 else if (VecWidth == 128 && EltWidth == 32 && !IsFloat)
1962 IID = Intrinsic::x86_avx512_vpermi2var_d_128;
1963 else if (VecWidth == 128 && EltWidth == 64 && IsFloat)
1964 IID = Intrinsic::x86_avx512_vpermi2var_pd_128;
1965 else if (VecWidth == 128 && EltWidth == 64 && !IsFloat)
1966 IID = Intrinsic::x86_avx512_vpermi2var_q_128;
1967 else if (VecWidth == 256 && EltWidth == 32 && IsFloat)
1968 IID = Intrinsic::x86_avx512_vpermi2var_ps_256;
1969 else if (VecWidth == 256 && EltWidth == 32 && !IsFloat)
1970 IID = Intrinsic::x86_avx512_vpermi2var_d_256;
1971 else if (VecWidth == 256 && EltWidth == 64 && IsFloat)
1972 IID = Intrinsic::x86_avx512_vpermi2var_pd_256;
1973 else if (VecWidth == 256 && EltWidth == 64 && !IsFloat)
1974 IID = Intrinsic::x86_avx512_vpermi2var_q_256;
1975 else if (VecWidth == 512 && EltWidth == 32 && IsFloat)
1976 IID = Intrinsic::x86_avx512_vpermi2var_ps_512;
1977 else if (VecWidth == 512 && EltWidth == 32 && !IsFloat)
1978 IID = Intrinsic::x86_avx512_vpermi2var_d_512;
1979 else if (VecWidth == 512 && EltWidth == 64 && IsFloat)
1980 IID = Intrinsic::x86_avx512_vpermi2var_pd_512;
1981 else if (VecWidth == 512 && EltWidth == 64 && !IsFloat)
1982 IID = Intrinsic::x86_avx512_vpermi2var_q_512;
1983 else if (VecWidth == 128 && EltWidth == 16)
1984 IID = Intrinsic::x86_avx512_vpermi2var_hi_128;
1985 else if (VecWidth == 256 && EltWidth == 16)
1986 IID = Intrinsic::x86_avx512_vpermi2var_hi_256;
1987 else if (VecWidth == 512 && EltWidth == 16)
1988 IID = Intrinsic::x86_avx512_vpermi2var_hi_512;
1989 else if (VecWidth == 128 && EltWidth == 8)
1990 IID = Intrinsic::x86_avx512_vpermi2var_qi_128;
1991 else if (VecWidth == 256 && EltWidth == 8)
1992 IID = Intrinsic::x86_avx512_vpermi2var_qi_256;
1993 else if (VecWidth == 512 && EltWidth == 8)
1994 IID = Intrinsic::x86_avx512_vpermi2var_qi_512;
2005 Value *V = Builder.CreateIntrinsic(IID, Args);
2017 Value *Res = Builder.CreateIntrinsic(IID, Ty, {Op0, Op1});
2028 bool IsRotateRight) {
2038 Amt = Builder.CreateIntCast(Amt, Ty->getScalarType(),
false);
2039 Amt = Builder.CreateVectorSplat(NumElts, Amt);
2042 Intrinsic::ID IID = IsRotateRight ? Intrinsic::fshr : Intrinsic::fshl;
2043 Value *Res = Builder.CreateIntrinsic(IID, Ty, {Src, Src, Amt});
2088 Value *Ext = Builder.CreateSExt(Cmp, Ty);
2093 bool IsShiftRight,
bool ZeroMask) {
2107 Amt = Builder.CreateIntCast(Amt, Ty->getScalarType(),
false);
2108 Amt = Builder.CreateVectorSplat(NumElts, Amt);
2111 Intrinsic::ID IID = IsShiftRight ? Intrinsic::fshr : Intrinsic::fshl;
2112 Value *Res = Builder.CreateIntrinsic(IID, Ty, {Op0, Op1, Amt});
2127 const Align Alignment =
2129 ?
Align(
Data->getType()->getPrimitiveSizeInBits().getFixedValue() / 8)
2134 if (
C->isAllOnesValue())
2135 return Builder.CreateAlignedStore(
Data,
Ptr, Alignment);
2140 return Builder.CreateMaskedStore(
Data,
Ptr, Alignment, Mask);
2146 const Align Alignment =
2155 if (
C->isAllOnesValue())
2156 return Builder.CreateAlignedLoad(ValTy,
Ptr, Alignment);
2161 return Builder.CreateMaskedLoad(ValTy,
Ptr, Alignment, Mask, Passthru);
2167 Value *Res = Builder.CreateIntrinsic(Intrinsic::abs, Ty,
2168 {Op0, Builder.getInt1(
false)});
2183 Constant *ShiftAmt = ConstantInt::get(Ty, 32);
2184 LHS = Builder.CreateShl(
LHS, ShiftAmt);
2185 LHS = Builder.CreateAShr(
LHS, ShiftAmt);
2186 RHS = Builder.CreateShl(
RHS, ShiftAmt);
2187 RHS = Builder.CreateAShr(
RHS, ShiftAmt);
2190 Constant *Mask = ConstantInt::get(Ty, 0xffffffff);
2191 LHS = Builder.CreateAnd(
LHS, Mask);
2192 RHS = Builder.CreateAnd(
RHS, Mask);
2209 if (!
C || !
C->isAllOnesValue())
2210 Vec = Builder.CreateAnd(Vec,
getX86MaskVec(Builder, Mask, NumElts));
2215 for (
unsigned i = 0; i != NumElts; ++i)
2217 for (
unsigned i = NumElts; i != 8; ++i)
2218 Indices[i] = NumElts + i % NumElts;
2219 Vec = Builder.CreateShuffleVector(Vec,
2223 return Builder.CreateBitCast(Vec, Builder.getIntNTy(std::max(NumElts, 8U)));
2227 unsigned CC,
bool Signed) {
2235 }
else if (CC == 7) {
2271 Value* AndNode = Builder.CreateAnd(Mask,
APInt(8, 1));
2272 Value* Cmp = Builder.CreateIsNotNull(AndNode);
2274 Value* Extract2 = Builder.CreateExtractElement(Src, (
uint64_t)0);
2275 Value*
Select = Builder.CreateSelect(Cmp, Extract1, Extract2);
2284 return Builder.CreateSExt(Mask, ReturnOp,
"vpmovm2");
2290 Name = Name.substr(12);
2295 if (Name.starts_with(
"max.p")) {
2296 if (VecWidth == 128 && EltWidth == 32)
2297 IID = Intrinsic::x86_sse_max_ps;
2298 else if (VecWidth == 128 && EltWidth == 64)
2299 IID = Intrinsic::x86_sse2_max_pd;
2300 else if (VecWidth == 256 && EltWidth == 32)
2301 IID = Intrinsic::x86_avx_max_ps_256;
2302 else if (VecWidth == 256 && EltWidth == 64)
2303 IID = Intrinsic::x86_avx_max_pd_256;
2306 }
else if (Name.starts_with(
"min.p")) {
2307 if (VecWidth == 128 && EltWidth == 32)
2308 IID = Intrinsic::x86_sse_min_ps;
2309 else if (VecWidth == 128 && EltWidth == 64)
2310 IID = Intrinsic::x86_sse2_min_pd;
2311 else if (VecWidth == 256 && EltWidth == 32)
2312 IID = Intrinsic::x86_avx_min_ps_256;
2313 else if (VecWidth == 256 && EltWidth == 64)
2314 IID = Intrinsic::x86_avx_min_pd_256;
2317 }
else if (Name.starts_with(
"pshuf.b.")) {
2318 if (VecWidth == 128)
2319 IID = Intrinsic::x86_ssse3_pshuf_b_128;
2320 else if (VecWidth == 256)
2321 IID = Intrinsic::x86_avx2_pshuf_b;
2322 else if (VecWidth == 512)
2323 IID = Intrinsic::x86_avx512_pshuf_b_512;
2326 }
else if (Name.starts_with(
"pmul.hr.sw.")) {
2327 if (VecWidth == 128)
2328 IID = Intrinsic::x86_ssse3_pmul_hr_sw_128;
2329 else if (VecWidth == 256)
2330 IID = Intrinsic::x86_avx2_pmul_hr_sw;
2331 else if (VecWidth == 512)
2332 IID = Intrinsic::x86_avx512_pmul_hr_sw_512;
2335 }
else if (Name.starts_with(
"pmulh.w.")) {
2336 if (VecWidth == 128)
2337 IID = Intrinsic::x86_sse2_pmulh_w;
2338 else if (VecWidth == 256)
2339 IID = Intrinsic::x86_avx2_pmulh_w;
2340 else if (VecWidth == 512)
2341 IID = Intrinsic::x86_avx512_pmulh_w_512;
2344 }
else if (Name.starts_with(
"pmulhu.w.")) {
2345 if (VecWidth == 128)
2346 IID = Intrinsic::x86_sse2_pmulhu_w;
2347 else if (VecWidth == 256)
2348 IID = Intrinsic::x86_avx2_pmulhu_w;
2349 else if (VecWidth == 512)
2350 IID = Intrinsic::x86_avx512_pmulhu_w_512;
2353 }
else if (Name.starts_with(
"pmaddw.d.")) {
2354 if (VecWidth == 128)
2355 IID = Intrinsic::x86_sse2_pmadd_wd;
2356 else if (VecWidth == 256)
2357 IID = Intrinsic::x86_avx2_pmadd_wd;
2358 else if (VecWidth == 512)
2359 IID = Intrinsic::x86_avx512_pmaddw_d_512;
2362 }
else if (Name.starts_with(
"pmaddubs.w.")) {
2363 if (VecWidth == 128)
2364 IID = Intrinsic::x86_ssse3_pmadd_ub_sw_128;
2365 else if (VecWidth == 256)
2366 IID = Intrinsic::x86_avx2_pmadd_ub_sw;
2367 else if (VecWidth == 512)
2368 IID = Intrinsic::x86_avx512_pmaddubs_w_512;
2371 }
else if (Name.starts_with(
"packsswb.")) {
2372 if (VecWidth == 128)
2373 IID = Intrinsic::x86_sse2_packsswb_128;
2374 else if (VecWidth == 256)
2375 IID = Intrinsic::x86_avx2_packsswb;
2376 else if (VecWidth == 512)
2377 IID = Intrinsic::x86_avx512_packsswb_512;
2380 }
else if (Name.starts_with(
"packssdw.")) {
2381 if (VecWidth == 128)
2382 IID = Intrinsic::x86_sse2_packssdw_128;
2383 else if (VecWidth == 256)
2384 IID = Intrinsic::x86_avx2_packssdw;
2385 else if (VecWidth == 512)
2386 IID = Intrinsic::x86_avx512_packssdw_512;
2389 }
else if (Name.starts_with(
"packuswb.")) {
2390 if (VecWidth == 128)
2391 IID = Intrinsic::x86_sse2_packuswb_128;
2392 else if (VecWidth == 256)
2393 IID = Intrinsic::x86_avx2_packuswb;
2394 else if (VecWidth == 512)
2395 IID = Intrinsic::x86_avx512_packuswb_512;
2398 }
else if (Name.starts_with(
"packusdw.")) {
2399 if (VecWidth == 128)
2400 IID = Intrinsic::x86_sse41_packusdw;
2401 else if (VecWidth == 256)
2402 IID = Intrinsic::x86_avx2_packusdw;
2403 else if (VecWidth == 512)
2404 IID = Intrinsic::x86_avx512_packusdw_512;
2407 }
else if (Name.starts_with(
"vpermilvar.")) {
2408 if (VecWidth == 128 && EltWidth == 32)
2409 IID = Intrinsic::x86_avx_vpermilvar_ps;
2410 else if (VecWidth == 128 && EltWidth == 64)
2411 IID = Intrinsic::x86_avx_vpermilvar_pd;
2412 else if (VecWidth == 256 && EltWidth == 32)
2413 IID = Intrinsic::x86_avx_vpermilvar_ps_256;
2414 else if (VecWidth == 256 && EltWidth == 64)
2415 IID = Intrinsic::x86_avx_vpermilvar_pd_256;
2416 else if (VecWidth == 512 && EltWidth == 32)
2417 IID = Intrinsic::x86_avx512_vpermilvar_ps_512;
2418 else if (VecWidth == 512 && EltWidth == 64)
2419 IID = Intrinsic::x86_avx512_vpermilvar_pd_512;
2422 }
else if (Name ==
"cvtpd2dq.256") {
2423 IID = Intrinsic::x86_avx_cvt_pd2dq_256;
2424 }
else if (Name ==
"cvtpd2ps.256") {
2425 IID = Intrinsic::x86_avx_cvt_pd2_ps_256;
2426 }
else if (Name ==
"cvttpd2dq.256") {
2427 IID = Intrinsic::x86_avx_cvtt_pd2dq_256;
2428 }
else if (Name ==
"cvttps2dq.128") {
2429 IID = Intrinsic::x86_sse2_cvttps2dq;
2430 }
else if (Name ==
"cvttps2dq.256") {
2431 IID = Intrinsic::x86_avx_cvtt_ps2dq_256;
2432 }
else if (Name.starts_with(
"permvar.")) {
2434 if (VecWidth == 256 && EltWidth == 32 && IsFloat)
2435 IID = Intrinsic::x86_avx2_permps;
2436 else if (VecWidth == 256 && EltWidth == 32 && !IsFloat)
2437 IID = Intrinsic::x86_avx2_permd;
2438 else if (VecWidth == 256 && EltWidth == 64 && IsFloat)
2439 IID = Intrinsic::x86_avx512_permvar_df_256;
2440 else if (VecWidth == 256 && EltWidth == 64 && !IsFloat)
2441 IID = Intrinsic::x86_avx512_permvar_di_256;
2442 else if (VecWidth == 512 && EltWidth == 32 && IsFloat)
2443 IID = Intrinsic::x86_avx512_permvar_sf_512;
2444 else if (VecWidth == 512 && EltWidth == 32 && !IsFloat)
2445 IID = Intrinsic::x86_avx512_permvar_si_512;
2446 else if (VecWidth == 512 && EltWidth == 64 && IsFloat)
2447 IID = Intrinsic::x86_avx512_permvar_df_512;
2448 else if (VecWidth == 512 && EltWidth == 64 && !IsFloat)
2449 IID = Intrinsic::x86_avx512_permvar_di_512;
2450 else if (VecWidth == 128 && EltWidth == 16)
2451 IID = Intrinsic::x86_avx512_permvar_hi_128;
2452 else if (VecWidth == 256 && EltWidth == 16)
2453 IID = Intrinsic::x86_avx512_permvar_hi_256;
2454 else if (VecWidth == 512 && EltWidth == 16)
2455 IID = Intrinsic::x86_avx512_permvar_hi_512;
2456 else if (VecWidth == 128 && EltWidth == 8)
2457 IID = Intrinsic::x86_avx512_permvar_qi_128;
2458 else if (VecWidth == 256 && EltWidth == 8)
2459 IID = Intrinsic::x86_avx512_permvar_qi_256;
2460 else if (VecWidth == 512 && EltWidth == 8)
2461 IID = Intrinsic::x86_avx512_permvar_qi_512;
2464 }
else if (Name.starts_with(
"dbpsadbw.")) {
2465 if (VecWidth == 128)
2466 IID = Intrinsic::x86_avx512_dbpsadbw_128;
2467 else if (VecWidth == 256)
2468 IID = Intrinsic::x86_avx512_dbpsadbw_256;
2469 else if (VecWidth == 512)
2470 IID = Intrinsic::x86_avx512_dbpsadbw_512;
2473 }
else if (Name.starts_with(
"pmultishift.qb.")) {
2474 if (VecWidth == 128)
2475 IID = Intrinsic::x86_avx512_pmultishift_qb_128;
2476 else if (VecWidth == 256)
2477 IID = Intrinsic::x86_avx512_pmultishift_qb_256;
2478 else if (VecWidth == 512)
2479 IID = Intrinsic::x86_avx512_pmultishift_qb_512;
2482 }
else if (Name.starts_with(
"conflict.")) {
2483 if (Name[9] ==
'd' && VecWidth == 128)
2484 IID = Intrinsic::x86_avx512_conflict_d_128;
2485 else if (Name[9] ==
'd' && VecWidth == 256)
2486 IID = Intrinsic::x86_avx512_conflict_d_256;
2487 else if (Name[9] ==
'd' && VecWidth == 512)
2488 IID = Intrinsic::x86_avx512_conflict_d_512;
2489 else if (Name[9] ==
'q' && VecWidth == 128)
2490 IID = Intrinsic::x86_avx512_conflict_q_128;
2491 else if (Name[9] ==
'q' && VecWidth == 256)
2492 IID = Intrinsic::x86_avx512_conflict_q_256;
2493 else if (Name[9] ==
'q' && VecWidth == 512)
2494 IID = Intrinsic::x86_avx512_conflict_q_512;
2497 }
else if (Name.starts_with(
"pavg.")) {
2498 if (Name[5] ==
'b' && VecWidth == 128)
2499 IID = Intrinsic::x86_sse2_pavg_b;
2500 else if (Name[5] ==
'b' && VecWidth == 256)
2501 IID = Intrinsic::x86_avx2_pavg_b;
2502 else if (Name[5] ==
'b' && VecWidth == 512)
2503 IID = Intrinsic::x86_avx512_pavg_b_512;
2504 else if (Name[5] ==
'w' && VecWidth == 128)
2505 IID = Intrinsic::x86_sse2_pavg_w;
2506 else if (Name[5] ==
'w' && VecWidth == 256)
2507 IID = Intrinsic::x86_avx2_pavg_w;
2508 else if (Name[5] ==
'w' && VecWidth == 512)
2509 IID = Intrinsic::x86_avx512_pavg_w_512;
2518 Rep = Builder.CreateIntrinsic(IID, Args);
2529 if (AsmStr->find(
"mov\tfp") == 0 &&
2530 AsmStr->find(
"objc_retainAutoreleaseReturnValue") != std::string::npos &&
2531 (Pos = AsmStr->find(
"# marker")) != std::string::npos) {
2532 AsmStr->replace(Pos, 1,
";");
2538 Value *Rep =
nullptr;
2540 if (Name ==
"abs.i" || Name ==
"abs.ll") {
2542 Value *Neg = Builder.CreateNeg(Arg,
"neg");
2543 Value *Cmp = Builder.CreateICmpSGE(
2545 Rep = Builder.CreateSelect(Cmp, Arg, Neg,
"abs");
2546 }
else if (Name ==
"abs.bf16" || Name ==
"abs.bf16x2") {
2547 Type *Ty = (Name ==
"abs.bf16")
2551 Value *Abs = Builder.CreateUnaryIntrinsic(Intrinsic::nvvm_fabs, Arg);
2552 Rep = Builder.CreateBitCast(Abs, CI->
getType());
2553 }
else if (Name ==
"fabs.f" || Name ==
"fabs.ftz.f" || Name ==
"fabs.d") {
2554 Intrinsic::ID IID = (Name ==
"fabs.ftz.f") ? Intrinsic::nvvm_fabs_ftz
2555 : Intrinsic::nvvm_fabs;
2556 Rep = Builder.CreateUnaryIntrinsic(IID, CI->
getArgOperand(0));
2557 }
else if (Name.consume_front(
"ex2.approx.")) {
2559 Intrinsic::ID IID = Name.starts_with(
"ftz") ? Intrinsic::nvvm_ex2_approx_ftz
2560 : Intrinsic::nvvm_ex2_approx;
2561 Rep = Builder.CreateUnaryIntrinsic(IID, CI->
getArgOperand(0));
2562 }
else if (Name.starts_with(
"atomic.load.add.f32.p") ||
2563 Name.starts_with(
"atomic.load.add.f64.p")) {
2568 }
else if (Name.starts_with(
"atomic.load.inc.32.p") ||
2569 Name.starts_with(
"atomic.load.dec.32.p")) {
2576 }
else if (Name.consume_front(
"max.") &&
2577 (Name ==
"s" || Name ==
"i" || Name ==
"ll" || Name ==
"us" ||
2578 Name ==
"ui" || Name ==
"ull")) {
2581 Value *Cmp = Name.starts_with(
"u")
2582 ? Builder.CreateICmpUGE(Arg0, Arg1,
"max.cond")
2583 : Builder.CreateICmpSGE(Arg0, Arg1,
"max.cond");
2584 Rep = Builder.CreateSelect(Cmp, Arg0, Arg1,
"max");
2585 }
else if (Name.consume_front(
"min.") &&
2586 (Name ==
"s" || Name ==
"i" || Name ==
"ll" || Name ==
"us" ||
2587 Name ==
"ui" || Name ==
"ull")) {
2590 Value *Cmp = Name.starts_with(
"u")
2591 ? Builder.CreateICmpULE(Arg0, Arg1,
"min.cond")
2592 : Builder.CreateICmpSLE(Arg0, Arg1,
"min.cond");
2593 Rep = Builder.CreateSelect(Cmp, Arg0, Arg1,
"min");
2594 }
else if (Name ==
"clz.ll") {
2597 Value *Ctlz = Builder.CreateIntrinsic(Intrinsic::ctlz, {Arg->
getType()},
2598 {Arg, Builder.getFalse()},
2600 Rep = Builder.CreateTrunc(Ctlz, Builder.getInt32Ty(),
"ctlz.trunc");
2601 }
else if (Name ==
"popc.ll") {
2605 Value *Popc = Builder.CreateIntrinsic(Intrinsic::ctpop, {Arg->
getType()},
2606 Arg,
nullptr,
"ctpop");
2607 Rep = Builder.CreateTrunc(Popc, Builder.getInt32Ty(),
"ctpop.trunc");
2608 }
else if (Name ==
"h2f") {
2609 Rep = Builder.CreateIntrinsic(Intrinsic::convert_from_fp16,
2612 }
else if (Name.consume_front(
"bitcast.") &&
2613 (Name ==
"f2i" || Name ==
"i2f" || Name ==
"ll2d" ||
2616 }
else if (Name ==
"rotate.b32") {
2619 Rep = Builder.CreateIntrinsic(Builder.getInt32Ty(), Intrinsic::fshl,
2620 {Arg, Arg, ShiftAmt});
2621 }
else if (Name ==
"rotate.b64") {
2625 Rep = Builder.CreateIntrinsic(Int64Ty, Intrinsic::fshl,
2626 {Arg, Arg, ZExtShiftAmt});
2627 }
else if (Name ==
"rotate.right.b64") {
2631 Rep = Builder.CreateIntrinsic(Int64Ty, Intrinsic::fshr,
2632 {Arg, Arg, ZExtShiftAmt});
2633 }
else if (Name ==
"swap.lo.hi.b64") {
2636 Rep = Builder.CreateIntrinsic(Int64Ty, Intrinsic::fshl,
2637 {Arg, Arg, Builder.getInt64(32)});
2638 }
else if ((Name.consume_front(
"ptr.gen.to.") &&
2641 Name.starts_with(
".to.gen"))) {
2643 }
else if (Name.consume_front(
"ldg.global")) {
2647 Value *ASC = Builder.CreateAddrSpaceCast(
Ptr, Builder.getPtrTy(1));
2650 LD->setMetadata(LLVMContext::MD_invariant_load, MD);
2652 }
else if (Name ==
"tanh.approx.f32") {
2656 Rep = Builder.CreateUnaryIntrinsic(Intrinsic::tanh, CI->
getArgOperand(0),
2658 }
else if (Name ==
"barrier0" || Name ==
"barrier.n" || Name ==
"bar.sync") {
2660 Name.ends_with(
'0') ? Builder.getInt32(0) : CI->
getArgOperand(0);
2661 Rep = Builder.CreateIntrinsic(Intrinsic::nvvm_barrier_cta_sync_aligned_all,
2663 }
else if (Name ==
"barrier") {
2664 Rep = Builder.CreateIntrinsic(
2665 Intrinsic::nvvm_barrier_cta_sync_aligned_count, {},
2667 }
else if (Name ==
"barrier.sync") {
2668 Rep = Builder.CreateIntrinsic(Intrinsic::nvvm_barrier_cta_sync_all, {},
2670 }
else if (Name ==
"barrier.sync.cnt") {
2671 Rep = Builder.CreateIntrinsic(Intrinsic::nvvm_barrier_cta_sync_count, {},
2676 !
F->getReturnType()->getScalarType()->isBFloatTy()) {
2686 ? Builder.CreateBitCast(Arg, NewType)
2689 Rep = Builder.CreateCall(NewFn, Args);
2690 if (
F->getReturnType()->isIntegerTy())
2691 Rep = Builder.CreateBitCast(Rep,
F->getReturnType());
2701 Value *Rep =
nullptr;
2703 if (Name.starts_with(
"sse4a.movnt.")) {
2715 Builder.CreateExtractElement(Arg1, (
uint64_t)0,
"extractelement");
2718 SI->setMetadata(LLVMContext::MD_nontemporal,
Node);
2719 }
else if (Name.starts_with(
"avx.movnt.") ||
2720 Name.starts_with(
"avx512.storent.")) {
2732 SI->setMetadata(LLVMContext::MD_nontemporal,
Node);
2733 }
else if (Name ==
"sse2.storel.dq") {
2738 Value *BC0 = Builder.CreateBitCast(Arg1, NewVecTy,
"cast");
2739 Value *Elt = Builder.CreateExtractElement(BC0, (
uint64_t)0);
2740 Builder.CreateAlignedStore(Elt, Arg0,
Align(1));
2741 }
else if (Name.starts_with(
"sse.storeu.") ||
2742 Name.starts_with(
"sse2.storeu.") ||
2743 Name.starts_with(
"avx.storeu.")) {
2746 Builder.CreateAlignedStore(Arg1, Arg0,
Align(1));
2747 }
else if (Name ==
"avx512.mask.store.ss") {
2751 }
else if (Name.starts_with(
"avx512.mask.store")) {
2753 bool Aligned = Name[17] !=
'u';
2756 }
else if (Name.starts_with(
"sse2.pcmp") || Name.starts_with(
"avx2.pcmp")) {
2759 bool CmpEq = Name[9] ==
'e';
2762 Rep = Builder.CreateSExt(Rep, CI->
getType(),
"");
2763 }
else if (Name.starts_with(
"avx512.broadcastm")) {
2770 Rep = Builder.CreateVectorSplat(NumElts, Rep);
2771 }
else if (Name ==
"sse.sqrt.ss" || Name ==
"sse2.sqrt.sd") {
2773 Value *Elt0 = Builder.CreateExtractElement(Vec, (
uint64_t)0);
2774 Elt0 = Builder.CreateIntrinsic(Intrinsic::sqrt, Elt0->
getType(), Elt0);
2775 Rep = Builder.CreateInsertElement(Vec, Elt0, (
uint64_t)0);
2776 }
else if (Name.starts_with(
"avx.sqrt.p") ||
2777 Name.starts_with(
"sse2.sqrt.p") ||
2778 Name.starts_with(
"sse.sqrt.p")) {
2779 Rep = Builder.CreateIntrinsic(Intrinsic::sqrt, CI->
getType(),
2780 {CI->getArgOperand(0)});
2781 }
else if (Name.starts_with(
"avx512.mask.sqrt.p")) {
2785 Intrinsic::ID IID = Name[18] ==
's' ? Intrinsic::x86_avx512_sqrt_ps_512
2786 : Intrinsic::x86_avx512_sqrt_pd_512;
2789 Rep = Builder.CreateIntrinsic(IID, Args);
2791 Rep = Builder.CreateIntrinsic(Intrinsic::sqrt, CI->
getType(),
2792 {CI->getArgOperand(0)});
2796 }
else if (Name.starts_with(
"avx512.ptestm") ||
2797 Name.starts_with(
"avx512.ptestnm")) {
2801 Rep = Builder.CreateAnd(Op0, Op1);
2807 Rep = Builder.CreateICmp(Pred, Rep, Zero);
2809 }
else if (Name.starts_with(
"avx512.mask.pbroadcast")) {
2812 Rep = Builder.CreateVectorSplat(NumElts, CI->
getArgOperand(0));
2815 }
else if (Name.starts_with(
"avx512.kunpck")) {
2820 for (
unsigned i = 0; i != NumElts; ++i)
2829 Rep = Builder.CreateShuffleVector(
RHS,
LHS,
ArrayRef(Indices, NumElts));
2830 Rep = Builder.CreateBitCast(Rep, CI->
getType());
2831 }
else if (Name ==
"avx512.kand.w") {
2834 Rep = Builder.CreateAnd(
LHS,
RHS);
2835 Rep = Builder.CreateBitCast(Rep, CI->
getType());
2836 }
else if (Name ==
"avx512.kandn.w") {
2839 LHS = Builder.CreateNot(
LHS);
2840 Rep = Builder.CreateAnd(
LHS,
RHS);
2841 Rep = Builder.CreateBitCast(Rep, CI->
getType());
2842 }
else if (Name ==
"avx512.kor.w") {
2845 Rep = Builder.CreateOr(
LHS,
RHS);
2846 Rep = Builder.CreateBitCast(Rep, CI->
getType());
2847 }
else if (Name ==
"avx512.kxor.w") {
2850 Rep = Builder.CreateXor(
LHS,
RHS);
2851 Rep = Builder.CreateBitCast(Rep, CI->
getType());
2852 }
else if (Name ==
"avx512.kxnor.w") {
2855 LHS = Builder.CreateNot(
LHS);
2856 Rep = Builder.CreateXor(
LHS,
RHS);
2857 Rep = Builder.CreateBitCast(Rep, CI->
getType());
2858 }
else if (Name ==
"avx512.knot.w") {
2860 Rep = Builder.CreateNot(Rep);
2861 Rep = Builder.CreateBitCast(Rep, CI->
getType());
2862 }
else if (Name ==
"avx512.kortestz.w" || Name ==
"avx512.kortestc.w") {
2865 Rep = Builder.CreateOr(
LHS,
RHS);
2866 Rep = Builder.CreateBitCast(Rep, Builder.getInt16Ty());
2868 if (Name[14] ==
'c')
2872 Rep = Builder.CreateICmpEQ(Rep,
C);
2873 Rep = Builder.CreateZExt(Rep, Builder.getInt32Ty());
2874 }
else if (Name ==
"sse.add.ss" || Name ==
"sse2.add.sd" ||
2875 Name ==
"sse.sub.ss" || Name ==
"sse2.sub.sd" ||
2876 Name ==
"sse.mul.ss" || Name ==
"sse2.mul.sd" ||
2877 Name ==
"sse.div.ss" || Name ==
"sse2.div.sd") {
2880 ConstantInt::get(I32Ty, 0));
2882 ConstantInt::get(I32Ty, 0));
2884 if (Name.contains(
".add."))
2885 EltOp = Builder.CreateFAdd(Elt0, Elt1);
2886 else if (Name.contains(
".sub."))
2887 EltOp = Builder.CreateFSub(Elt0, Elt1);
2888 else if (Name.contains(
".mul."))
2889 EltOp = Builder.CreateFMul(Elt0, Elt1);
2891 EltOp = Builder.CreateFDiv(Elt0, Elt1);
2892 Rep = Builder.CreateInsertElement(CI->
getArgOperand(0), EltOp,
2893 ConstantInt::get(I32Ty, 0));
2894 }
else if (Name.starts_with(
"avx512.mask.pcmp")) {
2896 bool CmpEq = Name[16] ==
'e';
2898 }
else if (Name.starts_with(
"avx512.mask.vpshufbitqmb.")) {
2906 IID = Intrinsic::x86_avx512_vpshufbitqmb_128;
2909 IID = Intrinsic::x86_avx512_vpshufbitqmb_256;
2912 IID = Intrinsic::x86_avx512_vpshufbitqmb_512;
2919 }
else if (Name.starts_with(
"avx512.mask.fpclass.p")) {
2924 if (VecWidth == 128 && EltWidth == 32)
2925 IID = Intrinsic::x86_avx512_fpclass_ps_128;
2926 else if (VecWidth == 256 && EltWidth == 32)
2927 IID = Intrinsic::x86_avx512_fpclass_ps_256;
2928 else if (VecWidth == 512 && EltWidth == 32)
2929 IID = Intrinsic::x86_avx512_fpclass_ps_512;
2930 else if (VecWidth == 128 && EltWidth == 64)
2931 IID = Intrinsic::x86_avx512_fpclass_pd_128;
2932 else if (VecWidth == 256 && EltWidth == 64)
2933 IID = Intrinsic::x86_avx512_fpclass_pd_256;
2934 else if (VecWidth == 512 && EltWidth == 64)
2935 IID = Intrinsic::x86_avx512_fpclass_pd_512;
2942 }
else if (Name.starts_with(
"avx512.cmp.p")) {
2944 Type *OpTy = Args[0]->getType();
2948 if (VecWidth == 128 && EltWidth == 32)
2949 IID = Intrinsic::x86_avx512_mask_cmp_ps_128;
2950 else if (VecWidth == 256 && EltWidth == 32)
2951 IID = Intrinsic::x86_avx512_mask_cmp_ps_256;
2952 else if (VecWidth == 512 && EltWidth == 32)
2953 IID = Intrinsic::x86_avx512_mask_cmp_ps_512;
2954 else if (VecWidth == 128 && EltWidth == 64)
2955 IID = Intrinsic::x86_avx512_mask_cmp_pd_128;
2956 else if (VecWidth == 256 && EltWidth == 64)
2957 IID = Intrinsic::x86_avx512_mask_cmp_pd_256;
2958 else if (VecWidth == 512 && EltWidth == 64)
2959 IID = Intrinsic::x86_avx512_mask_cmp_pd_512;
2964 if (VecWidth == 512)
2966 Args.push_back(Mask);
2968 Rep = Builder.CreateIntrinsic(IID, Args);
2969 }
else if (Name.starts_with(
"avx512.mask.cmp.")) {
2973 }
else if (Name.starts_with(
"avx512.mask.ucmp.")) {
2976 }
else if (Name.starts_with(
"avx512.cvtb2mask.") ||
2977 Name.starts_with(
"avx512.cvtw2mask.") ||
2978 Name.starts_with(
"avx512.cvtd2mask.") ||
2979 Name.starts_with(
"avx512.cvtq2mask.")) {
2984 }
else if (Name ==
"ssse3.pabs.b.128" || Name ==
"ssse3.pabs.w.128" ||
2985 Name ==
"ssse3.pabs.d.128" || Name.starts_with(
"avx2.pabs") ||
2986 Name.starts_with(
"avx512.mask.pabs")) {
2988 }
else if (Name ==
"sse41.pmaxsb" || Name ==
"sse2.pmaxs.w" ||
2989 Name ==
"sse41.pmaxsd" || Name.starts_with(
"avx2.pmaxs") ||
2990 Name.starts_with(
"avx512.mask.pmaxs")) {
2992 }
else if (Name ==
"sse2.pmaxu.b" || Name ==
"sse41.pmaxuw" ||
2993 Name ==
"sse41.pmaxud" || Name.starts_with(
"avx2.pmaxu") ||
2994 Name.starts_with(
"avx512.mask.pmaxu")) {
2996 }
else if (Name ==
"sse41.pminsb" || Name ==
"sse2.pmins.w" ||
2997 Name ==
"sse41.pminsd" || Name.starts_with(
"avx2.pmins") ||
2998 Name.starts_with(
"avx512.mask.pmins")) {
3000 }
else if (Name ==
"sse2.pminu.b" || Name ==
"sse41.pminuw" ||
3001 Name ==
"sse41.pminud" || Name.starts_with(
"avx2.pminu") ||
3002 Name.starts_with(
"avx512.mask.pminu")) {
3004 }
else if (Name ==
"sse2.pmulu.dq" || Name ==
"avx2.pmulu.dq" ||
3005 Name ==
"avx512.pmulu.dq.512" ||
3006 Name.starts_with(
"avx512.mask.pmulu.dq.")) {
3008 }
else if (Name ==
"sse41.pmuldq" || Name ==
"avx2.pmul.dq" ||
3009 Name ==
"avx512.pmul.dq.512" ||
3010 Name.starts_with(
"avx512.mask.pmul.dq.")) {
3012 }
else if (Name ==
"sse.cvtsi2ss" || Name ==
"sse2.cvtsi2sd" ||
3013 Name ==
"sse.cvtsi642ss" || Name ==
"sse2.cvtsi642sd") {
3018 }
else if (Name ==
"avx512.cvtusi2sd") {
3023 }
else if (Name ==
"sse2.cvtss2sd") {
3025 Rep = Builder.CreateFPExt(
3028 }
else if (Name ==
"sse2.cvtdq2pd" || Name ==
"sse2.cvtdq2ps" ||
3029 Name ==
"avx.cvtdq2.pd.256" || Name ==
"avx.cvtdq2.ps.256" ||
3030 Name.starts_with(
"avx512.mask.cvtdq2pd.") ||
3031 Name.starts_with(
"avx512.mask.cvtudq2pd.") ||
3032 Name.starts_with(
"avx512.mask.cvtdq2ps.") ||
3033 Name.starts_with(
"avx512.mask.cvtudq2ps.") ||
3034 Name.starts_with(
"avx512.mask.cvtqq2pd.") ||
3035 Name.starts_with(
"avx512.mask.cvtuqq2pd.") ||
3036 Name ==
"avx512.mask.cvtqq2ps.256" ||
3037 Name ==
"avx512.mask.cvtqq2ps.512" ||
3038 Name ==
"avx512.mask.cvtuqq2ps.256" ||
3039 Name ==
"avx512.mask.cvtuqq2ps.512" || Name ==
"sse2.cvtps2pd" ||
3040 Name ==
"avx.cvt.ps2.pd.256" ||
3041 Name ==
"avx512.mask.cvtps2pd.128" ||
3042 Name ==
"avx512.mask.cvtps2pd.256") {
3047 unsigned NumDstElts = DstTy->getNumElements();
3049 assert(NumDstElts == 2 &&
"Unexpected vector size");
3050 Rep = Builder.CreateShuffleVector(Rep, Rep,
ArrayRef<int>{0, 1});
3053 bool IsPS2PD = SrcTy->getElementType()->isFloatTy();
3054 bool IsUnsigned = Name.contains(
"cvtu");
3056 Rep = Builder.CreateFPExt(Rep, DstTy,
"cvtps2pd");
3060 Intrinsic::ID IID = IsUnsigned ? Intrinsic::x86_avx512_uitofp_round
3061 : Intrinsic::x86_avx512_sitofp_round;
3062 Rep = Builder.CreateIntrinsic(IID, {DstTy, SrcTy},
3065 Rep = IsUnsigned ? Builder.CreateUIToFP(Rep, DstTy,
"cvt")
3066 : Builder.CreateSIToFP(Rep, DstTy,
"cvt");
3072 }
else if (Name.starts_with(
"avx512.mask.vcvtph2ps.") ||
3073 Name.starts_with(
"vcvtph2ps.")) {
3077 unsigned NumDstElts = DstTy->getNumElements();
3078 if (NumDstElts != SrcTy->getNumElements()) {
3079 assert(NumDstElts == 4 &&
"Unexpected vector size");
3080 Rep = Builder.CreateShuffleVector(Rep, Rep,
ArrayRef<int>{0, 1, 2, 3});
3082 Rep = Builder.CreateBitCast(
3084 Rep = Builder.CreateFPExt(Rep, DstTy,
"cvtph2ps");
3088 }
else if (Name.starts_with(
"avx512.mask.load")) {
3090 bool Aligned = Name[16] !=
'u';
3093 }
else if (Name.starts_with(
"avx512.mask.expand.load.")) {
3096 ResultTy->getNumElements());
3098 Rep = Builder.CreateIntrinsic(
3099 Intrinsic::masked_expandload, ResultTy,
3101 }
else if (Name.starts_with(
"avx512.mask.compress.store.")) {
3107 Rep = Builder.CreateIntrinsic(
3108 Intrinsic::masked_compressstore, ResultTy,
3110 }
else if (Name.starts_with(
"avx512.mask.compress.") ||
3111 Name.starts_with(
"avx512.mask.expand.")) {
3115 ResultTy->getNumElements());
3117 bool IsCompress = Name[12] ==
'c';
3118 Intrinsic::ID IID = IsCompress ? Intrinsic::x86_avx512_mask_compress
3119 : Intrinsic::x86_avx512_mask_expand;
3120 Rep = Builder.CreateIntrinsic(
3122 }
else if (Name.starts_with(
"xop.vpcom")) {
3124 if (Name.ends_with(
"ub") || Name.ends_with(
"uw") || Name.ends_with(
"ud") ||
3125 Name.ends_with(
"uq"))
3127 else if (Name.ends_with(
"b") || Name.ends_with(
"w") ||
3128 Name.ends_with(
"d") || Name.ends_with(
"q"))
3137 Name = Name.substr(9);
3138 if (Name.starts_with(
"lt"))
3140 else if (Name.starts_with(
"le"))
3142 else if (Name.starts_with(
"gt"))
3144 else if (Name.starts_with(
"ge"))
3146 else if (Name.starts_with(
"eq"))
3148 else if (Name.starts_with(
"ne"))
3150 else if (Name.starts_with(
"false"))
3152 else if (Name.starts_with(
"true"))
3159 }
else if (Name.starts_with(
"xop.vpcmov")) {
3161 Value *NotSel = Builder.CreateNot(Sel);
3164 Rep = Builder.CreateOr(Sel0, Sel1);
3165 }
else if (Name.starts_with(
"xop.vprot") || Name.starts_with(
"avx512.prol") ||
3166 Name.starts_with(
"avx512.mask.prol")) {
3168 }
else if (Name.starts_with(
"avx512.pror") ||
3169 Name.starts_with(
"avx512.mask.pror")) {
3171 }
else if (Name.starts_with(
"avx512.vpshld.") ||
3172 Name.starts_with(
"avx512.mask.vpshld") ||
3173 Name.starts_with(
"avx512.maskz.vpshld")) {
3174 bool ZeroMask = Name[11] ==
'z';
3176 }
else if (Name.starts_with(
"avx512.vpshrd.") ||
3177 Name.starts_with(
"avx512.mask.vpshrd") ||
3178 Name.starts_with(
"avx512.maskz.vpshrd")) {
3179 bool ZeroMask = Name[11] ==
'z';
3181 }
else if (Name ==
"sse42.crc32.64.8") {
3184 Rep = Builder.CreateIntrinsic(Intrinsic::x86_sse42_crc32_32_8,
3186 Rep = Builder.CreateZExt(Rep, CI->
getType(),
"");
3187 }
else if (Name.starts_with(
"avx.vbroadcast.s") ||
3188 Name.starts_with(
"avx512.vbroadcast.s")) {
3191 Type *EltTy = VecTy->getElementType();
3192 unsigned EltNum = VecTy->getNumElements();
3196 for (
unsigned I = 0;
I < EltNum; ++
I)
3197 Rep = Builder.CreateInsertElement(Rep, Load, ConstantInt::get(I32Ty,
I));
3198 }
else if (Name.starts_with(
"sse41.pmovsx") ||
3199 Name.starts_with(
"sse41.pmovzx") ||
3200 Name.starts_with(
"avx2.pmovsx") ||
3201 Name.starts_with(
"avx2.pmovzx") ||
3202 Name.starts_with(
"avx512.mask.pmovsx") ||
3203 Name.starts_with(
"avx512.mask.pmovzx")) {
3205 unsigned NumDstElts = DstTy->getNumElements();
3209 for (
unsigned i = 0; i != NumDstElts; ++i)
3214 bool DoSext = Name.contains(
"pmovsx");
3216 DoSext ? Builder.CreateSExt(SV, DstTy) : Builder.CreateZExt(SV, DstTy);
3221 }
else if (Name ==
"avx512.mask.pmov.qd.256" ||
3222 Name ==
"avx512.mask.pmov.qd.512" ||
3223 Name ==
"avx512.mask.pmov.wb.256" ||
3224 Name ==
"avx512.mask.pmov.wb.512") {
3229 }
else if (Name.starts_with(
"avx.vbroadcastf128") ||
3230 Name ==
"avx2.vbroadcasti128") {
3236 if (NumSrcElts == 2)
3237 Rep = Builder.CreateShuffleVector(Load,
ArrayRef<int>{0, 1, 0, 1});
3239 Rep = Builder.CreateShuffleVector(Load,
3241 }
else if (Name.starts_with(
"avx512.mask.shuf.i") ||
3242 Name.starts_with(
"avx512.mask.shuf.f")) {
3247 unsigned ControlBitsMask = NumLanes - 1;
3248 unsigned NumControlBits = NumLanes / 2;
3251 for (
unsigned l = 0; l != NumLanes; ++l) {
3252 unsigned LaneMask = (Imm >> (l * NumControlBits)) & ControlBitsMask;
3254 if (l >= NumLanes / 2)
3255 LaneMask += NumLanes;
3256 for (
unsigned i = 0; i != NumElementsInLane; ++i)
3257 ShuffleMask.push_back(LaneMask * NumElementsInLane + i);
3263 }
else if (Name.starts_with(
"avx512.mask.broadcastf") ||
3264 Name.starts_with(
"avx512.mask.broadcasti")) {
3267 unsigned NumDstElts =
3271 for (
unsigned i = 0; i != NumDstElts; ++i)
3272 ShuffleMask[i] = i % NumSrcElts;
3278 }
else if (Name.starts_with(
"avx2.pbroadcast") ||
3279 Name.starts_with(
"avx2.vbroadcast") ||
3280 Name.starts_with(
"avx512.pbroadcast") ||
3281 Name.starts_with(
"avx512.mask.broadcast.s")) {
3288 Rep = Builder.CreateShuffleVector(
Op, M);
3293 }
else if (Name.starts_with(
"sse2.padds.") ||
3294 Name.starts_with(
"avx2.padds.") ||
3295 Name.starts_with(
"avx512.padds.") ||
3296 Name.starts_with(
"avx512.mask.padds.")) {
3298 }
else if (Name.starts_with(
"sse2.psubs.") ||
3299 Name.starts_with(
"avx2.psubs.") ||
3300 Name.starts_with(
"avx512.psubs.") ||
3301 Name.starts_with(
"avx512.mask.psubs.")) {
3303 }
else if (Name.starts_with(
"sse2.paddus.") ||
3304 Name.starts_with(
"avx2.paddus.") ||
3305 Name.starts_with(
"avx512.mask.paddus.")) {
3307 }
else if (Name.starts_with(
"sse2.psubus.") ||
3308 Name.starts_with(
"avx2.psubus.") ||
3309 Name.starts_with(
"avx512.mask.psubus.")) {
3311 }
else if (Name.starts_with(
"avx512.mask.palignr.")) {
3316 }
else if (Name.starts_with(
"avx512.mask.valign.")) {
3320 }
else if (Name ==
"sse2.psll.dq" || Name ==
"avx2.psll.dq") {
3325 }
else if (Name ==
"sse2.psrl.dq" || Name ==
"avx2.psrl.dq") {
3330 }
else if (Name ==
"sse2.psll.dq.bs" || Name ==
"avx2.psll.dq.bs" ||
3331 Name ==
"avx512.psll.dq.512") {
3335 }
else if (Name ==
"sse2.psrl.dq.bs" || Name ==
"avx2.psrl.dq.bs" ||
3336 Name ==
"avx512.psrl.dq.512") {
3340 }
else if (Name ==
"sse41.pblendw" || Name.starts_with(
"sse41.blendp") ||
3341 Name.starts_with(
"avx.blend.p") || Name ==
"avx2.pblendw" ||
3342 Name.starts_with(
"avx2.pblendd.")) {
3347 unsigned NumElts = VecTy->getNumElements();
3350 for (
unsigned i = 0; i != NumElts; ++i)
3351 Idxs[i] = ((Imm >> (i % 8)) & 1) ? i + NumElts : i;
3353 Rep = Builder.CreateShuffleVector(Op0, Op1, Idxs);
3354 }
else if (Name.starts_with(
"avx.vinsertf128.") ||
3355 Name ==
"avx2.vinserti128" ||
3356 Name.starts_with(
"avx512.mask.insert")) {
3360 unsigned DstNumElts =
3362 unsigned SrcNumElts =
3364 unsigned Scale = DstNumElts / SrcNumElts;
3371 for (
unsigned i = 0; i != SrcNumElts; ++i)
3373 for (
unsigned i = SrcNumElts; i != DstNumElts; ++i)
3374 Idxs[i] = SrcNumElts;
3375 Rep = Builder.CreateShuffleVector(Op1, Idxs);
3389 for (
unsigned i = 0; i != DstNumElts; ++i)
3392 for (
unsigned i = 0; i != SrcNumElts; ++i)
3393 Idxs[i + Imm * SrcNumElts] = i + DstNumElts;
3394 Rep = Builder.CreateShuffleVector(Op0, Rep, Idxs);
3400 }
else if (Name.starts_with(
"avx.vextractf128.") ||
3401 Name ==
"avx2.vextracti128" ||
3402 Name.starts_with(
"avx512.mask.vextract")) {
3405 unsigned DstNumElts =
3407 unsigned SrcNumElts =
3409 unsigned Scale = SrcNumElts / DstNumElts;
3416 for (
unsigned i = 0; i != DstNumElts; ++i) {
3417 Idxs[i] = i + (Imm * DstNumElts);
3419 Rep = Builder.CreateShuffleVector(Op0, Op0, Idxs);
3425 }
else if (Name.starts_with(
"avx512.mask.perm.df.") ||
3426 Name.starts_with(
"avx512.mask.perm.di.")) {
3430 unsigned NumElts = VecTy->getNumElements();
3433 for (
unsigned i = 0; i != NumElts; ++i)
3434 Idxs[i] = (i & ~0x3) + ((Imm >> (2 * (i & 0x3))) & 3);
3436 Rep = Builder.CreateShuffleVector(Op0, Op0, Idxs);
3441 }
else if (Name.starts_with(
"avx.vperm2f128.") || Name ==
"avx2.vperm2i128") {
3453 unsigned HalfSize = NumElts / 2;
3465 unsigned StartIndex = (Imm & 0x01) ? HalfSize : 0;
3466 for (
unsigned i = 0; i < HalfSize; ++i)
3467 ShuffleMask[i] = StartIndex + i;
3470 StartIndex = (Imm & 0x10) ? HalfSize : 0;
3471 for (
unsigned i = 0; i < HalfSize; ++i)
3472 ShuffleMask[i + HalfSize] = NumElts + StartIndex + i;
3474 Rep = Builder.CreateShuffleVector(V0, V1, ShuffleMask);
3476 }
else if (Name.starts_with(
"avx.vpermil.") || Name ==
"sse2.pshuf.d" ||
3477 Name.starts_with(
"avx512.mask.vpermil.p") ||
3478 Name.starts_with(
"avx512.mask.pshuf.d.")) {
3482 unsigned NumElts = VecTy->getNumElements();
3484 unsigned IdxSize = 64 / VecTy->getScalarSizeInBits();
3485 unsigned IdxMask = ((1 << IdxSize) - 1);
3491 for (
unsigned i = 0; i != NumElts; ++i)
3492 Idxs[i] = ((Imm >> ((i * IdxSize) % 8)) & IdxMask) | (i & ~IdxMask);
3494 Rep = Builder.CreateShuffleVector(Op0, Op0, Idxs);
3499 }
else if (Name ==
"sse2.pshufl.w" ||
3500 Name.starts_with(
"avx512.mask.pshufl.w.")) {
3506 for (
unsigned l = 0; l != NumElts; l += 8) {
3507 for (
unsigned i = 0; i != 4; ++i)
3508 Idxs[i + l] = ((Imm >> (2 * i)) & 0x3) + l;
3509 for (
unsigned i = 4; i != 8; ++i)
3510 Idxs[i + l] = i + l;
3513 Rep = Builder.CreateShuffleVector(Op0, Op0, Idxs);
3518 }
else if (Name ==
"sse2.pshufh.w" ||
3519 Name.starts_with(
"avx512.mask.pshufh.w.")) {
3525 for (
unsigned l = 0; l != NumElts; l += 8) {
3526 for (
unsigned i = 0; i != 4; ++i)
3527 Idxs[i + l] = i + l;
3528 for (
unsigned i = 0; i != 4; ++i)
3529 Idxs[i + l + 4] = ((Imm >> (2 * i)) & 0x3) + 4 + l;
3532 Rep = Builder.CreateShuffleVector(Op0, Op0, Idxs);
3537 }
else if (Name.starts_with(
"avx512.mask.shuf.p")) {
3544 unsigned HalfLaneElts = NumLaneElts / 2;
3547 for (
unsigned i = 0; i != NumElts; ++i) {
3549 Idxs[i] = i - (i % NumLaneElts);
3551 if ((i % NumLaneElts) >= HalfLaneElts)
3555 Idxs[i] += (Imm >> ((i * HalfLaneElts) % 8)) & ((1 << HalfLaneElts) - 1);
3558 Rep = Builder.CreateShuffleVector(Op0, Op1, Idxs);
3562 }
else if (Name.starts_with(
"avx512.mask.movddup") ||
3563 Name.starts_with(
"avx512.mask.movshdup") ||
3564 Name.starts_with(
"avx512.mask.movsldup")) {
3570 if (Name.starts_with(
"avx512.mask.movshdup."))
3574 for (
unsigned l = 0; l != NumElts; l += NumLaneElts)
3575 for (
unsigned i = 0; i != NumLaneElts; i += 2) {
3576 Idxs[i + l + 0] = i + l +
Offset;
3577 Idxs[i + l + 1] = i + l +
Offset;
3580 Rep = Builder.CreateShuffleVector(Op0, Op0, Idxs);
3584 }
else if (Name.starts_with(
"avx512.mask.punpckl") ||
3585 Name.starts_with(
"avx512.mask.unpckl.")) {
3592 for (
int l = 0; l != NumElts; l += NumLaneElts)
3593 for (
int i = 0; i != NumLaneElts; ++i)
3594 Idxs[i + l] = l + (i / 2) + NumElts * (i % 2);
3596 Rep = Builder.CreateShuffleVector(Op0, Op1, Idxs);
3600 }
else if (Name.starts_with(
"avx512.mask.punpckh") ||
3601 Name.starts_with(
"avx512.mask.unpckh.")) {
3608 for (
int l = 0; l != NumElts; l += NumLaneElts)
3609 for (
int i = 0; i != NumLaneElts; ++i)
3610 Idxs[i + l] = (NumLaneElts / 2) + l + (i / 2) + NumElts * (i % 2);
3612 Rep = Builder.CreateShuffleVector(Op0, Op1, Idxs);
3616 }
else if (Name.starts_with(
"avx512.mask.and.") ||
3617 Name.starts_with(
"avx512.mask.pand.")) {
3620 Rep = Builder.CreateAnd(Builder.CreateBitCast(CI->
getArgOperand(0), ITy),
3622 Rep = Builder.CreateBitCast(Rep, FTy);
3625 }
else if (Name.starts_with(
"avx512.mask.andn.") ||
3626 Name.starts_with(
"avx512.mask.pandn.")) {
3629 Rep = Builder.CreateNot(Builder.CreateBitCast(CI->
getArgOperand(0), ITy));
3630 Rep = Builder.CreateAnd(Rep,
3632 Rep = Builder.CreateBitCast(Rep, FTy);
3635 }
else if (Name.starts_with(
"avx512.mask.or.") ||
3636 Name.starts_with(
"avx512.mask.por.")) {
3639 Rep = Builder.CreateOr(Builder.CreateBitCast(CI->
getArgOperand(0), ITy),
3641 Rep = Builder.CreateBitCast(Rep, FTy);
3644 }
else if (Name.starts_with(
"avx512.mask.xor.") ||
3645 Name.starts_with(
"avx512.mask.pxor.")) {
3648 Rep = Builder.CreateXor(Builder.CreateBitCast(CI->
getArgOperand(0), ITy),
3650 Rep = Builder.CreateBitCast(Rep, FTy);
3653 }
else if (Name.starts_with(
"avx512.mask.padd.")) {
3657 }
else if (Name.starts_with(
"avx512.mask.psub.")) {
3661 }
else if (Name.starts_with(
"avx512.mask.pmull.")) {
3665 }
else if (Name.starts_with(
"avx512.mask.add.p")) {
3666 if (Name.ends_with(
".512")) {
3668 if (Name[17] ==
's')
3669 IID = Intrinsic::x86_avx512_add_ps_512;
3671 IID = Intrinsic::x86_avx512_add_pd_512;
3673 Rep = Builder.CreateIntrinsic(
3681 }
else if (Name.starts_with(
"avx512.mask.div.p")) {
3682 if (Name.ends_with(
".512")) {
3684 if (Name[17] ==
's')
3685 IID = Intrinsic::x86_avx512_div_ps_512;
3687 IID = Intrinsic::x86_avx512_div_pd_512;
3689 Rep = Builder.CreateIntrinsic(
3697 }
else if (Name.starts_with(
"avx512.mask.mul.p")) {
3698 if (Name.ends_with(
".512")) {
3700 if (Name[17] ==
's')
3701 IID = Intrinsic::x86_avx512_mul_ps_512;
3703 IID = Intrinsic::x86_avx512_mul_pd_512;
3705 Rep = Builder.CreateIntrinsic(
3713 }
else if (Name.starts_with(
"avx512.mask.sub.p")) {
3714 if (Name.ends_with(
".512")) {
3716 if (Name[17] ==
's')
3717 IID = Intrinsic::x86_avx512_sub_ps_512;
3719 IID = Intrinsic::x86_avx512_sub_pd_512;
3721 Rep = Builder.CreateIntrinsic(
3729 }
else if ((Name.starts_with(
"avx512.mask.max.p") ||
3730 Name.starts_with(
"avx512.mask.min.p")) &&
3731 Name.drop_front(18) ==
".512") {
3732 bool IsDouble = Name[17] ==
'd';
3733 bool IsMin = Name[13] ==
'i';
3735 {Intrinsic::x86_avx512_max_ps_512, Intrinsic::x86_avx512_max_pd_512},
3736 {Intrinsic::x86_avx512_min_ps_512, Intrinsic::x86_avx512_min_pd_512}};
3739 Rep = Builder.CreateIntrinsic(
3744 }
else if (Name.starts_with(
"avx512.mask.lzcnt.")) {
3746 Builder.CreateIntrinsic(Intrinsic::ctlz, CI->
getType(),
3747 {CI->getArgOperand(0), Builder.getInt1(false)});
3750 }
else if (Name.starts_with(
"avx512.mask.psll")) {
3751 bool IsImmediate = Name[16] ==
'i' || (Name.size() > 18 && Name[18] ==
'i');
3752 bool IsVariable = Name[16] ==
'v';
3753 char Size = Name[16] ==
'.' ? Name[17]
3754 : Name[17] ==
'.' ? Name[18]
3755 : Name[18] ==
'.' ? Name[19]
3759 if (IsVariable && Name[17] !=
'.') {
3760 if (
Size ==
'd' && Name[17] ==
'2')
3761 IID = Intrinsic::x86_avx2_psllv_q;
3762 else if (
Size ==
'd' && Name[17] ==
'4')
3763 IID = Intrinsic::x86_avx2_psllv_q_256;
3764 else if (
Size ==
's' && Name[17] ==
'4')
3765 IID = Intrinsic::x86_avx2_psllv_d;
3766 else if (
Size ==
's' && Name[17] ==
'8')
3767 IID = Intrinsic::x86_avx2_psllv_d_256;
3768 else if (
Size ==
'h' && Name[17] ==
'8')
3769 IID = Intrinsic::x86_avx512_psllv_w_128;
3770 else if (
Size ==
'h' && Name[17] ==
'1')
3771 IID = Intrinsic::x86_avx512_psllv_w_256;
3772 else if (Name[17] ==
'3' && Name[18] ==
'2')
3773 IID = Intrinsic::x86_avx512_psllv_w_512;
3776 }
else if (Name.ends_with(
".128")) {
3778 IID = IsImmediate ? Intrinsic::x86_sse2_pslli_d
3779 : Intrinsic::x86_sse2_psll_d;
3780 else if (
Size ==
'q')
3781 IID = IsImmediate ? Intrinsic::x86_sse2_pslli_q
3782 : Intrinsic::x86_sse2_psll_q;
3783 else if (
Size ==
'w')
3784 IID = IsImmediate ? Intrinsic::x86_sse2_pslli_w
3785 : Intrinsic::x86_sse2_psll_w;
3788 }
else if (Name.ends_with(
".256")) {
3790 IID = IsImmediate ? Intrinsic::x86_avx2_pslli_d
3791 : Intrinsic::x86_avx2_psll_d;
3792 else if (
Size ==
'q')
3793 IID = IsImmediate ? Intrinsic::x86_avx2_pslli_q
3794 : Intrinsic::x86_avx2_psll_q;
3795 else if (
Size ==
'w')
3796 IID = IsImmediate ? Intrinsic::x86_avx2_pslli_w
3797 : Intrinsic::x86_avx2_psll_w;
3802 IID = IsImmediate ? Intrinsic::x86_avx512_pslli_d_512
3803 : IsVariable ? Intrinsic::x86_avx512_psllv_d_512
3804 : Intrinsic::x86_avx512_psll_d_512;
3805 else if (
Size ==
'q')
3806 IID = IsImmediate ? Intrinsic::x86_avx512_pslli_q_512
3807 : IsVariable ? Intrinsic::x86_avx512_psllv_q_512
3808 : Intrinsic::x86_avx512_psll_q_512;
3809 else if (
Size ==
'w')
3810 IID = IsImmediate ? Intrinsic::x86_avx512_pslli_w_512
3811 : Intrinsic::x86_avx512_psll_w_512;
3817 }
else if (Name.starts_with(
"avx512.mask.psrl")) {
3818 bool IsImmediate = Name[16] ==
'i' || (Name.size() > 18 && Name[18] ==
'i');
3819 bool IsVariable = Name[16] ==
'v';
3820 char Size = Name[16] ==
'.' ? Name[17]
3821 : Name[17] ==
'.' ? Name[18]
3822 : Name[18] ==
'.' ? Name[19]
3826 if (IsVariable && Name[17] !=
'.') {
3827 if (
Size ==
'd' && Name[17] ==
'2')
3828 IID = Intrinsic::x86_avx2_psrlv_q;
3829 else if (
Size ==
'd' && Name[17] ==
'4')
3830 IID = Intrinsic::x86_avx2_psrlv_q_256;
3831 else if (
Size ==
's' && Name[17] ==
'4')
3832 IID = Intrinsic::x86_avx2_psrlv_d;
3833 else if (
Size ==
's' && Name[17] ==
'8')
3834 IID = Intrinsic::x86_avx2_psrlv_d_256;
3835 else if (
Size ==
'h' && Name[17] ==
'8')
3836 IID = Intrinsic::x86_avx512_psrlv_w_128;
3837 else if (
Size ==
'h' && Name[17] ==
'1')
3838 IID = Intrinsic::x86_avx512_psrlv_w_256;
3839 else if (Name[17] ==
'3' && Name[18] ==
'2')
3840 IID = Intrinsic::x86_avx512_psrlv_w_512;
3843 }
else if (Name.ends_with(
".128")) {
3845 IID = IsImmediate ? Intrinsic::x86_sse2_psrli_d
3846 : Intrinsic::x86_sse2_psrl_d;
3847 else if (
Size ==
'q')
3848 IID = IsImmediate ? Intrinsic::x86_sse2_psrli_q
3849 : Intrinsic::x86_sse2_psrl_q;
3850 else if (
Size ==
'w')
3851 IID = IsImmediate ? Intrinsic::x86_sse2_psrli_w
3852 : Intrinsic::x86_sse2_psrl_w;
3855 }
else if (Name.ends_with(
".256")) {
3857 IID = IsImmediate ? Intrinsic::x86_avx2_psrli_d
3858 : Intrinsic::x86_avx2_psrl_d;
3859 else if (
Size ==
'q')
3860 IID = IsImmediate ? Intrinsic::x86_avx2_psrli_q
3861 : Intrinsic::x86_avx2_psrl_q;
3862 else if (
Size ==
'w')
3863 IID = IsImmediate ? Intrinsic::x86_avx2_psrli_w
3864 : Intrinsic::x86_avx2_psrl_w;
3869 IID = IsImmediate ? Intrinsic::x86_avx512_psrli_d_512
3870 : IsVariable ? Intrinsic::x86_avx512_psrlv_d_512
3871 : Intrinsic::x86_avx512_psrl_d_512;
3872 else if (
Size ==
'q')
3873 IID = IsImmediate ? Intrinsic::x86_avx512_psrli_q_512
3874 : IsVariable ? Intrinsic::x86_avx512_psrlv_q_512
3875 : Intrinsic::x86_avx512_psrl_q_512;
3876 else if (
Size ==
'w')
3877 IID = IsImmediate ? Intrinsic::x86_avx512_psrli_w_512
3878 : Intrinsic::x86_avx512_psrl_w_512;
3884 }
else if (Name.starts_with(
"avx512.mask.psra")) {
3885 bool IsImmediate = Name[16] ==
'i' || (Name.size() > 18 && Name[18] ==
'i');
3886 bool IsVariable = Name[16] ==
'v';
3887 char Size = Name[16] ==
'.' ? Name[17]
3888 : Name[17] ==
'.' ? Name[18]
3889 : Name[18] ==
'.' ? Name[19]
3893 if (IsVariable && Name[17] !=
'.') {
3894 if (
Size ==
's' && Name[17] ==
'4')
3895 IID = Intrinsic::x86_avx2_psrav_d;
3896 else if (
Size ==
's' && Name[17] ==
'8')
3897 IID = Intrinsic::x86_avx2_psrav_d_256;
3898 else if (
Size ==
'h' && Name[17] ==
'8')
3899 IID = Intrinsic::x86_avx512_psrav_w_128;
3900 else if (
Size ==
'h' && Name[17] ==
'1')
3901 IID = Intrinsic::x86_avx512_psrav_w_256;
3902 else if (Name[17] ==
'3' && Name[18] ==
'2')
3903 IID = Intrinsic::x86_avx512_psrav_w_512;
3906 }
else if (Name.ends_with(
".128")) {
3908 IID = IsImmediate ? Intrinsic::x86_sse2_psrai_d
3909 : Intrinsic::x86_sse2_psra_d;
3910 else if (
Size ==
'q')
3911 IID = IsImmediate ? Intrinsic::x86_avx512_psrai_q_128
3912 : IsVariable ? Intrinsic::x86_avx512_psrav_q_128
3913 : Intrinsic::x86_avx512_psra_q_128;
3914 else if (
Size ==
'w')
3915 IID = IsImmediate ? Intrinsic::x86_sse2_psrai_w
3916 : Intrinsic::x86_sse2_psra_w;
3919 }
else if (Name.ends_with(
".256")) {
3921 IID = IsImmediate ? Intrinsic::x86_avx2_psrai_d
3922 : Intrinsic::x86_avx2_psra_d;
3923 else if (
Size ==
'q')
3924 IID = IsImmediate ? Intrinsic::x86_avx512_psrai_q_256
3925 : IsVariable ? Intrinsic::x86_avx512_psrav_q_256
3926 : Intrinsic::x86_avx512_psra_q_256;
3927 else if (
Size ==
'w')
3928 IID = IsImmediate ? Intrinsic::x86_avx2_psrai_w
3929 : Intrinsic::x86_avx2_psra_w;
3934 IID = IsImmediate ? Intrinsic::x86_avx512_psrai_d_512
3935 : IsVariable ? Intrinsic::x86_avx512_psrav_d_512
3936 : Intrinsic::x86_avx512_psra_d_512;
3937 else if (
Size ==
'q')
3938 IID = IsImmediate ? Intrinsic::x86_avx512_psrai_q_512
3939 : IsVariable ? Intrinsic::x86_avx512_psrav_q_512
3940 : Intrinsic::x86_avx512_psra_q_512;
3941 else if (
Size ==
'w')
3942 IID = IsImmediate ? Intrinsic::x86_avx512_psrai_w_512
3943 : Intrinsic::x86_avx512_psra_w_512;
3949 }
else if (Name.starts_with(
"avx512.mask.move.s")) {
3951 }
else if (Name.starts_with(
"avx512.cvtmask2")) {
3953 }
else if (Name.ends_with(
".movntdqa")) {
3957 LoadInst *LI = Builder.CreateAlignedLoad(
3962 }
else if (Name.starts_with(
"fma.vfmadd.") ||
3963 Name.starts_with(
"fma.vfmsub.") ||
3964 Name.starts_with(
"fma.vfnmadd.") ||
3965 Name.starts_with(
"fma.vfnmsub.")) {
3966 bool NegMul = Name[6] ==
'n';
3967 bool NegAcc = NegMul ? Name[8] ==
's' : Name[7] ==
's';
3968 bool IsScalar = NegMul ? Name[12] ==
's' : Name[11] ==
's';
3979 if (NegMul && !IsScalar)
3980 Ops[0] = Builder.CreateFNeg(
Ops[0]);
3981 if (NegMul && IsScalar)
3982 Ops[1] = Builder.CreateFNeg(
Ops[1]);
3984 Ops[2] = Builder.CreateFNeg(
Ops[2]);
3986 Rep = Builder.CreateIntrinsic(Intrinsic::fma,
Ops[0]->
getType(),
Ops);
3990 }
else if (Name.starts_with(
"fma4.vfmadd.s")) {
3998 Rep = Builder.CreateIntrinsic(Intrinsic::fma,
Ops[0]->
getType(),
Ops);
4002 }
else if (Name.starts_with(
"avx512.mask.vfmadd.s") ||
4003 Name.starts_with(
"avx512.maskz.vfmadd.s") ||
4004 Name.starts_with(
"avx512.mask3.vfmadd.s") ||
4005 Name.starts_with(
"avx512.mask3.vfmsub.s") ||
4006 Name.starts_with(
"avx512.mask3.vfnmsub.s")) {
4007 bool IsMask3 = Name[11] ==
'3';
4008 bool IsMaskZ = Name[11] ==
'z';
4010 Name = Name.drop_front(IsMask3 || IsMaskZ ? 13 : 12);
4011 bool NegMul = Name[2] ==
'n';
4012 bool NegAcc = NegMul ? Name[4] ==
's' : Name[3] ==
's';
4018 if (NegMul && (IsMask3 || IsMaskZ))
4019 A = Builder.CreateFNeg(
A);
4020 if (NegMul && !(IsMask3 || IsMaskZ))
4021 B = Builder.CreateFNeg(
B);
4023 C = Builder.CreateFNeg(
C);
4025 A = Builder.CreateExtractElement(
A, (
uint64_t)0);
4026 B = Builder.CreateExtractElement(
B, (
uint64_t)0);
4027 C = Builder.CreateExtractElement(
C, (
uint64_t)0);
4034 if (Name.back() ==
'd')
4035 IID = Intrinsic::x86_avx512_vfmadd_f64;
4037 IID = Intrinsic::x86_avx512_vfmadd_f32;
4038 Rep = Builder.CreateIntrinsic(IID,
Ops);
4040 Rep = Builder.CreateFMA(
A,
B,
C);
4049 if (NegAcc && IsMask3)
4054 Rep = Builder.CreateInsertElement(CI->
getArgOperand(IsMask3 ? 2 : 0), Rep,
4056 }
else if (Name.starts_with(
"avx512.mask.vfmadd.p") ||
4057 Name.starts_with(
"avx512.mask.vfnmadd.p") ||
4058 Name.starts_with(
"avx512.mask.vfnmsub.p") ||
4059 Name.starts_with(
"avx512.mask3.vfmadd.p") ||
4060 Name.starts_with(
"avx512.mask3.vfmsub.p") ||
4061 Name.starts_with(
"avx512.mask3.vfnmsub.p") ||
4062 Name.starts_with(
"avx512.maskz.vfmadd.p")) {
4063 bool IsMask3 = Name[11] ==
'3';
4064 bool IsMaskZ = Name[11] ==
'z';
4066 Name = Name.drop_front(IsMask3 || IsMaskZ ? 13 : 12);
4067 bool NegMul = Name[2] ==
'n';
4068 bool NegAcc = NegMul ? Name[4] ==
's' : Name[3] ==
's';
4074 if (NegMul && (IsMask3 || IsMaskZ))
4075 A = Builder.CreateFNeg(
A);
4076 if (NegMul && !(IsMask3 || IsMaskZ))
4077 B = Builder.CreateFNeg(
B);
4079 C = Builder.CreateFNeg(
C);
4086 if (Name[Name.size() - 5] ==
's')
4087 IID = Intrinsic::x86_avx512_vfmadd_ps_512;
4089 IID = Intrinsic::x86_avx512_vfmadd_pd_512;
4093 Rep = Builder.CreateFMA(
A,
B,
C);
4101 }
else if (Name.starts_with(
"fma.vfmsubadd.p")) {
4105 if (VecWidth == 128 && EltWidth == 32)
4106 IID = Intrinsic::x86_fma_vfmaddsub_ps;
4107 else if (VecWidth == 256 && EltWidth == 32)
4108 IID = Intrinsic::x86_fma_vfmaddsub_ps_256;
4109 else if (VecWidth == 128 && EltWidth == 64)
4110 IID = Intrinsic::x86_fma_vfmaddsub_pd;
4111 else if (VecWidth == 256 && EltWidth == 64)
4112 IID = Intrinsic::x86_fma_vfmaddsub_pd_256;
4118 Ops[2] = Builder.CreateFNeg(
Ops[2]);
4119 Rep = Builder.CreateIntrinsic(IID,
Ops);
4120 }
else if (Name.starts_with(
"avx512.mask.vfmaddsub.p") ||
4121 Name.starts_with(
"avx512.mask3.vfmaddsub.p") ||
4122 Name.starts_with(
"avx512.maskz.vfmaddsub.p") ||
4123 Name.starts_with(
"avx512.mask3.vfmsubadd.p")) {
4124 bool IsMask3 = Name[11] ==
'3';
4125 bool IsMaskZ = Name[11] ==
'z';
4127 Name = Name.drop_front(IsMask3 || IsMaskZ ? 13 : 12);
4128 bool IsSubAdd = Name[3] ==
's';
4132 if (Name[Name.size() - 5] ==
's')
4133 IID = Intrinsic::x86_avx512_vfmaddsub_ps_512;
4135 IID = Intrinsic::x86_avx512_vfmaddsub_pd_512;
4140 Ops[2] = Builder.CreateFNeg(
Ops[2]);
4142 Rep = Builder.CreateIntrinsic(IID,
Ops);
4151 Value *Odd = Builder.CreateCall(FMA,
Ops);
4152 Ops[2] = Builder.CreateFNeg(
Ops[2]);
4153 Value *Even = Builder.CreateCall(FMA,
Ops);
4159 for (
int i = 0; i != NumElts; ++i)
4160 Idxs[i] = i + (i % 2) * NumElts;
4162 Rep = Builder.CreateShuffleVector(Even, Odd, Idxs);
4170 }
else if (Name.starts_with(
"avx512.mask.pternlog.") ||
4171 Name.starts_with(
"avx512.maskz.pternlog.")) {
4172 bool ZeroMask = Name[11] ==
'z';
4176 if (VecWidth == 128 && EltWidth == 32)
4177 IID = Intrinsic::x86_avx512_pternlog_d_128;
4178 else if (VecWidth == 256 && EltWidth == 32)
4179 IID = Intrinsic::x86_avx512_pternlog_d_256;
4180 else if (VecWidth == 512 && EltWidth == 32)
4181 IID = Intrinsic::x86_avx512_pternlog_d_512;
4182 else if (VecWidth == 128 && EltWidth == 64)
4183 IID = Intrinsic::x86_avx512_pternlog_q_128;
4184 else if (VecWidth == 256 && EltWidth == 64)
4185 IID = Intrinsic::x86_avx512_pternlog_q_256;
4186 else if (VecWidth == 512 && EltWidth == 64)
4187 IID = Intrinsic::x86_avx512_pternlog_q_512;
4193 Rep = Builder.CreateIntrinsic(IID, Args);
4197 }
else if (Name.starts_with(
"avx512.mask.vpmadd52") ||
4198 Name.starts_with(
"avx512.maskz.vpmadd52")) {
4199 bool ZeroMask = Name[11] ==
'z';
4200 bool High = Name[20] ==
'h' || Name[21] ==
'h';
4203 if (VecWidth == 128 && !
High)
4204 IID = Intrinsic::x86_avx512_vpmadd52l_uq_128;
4205 else if (VecWidth == 256 && !
High)
4206 IID = Intrinsic::x86_avx512_vpmadd52l_uq_256;
4207 else if (VecWidth == 512 && !
High)
4208 IID = Intrinsic::x86_avx512_vpmadd52l_uq_512;
4209 else if (VecWidth == 128 &&
High)
4210 IID = Intrinsic::x86_avx512_vpmadd52h_uq_128;
4211 else if (VecWidth == 256 &&
High)
4212 IID = Intrinsic::x86_avx512_vpmadd52h_uq_256;
4213 else if (VecWidth == 512 &&
High)
4214 IID = Intrinsic::x86_avx512_vpmadd52h_uq_512;
4220 Rep = Builder.CreateIntrinsic(IID, Args);
4224 }
else if (Name.starts_with(
"avx512.mask.vpermi2var.") ||
4225 Name.starts_with(
"avx512.mask.vpermt2var.") ||
4226 Name.starts_with(
"avx512.maskz.vpermt2var.")) {
4227 bool ZeroMask = Name[11] ==
'z';
4228 bool IndexForm = Name[17] ==
'i';
4230 }
else if (Name.starts_with(
"avx512.mask.vpdpbusd.") ||
4231 Name.starts_with(
"avx512.maskz.vpdpbusd.") ||
4232 Name.starts_with(
"avx512.mask.vpdpbusds.") ||
4233 Name.starts_with(
"avx512.maskz.vpdpbusds.")) {
4234 bool ZeroMask = Name[11] ==
'z';
4235 bool IsSaturating = Name[ZeroMask ? 21 : 20] ==
's';
4238 if (VecWidth == 128 && !IsSaturating)
4239 IID = Intrinsic::x86_avx512_vpdpbusd_128;
4240 else if (VecWidth == 256 && !IsSaturating)
4241 IID = Intrinsic::x86_avx512_vpdpbusd_256;
4242 else if (VecWidth == 512 && !IsSaturating)
4243 IID = Intrinsic::x86_avx512_vpdpbusd_512;
4244 else if (VecWidth == 128 && IsSaturating)
4245 IID = Intrinsic::x86_avx512_vpdpbusds_128;
4246 else if (VecWidth == 256 && IsSaturating)
4247 IID = Intrinsic::x86_avx512_vpdpbusds_256;
4248 else if (VecWidth == 512 && IsSaturating)
4249 IID = Intrinsic::x86_avx512_vpdpbusds_512;
4259 if (Args[1]->
getType()->isVectorTy() &&
4262 ->isIntegerTy(32) &&
4263 Args[2]->
getType()->isVectorTy() &&
4266 ->isIntegerTy(32)) {
4267 Type *NewArgType =
nullptr;
4268 if (VecWidth == 128)
4270 else if (VecWidth == 256)
4272 else if (VecWidth == 512)
4277 Args[1] = Builder.CreateBitCast(Args[1], NewArgType);
4278 Args[2] = Builder.CreateBitCast(Args[2], NewArgType);
4281 Rep = Builder.CreateIntrinsic(IID, Args);
4285 }
else if (Name.starts_with(
"avx512.mask.vpdpwssd.") ||
4286 Name.starts_with(
"avx512.maskz.vpdpwssd.") ||
4287 Name.starts_with(
"avx512.mask.vpdpwssds.") ||
4288 Name.starts_with(
"avx512.maskz.vpdpwssds.")) {
4289 bool ZeroMask = Name[11] ==
'z';
4290 bool IsSaturating = Name[ZeroMask ? 21 : 20] ==
's';
4293 if (VecWidth == 128 && !IsSaturating)
4294 IID = Intrinsic::x86_avx512_vpdpwssd_128;
4295 else if (VecWidth == 256 && !IsSaturating)
4296 IID = Intrinsic::x86_avx512_vpdpwssd_256;
4297 else if (VecWidth == 512 && !IsSaturating)
4298 IID = Intrinsic::x86_avx512_vpdpwssd_512;
4299 else if (VecWidth == 128 && IsSaturating)
4300 IID = Intrinsic::x86_avx512_vpdpwssds_128;
4301 else if (VecWidth == 256 && IsSaturating)
4302 IID = Intrinsic::x86_avx512_vpdpwssds_256;
4303 else if (VecWidth == 512 && IsSaturating)
4304 IID = Intrinsic::x86_avx512_vpdpwssds_512;
4310 Rep = Builder.CreateIntrinsic(IID, Args);
4314 }
else if (Name ==
"addcarryx.u32" || Name ==
"addcarryx.u64" ||
4315 Name ==
"addcarry.u32" || Name ==
"addcarry.u64" ||
4316 Name ==
"subborrow.u32" || Name ==
"subborrow.u64") {
4318 if (Name[0] ==
'a' && Name.back() ==
'2')
4319 IID = Intrinsic::x86_addcarry_32;
4320 else if (Name[0] ==
'a' && Name.back() ==
'4')
4321 IID = Intrinsic::x86_addcarry_64;
4322 else if (Name[0] ==
's' && Name.back() ==
'2')
4323 IID = Intrinsic::x86_subborrow_32;
4324 else if (Name[0] ==
's' && Name.back() ==
'4')
4325 IID = Intrinsic::x86_subborrow_64;
4332 Value *NewCall = Builder.CreateIntrinsic(IID, Args);
4335 Value *
Data = Builder.CreateExtractValue(NewCall, 1);
4338 Value *CF = Builder.CreateExtractValue(NewCall, 0);
4342 }
else if (Name.starts_with(
"avx512.mask.") &&
4352 if (Name.starts_with(
"neon.bfcvt")) {
4353 if (Name.starts_with(
"neon.bfcvtn2")) {
4355 std::iota(LoMask.
begin(), LoMask.
end(), 0);
4357 std::iota(ConcatMask.
begin(), ConcatMask.
end(), 0);
4358 Value *Inactive = Builder.CreateShuffleVector(CI->
getOperand(0), LoMask);
4361 return Builder.CreateShuffleVector(Inactive, Trunc, ConcatMask);
4362 }
else if (Name.starts_with(
"neon.bfcvtn")) {
4364 std::iota(ConcatMask.
begin(), ConcatMask.
end(), 0);
4368 dbgs() <<
"Trunc: " << *Trunc <<
"\n";
4369 return Builder.CreateShuffleVector(
4372 return Builder.CreateFPTrunc(CI->
getOperand(0),
4375 }
else if (Name.starts_with(
"sve.fcvt")) {
4378 .
Case(
"sve.fcvt.bf16f32", Intrinsic::aarch64_sve_fcvt_bf16f32_v2)
4379 .
Case(
"sve.fcvtnt.bf16f32",
4380 Intrinsic::aarch64_sve_fcvtnt_bf16f32_v2)
4392 if (Args[1]->
getType() != BadPredTy)
4395 Args[1] = Builder.CreateIntrinsic(Intrinsic::aarch64_sve_convert_to_svbool,
4396 BadPredTy, Args[1]);
4397 Args[1] = Builder.CreateIntrinsic(
4398 Intrinsic::aarch64_sve_convert_from_svbool, GoodPredTy, Args[1]);
4400 return Builder.CreateIntrinsic(NewID, Args,
nullptr,
4409 if (Name ==
"mve.vctp64.old") {
4412 Value *VCTP = Builder.CreateIntrinsic(Intrinsic::arm_mve_vctp64, {},
4415 Value *C1 = Builder.CreateIntrinsic(
4416 Intrinsic::arm_mve_pred_v2i,
4418 return Builder.CreateIntrinsic(
4419 Intrinsic::arm_mve_pred_i2v,
4421 }
else if (Name ==
"mve.mull.int.predicated.v2i64.v4i32.v4i1" ||
4422 Name ==
"mve.vqdmull.predicated.v2i64.v4i32.v4i1" ||
4423 Name ==
"mve.vldr.gather.base.predicated.v2i64.v2i64.v4i1" ||
4424 Name ==
"mve.vldr.gather.base.wb.predicated.v2i64.v2i64.v4i1" ||
4426 "mve.vldr.gather.offset.predicated.v2i64.p0i64.v2i64.v4i1" ||
4427 Name ==
"mve.vldr.gather.offset.predicated.v2i64.p0.v2i64.v4i1" ||
4428 Name ==
"mve.vstr.scatter.base.predicated.v2i64.v2i64.v4i1" ||
4429 Name ==
"mve.vstr.scatter.base.wb.predicated.v2i64.v2i64.v4i1" ||
4431 "mve.vstr.scatter.offset.predicated.p0i64.v2i64.v2i64.v4i1" ||
4432 Name ==
"mve.vstr.scatter.offset.predicated.p0.v2i64.v2i64.v4i1" ||
4433 Name ==
"cde.vcx1q.predicated.v2i64.v4i1" ||
4434 Name ==
"cde.vcx1qa.predicated.v2i64.v4i1" ||
4435 Name ==
"cde.vcx2q.predicated.v2i64.v4i1" ||
4436 Name ==
"cde.vcx2qa.predicated.v2i64.v4i1" ||
4437 Name ==
"cde.vcx3q.predicated.v2i64.v4i1" ||
4438 Name ==
"cde.vcx3qa.predicated.v2i64.v4i1") {
4439 std::vector<Type *> Tys;
4443 case Intrinsic::arm_mve_mull_int_predicated:
4444 case Intrinsic::arm_mve_vqdmull_predicated:
4445 case Intrinsic::arm_mve_vldr_gather_base_predicated:
4448 case Intrinsic::arm_mve_vldr_gather_base_wb_predicated:
4449 case Intrinsic::arm_mve_vstr_scatter_base_predicated:
4450 case Intrinsic::arm_mve_vstr_scatter_base_wb_predicated:
4454 case Intrinsic::arm_mve_vldr_gather_offset_predicated:
4458 case Intrinsic::arm_mve_vstr_scatter_offset_predicated:
4462 case Intrinsic::arm_cde_vcx1q_predicated:
4463 case Intrinsic::arm_cde_vcx1qa_predicated:
4464 case Intrinsic::arm_cde_vcx2q_predicated:
4465 case Intrinsic::arm_cde_vcx2qa_predicated:
4466 case Intrinsic::arm_cde_vcx3q_predicated:
4467 case Intrinsic::arm_cde_vcx3qa_predicated:
4474 std::vector<Value *>
Ops;
4476 Type *Ty =
Op->getType();
4477 if (Ty->getScalarSizeInBits() == 1) {
4478 Value *C1 = Builder.CreateIntrinsic(
4479 Intrinsic::arm_mve_pred_v2i,
4481 Op = Builder.CreateIntrinsic(Intrinsic::arm_mve_pred_i2v, {V2I1Ty}, C1);
4486 return Builder.CreateIntrinsic(
ID, Tys,
Ops,
nullptr,
4514 if (NumOperands < 3)
4527 bool IsVolatile =
false;
4531 if (NumOperands > 3)
4536 if (NumOperands > 5) {
4538 IsVolatile = !VolatileArg || !VolatileArg->
isZero();
4552 if (VT->getElementType()->isIntegerTy(16)) {
4555 Val = Builder.CreateBitCast(Val, AsBF16);
4563 Builder.CreateAtomicRMW(RMWOp,
Ptr, Val, std::nullopt, Order, SSID);
4565 unsigned AddrSpace = PtrTy->getAddressSpace();
4568 RMW->
setMetadata(
"amdgpu.no.fine.grained.memory", EmptyMD);
4570 RMW->
setMetadata(
"amdgpu.ignore.denormal.mode", EmptyMD);
4575 MDNode *RangeNotPrivate =
4578 RMW->
setMetadata(LLVMContext::MD_noalias_addrspace, RangeNotPrivate);
4584 return Builder.CreateBitCast(RMW, RetTy);
4605 return MAV->getMetadata();
4612 return I->getDebugLoc().getAsMDNode();
4620 if (Name ==
"label") {
4623 }
else if (Name ==
"assign") {
4630 }
else if (Name ==
"declare") {
4635 }
else if (Name ==
"addr") {
4645 unwrapMAVOp(CI, 1), ExprNode,
nullptr,
nullptr,
nullptr,
4647 }
else if (Name ==
"value") {
4650 unsigned ExprOp = 2;
4664 assert(DR &&
"Unhandled intrinsic kind in upgrade to DbgRecord");
4686 assert(Name.starts_with(
"llvm.") &&
"Intrinsic doesn't start with 'llvm.'");
4687 Name = Name.substr(5);
4689 bool IsX86 = Name.consume_front(
"x86.");
4690 bool IsNVVM = Name.consume_front(
"nvvm.");
4691 bool IsAArch64 = Name.consume_front(
"aarch64.");
4692 bool IsARM = Name.consume_front(
"arm.");
4693 bool IsAMDGCN = Name.consume_front(
"amdgcn.");
4694 bool IsDbg = Name.consume_front(
"dbg.");
4695 Value *Rep =
nullptr;
4697 if (!IsX86 && Name ==
"stackprotectorcheck") {
4699 }
else if (IsNVVM) {
4703 }
else if (IsAArch64) {
4707 }
else if (IsAMDGCN) {
4721 const auto &DefaultCase = [&]() ->
void {
4729 "Unknown function for CallBase upgrade and isn't just a name change");
4737 "Return type must have changed");
4738 assert(OldST->getNumElements() ==
4740 "Must have same number of elements");
4743 CallInst *NewCI = Builder.CreateCall(NewFn, Args);
4746 for (
unsigned Idx = 0; Idx < OldST->getNumElements(); ++Idx) {
4747 Value *Elem = Builder.CreateExtractValue(NewCI, Idx);
4748 Res = Builder.CreateInsertValue(Res, Elem, Idx);
4767 case Intrinsic::arm_neon_vst1:
4768 case Intrinsic::arm_neon_vst2:
4769 case Intrinsic::arm_neon_vst3:
4770 case Intrinsic::arm_neon_vst4:
4771 case Intrinsic::arm_neon_vst2lane:
4772 case Intrinsic::arm_neon_vst3lane:
4773 case Intrinsic::arm_neon_vst4lane: {
4775 NewCall = Builder.CreateCall(NewFn, Args);
4778 case Intrinsic::aarch64_sve_bfmlalb_lane_v2:
4779 case Intrinsic::aarch64_sve_bfmlalt_lane_v2:
4780 case Intrinsic::aarch64_sve_bfdot_lane_v2: {
4785 NewCall = Builder.CreateCall(NewFn, Args);
4788 case Intrinsic::aarch64_sve_ld3_sret:
4789 case Intrinsic::aarch64_sve_ld4_sret:
4790 case Intrinsic::aarch64_sve_ld2_sret: {
4792 Name = Name.substr(5);
4799 unsigned MinElts = RetTy->getMinNumElements() /
N;
4801 Value *NewLdCall = Builder.CreateCall(NewFn, Args);
4803 for (
unsigned I = 0;
I <
N;
I++) {
4804 Value *SRet = Builder.CreateExtractValue(NewLdCall,
I);
4805 Ret = Builder.CreateInsertVector(RetTy, Ret, SRet,
I * MinElts);
4811 case Intrinsic::coro_end: {
4814 NewCall = Builder.CreateCall(NewFn, Args);
4818 case Intrinsic::vector_extract: {
4820 Name = Name.substr(5);
4821 if (!Name.starts_with(
"aarch64.sve.tuple.get")) {
4826 unsigned MinElts = RetTy->getMinNumElements();
4829 NewCall = Builder.CreateCall(NewFn, {CI->
getArgOperand(0), NewIdx});
4833 case Intrinsic::vector_insert: {
4835 Name = Name.substr(5);
4836 if (!Name.starts_with(
"aarch64.sve.tuple")) {
4840 if (Name.starts_with(
"aarch64.sve.tuple.set")) {
4845 NewCall = Builder.CreateCall(
4849 if (Name.starts_with(
"aarch64.sve.tuple.create")) {
4855 assert(
N > 1 &&
"Create is expected to be between 2-4");
4858 unsigned MinElts = RetTy->getMinNumElements() /
N;
4859 for (
unsigned I = 0;
I <
N;
I++) {
4861 Ret = Builder.CreateInsertVector(RetTy, Ret, V,
I * MinElts);
4868 case Intrinsic::arm_neon_bfdot:
4869 case Intrinsic::arm_neon_bfmmla:
4870 case Intrinsic::arm_neon_bfmlalb:
4871 case Intrinsic::arm_neon_bfmlalt:
4872 case Intrinsic::aarch64_neon_bfdot:
4873 case Intrinsic::aarch64_neon_bfmmla:
4874 case Intrinsic::aarch64_neon_bfmlalb:
4875 case Intrinsic::aarch64_neon_bfmlalt: {
4878 "Mismatch between function args and call args");
4879 size_t OperandWidth =
4881 assert((OperandWidth == 64 || OperandWidth == 128) &&
4882 "Unexpected operand width");
4884 auto Iter = CI->
args().begin();
4885 Args.push_back(*Iter++);
4886 Args.push_back(Builder.CreateBitCast(*Iter++, NewTy));
4887 Args.push_back(Builder.CreateBitCast(*Iter++, NewTy));
4888 NewCall = Builder.CreateCall(NewFn, Args);
4892 case Intrinsic::bitreverse:
4893 NewCall = Builder.CreateCall(NewFn, {CI->
getArgOperand(0)});
4896 case Intrinsic::ctlz:
4897 case Intrinsic::cttz:
4899 "Mismatch between function args and call args");
4901 Builder.CreateCall(NewFn, {CI->
getArgOperand(0), Builder.getFalse()});
4904 case Intrinsic::objectsize: {
4905 Value *NullIsUnknownSize =
4909 NewCall = Builder.CreateCall(
4914 case Intrinsic::ctpop:
4915 NewCall = Builder.CreateCall(NewFn, {CI->
getArgOperand(0)});
4918 case Intrinsic::convert_from_fp16:
4919 NewCall = Builder.CreateCall(NewFn, {CI->
getArgOperand(0)});
4922 case Intrinsic::dbg_value: {
4924 Name = Name.substr(5);
4926 if (Name.starts_with(
"dbg.addr")) {
4940 if (
Offset->isZeroValue()) {
4941 NewCall = Builder.CreateCall(
4950 case Intrinsic::ptr_annotation:
4958 NewCall = Builder.CreateCall(
4967 case Intrinsic::var_annotation:
4974 NewCall = Builder.CreateCall(
4983 case Intrinsic::riscv_aes32dsi:
4984 case Intrinsic::riscv_aes32dsmi:
4985 case Intrinsic::riscv_aes32esi:
4986 case Intrinsic::riscv_aes32esmi:
4987 case Intrinsic::riscv_sm4ks:
4988 case Intrinsic::riscv_sm4ed: {
4998 Arg0 = Builder.CreateTrunc(Arg0, Builder.getInt32Ty());
4999 Arg1 = Builder.CreateTrunc(Arg1, Builder.getInt32Ty());
5005 NewCall = Builder.CreateCall(NewFn, {Arg0, Arg1, Arg2});
5006 Value *Res = NewCall;
5008 Res = Builder.CreateIntCast(NewCall, CI->
getType(),
true);
5014 case Intrinsic::nvvm_mapa_shared_cluster: {
5018 Value *Res = NewCall;
5019 Res = Builder.CreateAddrSpaceCast(
5026 case Intrinsic::nvvm_cp_async_bulk_global_to_shared_cluster:
5027 case Intrinsic::nvvm_cp_async_bulk_shared_cta_to_cluster: {
5030 Args[0] = Builder.CreateAddrSpaceCast(
5033 NewCall = Builder.CreateCall(NewFn, Args);
5039 case Intrinsic::nvvm_cp_async_bulk_tensor_g2s_im2col_3d:
5040 case Intrinsic::nvvm_cp_async_bulk_tensor_g2s_im2col_4d:
5041 case Intrinsic::nvvm_cp_async_bulk_tensor_g2s_im2col_5d:
5042 case Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_1d:
5043 case Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_2d:
5044 case Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_3d:
5045 case Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_4d:
5046 case Intrinsic::nvvm_cp_async_bulk_tensor_g2s_tile_5d: {
5053 Args[0] = Builder.CreateAddrSpaceCast(
5062 Args.push_back(ConstantInt::get(Builder.getInt32Ty(), 0));
5064 NewCall = Builder.CreateCall(NewFn, Args);
5070 case Intrinsic::riscv_sha256sig0:
5071 case Intrinsic::riscv_sha256sig1:
5072 case Intrinsic::riscv_sha256sum0:
5073 case Intrinsic::riscv_sha256sum1:
5074 case Intrinsic::riscv_sm3p0:
5075 case Intrinsic::riscv_sm3p1: {
5082 Builder.CreateTrunc(CI->
getArgOperand(0), Builder.getInt32Ty());
5084 NewCall = Builder.CreateCall(NewFn, Arg);
5086 Builder.CreateIntCast(NewCall, CI->
getType(),
true);
5093 case Intrinsic::x86_xop_vfrcz_ss:
5094 case Intrinsic::x86_xop_vfrcz_sd:
5095 NewCall = Builder.CreateCall(NewFn, {CI->
getArgOperand(1)});
5098 case Intrinsic::x86_xop_vpermil2pd:
5099 case Intrinsic::x86_xop_vpermil2ps:
5100 case Intrinsic::x86_xop_vpermil2pd_256:
5101 case Intrinsic::x86_xop_vpermil2ps_256: {
5105 Args[2] = Builder.CreateBitCast(Args[2], IntIdxTy);
5106 NewCall = Builder.CreateCall(NewFn, Args);
5110 case Intrinsic::x86_sse41_ptestc:
5111 case Intrinsic::x86_sse41_ptestz:
5112 case Intrinsic::x86_sse41_ptestnzc: {
5126 Value *BC0 = Builder.CreateBitCast(Arg0, NewVecTy,
"cast");
5127 Value *BC1 = Builder.CreateBitCast(Arg1, NewVecTy,
"cast");
5129 NewCall = Builder.CreateCall(NewFn, {BC0, BC1});
5133 case Intrinsic::x86_rdtscp: {
5139 NewCall = Builder.CreateCall(NewFn);
5141 Value *
Data = Builder.CreateExtractValue(NewCall, 1);
5144 Value *TSC = Builder.CreateExtractValue(NewCall, 0);
5152 case Intrinsic::x86_sse41_insertps:
5153 case Intrinsic::x86_sse41_dppd:
5154 case Intrinsic::x86_sse41_dpps:
5155 case Intrinsic::x86_sse41_mpsadbw:
5156 case Intrinsic::x86_avx_dp_ps_256:
5157 case Intrinsic::x86_avx2_mpsadbw: {
5163 Args.back() = Builder.CreateTrunc(Args.back(),
Type::getInt8Ty(
C),
"trunc");
5164 NewCall = Builder.CreateCall(NewFn, Args);
5168 case Intrinsic::x86_avx512_mask_cmp_pd_128:
5169 case Intrinsic::x86_avx512_mask_cmp_pd_256:
5170 case Intrinsic::x86_avx512_mask_cmp_pd_512:
5171 case Intrinsic::x86_avx512_mask_cmp_ps_128:
5172 case Intrinsic::x86_avx512_mask_cmp_ps_256:
5173 case Intrinsic::x86_avx512_mask_cmp_ps_512: {
5179 NewCall = Builder.CreateCall(NewFn, Args);
5188 case Intrinsic::x86_avx512bf16_cvtne2ps2bf16_128:
5189 case Intrinsic::x86_avx512bf16_cvtne2ps2bf16_256:
5190 case Intrinsic::x86_avx512bf16_cvtne2ps2bf16_512:
5191 case Intrinsic::x86_avx512bf16_mask_cvtneps2bf16_128:
5192 case Intrinsic::x86_avx512bf16_cvtneps2bf16_256:
5193 case Intrinsic::x86_avx512bf16_cvtneps2bf16_512: {
5197 Intrinsic::x86_avx512bf16_mask_cvtneps2bf16_128)
5198 Args[1] = Builder.CreateBitCast(
5201 NewCall = Builder.CreateCall(NewFn, Args);
5202 Value *Res = Builder.CreateBitCast(
5210 case Intrinsic::x86_avx512bf16_dpbf16ps_128:
5211 case Intrinsic::x86_avx512bf16_dpbf16ps_256:
5212 case Intrinsic::x86_avx512bf16_dpbf16ps_512:{
5216 Args[1] = Builder.CreateBitCast(
5218 Args[2] = Builder.CreateBitCast(
5221 NewCall = Builder.CreateCall(NewFn, Args);
5225 case Intrinsic::thread_pointer: {
5226 NewCall = Builder.CreateCall(NewFn, {});
5230 case Intrinsic::memcpy:
5231 case Intrinsic::memmove:
5232 case Intrinsic::memset: {
5248 NewCall = Builder.CreateCall(NewFn, Args);
5250 AttributeList NewAttrs = AttributeList::get(
5251 C, OldAttrs.getFnAttrs(), OldAttrs.getRetAttrs(),
5252 {OldAttrs.getParamAttrs(0), OldAttrs.getParamAttrs(1),
5253 OldAttrs.getParamAttrs(2), OldAttrs.getParamAttrs(4)});
5258 MemCI->setDestAlignment(
Align->getMaybeAlignValue());
5261 MTI->setSourceAlignment(
Align->getMaybeAlignValue());
5265 case Intrinsic::masked_load:
5266 case Intrinsic::masked_gather:
5267 case Intrinsic::masked_store:
5268 case Intrinsic::masked_scatter: {
5274 auto GetMaybeAlign = [](
Value *
Op) {
5284 auto GetAlign = [&](
Value *
Op) {
5293 case Intrinsic::masked_load:
5294 NewCall = Builder.CreateMaskedLoad(
5298 case Intrinsic::masked_gather:
5299 NewCall = Builder.CreateMaskedGather(
5305 case Intrinsic::masked_store:
5306 NewCall = Builder.CreateMaskedStore(
5310 case Intrinsic::masked_scatter:
5311 NewCall = Builder.CreateMaskedScatter(
5313 DL.getValueOrABITypeAlignment(
5327 case Intrinsic::lifetime_start:
5328 case Intrinsic::lifetime_end: {
5336 Ptr =
Ptr->stripPointerCasts();
5340 NewCall = Builder.CreateLifetimeStart(
Ptr);
5342 NewCall = Builder.CreateLifetimeEnd(
Ptr);
5351 case Intrinsic::x86_avx512_vpdpbusd_128:
5352 case Intrinsic::x86_avx512_vpdpbusd_256:
5353 case Intrinsic::x86_avx512_vpdpbusd_512:
5354 case Intrinsic::x86_avx512_vpdpbusds_128:
5355 case Intrinsic::x86_avx512_vpdpbusds_256:
5356 case Intrinsic::x86_avx512_vpdpbusds_512:
5357 case Intrinsic::x86_avx2_vpdpbssd_128:
5358 case Intrinsic::x86_avx2_vpdpbssd_256:
5359 case Intrinsic::x86_avx10_vpdpbssd_512:
5360 case Intrinsic::x86_avx2_vpdpbssds_128:
5361 case Intrinsic::x86_avx2_vpdpbssds_256:
5362 case Intrinsic::x86_avx10_vpdpbssds_512:
5363 case Intrinsic::x86_avx2_vpdpbsud_128:
5364 case Intrinsic::x86_avx2_vpdpbsud_256:
5365 case Intrinsic::x86_avx10_vpdpbsud_512:
5366 case Intrinsic::x86_avx2_vpdpbsuds_128:
5367 case Intrinsic::x86_avx2_vpdpbsuds_256:
5368 case Intrinsic::x86_avx10_vpdpbsuds_512:
5369 case Intrinsic::x86_avx2_vpdpbuud_128:
5370 case Intrinsic::x86_avx2_vpdpbuud_256:
5371 case Intrinsic::x86_avx10_vpdpbuud_512:
5372 case Intrinsic::x86_avx2_vpdpbuuds_128:
5373 case Intrinsic::x86_avx2_vpdpbuuds_256:
5374 case Intrinsic::x86_avx10_vpdpbuuds_512: {
5379 Args[1] = Builder.CreateBitCast(Args[1], NewArgType);
5380 Args[2] = Builder.CreateBitCast(Args[2], NewArgType);
5382 NewCall = Builder.CreateCall(NewFn, Args);
5386 assert(NewCall &&
"Should have either set this variable or returned through "
5387 "the default case");
5394 assert(
F &&
"Illegal attempt to upgrade a non-existent intrinsic.");
5408 F->eraseFromParent();
5414 if (NumOperands == 0)
5422 if (NumOperands == 3) {
5426 Metadata *Elts2[] = {ScalarType, ScalarType,
5440 if (
Opc != Instruction::BitCast)
5444 Type *SrcTy = V->getType();
5461 if (
Opc != Instruction::BitCast)
5464 Type *SrcTy =
C->getType();
5491 if (
NamedMDNode *ModFlags = M.getModuleFlagsMetadata()) {
5492 auto OpIt =
find_if(ModFlags->operands(), [](
const MDNode *Flag) {
5493 if (Flag->getNumOperands() < 3)
5495 if (MDString *K = dyn_cast_or_null<MDString>(Flag->getOperand(1)))
5496 return K->getString() ==
"Debug Info Version";
5499 if (OpIt != ModFlags->op_end()) {
5500 const MDOperand &ValOp = (*OpIt)->getOperand(2);
5507 bool BrokenDebugInfo =
false;
5510 if (!BrokenDebugInfo)
5516 M.getContext().diagnose(Diag);
5523 M.getContext().diagnose(DiagVersion);
5533 StringRef Vect3[3] = {DefaultValue, DefaultValue, DefaultValue};
5536 if (
F->hasFnAttribute(Attr)) {
5539 StringRef S =
F->getFnAttribute(Attr).getValueAsString();
5541 auto [Part, Rest] = S.
split(
',');
5547 const unsigned Dim = DimC -
'x';
5548 assert(Dim < 3 &&
"Unexpected dim char");
5558 F->addFnAttr(Attr, NewAttr);
5562 return S ==
"x" || S ==
"y" || S ==
"z";
5567 if (K ==
"kernel") {
5579 const unsigned Idx = (AlignIdxValuePair >> 16);
5580 const Align StackAlign =
Align(AlignIdxValuePair & 0xFFFF);
5585 if (K ==
"maxclusterrank" || K ==
"cluster_max_blocks") {
5590 if (K ==
"minctasm") {
5595 if (K ==
"maxnreg") {
5600 if (K.consume_front(
"maxntid") &&
isXYZ(K)) {
5604 if (K.consume_front(
"reqntid") &&
isXYZ(K)) {
5608 if (K.consume_front(
"cluster_dim_") &&
isXYZ(K)) {
5612 if (K ==
"grid_constant") {
5627 NamedMDNode *NamedMD = M.getNamedMetadata(
"nvvm.annotations");
5634 if (!SeenNodes.
insert(MD).second)
5641 assert((MD->getNumOperands() % 2) == 1 &&
"Invalid number of operands");
5648 for (
unsigned j = 1, je = MD->getNumOperands(); j < je; j += 2) {
5650 const MDOperand &V = MD->getOperand(j + 1);
5653 NewOperands.
append({K, V});
5656 if (NewOperands.
size() > 1)
5669 const char *MarkerKey =
"clang.arc.retainAutoreleasedReturnValueMarker";
5670 NamedMDNode *ModRetainReleaseMarker = M.getNamedMetadata(MarkerKey);
5671 if (ModRetainReleaseMarker) {
5677 ID->getString().split(ValueComp,
"#");
5678 if (ValueComp.
size() == 2) {
5679 std::string NewValue = ValueComp[0].str() +
";" + ValueComp[1].str();
5683 M.eraseNamedMetadata(ModRetainReleaseMarker);
5694 auto UpgradeToIntrinsic = [&](
const char *OldFunc,
5720 bool InvalidCast =
false;
5722 for (
unsigned I = 0, E = CI->
arg_size();
I != E; ++
I) {
5735 Arg = Builder.CreateBitCast(Arg, NewFuncTy->
getParamType(
I));
5737 Args.push_back(Arg);
5744 CallInst *NewCall = Builder.CreateCall(NewFuncTy, NewFn, Args);
5749 Value *NewRetVal = Builder.CreateBitCast(NewCall, CI->
getType());
5762 UpgradeToIntrinsic(
"clang.arc.use", llvm::Intrinsic::objc_clang_arc_use);
5770 std::pair<const char *, llvm::Intrinsic::ID> RuntimeFuncs[] = {
5771 {
"objc_autorelease", llvm::Intrinsic::objc_autorelease},
5772 {
"objc_autoreleasePoolPop", llvm::Intrinsic::objc_autoreleasePoolPop},
5773 {
"objc_autoreleasePoolPush", llvm::Intrinsic::objc_autoreleasePoolPush},
5774 {
"objc_autoreleaseReturnValue",
5775 llvm::Intrinsic::objc_autoreleaseReturnValue},
5776 {
"objc_copyWeak", llvm::Intrinsic::objc_copyWeak},
5777 {
"objc_destroyWeak", llvm::Intrinsic::objc_destroyWeak},
5778 {
"objc_initWeak", llvm::Intrinsic::objc_initWeak},
5779 {
"objc_loadWeak", llvm::Intrinsic::objc_loadWeak},
5780 {
"objc_loadWeakRetained", llvm::Intrinsic::objc_loadWeakRetained},
5781 {
"objc_moveWeak", llvm::Intrinsic::objc_moveWeak},
5782 {
"objc_release", llvm::Intrinsic::objc_release},
5783 {
"objc_retain", llvm::Intrinsic::objc_retain},
5784 {
"objc_retainAutorelease", llvm::Intrinsic::objc_retainAutorelease},
5785 {
"objc_retainAutoreleaseReturnValue",
5786 llvm::Intrinsic::objc_retainAutoreleaseReturnValue},
5787 {
"objc_retainAutoreleasedReturnValue",
5788 llvm::Intrinsic::objc_retainAutoreleasedReturnValue},
5789 {
"objc_retainBlock", llvm::Intrinsic::objc_retainBlock},
5790 {
"objc_storeStrong", llvm::Intrinsic::objc_storeStrong},
5791 {
"objc_storeWeak", llvm::Intrinsic::objc_storeWeak},
5792 {
"objc_unsafeClaimAutoreleasedReturnValue",
5793 llvm::Intrinsic::objc_unsafeClaimAutoreleasedReturnValue},
5794 {
"objc_retainedObject", llvm::Intrinsic::objc_retainedObject},
5795 {
"objc_unretainedObject", llvm::Intrinsic::objc_unretainedObject},
5796 {
"objc_unretainedPointer", llvm::Intrinsic::objc_unretainedPointer},
5797 {
"objc_retain_autorelease", llvm::Intrinsic::objc_retain_autorelease},
5798 {
"objc_sync_enter", llvm::Intrinsic::objc_sync_enter},
5799 {
"objc_sync_exit", llvm::Intrinsic::objc_sync_exit},
5800 {
"objc_arc_annotation_topdown_bbstart",
5801 llvm::Intrinsic::objc_arc_annotation_topdown_bbstart},
5802 {
"objc_arc_annotation_topdown_bbend",
5803 llvm::Intrinsic::objc_arc_annotation_topdown_bbend},
5804 {
"objc_arc_annotation_bottomup_bbstart",
5805 llvm::Intrinsic::objc_arc_annotation_bottomup_bbstart},
5806 {
"objc_arc_annotation_bottomup_bbend",
5807 llvm::Intrinsic::objc_arc_annotation_bottomup_bbend}};
5809 for (
auto &
I : RuntimeFuncs)
5810 UpgradeToIntrinsic(
I.first,
I.second);
5814 NamedMDNode *ModFlags = M.getModuleFlagsMetadata();
5818 bool HasObjCFlag =
false, HasClassProperties =
false,
Changed =
false;
5819 bool HasSwiftVersionFlag =
false;
5820 uint8_t SwiftMajorVersion, SwiftMinorVersion;
5827 if (
Op->getNumOperands() != 3)
5841 if (
ID->getString() ==
"Objective-C Image Info Version")
5843 if (
ID->getString() ==
"Objective-C Class Properties")
5844 HasClassProperties =
true;
5846 if (
ID->getString() ==
"PIC Level") {
5847 if (
auto *Behavior =
5849 uint64_t V = Behavior->getLimitedValue();
5855 if (
ID->getString() ==
"PIE Level")
5856 if (
auto *Behavior =
5863 if (
ID->getString() ==
"branch-target-enforcement" ||
5864 ID->getString().starts_with(
"sign-return-address")) {
5865 if (
auto *Behavior =
5871 Op->getOperand(1),
Op->getOperand(2)};
5881 if (
ID->getString() ==
"Objective-C Image Info Section") {
5884 Value->getString().split(ValueComp,
" ");
5885 if (ValueComp.
size() != 1) {
5886 std::string NewValue;
5887 for (
auto &S : ValueComp)
5888 NewValue += S.str();
5899 if (
ID->getString() ==
"Objective-C Garbage Collection") {
5902 assert(Md->getValue() &&
"Expected non-empty metadata");
5903 auto Type = Md->getValue()->getType();
5906 unsigned Val = Md->getValue()->getUniqueInteger().getZExtValue();
5907 if ((Val & 0xff) != Val) {
5908 HasSwiftVersionFlag =
true;
5909 SwiftABIVersion = (Val & 0xff00) >> 8;
5910 SwiftMajorVersion = (Val & 0xff000000) >> 24;
5911 SwiftMinorVersion = (Val & 0xff0000) >> 16;
5922 if (
ID->getString() ==
"amdgpu_code_object_version") {
5925 MDString::get(M.getContext(),
"amdhsa_code_object_version"),
5937 if (HasObjCFlag && !HasClassProperties) {
5943 if (HasSwiftVersionFlag) {
5947 ConstantInt::get(Int8Ty, SwiftMajorVersion));
5949 ConstantInt::get(Int8Ty, SwiftMinorVersion));
5957 auto TrimSpaces = [](
StringRef Section) -> std::string {
5959 Section.split(Components,
',');
5964 for (
auto Component : Components)
5965 OS <<
',' << Component.trim();
5970 for (
auto &GV : M.globals()) {
5971 if (!GV.hasSection())
5976 if (!Section.starts_with(
"__DATA, __objc_catlist"))
5981 GV.setSection(TrimSpaces(Section));
5997struct StrictFPUpgradeVisitor :
public InstVisitor<StrictFPUpgradeVisitor> {
5998 StrictFPUpgradeVisitor() =
default;
6001 if (!
Call.isStrictFP())
6007 Call.removeFnAttr(Attribute::StrictFP);
6008 Call.addFnAttr(Attribute::NoBuiltin);
6013struct AMDGPUUnsafeFPAtomicsUpgradeVisitor
6014 :
public InstVisitor<AMDGPUUnsafeFPAtomicsUpgradeVisitor> {
6015 AMDGPUUnsafeFPAtomicsUpgradeVisitor() =
default;
6017 void visitAtomicRMWInst(AtomicRMWInst &RMW) {
6032 if (!
F.isDeclaration() && !
F.hasFnAttribute(Attribute::StrictFP)) {
6033 StrictFPUpgradeVisitor SFPV;
6038 F.removeRetAttrs(AttributeFuncs::typeIncompatible(
6039 F.getReturnType(),
F.getAttributes().getRetAttrs()));
6040 for (
auto &Arg :
F.args())
6042 AttributeFuncs::typeIncompatible(Arg.getType(), Arg.getAttributes()));
6046 if (
Attribute A =
F.getFnAttribute(
"implicit-section-name");
6047 A.isValid() &&
A.isStringAttribute()) {
6048 F.setSection(
A.getValueAsString());
6049 F.removeFnAttr(
"implicit-section-name");
6056 if (
Attribute A =
F.getFnAttribute(
"amdgpu-unsafe-fp-atomics");
6059 if (
A.getValueAsBool()) {
6060 AMDGPUUnsafeFPAtomicsUpgradeVisitor Visitor;
6066 F.removeFnAttr(
"amdgpu-unsafe-fp-atomics");
6074 if (!
F.hasFnAttribute(FnAttrName))
6075 F.addFnAttr(FnAttrName,
Value);
6082 if (!
F.hasFnAttribute(FnAttrName)) {
6084 F.addFnAttr(FnAttrName);
6086 auto A =
F.getFnAttribute(FnAttrName);
6087 if (
"false" ==
A.getValueAsString())
6088 F.removeFnAttr(FnAttrName);
6089 else if (
"true" ==
A.getValueAsString()) {
6090 F.removeFnAttr(FnAttrName);
6091 F.addFnAttr(FnAttrName);
6097 Triple T(M.getTargetTriple());
6098 if (!
T.isThumb() && !
T.isARM() && !
T.isAArch64())
6108 NamedMDNode *ModFlags = M.getModuleFlagsMetadata();
6112 if (
Op->getNumOperands() != 3)
6121 uint64_t *ValPtr = IDStr ==
"branch-target-enforcement" ? &BTEValue
6122 : IDStr ==
"branch-protection-pauth-lr" ? &BPPLRValue
6123 : IDStr ==
"guarded-control-stack" ? &GCSValue
6124 : IDStr ==
"sign-return-address" ? &SRAValue
6125 : IDStr ==
"sign-return-address-all" ? &SRAALLValue
6126 : IDStr ==
"sign-return-address-with-bkey"
6132 *ValPtr = CI->getZExtValue();
6138 bool BTE = BTEValue == 1;
6139 bool BPPLR = BPPLRValue == 1;
6140 bool GCS = GCSValue == 1;
6141 bool SRA = SRAValue == 1;
6144 if (SRA && SRAALLValue == 1)
6145 SignTypeValue =
"all";
6148 if (SRA && SRABKeyValue == 1)
6149 SignKeyValue =
"b_key";
6151 for (
Function &
F : M.getFunctionList()) {
6152 if (
F.isDeclaration())
6159 if (
auto A =
F.getFnAttribute(
"sign-return-address");
6160 A.isValid() &&
"none" ==
A.getValueAsString()) {
6161 F.removeFnAttr(
"sign-return-address");
6162 F.removeFnAttr(
"sign-return-address-key");
6178 if (SRAALLValue == 1)
6180 if (SRABKeyValue == 1)
6189 if (
T->getNumOperands() < 1)
6194 return S->getString().starts_with(
"llvm.vectorizer.");
6198 StringRef OldPrefix =
"llvm.vectorizer.";
6201 if (OldTag ==
"llvm.vectorizer.unroll")
6213 if (
T->getNumOperands() < 1)
6218 if (!OldTag->getString().starts_with(
"llvm.vectorizer."))
6223 Ops.reserve(
T->getNumOperands());
6225 for (
unsigned I = 1,
E =
T->getNumOperands();
I !=
E; ++
I)
6226 Ops.push_back(
T->getOperand(
I));
6240 Ops.reserve(
T->getNumOperands());
6251 if ((
T.isSPIR() || (
T.isSPIRV() && !
T.isSPIRVLogical())) &&
6252 !
DL.contains(
"-G") && !
DL.starts_with(
"G")) {
6253 return DL.empty() ? std::string(
"G1") : (
DL +
"-G1").str();
6256 if (
T.isLoongArch64() ||
T.isRISCV64()) {
6258 auto I =
DL.find(
"-n64-");
6260 return (
DL.take_front(
I) +
"-n32:64-" +
DL.drop_front(
I + 5)).str();
6265 std::string Res =
DL.str();
6268 if (!
DL.contains(
"-G") && !
DL.starts_with(
"G"))
6269 Res.append(Res.empty() ?
"G1" :
"-G1");
6277 if (!
DL.contains(
"-ni") && !
DL.starts_with(
"ni"))
6278 Res.append(
"-ni:7:8:9");
6280 if (
DL.ends_with(
"ni:7"))
6282 if (
DL.ends_with(
"ni:7:8"))
6287 if (!
DL.contains(
"-p7") && !
DL.starts_with(
"p7"))
6288 Res.append(
"-p7:160:256:256:32");
6289 if (!
DL.contains(
"-p8") && !
DL.starts_with(
"p8"))
6290 Res.append(
"-p8:128:128:128:48");
6291 constexpr StringRef OldP8(
"-p8:128:128-");
6292 if (
DL.contains(OldP8))
6293 Res.replace(Res.find(OldP8), OldP8.
size(),
"-p8:128:128:128:48-");
6294 if (!
DL.contains(
"-p9") && !
DL.starts_with(
"p9"))
6295 Res.append(
"-p9:192:256:256:32");
6299 if (!
DL.contains(
"m:e"))
6300 Res = Res.empty() ?
"m:e" :
"m:e-" + Res;
6305 auto AddPtr32Ptr64AddrSpaces = [&
DL, &Res]() {
6308 StringRef AddrSpaces{
"-p270:32:32-p271:32:32-p272:64:64"};
6309 if (!
DL.contains(AddrSpaces)) {
6311 Regex R(
"^([Ee]-m:[a-z](-p:32:32)?)(-.*)$");
6312 if (R.match(Res, &
Groups))
6318 if (
T.isAArch64()) {
6320 if (!
DL.empty() && !
DL.contains(
"-Fn32"))
6321 Res.append(
"-Fn32");
6322 AddPtr32Ptr64AddrSpaces();
6326 if (
T.isSPARC() || (
T.isMIPS64() && !
DL.contains(
"m:m")) ||
T.isPPC64() ||
6330 std::string I64 =
"-i64:64";
6331 std::string I128 =
"-i128:128";
6333 size_t Pos = Res.find(I64);
6334 if (Pos !=
size_t(-1))
6335 Res.insert(Pos + I64.size(), I128);
6343 AddPtr32Ptr64AddrSpaces();
6351 if (!
T.isOSIAMCU()) {
6352 std::string I128 =
"-i128:128";
6355 Regex R(
"^(e(-[mpi][^-]*)*)((-[^mpi][^-]*)*)$");
6356 if (R.match(Res, &
Groups))
6364 if (
T.isWindowsMSVCEnvironment() && !
T.isArch64Bit()) {
6366 auto I =
Ref.find(
"-f80:32-");
6368 Res = (
Ref.take_front(
I) +
"-f80:128-" +
Ref.drop_front(
I + 8)).str();
6376 Attribute A =
B.getAttribute(
"no-frame-pointer-elim");
6379 FramePointer =
A.getValueAsString() ==
"true" ?
"all" :
"none";
6380 B.removeAttribute(
"no-frame-pointer-elim");
6382 if (
B.contains(
"no-frame-pointer-elim-non-leaf")) {
6384 if (FramePointer !=
"all")
6385 FramePointer =
"non-leaf";
6386 B.removeAttribute(
"no-frame-pointer-elim-non-leaf");
6388 if (!FramePointer.
empty())
6389 B.addAttribute(
"frame-pointer", FramePointer);
6391 A =
B.getAttribute(
"null-pointer-is-valid");
6394 bool NullPointerIsValid =
A.getValueAsString() ==
"true";
6395 B.removeAttribute(
"null-pointer-is-valid");
6396 if (NullPointerIsValid)
6397 B.addAttribute(Attribute::NullPointerIsValid);
6407 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 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.
@ 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 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.