219 Intrinsic::ID ID = Intrinsic::not_intrinsic;
225 case Builtin::BI__builtin_cpu_is:
226 case Builtin::BI__builtin_cpu_supports: {
233 case PPC::BI__builtin_ppc_get_timebase:
234 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::readcyclecounter));
237 case PPC::BI__builtin_altivec_lvx:
238 case PPC::BI__builtin_altivec_lvxl:
239 case PPC::BI__builtin_altivec_lvebx:
240 case PPC::BI__builtin_altivec_lvehx:
241 case PPC::BI__builtin_altivec_lvewx:
242 case PPC::BI__builtin_altivec_lvsl:
243 case PPC::BI__builtin_altivec_lvsr:
244 case PPC::BI__builtin_vsx_lxvd2x:
245 case PPC::BI__builtin_vsx_lxvw4x:
246 case PPC::BI__builtin_vsx_lxvd2x_be:
247 case PPC::BI__builtin_vsx_lxvw4x_be:
248 case PPC::BI__builtin_vsx_lxvl:
249 case PPC::BI__builtin_vsx_lxvll:
254 if (!(BuiltinID == PPC::BI__builtin_vsx_lxvl ||
255 BuiltinID == PPC::BI__builtin_vsx_lxvll)) {
261 default: llvm_unreachable(
"Unsupported ld/lvsl/lvsr intrinsic!");
262 case PPC::BI__builtin_altivec_lvx:
263 ID = Intrinsic::ppc_altivec_lvx;
265 case PPC::BI__builtin_altivec_lvxl:
266 ID = Intrinsic::ppc_altivec_lvxl;
268 case PPC::BI__builtin_altivec_lvebx:
269 ID = Intrinsic::ppc_altivec_lvebx;
271 case PPC::BI__builtin_altivec_lvehx:
272 ID = Intrinsic::ppc_altivec_lvehx;
274 case PPC::BI__builtin_altivec_lvewx:
275 ID = Intrinsic::ppc_altivec_lvewx;
277 case PPC::BI__builtin_altivec_lvsl:
278 ID = Intrinsic::ppc_altivec_lvsl;
280 case PPC::BI__builtin_altivec_lvsr:
281 ID = Intrinsic::ppc_altivec_lvsr;
283 case PPC::BI__builtin_vsx_lxvd2x:
284 ID = Intrinsic::ppc_vsx_lxvd2x;
286 case PPC::BI__builtin_vsx_lxvw4x:
287 ID = Intrinsic::ppc_vsx_lxvw4x;
289 case PPC::BI__builtin_vsx_lxvd2x_be:
290 ID = Intrinsic::ppc_vsx_lxvd2x_be;
292 case PPC::BI__builtin_vsx_lxvw4x_be:
293 ID = Intrinsic::ppc_vsx_lxvw4x_be;
295 case PPC::BI__builtin_vsx_lxvl:
296 ID = Intrinsic::ppc_vsx_lxvl;
298 case PPC::BI__builtin_vsx_lxvll:
299 ID = Intrinsic::ppc_vsx_lxvll;
302 llvm::Function *F =
CGM.getIntrinsic(ID);
303 return Builder.CreateCall(F, Ops,
"");
307 case PPC::BI__builtin_altivec_stvx:
308 case PPC::BI__builtin_altivec_stvxl:
309 case PPC::BI__builtin_altivec_stvebx:
310 case PPC::BI__builtin_altivec_stvehx:
311 case PPC::BI__builtin_altivec_stvewx:
312 case PPC::BI__builtin_vsx_stxvd2x:
313 case PPC::BI__builtin_vsx_stxvw4x:
314 case PPC::BI__builtin_vsx_stxvd2x_be:
315 case PPC::BI__builtin_vsx_stxvw4x_be:
316 case PPC::BI__builtin_vsx_stxvl:
317 case PPC::BI__builtin_vsx_stxvll:
323 if (!(BuiltinID == PPC::BI__builtin_vsx_stxvl ||
324 BuiltinID == PPC::BI__builtin_vsx_stxvll)) {
330 default: llvm_unreachable(
"Unsupported st intrinsic!");
331 case PPC::BI__builtin_altivec_stvx:
332 ID = Intrinsic::ppc_altivec_stvx;
334 case PPC::BI__builtin_altivec_stvxl:
335 ID = Intrinsic::ppc_altivec_stvxl;
337 case PPC::BI__builtin_altivec_stvebx:
338 ID = Intrinsic::ppc_altivec_stvebx;
340 case PPC::BI__builtin_altivec_stvehx:
341 ID = Intrinsic::ppc_altivec_stvehx;
343 case PPC::BI__builtin_altivec_stvewx:
344 ID = Intrinsic::ppc_altivec_stvewx;
346 case PPC::BI__builtin_vsx_stxvd2x:
347 ID = Intrinsic::ppc_vsx_stxvd2x;
349 case PPC::BI__builtin_vsx_stxvw4x:
350 ID = Intrinsic::ppc_vsx_stxvw4x;
352 case PPC::BI__builtin_vsx_stxvd2x_be:
353 ID = Intrinsic::ppc_vsx_stxvd2x_be;
355 case PPC::BI__builtin_vsx_stxvw4x_be:
356 ID = Intrinsic::ppc_vsx_stxvw4x_be;
358 case PPC::BI__builtin_vsx_stxvl:
359 ID = Intrinsic::ppc_vsx_stxvl;
361 case PPC::BI__builtin_vsx_stxvll:
362 ID = Intrinsic::ppc_vsx_stxvll;
365 llvm::Function *F =
CGM.getIntrinsic(ID);
366 return Builder.CreateCall(F, Ops,
"");
368 case PPC::BI__builtin_vsx_ldrmb: {
379 if (NumBytes == 16) {
387 for (
int Idx = 0; Idx < 16; Idx++)
388 RevMask.push_back(15 - Idx);
389 return Builder.CreateShuffleVector(LD, LD, RevMask);
392 llvm::Function *Lvx =
CGM.getIntrinsic(Intrinsic::ppc_altivec_lvx);
393 llvm::Function *Lvs =
CGM.getIntrinsic(IsLE ? Intrinsic::ppc_altivec_lvsr
394 : Intrinsic::ppc_altivec_lvsl);
395 llvm::Function *Vperm =
CGM.getIntrinsic(Intrinsic::ppc_altivec_vperm);
397 Int8Ty, Op0, ConstantInt::get(Op1->
getType(), NumBytes - 1));
402 Op0 = IsLE ? HiLd : LoLd;
403 Op1 = IsLE ? LoLd : HiLd;
404 Value *AllElts =
Builder.CreateCall(Vperm, {Op0, Op1, Mask1},
"shuffle1");
405 Constant *
Zero = llvm::Constant::getNullValue(IsLE ? ResTy : AllElts->
getType());
409 for (
int Idx = 0; Idx < 16; Idx++) {
410 int Val = (NumBytes - Idx - 1 >= 0) ? (NumBytes - Idx - 1)
411 : 16 - (NumBytes - Idx);
412 Consts.push_back(Val);
414 return Builder.CreateShuffleVector(
Builder.CreateBitCast(AllElts, ResTy),
418 for (
int Idx = 0; Idx < 16; Idx++)
419 Consts.push_back(
Builder.getInt8(NumBytes + Idx));
420 Value *Mask2 = ConstantVector::get(Consts);
422 Builder.CreateCall(Vperm, {Zero, AllElts, Mask2},
"shuffle2"), ResTy);
424 case PPC::BI__builtin_vsx_strmb: {
430 auto StoreSubVec = [&](
unsigned Width,
unsigned Offset,
unsigned EltNo) {
437 for (
int Idx = 0; Idx < 16; Idx++)
438 RevMask.push_back(15 - Idx);
439 StVec =
Builder.CreateShuffleVector(Op2, Op2, RevMask);
445 unsigned NumElts = 0;
448 llvm_unreachable(
"width for stores must be a power of 2");
467 Op2, llvm::FixedVectorType::get(ConvTy, NumElts));
471 if (IsLE && Width > 1) {
472 Function *F =
CGM.getIntrinsic(Intrinsic::bswap, ConvTy);
473 Elt =
Builder.CreateCall(F, Elt);
479 unsigned RemainingBytes = NumBytes;
482 return StoreSubVec(16, 0, 0);
484 Result = StoreSubVec(8, NumBytes - 8, IsLE ? 0 : 1);
488 if (RemainingBytes >= 4) {
489 Result = StoreSubVec(4, NumBytes - Stored - 4,
490 IsLE ? (Stored >> 2) : 3 - (Stored >> 2));
494 if (RemainingBytes >= 2) {
495 Result = StoreSubVec(2, NumBytes - Stored - 2,
496 IsLE ? (Stored >> 1) : 7 - (Stored >> 1));
502 StoreSubVec(1, NumBytes - Stored - 1, IsLE ? Stored : 15 - Stored);
506 case PPC::BI__builtin_vsx_xvsqrtsp:
507 case PPC::BI__builtin_vsx_xvsqrtdp: {
510 if (
Builder.getIsFPConstrained()) {
511 llvm::Function *F =
CGM.getIntrinsic(
512 Intrinsic::experimental_constrained_sqrt, ResultType);
513 return Builder.CreateConstrainedFPCall(F,
X);
515 llvm::Function *F =
CGM.getIntrinsic(Intrinsic::sqrt, ResultType);
520 case PPC::BI__builtin_altivec_vclzb:
521 case PPC::BI__builtin_altivec_vclzh:
522 case PPC::BI__builtin_altivec_vclzw:
523 case PPC::BI__builtin_altivec_vclzd: {
526 Value *Undef = ConstantInt::get(
Builder.getInt1Ty(),
false);
527 Function *F =
CGM.getIntrinsic(Intrinsic::ctlz, ResultType);
528 return Builder.CreateCall(F, {
X, Undef});
530 case PPC::BI__builtin_altivec_vctzb:
531 case PPC::BI__builtin_altivec_vctzh:
532 case PPC::BI__builtin_altivec_vctzw:
533 case PPC::BI__builtin_altivec_vctzd: {
536 Value *Undef = ConstantInt::get(
Builder.getInt1Ty(),
false);
537 Function *F =
CGM.getIntrinsic(Intrinsic::cttz, ResultType);
538 return Builder.CreateCall(F, {
X, Undef});
540 case PPC::BI__builtin_altivec_vinsd:
541 case PPC::BI__builtin_altivec_vinsw:
542 case PPC::BI__builtin_altivec_vinsd_elt:
543 case PPC::BI__builtin_altivec_vinsw_elt: {
549 bool IsUnaligned = (BuiltinID == PPC::BI__builtin_altivec_vinsw ||
550 BuiltinID == PPC::BI__builtin_altivec_vinsd);
552 bool Is32bit = (BuiltinID == PPC::BI__builtin_altivec_vinsw ||
553 BuiltinID == PPC::BI__builtin_altivec_vinsw_elt);
556 ConstantInt *ArgCI = dyn_cast<ConstantInt>(Op2);
558 "Third Arg to vinsw/vinsd intrinsic must be a constant integer!");
562 int ValidMaxValue = 0;
564 ValidMaxValue = (Is32bit) ? 12 : 8;
566 ValidMaxValue = (Is32bit) ? 3 : 1;
569 int64_t ConstArg = ArgCI->getSExtValue();
572 std::string RangeErrMsg = IsUnaligned ?
"byte" :
"element";
573 RangeErrMsg +=
" number " + llvm::to_string(ConstArg);
574 RangeErrMsg +=
" is outside of the valid range [0, ";
575 RangeErrMsg += llvm::to_string(ValidMaxValue) +
"]";
578 if (ConstArg < 0 || ConstArg > ValidMaxValue)
583 ConstArg *= Is32bit ? 4 : 8;
586 ConstArg = (Is32bit ? 12 : 8) - ConstArg;
589 ID = Is32bit ? Intrinsic::ppc_altivec_vinsw : Intrinsic::ppc_altivec_vinsd;
590 Op2 = ConstantInt::getSigned(
Int32Ty, ConstArg);
594 ?
Builder.CreateBitCast(Op0, llvm::FixedVectorType::get(
Int32Ty, 4))
596 llvm::FixedVectorType::get(
Int64Ty, 2));
598 Builder.CreateCall(
CGM.getIntrinsic(ID), {Op0, Op1, Op2}), ResultType);
600 case PPC::BI__builtin_altivec_vadduqm:
601 case PPC::BI__builtin_altivec_vsubuqm: {
604 llvm::Type *Int128Ty = llvm::IntegerType::get(
getLLVMContext(), 128);
605 Op0 =
Builder.CreateBitCast(Op0, llvm::FixedVectorType::get(Int128Ty, 1));
606 Op1 =
Builder.CreateBitCast(Op1, llvm::FixedVectorType::get(Int128Ty, 1));
607 if (BuiltinID == PPC::BI__builtin_altivec_vadduqm)
608 return Builder.CreateAdd(Op0, Op1,
"vadduqm");
610 return Builder.CreateSub(Op0, Op1,
"vsubuqm");
612 case PPC::BI__builtin_altivec_vaddcuq_c:
613 case PPC::BI__builtin_altivec_vsubcuq_c: {
617 llvm::Type *V1I128Ty = llvm::FixedVectorType::get(
619 Ops.push_back(
Builder.CreateBitCast(Op0, V1I128Ty));
620 Ops.push_back(
Builder.CreateBitCast(Op1, V1I128Ty));
621 ID = (BuiltinID == PPC::BI__builtin_altivec_vaddcuq_c)
622 ? Intrinsic::ppc_altivec_vaddcuq
623 : Intrinsic::ppc_altivec_vsubcuq;
624 return Builder.CreateCall(
CGM.getIntrinsic(ID), Ops,
"");
626 case PPC::BI__builtin_altivec_vaddeuqm_c:
627 case PPC::BI__builtin_altivec_vaddecuq_c:
628 case PPC::BI__builtin_altivec_vsubeuqm_c:
629 case PPC::BI__builtin_altivec_vsubecuq_c: {
634 llvm::Type *V1I128Ty = llvm::FixedVectorType::get(
636 Ops.push_back(
Builder.CreateBitCast(Op0, V1I128Ty));
637 Ops.push_back(
Builder.CreateBitCast(Op1, V1I128Ty));
638 Ops.push_back(
Builder.CreateBitCast(Op2, V1I128Ty));
641 llvm_unreachable(
"Unsupported intrinsic!");
642 case PPC::BI__builtin_altivec_vaddeuqm_c:
643 ID = Intrinsic::ppc_altivec_vaddeuqm;
645 case PPC::BI__builtin_altivec_vaddecuq_c:
646 ID = Intrinsic::ppc_altivec_vaddecuq;
648 case PPC::BI__builtin_altivec_vsubeuqm_c:
649 ID = Intrinsic::ppc_altivec_vsubeuqm;
651 case PPC::BI__builtin_altivec_vsubecuq_c:
652 ID = Intrinsic::ppc_altivec_vsubecuq;
655 return Builder.CreateCall(
CGM.getIntrinsic(ID), Ops,
"");
657 case PPC::BI__builtin_ppc_rldimi:
658 case PPC::BI__builtin_ppc_rlwimi: {
665 if (BuiltinID == PPC::BI__builtin_ppc_rldimi &&
674 CGM.getIntrinsic(BuiltinID == PPC::BI__builtin_ppc_rldimi
675 ? Intrinsic::ppc_rldimi
676 : Intrinsic::ppc_rlwimi),
677 {Op0, Op1, Op2, Op3});
679 case PPC::BI__builtin_ppc_rlwnm: {
683 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::ppc_rlwnm),
686 case PPC::BI__builtin_ppc_poppar4:
687 case PPC::BI__builtin_ppc_poppar8: {
695 if (
Result->getType() != ResultType)
700 case PPC::BI__builtin_ppc_cmpb: {
706 return Builder.CreateCall(F, {Op0, Op1},
"cmpb");
726 Constant *ShiftAmt = ConstantInt::get(
Int64Ty, 32);
736 return Builder.CreateOr(ResLo, ResHi);
739 case PPC::BI__builtin_vsx_xvcpsgnsp:
740 case PPC::BI__builtin_vsx_xvcpsgndp: {
744 ID = Intrinsic::copysign;
745 llvm::Function *F =
CGM.getIntrinsic(ID, ResultType);
746 return Builder.CreateCall(F, {
X, Y});
749 case PPC::BI__builtin_vsx_xvrspip:
750 case PPC::BI__builtin_vsx_xvrdpip:
751 case PPC::BI__builtin_vsx_xvrdpim:
752 case PPC::BI__builtin_vsx_xvrspim:
753 case PPC::BI__builtin_vsx_xvrdpi:
754 case PPC::BI__builtin_vsx_xvrspi:
755 case PPC::BI__builtin_vsx_xvrdpic:
756 case PPC::BI__builtin_vsx_xvrspic:
757 case PPC::BI__builtin_vsx_xvrdpiz:
758 case PPC::BI__builtin_vsx_xvrspiz: {
761 if (BuiltinID == PPC::BI__builtin_vsx_xvrdpim ||
762 BuiltinID == PPC::BI__builtin_vsx_xvrspim)
763 ID =
Builder.getIsFPConstrained()
764 ? Intrinsic::experimental_constrained_floor
766 else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpi ||
767 BuiltinID == PPC::BI__builtin_vsx_xvrspi)
768 ID =
Builder.getIsFPConstrained()
769 ? Intrinsic::experimental_constrained_round
771 else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpic ||
772 BuiltinID == PPC::BI__builtin_vsx_xvrspic)
773 ID =
Builder.getIsFPConstrained()
774 ? Intrinsic::experimental_constrained_rint
776 else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpip ||
777 BuiltinID == PPC::BI__builtin_vsx_xvrspip)
778 ID =
Builder.getIsFPConstrained()
779 ? Intrinsic::experimental_constrained_ceil
781 else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpiz ||
782 BuiltinID == PPC::BI__builtin_vsx_xvrspiz)
783 ID =
Builder.getIsFPConstrained()
784 ? Intrinsic::experimental_constrained_trunc
786 llvm::Function *F =
CGM.getIntrinsic(ID, ResultType);
787 return Builder.getIsFPConstrained() ?
Builder.CreateConstrainedFPCall(F,
X)
792 case PPC::BI__builtin_vsx_xvabsdp:
793 case PPC::BI__builtin_vsx_xvabssp: {
799 case PPC::BI__builtin_ppc_recipdivf:
800 case PPC::BI__builtin_ppc_recipdivd:
801 case PPC::BI__builtin_ppc_rsqrtf:
802 case PPC::BI__builtin_ppc_rsqrtd: {
803 FastMathFlags FMF =
Builder.getFastMathFlags();
804 Builder.getFastMathFlags().setFast();
808 if (BuiltinID == PPC::BI__builtin_ppc_recipdivf ||
809 BuiltinID == PPC::BI__builtin_ppc_recipdivd) {
812 Builder.getFastMathFlags() &= (FMF);
815 auto *One = ConstantFP::get(ResultType, 1.0);
816 llvm::Function *F =
CGM.getIntrinsic(Intrinsic::sqrt, ResultType);
818 Builder.getFastMathFlags() &= (FMF);
821 case PPC::BI__builtin_ppc_alignx: {
825 if (AlignmentCI->getValue().ugt(llvm::Value::MaximumAlignment))
826 AlignmentCI = ConstantInt::get(AlignmentCI->getIntegerType(),
827 llvm::Value::MaximumAlignment);
831 AlignmentCI,
nullptr);
834 case PPC::BI__builtin_ppc_rdlam: {
838 llvm::Type *Ty = Op0->
getType();
839 Value *ShiftAmt =
Builder.CreateIntCast(Op1, Ty,
false);
840 Function *F =
CGM.getIntrinsic(Intrinsic::fshl, Ty);
841 Value *Rotate =
Builder.CreateCall(F, {Op0, Op0, ShiftAmt});
842 return Builder.CreateAnd(Rotate, Op2);
844 case PPC::BI__builtin_ppc_load2r: {
845 Function *F =
CGM.getIntrinsic(Intrinsic::ppc_load2r);
851 case PPC::BI__builtin_ppc_fnmsub:
852 case PPC::BI__builtin_ppc_fnmsubs:
853 case PPC::BI__builtin_vsx_xvmaddadp:
854 case PPC::BI__builtin_vsx_xvmaddasp:
855 case PPC::BI__builtin_vsx_xvnmaddadp:
856 case PPC::BI__builtin_vsx_xvnmaddasp:
857 case PPC::BI__builtin_vsx_xvmsubadp:
858 case PPC::BI__builtin_vsx_xvmsubasp:
859 case PPC::BI__builtin_vsx_xvnmsubadp:
860 case PPC::BI__builtin_vsx_xvnmsubasp: {
866 if (
Builder.getIsFPConstrained())
867 F =
CGM.getIntrinsic(Intrinsic::experimental_constrained_fma, ResultType);
869 F =
CGM.getIntrinsic(Intrinsic::fma, ResultType);
871 case PPC::BI__builtin_vsx_xvmaddadp:
872 case PPC::BI__builtin_vsx_xvmaddasp:
873 if (
Builder.getIsFPConstrained())
874 return Builder.CreateConstrainedFPCall(F, {
X, Y, Z});
876 return Builder.CreateCall(F, {
X, Y, Z});
877 case PPC::BI__builtin_vsx_xvnmaddadp:
878 case PPC::BI__builtin_vsx_xvnmaddasp:
879 if (
Builder.getIsFPConstrained())
881 Builder.CreateConstrainedFPCall(F, {X, Y, Z}),
"neg");
883 return Builder.CreateFNeg(
Builder.CreateCall(F, {X, Y, Z}),
"neg");
884 case PPC::BI__builtin_vsx_xvmsubadp:
885 case PPC::BI__builtin_vsx_xvmsubasp:
886 if (
Builder.getIsFPConstrained())
887 return Builder.CreateConstrainedFPCall(
888 F, {
X, Y,
Builder.CreateFNeg(Z,
"neg")});
891 case PPC::BI__builtin_ppc_fnmsub:
892 case PPC::BI__builtin_ppc_fnmsubs:
893 case PPC::BI__builtin_vsx_xvnmsubadp:
894 case PPC::BI__builtin_vsx_xvnmsubasp:
895 if (
Builder.getIsFPConstrained())
897 Builder.CreateConstrainedFPCall(
898 F, {X, Y, Builder.CreateFNeg(Z,
"neg")}),
902 CGM.getIntrinsic(Intrinsic::ppc_fnmsub, ResultType), {X, Y, Z});
904 llvm_unreachable(
"Unknown FMA operation");
908 case PPC::BI__builtin_vsx_insertword: {
912 llvm::Function *F =
CGM.getIntrinsic(Intrinsic::ppc_vsx_xxinsertw);
916 ConstantInt *ArgCI = dyn_cast<ConstantInt>(Op2);
918 "Third arg to xxinsertw intrinsic must be constant integer");
919 const int64_t MaxIndex = 12;
920 int64_t Index = std::clamp(ArgCI->getSExtValue(), (int64_t)0, MaxIndex);
931 Op1 =
Builder.CreateBitCast(Op1, llvm::FixedVectorType::get(
Int64Ty, 2));
935 Op0 =
Builder.CreateBitCast(Op0, llvm::FixedVectorType::get(
Int64Ty, 2));
936 Op0 =
Builder.CreateShuffleVector(Op0, Op0, {1, 0});
939 Index = MaxIndex - Index;
943 Op0 =
Builder.CreateBitCast(Op0, llvm::FixedVectorType::get(
Int32Ty, 4));
944 Op2 = ConstantInt::getSigned(
Int32Ty, Index);
945 return Builder.CreateCall(F, {Op0, Op1, Op2});
948 case PPC::BI__builtin_vsx_extractuword: {
951 llvm::Function *F =
CGM.getIntrinsic(Intrinsic::ppc_vsx_xxextractuw);
954 Op0 =
Builder.CreateBitCast(Op0, llvm::FixedVectorType::get(
Int64Ty, 2));
958 ConstantInt *ArgCI = dyn_cast<ConstantInt>(Op1);
960 "Second Arg to xxextractuw intrinsic must be a constant integer!");
961 const int64_t MaxIndex = 12;
962 int64_t Index = std::clamp(ArgCI->getSExtValue(), (int64_t)0, MaxIndex);
966 Index = MaxIndex - Index;
967 Op1 = ConstantInt::getSigned(
Int32Ty, Index);
976 Op1 = ConstantInt::getSigned(
Int32Ty, Index);
977 return Builder.CreateCall(F, {Op0, Op1});
981 case PPC::BI__builtin_vsx_xxpermdi: {
985 ConstantInt *ArgCI = dyn_cast<ConstantInt>(Op2);
986 assert(ArgCI &&
"Third arg must be constant integer!");
988 unsigned Index = ArgCI->getZExtValue();
989 Op0 =
Builder.CreateBitCast(Op0, llvm::FixedVectorType::get(
Int64Ty, 2));
990 Op1 =
Builder.CreateBitCast(Op1, llvm::FixedVectorType::get(
Int64Ty, 2));
995 int ElemIdx0 = (Index & 2) >> 1;
996 int ElemIdx1 = 2 + (Index & 1);
998 int ShuffleElts[2] = {ElemIdx0, ElemIdx1};
999 Value *ShuffleCall =
Builder.CreateShuffleVector(Op0, Op1, ShuffleElts);
1002 return Builder.CreateBitCast(ShuffleCall, RetTy);
1005 case PPC::BI__builtin_vsx_xxsldwi: {
1009 ConstantInt *ArgCI = dyn_cast<ConstantInt>(Op2);
1010 assert(ArgCI &&
"Third argument must be a compile time constant");
1011 unsigned Index = ArgCI->getZExtValue() & 0x3;
1012 Op0 =
Builder.CreateBitCast(Op0, llvm::FixedVectorType::get(
Int32Ty, 4));
1013 Op1 =
Builder.CreateBitCast(Op1, llvm::FixedVectorType::get(
Int32Ty, 4));
1024 ElemIdx0 = (8 - Index) % 8;
1025 ElemIdx1 = (9 - Index) % 8;
1026 ElemIdx2 = (10 - Index) % 8;
1027 ElemIdx3 = (11 - Index) % 8;
1031 ElemIdx1 = Index + 1;
1032 ElemIdx2 = Index + 2;
1033 ElemIdx3 = Index + 3;
1036 int ShuffleElts[4] = {ElemIdx0, ElemIdx1, ElemIdx2, ElemIdx3};
1037 Value *ShuffleCall =
Builder.CreateShuffleVector(Op0, Op1, ShuffleElts);
1040 return Builder.CreateBitCast(ShuffleCall, RetTy);
1043 case PPC::BI__builtin_pack_vector_int128: {
1047 Value *PoisonValue =
1048 llvm::PoisonValue::get(llvm::FixedVectorType::get(Op0->
getType(), 2));
1050 PoisonValue, Op0, (uint64_t)(isLittleEndian ? 1 : 0));
1051 Res =
Builder.CreateInsertElement(Res, Op1,
1052 (uint64_t)(isLittleEndian ? 0 : 1));
1056 case PPC::BI__builtin_unpack_vector_int128: {
1065 ConstantInt::get(Index->getIntegerType(), 1 - Index->getZExtValue());
1067 return Builder.CreateExtractElement(Unpacked, Index);
1070 case PPC::BI__builtin_ppc_sthcx: {
1071 llvm::Function *F =
CGM.getIntrinsic(Intrinsic::ppc_sthcx);
1074 return Builder.CreateCall(F, {Op0, Op1});
1083#define CUSTOM_BUILTIN(Name, Intr, Types, Accumulate, Feature) \
1084 case PPC::BI__builtin_##Name:
1085#include "clang/Basic/BuiltinsPPC.def"
1088 for (
unsigned i = 0, e = E->
getNumArgs(); i != e; i++)
1098 if (BuiltinID == PPC::BI__builtin_mma_disassemble_acc ||
1099 BuiltinID == PPC::BI__builtin_vsx_disassemble_pair ||
1100 BuiltinID == PPC::BI__builtin_mma_disassemble_pair) {
1101 unsigned NumVecs = 2;
1102 auto Intrinsic = Intrinsic::ppc_vsx_disassemble_pair;
1103 if (BuiltinID == PPC::BI__builtin_mma_disassemble_acc) {
1105 Intrinsic = Intrinsic::ppc_mma_disassemble_acc;
1107 llvm::Function *F =
CGM.getIntrinsic(Intrinsic);
1111 llvm::Type *VTy = llvm::FixedVectorType::get(
Int8Ty, 16);
1112 Value *Ptr = Ops[0];
1113 for (
unsigned i=0; i<NumVecs; i++) {
1115 llvm::ConstantInt* Index = llvm::ConstantInt::get(
IntTy, i);
1116 Value *GEP =
Builder.CreateInBoundsGEP(VTy, Ptr, Index);
1117 Builder.CreateAlignedStore(Vec, GEP, MaybeAlign(16));
1121 if (BuiltinID == PPC::BI__builtin_vsx_build_pair ||
1122 BuiltinID == PPC::BI__builtin_mma_build_acc) {
1130 std::reverse(Ops.begin() + 1, Ops.end());
1133 switch (BuiltinID) {
1134 #define CUSTOM_BUILTIN(Name, Intr, Types, Acc, Feature) \
1135 case PPC::BI__builtin_##Name: \
1136 ID = Intrinsic::ppc_##Intr; \
1139 #include "clang/Basic/BuiltinsPPC.def"
1141 if (BuiltinID == PPC::BI__builtin_vsx_lxvp ||
1142 BuiltinID == PPC::BI__builtin_vsx_stxvp ||
1143 BuiltinID == PPC::BI__builtin_mma_lxvp ||
1144 BuiltinID == PPC::BI__builtin_mma_stxvp) {
1145 if (BuiltinID == PPC::BI__builtin_vsx_lxvp ||
1146 BuiltinID == PPC::BI__builtin_mma_lxvp) {
1152 llvm::Function *F =
CGM.getIntrinsic(ID);
1153 return Builder.CreateCall(F, Ops,
"");
1159 CallOps.push_back(Acc);
1161 switch (BuiltinID) {
1162 case PPC::BI__builtin_dmmr:
1163 case PPC::BI__builtin_dmxor:
1164 case PPC::BI__builtin_mma_dmsha2hash: {
1169 case PPC::BI__builtin_disassemble_dmr: {
1171 return Builder.CreateAlignedStore(Ops[1], Ops[0], MaybeAlign());
1173 case PPC::BI__builtin_dmsha256hash:
1174 case PPC::BI__builtin_dmsha512hash: {
1176 int Imm = (BuiltinID == PPC::BI__builtin_dmsha256hash) ? 0 : 1;
1177 Ops.push_back(llvm::ConstantInt::get(
Int32Ty, Imm));
1180 case PPC::BI__builtin_dmsha3dw:
1181 Ops.push_back(llvm::ConstantInt::get(
Int32Ty, 0));
1183 case PPC::BI__builtin_dmcryshash:
1184 Ops.push_back(llvm::ConstantInt::get(
Int32Ty, 12));
1186 case PPC::BI__builtin_dmxxsha384512pad:
1187 case PPC::BI__builtin_dmxxsha224256pad: {
1188 int Imm = (BuiltinID == PPC::BI__builtin_dmxxsha384512pad) ? 2 : 3;
1189 Ops.push_back(ConstantInt::get(
Int32Ty, Imm));
1190 Ops.push_back(ConstantInt::get(
Int32Ty, 0));
1191 Ops.push_back(ConstantInt::get(
Int32Ty, 0));
1194 case PPC::BI__builtin_dmxxsha3512pad:
1195 case PPC::BI__builtin_dmxxsha3384pad:
1196 case PPC::BI__builtin_dmxxsha3256pad:
1197 case PPC::BI__builtin_dmxxsha3224pad:
1198 case PPC::BI__builtin_dmxxshake256pad:
1199 case PPC::BI__builtin_dmxxshake128pad: {
1200 Value *E_val = Ops[2];
1202 switch (BuiltinID) {
1203 case PPC::BI__builtin_dmxxsha3512pad:
1207 case PPC::BI__builtin_dmxxsha3384pad:
1211 case PPC::BI__builtin_dmxxsha3256pad:
1215 case PPC::BI__builtin_dmxxsha3224pad:
1219 case PPC::BI__builtin_dmxxshake256pad:
1223 case PPC::BI__builtin_dmxxshake128pad:
1228 Ops[2] = ConstantInt::get(
Int32Ty, ID);
1229 Ops.push_back(E_val);
1230 Ops.push_back(ConstantInt::get(
Int32Ty, BL));
1234 for (
unsigned i=1; i<Ops.size(); i++)
1235 CallOps.push_back(Ops[i]);
1236 llvm::Function *F =
CGM.getIntrinsic(ID);
1238 return Builder.CreateAlignedStore(
Call, Ops[0], MaybeAlign());
1241 case PPC::BI__builtin_ppc_compare_and_swap:
1242 case PPC::BI__builtin_ppc_compare_and_swaplp: {
1251 llvm::AtomicOrdering::Monotonic, llvm::AtomicOrdering::Monotonic,
true);
1259 Value *LoadedVal = Pair.first.getScalarVal();
1260 Builder.CreateStore(LoadedVal, OldValAddr);
1263 case PPC::BI__builtin_ppc_fetch_and_add:
1264 case PPC::BI__builtin_ppc_fetch_and_addlp: {
1266 llvm::AtomicOrdering::Monotonic);
1268 case PPC::BI__builtin_ppc_fetch_and_and:
1269 case PPC::BI__builtin_ppc_fetch_and_andlp: {
1271 llvm::AtomicOrdering::Monotonic);
1274 case PPC::BI__builtin_ppc_fetch_and_or:
1275 case PPC::BI__builtin_ppc_fetch_and_orlp: {
1277 llvm::AtomicOrdering::Monotonic);
1279 case PPC::BI__builtin_ppc_fetch_and_swap:
1280 case PPC::BI__builtin_ppc_fetch_and_swaplp: {
1282 llvm::AtomicOrdering::Monotonic);
1284 case PPC::BI__builtin_ppc_ldarx:
1285 case PPC::BI__builtin_ppc_lwarx:
1286 case PPC::BI__builtin_ppc_lharx:
1287 case PPC::BI__builtin_ppc_lbarx:
1289 case PPC::BI__builtin_ppc_mfspr: {
1291 llvm::Type *RetType =
CGM.getDataLayout().getTypeSizeInBits(
VoidPtrTy) == 32
1294 Function *F =
CGM.getIntrinsic(Intrinsic::ppc_mfspr, RetType);
1295 return Builder.CreateCall(F, {Op0});
1297 case PPC::BI__builtin_ppc_mtspr: {
1300 llvm::Type *RetType =
CGM.getDataLayout().getTypeSizeInBits(
VoidPtrTy) == 32
1303 Function *F =
CGM.getIntrinsic(Intrinsic::ppc_mtspr, RetType);
1304 return Builder.CreateCall(F, {Op0, Op1});
1306 case PPC::BI__builtin_ppc_popcntb: {
1310 return Builder.CreateCall(F, {ArgValue},
"popcntb");
1312 case PPC::BI__builtin_ppc_mtfsf: {
1318 llvm::Function *F =
CGM.getIntrinsic(Intrinsic::ppc_mtfsf);
1319 return Builder.CreateCall(F, {Op0, Cast},
"");
1322 case PPC::BI__builtin_ppc_swdiv_nochk:
1323 case PPC::BI__builtin_ppc_swdivs_nochk: {
1326 FastMathFlags FMF =
Builder.getFastMathFlags();
1327 Builder.getFastMathFlags().setFast();
1328 Value *FDiv =
Builder.CreateFDiv(Op0, Op1,
"swdiv_nochk");
1329 Builder.getFastMathFlags() &= (FMF);
1332 case PPC::BI__builtin_ppc_fric:
1334 *
this, E, Intrinsic::rint,
1335 Intrinsic::experimental_constrained_rint))
1337 case PPC::BI__builtin_ppc_frim:
1338 case PPC::BI__builtin_ppc_frims:
1340 *
this, E, Intrinsic::floor,
1341 Intrinsic::experimental_constrained_floor))
1343 case PPC::BI__builtin_ppc_frin:
1344 case PPC::BI__builtin_ppc_frins:
1346 *
this, E, Intrinsic::round,
1347 Intrinsic::experimental_constrained_round))
1349 case PPC::BI__builtin_ppc_frip:
1350 case PPC::BI__builtin_ppc_frips:
1352 *
this, E, Intrinsic::ceil,
1353 Intrinsic::experimental_constrained_ceil))
1355 case PPC::BI__builtin_ppc_friz:
1356 case PPC::BI__builtin_ppc_frizs:
1358 *
this, E, Intrinsic::trunc,
1359 Intrinsic::experimental_constrained_trunc))
1361 case PPC::BI__builtin_ppc_fsqrt:
1362 case PPC::BI__builtin_ppc_fsqrts:
1364 *
this, E, Intrinsic::sqrt,
1365 Intrinsic::experimental_constrained_sqrt))
1367 case PPC::BI__builtin_ppc_test_data_class: {
1371 CGM.getIntrinsic(Intrinsic::ppc_test_data_class, Op0->
getType()),
1372 {Op0, Op1},
"test_data_class");
1374 case PPC::BI__builtin_ppc_maxfe: {
1379 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::ppc_maxfe),
1380 {Op0, Op1, Op2, Op3});
1382 case PPC::BI__builtin_ppc_maxfl: {
1387 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::ppc_maxfl),
1388 {Op0, Op1, Op2, Op3});
1390 case PPC::BI__builtin_ppc_maxfs: {
1395 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::ppc_maxfs),
1396 {Op0, Op1, Op2, Op3});
1398 case PPC::BI__builtin_ppc_minfe: {
1403 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::ppc_minfe),
1404 {Op0, Op1, Op2, Op3});
1406 case PPC::BI__builtin_ppc_minfl: {
1411 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::ppc_minfl),
1412 {Op0, Op1, Op2, Op3});
1414 case PPC::BI__builtin_ppc_minfs: {
1419 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::ppc_minfs),
1420 {Op0, Op1, Op2, Op3});
1422 case PPC::BI__builtin_ppc_swdiv:
1423 case PPC::BI__builtin_ppc_swdivs: {
1426 return Builder.CreateFDiv(Op0, Op1,
"swdiv");
1428 case PPC::BI__builtin_ppc_set_fpscr_rn:
1429 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::ppc_setrnd),
1430 {EmitScalarExpr(E->getArg(0))});
1431 case PPC::BI__builtin_ppc_mffs:
1432 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::ppc_readflm));
1434 case PPC::BI__builtin_amo_lwat_s: {
1438 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::ppc_amo_lwat),
1441 case PPC::BI__builtin_amo_ldat_s: {
1445 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::ppc_amo_ldat),
1448 case PPC::BI__builtin_amo_lwat_cond_s: {
1451 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::ppc_amo_lwat_cond),
1454 case PPC::BI__builtin_amo_ldat_cond_s: {
1457 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::ppc_amo_ldat_cond),
1460 case PPC::BI__builtin_amo_lwat_csne_s: {
1464 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::ppc_amo_lwat_csne),
1467 case PPC::BI__builtin_amo_ldat_csne_s: {
1471 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::ppc_amo_ldat_csne),
1474 case PPC::BI__builtin_amo_stwat_s: {
1478 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::ppc_amo_stwat),
1481 case PPC::BI__builtin_amo_stdat_s: {
1485 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::ppc_amo_stdat),