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: {
796 llvm::Function *F =
CGM.getIntrinsic(Intrinsic::fabs, ResultType);
801 case PPC::BI__builtin_ppc_recipdivf:
802 case PPC::BI__builtin_ppc_recipdivd:
803 case PPC::BI__builtin_ppc_rsqrtf:
804 case PPC::BI__builtin_ppc_rsqrtd: {
805 FastMathFlags FMF =
Builder.getFastMathFlags();
806 Builder.getFastMathFlags().setFast();
810 if (BuiltinID == PPC::BI__builtin_ppc_recipdivf ||
811 BuiltinID == PPC::BI__builtin_ppc_recipdivd) {
814 Builder.getFastMathFlags() &= (FMF);
817 auto *One = ConstantFP::get(ResultType, 1.0);
818 llvm::Function *F =
CGM.getIntrinsic(Intrinsic::sqrt, ResultType);
820 Builder.getFastMathFlags() &= (FMF);
823 case PPC::BI__builtin_ppc_alignx: {
827 if (AlignmentCI->getValue().ugt(llvm::Value::MaximumAlignment))
828 AlignmentCI = ConstantInt::get(AlignmentCI->getIntegerType(),
829 llvm::Value::MaximumAlignment);
833 AlignmentCI,
nullptr);
836 case PPC::BI__builtin_ppc_rdlam: {
840 llvm::Type *Ty = Op0->
getType();
841 Value *ShiftAmt =
Builder.CreateIntCast(Op1, Ty,
false);
842 Function *F =
CGM.getIntrinsic(Intrinsic::fshl, Ty);
843 Value *Rotate =
Builder.CreateCall(F, {Op0, Op0, ShiftAmt});
844 return Builder.CreateAnd(Rotate, Op2);
846 case PPC::BI__builtin_ppc_load2r: {
847 Function *F =
CGM.getIntrinsic(Intrinsic::ppc_load2r);
853 case PPC::BI__builtin_ppc_fnmsub:
854 case PPC::BI__builtin_ppc_fnmsubs:
855 case PPC::BI__builtin_vsx_xvmaddadp:
856 case PPC::BI__builtin_vsx_xvmaddasp:
857 case PPC::BI__builtin_vsx_xvnmaddadp:
858 case PPC::BI__builtin_vsx_xvnmaddasp:
859 case PPC::BI__builtin_vsx_xvmsubadp:
860 case PPC::BI__builtin_vsx_xvmsubasp:
861 case PPC::BI__builtin_vsx_xvnmsubadp:
862 case PPC::BI__builtin_vsx_xvnmsubasp: {
868 if (
Builder.getIsFPConstrained())
869 F =
CGM.getIntrinsic(Intrinsic::experimental_constrained_fma, ResultType);
871 F =
CGM.getIntrinsic(Intrinsic::fma, ResultType);
873 case PPC::BI__builtin_vsx_xvmaddadp:
874 case PPC::BI__builtin_vsx_xvmaddasp:
875 if (
Builder.getIsFPConstrained())
876 return Builder.CreateConstrainedFPCall(F, {
X, Y, Z});
878 return Builder.CreateCall(F, {
X, Y, Z});
879 case PPC::BI__builtin_vsx_xvnmaddadp:
880 case PPC::BI__builtin_vsx_xvnmaddasp:
881 if (
Builder.getIsFPConstrained())
883 Builder.CreateConstrainedFPCall(F, {X, Y, Z}),
"neg");
885 return Builder.CreateFNeg(
Builder.CreateCall(F, {X, Y, Z}),
"neg");
886 case PPC::BI__builtin_vsx_xvmsubadp:
887 case PPC::BI__builtin_vsx_xvmsubasp:
888 if (
Builder.getIsFPConstrained())
889 return Builder.CreateConstrainedFPCall(
890 F, {
X, Y,
Builder.CreateFNeg(Z,
"neg")});
893 case PPC::BI__builtin_ppc_fnmsub:
894 case PPC::BI__builtin_ppc_fnmsubs:
895 case PPC::BI__builtin_vsx_xvnmsubadp:
896 case PPC::BI__builtin_vsx_xvnmsubasp:
897 if (
Builder.getIsFPConstrained())
899 Builder.CreateConstrainedFPCall(
900 F, {X, Y, Builder.CreateFNeg(Z,
"neg")}),
904 CGM.getIntrinsic(Intrinsic::ppc_fnmsub, ResultType), {X, Y, Z});
906 llvm_unreachable(
"Unknown FMA operation");
910 case PPC::BI__builtin_vsx_insertword: {
914 llvm::Function *F =
CGM.getIntrinsic(Intrinsic::ppc_vsx_xxinsertw);
918 ConstantInt *ArgCI = dyn_cast<ConstantInt>(Op2);
920 "Third arg to xxinsertw intrinsic must be constant integer");
921 const int64_t MaxIndex = 12;
922 int64_t Index = std::clamp(ArgCI->getSExtValue(), (int64_t)0, MaxIndex);
933 Op1 =
Builder.CreateBitCast(Op1, llvm::FixedVectorType::get(
Int64Ty, 2));
937 Op0 =
Builder.CreateBitCast(Op0, llvm::FixedVectorType::get(
Int64Ty, 2));
938 Op0 =
Builder.CreateShuffleVector(Op0, Op0, {1, 0});
941 Index = MaxIndex - Index;
945 Op0 =
Builder.CreateBitCast(Op0, llvm::FixedVectorType::get(
Int32Ty, 4));
946 Op2 = ConstantInt::getSigned(
Int32Ty, Index);
947 return Builder.CreateCall(F, {Op0, Op1, Op2});
950 case PPC::BI__builtin_vsx_extractuword: {
953 llvm::Function *F =
CGM.getIntrinsic(Intrinsic::ppc_vsx_xxextractuw);
956 Op0 =
Builder.CreateBitCast(Op0, llvm::FixedVectorType::get(
Int64Ty, 2));
960 ConstantInt *ArgCI = dyn_cast<ConstantInt>(Op1);
962 "Second Arg to xxextractuw intrinsic must be a constant integer!");
963 const int64_t MaxIndex = 12;
964 int64_t Index = std::clamp(ArgCI->getSExtValue(), (int64_t)0, MaxIndex);
968 Index = MaxIndex - Index;
969 Op1 = ConstantInt::getSigned(
Int32Ty, Index);
978 Op1 = ConstantInt::getSigned(
Int32Ty, Index);
979 return Builder.CreateCall(F, {Op0, Op1});
983 case PPC::BI__builtin_vsx_xxpermdi: {
987 ConstantInt *ArgCI = dyn_cast<ConstantInt>(Op2);
988 assert(ArgCI &&
"Third arg must be constant integer!");
990 unsigned Index = ArgCI->getZExtValue();
991 Op0 =
Builder.CreateBitCast(Op0, llvm::FixedVectorType::get(
Int64Ty, 2));
992 Op1 =
Builder.CreateBitCast(Op1, llvm::FixedVectorType::get(
Int64Ty, 2));
997 int ElemIdx0 = (Index & 2) >> 1;
998 int ElemIdx1 = 2 + (Index & 1);
1000 int ShuffleElts[2] = {ElemIdx0, ElemIdx1};
1001 Value *ShuffleCall =
Builder.CreateShuffleVector(Op0, Op1, ShuffleElts);
1004 return Builder.CreateBitCast(ShuffleCall, RetTy);
1007 case PPC::BI__builtin_vsx_xxsldwi: {
1011 ConstantInt *ArgCI = dyn_cast<ConstantInt>(Op2);
1012 assert(ArgCI &&
"Third argument must be a compile time constant");
1013 unsigned Index = ArgCI->getZExtValue() & 0x3;
1014 Op0 =
Builder.CreateBitCast(Op0, llvm::FixedVectorType::get(
Int32Ty, 4));
1015 Op1 =
Builder.CreateBitCast(Op1, llvm::FixedVectorType::get(
Int32Ty, 4));
1026 ElemIdx0 = (8 - Index) % 8;
1027 ElemIdx1 = (9 - Index) % 8;
1028 ElemIdx2 = (10 - Index) % 8;
1029 ElemIdx3 = (11 - Index) % 8;
1033 ElemIdx1 = Index + 1;
1034 ElemIdx2 = Index + 2;
1035 ElemIdx3 = Index + 3;
1038 int ShuffleElts[4] = {ElemIdx0, ElemIdx1, ElemIdx2, ElemIdx3};
1039 Value *ShuffleCall =
Builder.CreateShuffleVector(Op0, Op1, ShuffleElts);
1042 return Builder.CreateBitCast(ShuffleCall, RetTy);
1045 case PPC::BI__builtin_pack_vector_int128: {
1049 Value *PoisonValue =
1050 llvm::PoisonValue::get(llvm::FixedVectorType::get(Op0->
getType(), 2));
1052 PoisonValue, Op0, (uint64_t)(isLittleEndian ? 1 : 0));
1053 Res =
Builder.CreateInsertElement(Res, Op1,
1054 (uint64_t)(isLittleEndian ? 0 : 1));
1058 case PPC::BI__builtin_unpack_vector_int128: {
1067 ConstantInt::get(Index->getIntegerType(), 1 - Index->getZExtValue());
1069 return Builder.CreateExtractElement(Unpacked, Index);
1072 case PPC::BI__builtin_ppc_sthcx: {
1073 llvm::Function *F =
CGM.getIntrinsic(Intrinsic::ppc_sthcx);
1076 return Builder.CreateCall(F, {Op0, Op1});
1085#define CUSTOM_BUILTIN(Name, Intr, Types, Accumulate, Feature) \
1086 case PPC::BI__builtin_##Name:
1087#include "clang/Basic/BuiltinsPPC.def"
1090 for (
unsigned i = 0, e = E->
getNumArgs(); i != e; i++)
1100 if (BuiltinID == PPC::BI__builtin_mma_disassemble_acc ||
1101 BuiltinID == PPC::BI__builtin_vsx_disassemble_pair ||
1102 BuiltinID == PPC::BI__builtin_mma_disassemble_pair) {
1103 unsigned NumVecs = 2;
1104 auto Intrinsic = Intrinsic::ppc_vsx_disassemble_pair;
1105 if (BuiltinID == PPC::BI__builtin_mma_disassemble_acc) {
1107 Intrinsic = Intrinsic::ppc_mma_disassemble_acc;
1109 llvm::Function *F =
CGM.getIntrinsic(Intrinsic);
1113 llvm::Type *VTy = llvm::FixedVectorType::get(
Int8Ty, 16);
1114 Value *Ptr = Ops[0];
1115 for (
unsigned i=0; i<NumVecs; i++) {
1117 llvm::ConstantInt* Index = llvm::ConstantInt::get(
IntTy, i);
1118 Value *GEP =
Builder.CreateInBoundsGEP(VTy, Ptr, Index);
1119 Builder.CreateAlignedStore(Vec, GEP, MaybeAlign(16));
1123 if (BuiltinID == PPC::BI__builtin_vsx_build_pair ||
1124 BuiltinID == PPC::BI__builtin_mma_build_acc) {
1132 std::reverse(Ops.begin() + 1, Ops.end());
1135 switch (BuiltinID) {
1136 #define CUSTOM_BUILTIN(Name, Intr, Types, Acc, Feature) \
1137 case PPC::BI__builtin_##Name: \
1138 ID = Intrinsic::ppc_##Intr; \
1141 #include "clang/Basic/BuiltinsPPC.def"
1143 if (BuiltinID == PPC::BI__builtin_vsx_lxvp ||
1144 BuiltinID == PPC::BI__builtin_vsx_stxvp ||
1145 BuiltinID == PPC::BI__builtin_mma_lxvp ||
1146 BuiltinID == PPC::BI__builtin_mma_stxvp) {
1147 if (BuiltinID == PPC::BI__builtin_vsx_lxvp ||
1148 BuiltinID == PPC::BI__builtin_mma_lxvp) {
1154 llvm::Function *F =
CGM.getIntrinsic(ID);
1155 return Builder.CreateCall(F, Ops,
"");
1161 CallOps.push_back(Acc);
1163 if (BuiltinID == PPC::BI__builtin_dmmr ||
1164 BuiltinID == PPC::BI__builtin_dmxor ||
1165 BuiltinID == PPC::BI__builtin_disassemble_dmr ||
1166 BuiltinID == PPC::BI__builtin_mma_dmsha2hash) {
1170 if (BuiltinID == PPC::BI__builtin_disassemble_dmr)
1171 return Builder.CreateAlignedStore(Ops[1], Ops[0], MaybeAlign());
1172 for (
unsigned i=1; i<Ops.size(); i++)
1173 CallOps.push_back(Ops[i]);
1174 llvm::Function *F =
CGM.getIntrinsic(ID);
1176 return Builder.CreateAlignedStore(
Call, Ops[0], MaybeAlign());
1179 case PPC::BI__builtin_ppc_compare_and_swap:
1180 case PPC::BI__builtin_ppc_compare_and_swaplp: {
1189 llvm::AtomicOrdering::Monotonic, llvm::AtomicOrdering::Monotonic,
true);
1197 Value *LoadedVal = Pair.first.getScalarVal();
1198 Builder.CreateStore(LoadedVal, OldValAddr);
1201 case PPC::BI__builtin_ppc_fetch_and_add:
1202 case PPC::BI__builtin_ppc_fetch_and_addlp: {
1204 llvm::AtomicOrdering::Monotonic);
1206 case PPC::BI__builtin_ppc_fetch_and_and:
1207 case PPC::BI__builtin_ppc_fetch_and_andlp: {
1209 llvm::AtomicOrdering::Monotonic);
1212 case PPC::BI__builtin_ppc_fetch_and_or:
1213 case PPC::BI__builtin_ppc_fetch_and_orlp: {
1215 llvm::AtomicOrdering::Monotonic);
1217 case PPC::BI__builtin_ppc_fetch_and_swap:
1218 case PPC::BI__builtin_ppc_fetch_and_swaplp: {
1220 llvm::AtomicOrdering::Monotonic);
1222 case PPC::BI__builtin_ppc_ldarx:
1223 case PPC::BI__builtin_ppc_lwarx:
1224 case PPC::BI__builtin_ppc_lharx:
1225 case PPC::BI__builtin_ppc_lbarx:
1227 case PPC::BI__builtin_ppc_mfspr: {
1229 llvm::Type *RetType =
CGM.getDataLayout().getTypeSizeInBits(
VoidPtrTy) == 32
1232 Function *F =
CGM.getIntrinsic(Intrinsic::ppc_mfspr, RetType);
1233 return Builder.CreateCall(F, {Op0});
1235 case PPC::BI__builtin_ppc_mtspr: {
1238 llvm::Type *RetType =
CGM.getDataLayout().getTypeSizeInBits(
VoidPtrTy) == 32
1241 Function *F =
CGM.getIntrinsic(Intrinsic::ppc_mtspr, RetType);
1242 return Builder.CreateCall(F, {Op0, Op1});
1244 case PPC::BI__builtin_ppc_popcntb: {
1248 return Builder.CreateCall(F, {ArgValue},
"popcntb");
1250 case PPC::BI__builtin_ppc_mtfsf: {
1256 llvm::Function *F =
CGM.getIntrinsic(Intrinsic::ppc_mtfsf);
1257 return Builder.CreateCall(F, {Op0, Cast},
"");
1260 case PPC::BI__builtin_ppc_swdiv_nochk:
1261 case PPC::BI__builtin_ppc_swdivs_nochk: {
1264 FastMathFlags FMF =
Builder.getFastMathFlags();
1265 Builder.getFastMathFlags().setFast();
1266 Value *FDiv =
Builder.CreateFDiv(Op0, Op1,
"swdiv_nochk");
1267 Builder.getFastMathFlags() &= (FMF);
1270 case PPC::BI__builtin_ppc_fric:
1272 *
this, E, Intrinsic::rint,
1273 Intrinsic::experimental_constrained_rint))
1275 case PPC::BI__builtin_ppc_frim:
1276 case PPC::BI__builtin_ppc_frims:
1278 *
this, E, Intrinsic::floor,
1279 Intrinsic::experimental_constrained_floor))
1281 case PPC::BI__builtin_ppc_frin:
1282 case PPC::BI__builtin_ppc_frins:
1284 *
this, E, Intrinsic::round,
1285 Intrinsic::experimental_constrained_round))
1287 case PPC::BI__builtin_ppc_frip:
1288 case PPC::BI__builtin_ppc_frips:
1290 *
this, E, Intrinsic::ceil,
1291 Intrinsic::experimental_constrained_ceil))
1293 case PPC::BI__builtin_ppc_friz:
1294 case PPC::BI__builtin_ppc_frizs:
1296 *
this, E, Intrinsic::trunc,
1297 Intrinsic::experimental_constrained_trunc))
1299 case PPC::BI__builtin_ppc_fsqrt:
1300 case PPC::BI__builtin_ppc_fsqrts:
1302 *
this, E, Intrinsic::sqrt,
1303 Intrinsic::experimental_constrained_sqrt))
1305 case PPC::BI__builtin_ppc_test_data_class: {
1309 CGM.getIntrinsic(Intrinsic::ppc_test_data_class, Op0->
getType()),
1310 {Op0, Op1},
"test_data_class");
1312 case PPC::BI__builtin_ppc_maxfe: {
1317 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::ppc_maxfe),
1318 {Op0, Op1, Op2, Op3});
1320 case PPC::BI__builtin_ppc_maxfl: {
1325 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::ppc_maxfl),
1326 {Op0, Op1, Op2, Op3});
1328 case PPC::BI__builtin_ppc_maxfs: {
1333 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::ppc_maxfs),
1334 {Op0, Op1, Op2, Op3});
1336 case PPC::BI__builtin_ppc_minfe: {
1341 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::ppc_minfe),
1342 {Op0, Op1, Op2, Op3});
1344 case PPC::BI__builtin_ppc_minfl: {
1349 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::ppc_minfl),
1350 {Op0, Op1, Op2, Op3});
1352 case PPC::BI__builtin_ppc_minfs: {
1357 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::ppc_minfs),
1358 {Op0, Op1, Op2, Op3});
1360 case PPC::BI__builtin_ppc_swdiv:
1361 case PPC::BI__builtin_ppc_swdivs: {
1364 return Builder.CreateFDiv(Op0, Op1,
"swdiv");
1366 case PPC::BI__builtin_ppc_set_fpscr_rn:
1367 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::ppc_setrnd),
1368 {EmitScalarExpr(E->getArg(0))});
1369 case PPC::BI__builtin_ppc_mffs:
1370 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::ppc_readflm));
1372 case PPC::BI__builtin_amo_lwat_s: {
1376 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::ppc_amo_lwat),
1379 case PPC::BI__builtin_amo_ldat_s: {
1383 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::ppc_amo_ldat),
1386 case PPC::BI__builtin_amo_lwat_cond_s: {
1389 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::ppc_amo_lwat_cond),
1392 case PPC::BI__builtin_amo_ldat_cond_s: {
1395 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::ppc_amo_ldat_cond),
1398 case PPC::BI__builtin_amo_lwat_csne_s: {
1402 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::ppc_amo_lwat_csne),
1405 case PPC::BI__builtin_amo_ldat_csne_s: {
1409 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::ppc_amo_ldat_csne),
1412 case PPC::BI__builtin_amo_stwat_s: {
1416 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::ppc_amo_stwat),
1419 case PPC::BI__builtin_amo_stdat_s: {
1423 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::ppc_amo_stdat),