541 NEONMAP1(__a32_vcvt_bf16_f32, arm_neon_vcvtfp2bf, 0),
549 NEONMAP1(vabsq_v, arm_neon_vabs, 0),
553 NEONMAP1(vaesdq_u8, arm_neon_aesd, 0),
554 NEONMAP1(vaeseq_u8, arm_neon_aese, 0),
555 NEONMAP1(vaesimcq_u8, arm_neon_aesimc, 0),
556 NEONMAP1(vaesmcq_u8, arm_neon_aesmc, 0),
557 NEONMAP1(vbfdot_f32, arm_neon_bfdot, 0),
558 NEONMAP1(vbfdotq_f32, arm_neon_bfdot, 0),
559 NEONMAP1(vbfmlalbq_f32, arm_neon_bfmlalb, 0),
560 NEONMAP1(vbfmlaltq_f32, arm_neon_bfmlalt, 0),
561 NEONMAP1(vbfmmlaq_f32, arm_neon_bfmmla, 0),
574 NEONMAP1(vcage_v, arm_neon_vacge, 0),
575 NEONMAP1(vcageq_v, arm_neon_vacge, 0),
576 NEONMAP1(vcagt_v, arm_neon_vacgt, 0),
577 NEONMAP1(vcagtq_v, arm_neon_vacgt, 0),
578 NEONMAP1(vcale_v, arm_neon_vacge, 0),
579 NEONMAP1(vcaleq_v, arm_neon_vacge, 0),
580 NEONMAP1(vcalt_v, arm_neon_vacgt, 0),
581 NEONMAP1(vcaltq_v, arm_neon_vacgt, 0),
601 NEONMAP1(vcvt_n_f16_s16, arm_neon_vcvtfxs2fp, 0),
602 NEONMAP1(vcvt_n_f16_u16, arm_neon_vcvtfxu2fp, 0),
603 NEONMAP2(vcvt_n_f32_v, arm_neon_vcvtfxu2fp, arm_neon_vcvtfxs2fp, 0),
604 NEONMAP1(vcvt_n_s16_f16, arm_neon_vcvtfp2fxs, 0),
605 NEONMAP1(vcvt_n_s32_v, arm_neon_vcvtfp2fxs, 0),
606 NEONMAP1(vcvt_n_s64_v, arm_neon_vcvtfp2fxs, 0),
607 NEONMAP1(vcvt_n_u16_f16, arm_neon_vcvtfp2fxu, 0),
608 NEONMAP1(vcvt_n_u32_v, arm_neon_vcvtfp2fxu, 0),
609 NEONMAP1(vcvt_n_u64_v, arm_neon_vcvtfp2fxu, 0),
616 NEONMAP1(vcvta_s16_f16, arm_neon_vcvtas, 0),
617 NEONMAP1(vcvta_s32_v, arm_neon_vcvtas, 0),
618 NEONMAP1(vcvta_s64_v, arm_neon_vcvtas, 0),
619 NEONMAP1(vcvta_u16_f16, arm_neon_vcvtau, 0),
620 NEONMAP1(vcvta_u32_v, arm_neon_vcvtau, 0),
621 NEONMAP1(vcvta_u64_v, arm_neon_vcvtau, 0),
622 NEONMAP1(vcvtaq_s16_f16, arm_neon_vcvtas, 0),
623 NEONMAP1(vcvtaq_s32_v, arm_neon_vcvtas, 0),
624 NEONMAP1(vcvtaq_s64_v, arm_neon_vcvtas, 0),
625 NEONMAP1(vcvtaq_u16_f16, arm_neon_vcvtau, 0),
626 NEONMAP1(vcvtaq_u32_v, arm_neon_vcvtau, 0),
627 NEONMAP1(vcvtaq_u64_v, arm_neon_vcvtau, 0),
628 NEONMAP1(vcvth_bf16_f32, arm_neon_vcvtbfp2bf, 0),
629 NEONMAP1(vcvtm_s16_f16, arm_neon_vcvtms, 0),
630 NEONMAP1(vcvtm_s32_v, arm_neon_vcvtms, 0),
631 NEONMAP1(vcvtm_s64_v, arm_neon_vcvtms, 0),
632 NEONMAP1(vcvtm_u16_f16, arm_neon_vcvtmu, 0),
633 NEONMAP1(vcvtm_u32_v, arm_neon_vcvtmu, 0),
634 NEONMAP1(vcvtm_u64_v, arm_neon_vcvtmu, 0),
635 NEONMAP1(vcvtmq_s16_f16, arm_neon_vcvtms, 0),
636 NEONMAP1(vcvtmq_s32_v, arm_neon_vcvtms, 0),
637 NEONMAP1(vcvtmq_s64_v, arm_neon_vcvtms, 0),
638 NEONMAP1(vcvtmq_u16_f16, arm_neon_vcvtmu, 0),
639 NEONMAP1(vcvtmq_u32_v, arm_neon_vcvtmu, 0),
640 NEONMAP1(vcvtmq_u64_v, arm_neon_vcvtmu, 0),
641 NEONMAP1(vcvtn_s16_f16, arm_neon_vcvtns, 0),
642 NEONMAP1(vcvtn_s32_v, arm_neon_vcvtns, 0),
643 NEONMAP1(vcvtn_s64_v, arm_neon_vcvtns, 0),
644 NEONMAP1(vcvtn_u16_f16, arm_neon_vcvtnu, 0),
645 NEONMAP1(vcvtn_u32_v, arm_neon_vcvtnu, 0),
646 NEONMAP1(vcvtn_u64_v, arm_neon_vcvtnu, 0),
647 NEONMAP1(vcvtnq_s16_f16, arm_neon_vcvtns, 0),
648 NEONMAP1(vcvtnq_s32_v, arm_neon_vcvtns, 0),
649 NEONMAP1(vcvtnq_s64_v, arm_neon_vcvtns, 0),
650 NEONMAP1(vcvtnq_u16_f16, arm_neon_vcvtnu, 0),
651 NEONMAP1(vcvtnq_u32_v, arm_neon_vcvtnu, 0),
652 NEONMAP1(vcvtnq_u64_v, arm_neon_vcvtnu, 0),
653 NEONMAP1(vcvtp_s16_f16, arm_neon_vcvtps, 0),
654 NEONMAP1(vcvtp_s32_v, arm_neon_vcvtps, 0),
655 NEONMAP1(vcvtp_s64_v, arm_neon_vcvtps, 0),
656 NEONMAP1(vcvtp_u16_f16, arm_neon_vcvtpu, 0),
657 NEONMAP1(vcvtp_u32_v, arm_neon_vcvtpu, 0),
658 NEONMAP1(vcvtp_u64_v, arm_neon_vcvtpu, 0),
659 NEONMAP1(vcvtpq_s16_f16, arm_neon_vcvtps, 0),
660 NEONMAP1(vcvtpq_s32_v, arm_neon_vcvtps, 0),
661 NEONMAP1(vcvtpq_s64_v, arm_neon_vcvtps, 0),
662 NEONMAP1(vcvtpq_u16_f16, arm_neon_vcvtpu, 0),
663 NEONMAP1(vcvtpq_u32_v, arm_neon_vcvtpu, 0),
664 NEONMAP1(vcvtpq_u64_v, arm_neon_vcvtpu, 0),
668 NEONMAP1(vcvtq_n_f16_s16, arm_neon_vcvtfxs2fp, 0),
669 NEONMAP1(vcvtq_n_f16_u16, arm_neon_vcvtfxu2fp, 0),
670 NEONMAP2(vcvtq_n_f32_v, arm_neon_vcvtfxu2fp, arm_neon_vcvtfxs2fp, 0),
671 NEONMAP1(vcvtq_n_s16_f16, arm_neon_vcvtfp2fxs, 0),
672 NEONMAP1(vcvtq_n_s32_v, arm_neon_vcvtfp2fxs, 0),
673 NEONMAP1(vcvtq_n_s64_v, arm_neon_vcvtfp2fxs, 0),
674 NEONMAP1(vcvtq_n_u16_f16, arm_neon_vcvtfp2fxu, 0),
675 NEONMAP1(vcvtq_n_u32_v, arm_neon_vcvtfp2fxu, 0),
676 NEONMAP1(vcvtq_n_u64_v, arm_neon_vcvtfp2fxu, 0),
683 NEONMAP1(vdot_s32, arm_neon_sdot, 0),
684 NEONMAP1(vdot_u32, arm_neon_udot, 0),
685 NEONMAP1(vdotq_s32, arm_neon_sdot, 0),
686 NEONMAP1(vdotq_u32, arm_neon_udot, 0),
697 NEONMAP1(vld1_x2_v, arm_neon_vld1x2, 0),
698 NEONMAP1(vld1_x3_v, arm_neon_vld1x3, 0),
699 NEONMAP1(vld1_x4_v, arm_neon_vld1x4, 0),
701 NEONMAP1(vld1q_v, arm_neon_vld1, 0),
702 NEONMAP1(vld1q_x2_v, arm_neon_vld1x2, 0),
703 NEONMAP1(vld1q_x3_v, arm_neon_vld1x3, 0),
704 NEONMAP1(vld1q_x4_v, arm_neon_vld1x4, 0),
705 NEONMAP1(vld2_dup_v, arm_neon_vld2dup, 0),
706 NEONMAP1(vld2_lane_v, arm_neon_vld2lane, 0),
708 NEONMAP1(vld2q_dup_v, arm_neon_vld2dup, 0),
709 NEONMAP1(vld2q_lane_v, arm_neon_vld2lane, 0),
710 NEONMAP1(vld2q_v, arm_neon_vld2, 0),
711 NEONMAP1(vld3_dup_v, arm_neon_vld3dup, 0),
712 NEONMAP1(vld3_lane_v, arm_neon_vld3lane, 0),
714 NEONMAP1(vld3q_dup_v, arm_neon_vld3dup, 0),
715 NEONMAP1(vld3q_lane_v, arm_neon_vld3lane, 0),
716 NEONMAP1(vld3q_v, arm_neon_vld3, 0),
717 NEONMAP1(vld4_dup_v, arm_neon_vld4dup, 0),
718 NEONMAP1(vld4_lane_v, arm_neon_vld4lane, 0),
720 NEONMAP1(vld4q_dup_v, arm_neon_vld4dup, 0),
721 NEONMAP1(vld4q_lane_v, arm_neon_vld4lane, 0),
722 NEONMAP1(vld4q_v, arm_neon_vld4, 0),
731 NEONMAP1(vmmlaq_s32, arm_neon_smmla, 0),
732 NEONMAP1(vmmlaq_u32, arm_neon_ummla, 0),
750 NEONMAP2(vqdmlal_v, arm_neon_vqdmull, sadd_sat, 0),
751 NEONMAP2(vqdmlsl_v, arm_neon_vqdmull, ssub_sat, 0),
775 NEONMAP1(vqshlu_n_v, arm_neon_vqshiftsu, 0),
776 NEONMAP1(vqshluq_n_v, arm_neon_vqshiftsu, 0),
780 NEONMAP2(vrecpe_v, arm_neon_vrecpe, arm_neon_vrecpe, 0),
781 NEONMAP2(vrecpeq_v, arm_neon_vrecpe, arm_neon_vrecpe, 0),
804 NEONMAP2(vrsqrte_v, arm_neon_vrsqrte, arm_neon_vrsqrte, 0),
805 NEONMAP2(vrsqrteq_v, arm_neon_vrsqrte, arm_neon_vrsqrte, 0),
809 NEONMAP1(vsha1su0q_u32, arm_neon_sha1su0, 0),
810 NEONMAP1(vsha1su1q_u32, arm_neon_sha1su1, 0),
811 NEONMAP1(vsha256h2q_u32, arm_neon_sha256h2, 0),
812 NEONMAP1(vsha256hq_u32, arm_neon_sha256h, 0),
813 NEONMAP1(vsha256su0q_u32, arm_neon_sha256su0, 0),
814 NEONMAP1(vsha256su1q_u32, arm_neon_sha256su1, 0),
824 NEONMAP1(vst1_x2_v, arm_neon_vst1x2, 0),
825 NEONMAP1(vst1_x3_v, arm_neon_vst1x3, 0),
826 NEONMAP1(vst1_x4_v, arm_neon_vst1x4, 0),
827 NEONMAP1(vst1q_v, arm_neon_vst1, 0),
828 NEONMAP1(vst1q_x2_v, arm_neon_vst1x2, 0),
829 NEONMAP1(vst1q_x3_v, arm_neon_vst1x3, 0),
830 NEONMAP1(vst1q_x4_v, arm_neon_vst1x4, 0),
831 NEONMAP1(vst2_lane_v, arm_neon_vst2lane, 0),
833 NEONMAP1(vst2q_lane_v, arm_neon_vst2lane, 0),
834 NEONMAP1(vst2q_v, arm_neon_vst2, 0),
835 NEONMAP1(vst3_lane_v, arm_neon_vst3lane, 0),
837 NEONMAP1(vst3q_lane_v, arm_neon_vst3lane, 0),
838 NEONMAP1(vst3q_v, arm_neon_vst3, 0),
839 NEONMAP1(vst4_lane_v, arm_neon_vst4lane, 0),
841 NEONMAP1(vst4q_lane_v, arm_neon_vst4lane, 0),
842 NEONMAP1(vst4q_v, arm_neon_vst4, 0),
848 NEONMAP1(vusdot_s32, arm_neon_usdot, 0),
849 NEONMAP1(vusdotq_s32, arm_neon_usdot, 0),
850 NEONMAP1(vusmmlaq_s32, arm_neon_usmmla, 0),
1121 unsigned BuiltinID,
unsigned LLVMIntrinsic,
unsigned AltLLVMIntrinsic,
1122 const char *NameHint,
unsigned Modifier,
const CallExpr *E,
1124 llvm::Triple::ArchType
Arch) {
1130 std::optional<llvm::APSInt> NeonTypeConst =
1137 const bool Usgn =
Type.isUnsigned();
1138 const bool Quad =
Type.isQuad();
1139 const bool Floating =
Type.isFloatingPoint();
1141 const bool AllowBFloatArgsAndRet =
1144 llvm::FixedVectorType *VTy =
1145 GetNeonType(
this,
Type, HasFastHalfType,
false, AllowBFloatArgsAndRet);
1146 llvm::Type *Ty = VTy;
1150 auto getAlignmentValue32 = [&](
Address addr) ->
Value* {
1151 return Builder.getInt32(addr.getAlignment().getQuantity());
1154 unsigned Int = LLVMIntrinsic;
1156 Int = AltLLVMIntrinsic;
1158 switch (BuiltinID) {
1160 case NEON::BI__builtin_neon_splat_lane_v:
1161 case NEON::BI__builtin_neon_splat_laneq_v:
1162 case NEON::BI__builtin_neon_splatq_lane_v:
1163 case NEON::BI__builtin_neon_splatq_laneq_v: {
1164 auto NumElements = VTy->getElementCount();
1165 if (BuiltinID == NEON::BI__builtin_neon_splatq_lane_v)
1166 NumElements = NumElements * 2;
1167 if (BuiltinID == NEON::BI__builtin_neon_splat_laneq_v)
1168 NumElements = NumElements.divideCoefficientBy(2);
1170 Ops[0] =
Builder.CreateBitCast(Ops[0], VTy);
1173 case NEON::BI__builtin_neon_vpadd_v:
1174 case NEON::BI__builtin_neon_vpaddq_v:
1176 if (VTy->getElementType()->isFloatingPointTy() &&
1177 Int == Intrinsic::aarch64_neon_addp)
1178 Int = Intrinsic::aarch64_neon_faddp;
1180 case NEON::BI__builtin_neon_vabs_v:
1181 case NEON::BI__builtin_neon_vabsq_v:
1182 if (VTy->getElementType()->isFloatingPointTy())
1183 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::fabs, Ty), Ops,
"vabs");
1184 return EmitNeonCall(
CGM.getIntrinsic(LLVMIntrinsic, Ty), Ops,
"vabs");
1185 case NEON::BI__builtin_neon_vadd_v:
1186 case NEON::BI__builtin_neon_vaddq_v: {
1187 llvm::Type *VTy = llvm::FixedVectorType::get(
Int8Ty, Quad ? 16 : 8);
1188 Ops[0] =
Builder.CreateBitCast(Ops[0], VTy);
1189 Ops[1] =
Builder.CreateBitCast(Ops[1], VTy);
1190 Ops[0] =
Builder.CreateXor(Ops[0], Ops[1]);
1191 return Builder.CreateBitCast(Ops[0], Ty);
1193 case NEON::BI__builtin_neon_vaddhn_v: {
1194 llvm::FixedVectorType *SrcTy =
1195 llvm::FixedVectorType::getExtendedElementVectorType(VTy);
1198 Ops[0] =
Builder.CreateBitCast(Ops[0], SrcTy);
1199 Ops[1] =
Builder.CreateBitCast(Ops[1], SrcTy);
1200 Ops[0] =
Builder.CreateAdd(Ops[0], Ops[1],
"vaddhn");
1204 ConstantInt::get(SrcTy, SrcTy->getScalarSizeInBits() / 2);
1205 Ops[0] =
Builder.CreateLShr(Ops[0], ShiftAmt,
"vaddhn");
1208 return Builder.CreateTrunc(Ops[0], VTy,
"vaddhn");
1210 case NEON::BI__builtin_neon_vcale_v:
1211 case NEON::BI__builtin_neon_vcaleq_v:
1212 case NEON::BI__builtin_neon_vcalt_v:
1213 case NEON::BI__builtin_neon_vcaltq_v:
1214 std::swap(Ops[0], Ops[1]);
1216 case NEON::BI__builtin_neon_vcage_v:
1217 case NEON::BI__builtin_neon_vcageq_v:
1218 case NEON::BI__builtin_neon_vcagt_v:
1219 case NEON::BI__builtin_neon_vcagtq_v: {
1221 switch (VTy->getScalarSizeInBits()) {
1222 default: llvm_unreachable(
"unexpected type");
1233 auto *VecFlt = llvm::FixedVectorType::get(Ty, VTy->getNumElements());
1234 llvm::Type *Tys[] = { VTy, VecFlt };
1235 Function *F =
CGM.getIntrinsic(LLVMIntrinsic, Tys);
1238 case NEON::BI__builtin_neon_vceqz_v:
1239 case NEON::BI__builtin_neon_vceqzq_v:
1241 Ops[0], Ty, Floating ? ICmpInst::FCMP_OEQ : ICmpInst::ICMP_EQ,
"vceqz");
1242 case NEON::BI__builtin_neon_vcgez_v:
1243 case NEON::BI__builtin_neon_vcgezq_v:
1245 Ops[0], Ty, Floating ? ICmpInst::FCMP_OGE : ICmpInst::ICMP_SGE,
1247 case NEON::BI__builtin_neon_vclez_v:
1248 case NEON::BI__builtin_neon_vclezq_v:
1250 Ops[0], Ty, Floating ? ICmpInst::FCMP_OLE : ICmpInst::ICMP_SLE,
1252 case NEON::BI__builtin_neon_vcgtz_v:
1253 case NEON::BI__builtin_neon_vcgtzq_v:
1255 Ops[0], Ty, Floating ? ICmpInst::FCMP_OGT : ICmpInst::ICMP_SGT,
1257 case NEON::BI__builtin_neon_vcltz_v:
1258 case NEON::BI__builtin_neon_vcltzq_v:
1260 Ops[0], Ty, Floating ? ICmpInst::FCMP_OLT : ICmpInst::ICMP_SLT,
1262 case NEON::BI__builtin_neon_vclz_v:
1263 case NEON::BI__builtin_neon_vclzq_v:
1268 case NEON::BI__builtin_neon_vcvt_f32_v:
1269 case NEON::BI__builtin_neon_vcvtq_f32_v:
1270 Ops[0] =
Builder.CreateBitCast(Ops[0], Ty);
1273 return Usgn ?
Builder.CreateUIToFP(Ops[0], Ty,
"vcvt")
1274 :
Builder.CreateSIToFP(Ops[0], Ty,
"vcvt");
1275 case NEON::BI__builtin_neon_vcvt_f16_s16:
1276 case NEON::BI__builtin_neon_vcvt_f16_u16:
1277 case NEON::BI__builtin_neon_vcvtq_f16_s16:
1278 case NEON::BI__builtin_neon_vcvtq_f16_u16:
1279 Ops[0] =
Builder.CreateBitCast(Ops[0], Ty);
1282 return Usgn ?
Builder.CreateUIToFP(Ops[0], Ty,
"vcvt")
1283 :
Builder.CreateSIToFP(Ops[0], Ty,
"vcvt");
1284 case NEON::BI__builtin_neon_vcvt_n_f16_s16:
1285 case NEON::BI__builtin_neon_vcvt_n_f16_u16:
1286 case NEON::BI__builtin_neon_vcvtq_n_f16_s16:
1287 case NEON::BI__builtin_neon_vcvtq_n_f16_u16: {
1292 case NEON::BI__builtin_neon_vcvt_n_f32_v:
1293 case NEON::BI__builtin_neon_vcvt_n_f64_v:
1294 case NEON::BI__builtin_neon_vcvtq_n_f32_v:
1295 case NEON::BI__builtin_neon_vcvtq_n_f64_v: {
1297 Int = Usgn ? LLVMIntrinsic : AltLLVMIntrinsic;
1301 case NEON::BI__builtin_neon_vcvt_n_s16_f16:
1302 case NEON::BI__builtin_neon_vcvt_n_s32_v:
1303 case NEON::BI__builtin_neon_vcvt_n_u16_f16:
1304 case NEON::BI__builtin_neon_vcvt_n_u32_v:
1305 case NEON::BI__builtin_neon_vcvt_n_s64_v:
1306 case NEON::BI__builtin_neon_vcvt_n_u64_v:
1307 case NEON::BI__builtin_neon_vcvtq_n_s16_f16:
1308 case NEON::BI__builtin_neon_vcvtq_n_s32_v:
1309 case NEON::BI__builtin_neon_vcvtq_n_u16_f16:
1310 case NEON::BI__builtin_neon_vcvtq_n_u32_v:
1311 case NEON::BI__builtin_neon_vcvtq_n_s64_v:
1312 case NEON::BI__builtin_neon_vcvtq_n_u64_v: {
1314 Function *F =
CGM.getIntrinsic(LLVMIntrinsic, Tys);
1317 case NEON::BI__builtin_neon_vcvt_s32_v:
1318 case NEON::BI__builtin_neon_vcvt_u32_v:
1319 case NEON::BI__builtin_neon_vcvt_s64_v:
1320 case NEON::BI__builtin_neon_vcvt_u64_v:
1321 case NEON::BI__builtin_neon_vcvt_s16_f16:
1322 case NEON::BI__builtin_neon_vcvt_u16_f16:
1323 case NEON::BI__builtin_neon_vcvtq_s32_v:
1324 case NEON::BI__builtin_neon_vcvtq_u32_v:
1325 case NEON::BI__builtin_neon_vcvtq_s64_v:
1326 case NEON::BI__builtin_neon_vcvtq_u64_v:
1327 case NEON::BI__builtin_neon_vcvtq_s16_f16:
1328 case NEON::BI__builtin_neon_vcvtq_u16_f16: {
1332 if (!
Builder.getIsFPConstrained())
1333 Int = Usgn ? Intrinsic::fptoui_sat : Intrinsic::fptosi_sat;
1334 llvm::Type *Tys[2] = {Ty, Ops[0]->getType()};
1339 return Usgn ?
Builder.CreateFPToUI(Ops[0], Ty,
"vcvt")
1340 :
Builder.CreateFPToSI(Ops[0], Ty,
"vcvt");
1342 case NEON::BI__builtin_neon_vcvta_s16_f16:
1343 case NEON::BI__builtin_neon_vcvta_s32_v:
1344 case NEON::BI__builtin_neon_vcvta_s64_v:
1345 case NEON::BI__builtin_neon_vcvta_u16_f16:
1346 case NEON::BI__builtin_neon_vcvta_u32_v:
1347 case NEON::BI__builtin_neon_vcvta_u64_v:
1348 case NEON::BI__builtin_neon_vcvtaq_s16_f16:
1349 case NEON::BI__builtin_neon_vcvtaq_s32_v:
1350 case NEON::BI__builtin_neon_vcvtaq_s64_v:
1351 case NEON::BI__builtin_neon_vcvtaq_u16_f16:
1352 case NEON::BI__builtin_neon_vcvtaq_u32_v:
1353 case NEON::BI__builtin_neon_vcvtaq_u64_v:
1354 case NEON::BI__builtin_neon_vcvtn_s16_f16:
1355 case NEON::BI__builtin_neon_vcvtn_s32_v:
1356 case NEON::BI__builtin_neon_vcvtn_s64_v:
1357 case NEON::BI__builtin_neon_vcvtn_u16_f16:
1358 case NEON::BI__builtin_neon_vcvtn_u32_v:
1359 case NEON::BI__builtin_neon_vcvtn_u64_v:
1360 case NEON::BI__builtin_neon_vcvtnq_s16_f16:
1361 case NEON::BI__builtin_neon_vcvtnq_s32_v:
1362 case NEON::BI__builtin_neon_vcvtnq_s64_v:
1363 case NEON::BI__builtin_neon_vcvtnq_u16_f16:
1364 case NEON::BI__builtin_neon_vcvtnq_u32_v:
1365 case NEON::BI__builtin_neon_vcvtnq_u64_v:
1366 case NEON::BI__builtin_neon_vcvtp_s16_f16:
1367 case NEON::BI__builtin_neon_vcvtp_s32_v:
1368 case NEON::BI__builtin_neon_vcvtp_s64_v:
1369 case NEON::BI__builtin_neon_vcvtp_u16_f16:
1370 case NEON::BI__builtin_neon_vcvtp_u32_v:
1371 case NEON::BI__builtin_neon_vcvtp_u64_v:
1372 case NEON::BI__builtin_neon_vcvtpq_s16_f16:
1373 case NEON::BI__builtin_neon_vcvtpq_s32_v:
1374 case NEON::BI__builtin_neon_vcvtpq_s64_v:
1375 case NEON::BI__builtin_neon_vcvtpq_u16_f16:
1376 case NEON::BI__builtin_neon_vcvtpq_u32_v:
1377 case NEON::BI__builtin_neon_vcvtpq_u64_v:
1378 case NEON::BI__builtin_neon_vcvtm_s16_f16:
1379 case NEON::BI__builtin_neon_vcvtm_s32_v:
1380 case NEON::BI__builtin_neon_vcvtm_s64_v:
1381 case NEON::BI__builtin_neon_vcvtm_u16_f16:
1382 case NEON::BI__builtin_neon_vcvtm_u32_v:
1383 case NEON::BI__builtin_neon_vcvtm_u64_v:
1384 case NEON::BI__builtin_neon_vcvtmq_s16_f16:
1385 case NEON::BI__builtin_neon_vcvtmq_s32_v:
1386 case NEON::BI__builtin_neon_vcvtmq_s64_v:
1387 case NEON::BI__builtin_neon_vcvtmq_u16_f16:
1388 case NEON::BI__builtin_neon_vcvtmq_u32_v:
1389 case NEON::BI__builtin_neon_vcvtmq_u64_v: {
1391 return EmitNeonCall(
CGM.getIntrinsic(LLVMIntrinsic, Tys), Ops, NameHint);
1393 case NEON::BI__builtin_neon_vcvtx_f32_v: {
1394 llvm::Type *Tys[2] = { VTy->getTruncatedElementVectorType(VTy), Ty};
1395 return EmitNeonCall(
CGM.getIntrinsic(LLVMIntrinsic, Tys), Ops, NameHint);
1398 case NEON::BI__builtin_neon_vext_v:
1399 case NEON::BI__builtin_neon_vextq_v: {
1402 for (
unsigned i = 0, e = VTy->getNumElements(); i != e; ++i)
1403 Indices.push_back(i+CV);
1405 Ops[0] =
Builder.CreateBitCast(Ops[0], Ty);
1406 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
1407 return Builder.CreateShuffleVector(Ops[0], Ops[1], Indices,
"vext");
1409 case NEON::BI__builtin_neon_vfma_v:
1410 case NEON::BI__builtin_neon_vfmaq_v: {
1411 Ops[0] =
Builder.CreateBitCast(Ops[0], Ty);
1412 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
1413 Ops[2] =
Builder.CreateBitCast(Ops[2], Ty);
1417 *
this, Intrinsic::fma, Intrinsic::experimental_constrained_fma, Ty,
1418 {Ops[1], Ops[2], Ops[0]});
1420 case NEON::BI__builtin_neon_vld1_x2_v:
1421 case NEON::BI__builtin_neon_vld1q_x2_v:
1422 case NEON::BI__builtin_neon_vld1_x3_v:
1423 case NEON::BI__builtin_neon_vld1q_x3_v:
1424 case NEON::BI__builtin_neon_vld1_x4_v:
1425 case NEON::BI__builtin_neon_vld1q_x4_v: {
1427 Function *F =
CGM.getIntrinsic(LLVMIntrinsic, Tys);
1428 Ops[1] =
Builder.CreateCall(F, Ops[1],
"vld1xN");
1429 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
1431 case NEON::BI__builtin_neon_vld1_v:
1432 case NEON::BI__builtin_neon_vld1q_v: {
1434 Ops.push_back(getAlignmentValue32(PtrOp0));
1435 return EmitNeonCall(
CGM.getIntrinsic(LLVMIntrinsic, Tys), Ops,
"vld1");
1437 case NEON::BI__builtin_neon_vld2_v:
1438 case NEON::BI__builtin_neon_vld2q_v:
1439 case NEON::BI__builtin_neon_vld3_v:
1440 case NEON::BI__builtin_neon_vld3q_v:
1441 case NEON::BI__builtin_neon_vld4_v:
1442 case NEON::BI__builtin_neon_vld4q_v:
1443 case NEON::BI__builtin_neon_vld2_dup_v:
1444 case NEON::BI__builtin_neon_vld2q_dup_v:
1445 case NEON::BI__builtin_neon_vld3_dup_v:
1446 case NEON::BI__builtin_neon_vld3q_dup_v:
1447 case NEON::BI__builtin_neon_vld4_dup_v:
1448 case NEON::BI__builtin_neon_vld4q_dup_v: {
1450 Function *F =
CGM.getIntrinsic(LLVMIntrinsic, Tys);
1451 Value *Align = getAlignmentValue32(PtrOp1);
1452 Ops[1] =
Builder.CreateCall(F, {Ops[1], Align}, NameHint);
1453 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
1455 case NEON::BI__builtin_neon_vld1_dup_v:
1456 case NEON::BI__builtin_neon_vld1q_dup_v: {
1457 Value *
V = PoisonValue::get(Ty);
1459 LoadInst *Ld =
Builder.CreateLoad(PtrOp0);
1460 llvm::Constant *CI = ConstantInt::get(
SizeTy, 0);
1461 Ops[0] =
Builder.CreateInsertElement(
V, Ld, CI);
1464 case NEON::BI__builtin_neon_vld2_lane_v:
1465 case NEON::BI__builtin_neon_vld2q_lane_v:
1466 case NEON::BI__builtin_neon_vld3_lane_v:
1467 case NEON::BI__builtin_neon_vld3q_lane_v:
1468 case NEON::BI__builtin_neon_vld4_lane_v:
1469 case NEON::BI__builtin_neon_vld4q_lane_v: {
1471 Function *F =
CGM.getIntrinsic(LLVMIntrinsic, Tys);
1472 for (
unsigned I = 2; I < Ops.size() - 1; ++I)
1473 Ops[I] =
Builder.CreateBitCast(Ops[I], Ty);
1474 Ops.push_back(getAlignmentValue32(PtrOp1));
1476 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
1478 case NEON::BI__builtin_neon_vmovl_v: {
1479 llvm::FixedVectorType *DTy =
1480 llvm::FixedVectorType::getTruncatedElementVectorType(VTy);
1481 Ops[0] =
Builder.CreateBitCast(Ops[0], DTy);
1483 return Builder.CreateZExt(Ops[0], Ty,
"vmovl");
1484 return Builder.CreateSExt(Ops[0], Ty,
"vmovl");
1486 case NEON::BI__builtin_neon_vmovn_v: {
1487 llvm::FixedVectorType *QTy =
1488 llvm::FixedVectorType::getExtendedElementVectorType(VTy);
1489 Ops[0] =
Builder.CreateBitCast(Ops[0], QTy);
1490 return Builder.CreateTrunc(Ops[0], Ty,
"vmovn");
1492 case NEON::BI__builtin_neon_vmull_v:
1498 Int = Usgn ? Intrinsic::arm_neon_vmullu : Intrinsic::arm_neon_vmulls;
1499 Int =
Type.isPoly() ? (
unsigned)Intrinsic::arm_neon_vmullp : Int;
1501 case NEON::BI__builtin_neon_vpadal_v:
1502 case NEON::BI__builtin_neon_vpadalq_v: {
1504 unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
1508 llvm::FixedVectorType::get(EltTy, VTy->getNumElements() * 2);
1509 llvm::Type *Tys[2] = { Ty, NarrowTy };
1512 case NEON::BI__builtin_neon_vpaddl_v:
1513 case NEON::BI__builtin_neon_vpaddlq_v: {
1515 unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
1516 llvm::Type *EltTy = llvm::IntegerType::get(
getLLVMContext(), EltBits / 2);
1518 llvm::FixedVectorType::get(EltTy, VTy->getNumElements() * 2);
1519 llvm::Type *Tys[2] = { Ty, NarrowTy };
1522 case NEON::BI__builtin_neon_vqdmlal_v:
1523 case NEON::BI__builtin_neon_vqdmlsl_v: {
1528 return EmitNeonCall(
CGM.getIntrinsic(AltLLVMIntrinsic, Ty), Ops, NameHint);
1530 case NEON::BI__builtin_neon_vqdmulhq_lane_v:
1531 case NEON::BI__builtin_neon_vqdmulh_lane_v:
1532 case NEON::BI__builtin_neon_vqrdmulhq_lane_v:
1533 case NEON::BI__builtin_neon_vqrdmulh_lane_v: {
1535 if (BuiltinID == NEON::BI__builtin_neon_vqdmulhq_lane_v ||
1536 BuiltinID == NEON::BI__builtin_neon_vqrdmulhq_lane_v)
1537 RTy = llvm::FixedVectorType::get(RTy->getElementType(),
1538 RTy->getNumElements() * 2);
1539 llvm::Type *Tys[2] = {
1544 case NEON::BI__builtin_neon_vqdmulhq_laneq_v:
1545 case NEON::BI__builtin_neon_vqdmulh_laneq_v:
1546 case NEON::BI__builtin_neon_vqrdmulhq_laneq_v:
1547 case NEON::BI__builtin_neon_vqrdmulh_laneq_v: {
1548 llvm::Type *Tys[2] = {
1553 case NEON::BI__builtin_neon_vqshl_n_v:
1554 case NEON::BI__builtin_neon_vqshlq_n_v:
1557 case NEON::BI__builtin_neon_vqshlu_n_v:
1558 case NEON::BI__builtin_neon_vqshluq_n_v:
1561 case NEON::BI__builtin_neon_vrecpe_v:
1562 case NEON::BI__builtin_neon_vrecpeq_v:
1563 case NEON::BI__builtin_neon_vrsqrte_v:
1564 case NEON::BI__builtin_neon_vrsqrteq_v:
1565 Int = Ty->isFPOrFPVectorTy() ? LLVMIntrinsic : AltLLVMIntrinsic;
1567 case NEON::BI__builtin_neon_vrndi_v:
1568 case NEON::BI__builtin_neon_vrndiq_v:
1569 Int =
Builder.getIsFPConstrained()
1570 ? Intrinsic::experimental_constrained_nearbyint
1571 : Intrinsic::nearbyint;
1573 case NEON::BI__builtin_neon_vrshr_n_v:
1574 case NEON::BI__builtin_neon_vrshrq_n_v:
1577 case NEON::BI__builtin_neon_vsha512hq_u64:
1578 case NEON::BI__builtin_neon_vsha512h2q_u64:
1579 case NEON::BI__builtin_neon_vsha512su0q_u64:
1580 case NEON::BI__builtin_neon_vsha512su1q_u64: {
1584 case NEON::BI__builtin_neon_vshl_n_v:
1585 case NEON::BI__builtin_neon_vshlq_n_v:
1587 return Builder.CreateShl(
Builder.CreateBitCast(Ops[0],Ty), Ops[1],
1589 case NEON::BI__builtin_neon_vshll_n_v: {
1590 llvm::FixedVectorType *SrcTy =
1591 llvm::FixedVectorType::getTruncatedElementVectorType(VTy);
1592 Ops[0] =
Builder.CreateBitCast(Ops[0], SrcTy);
1594 Ops[0] =
Builder.CreateZExt(Ops[0], VTy);
1596 Ops[0] =
Builder.CreateSExt(Ops[0], VTy);
1598 return Builder.CreateShl(Ops[0], Ops[1],
"vshll_n");
1600 case NEON::BI__builtin_neon_vshrn_n_v: {
1601 llvm::FixedVectorType *SrcTy =
1602 llvm::FixedVectorType::getExtendedElementVectorType(VTy);
1603 Ops[0] =
Builder.CreateBitCast(Ops[0], SrcTy);
1606 Ops[0] =
Builder.CreateLShr(Ops[0], Ops[1]);
1608 Ops[0] =
Builder.CreateAShr(Ops[0], Ops[1]);
1609 return Builder.CreateTrunc(Ops[0], Ty,
"vshrn_n");
1611 case NEON::BI__builtin_neon_vshr_n_v:
1612 case NEON::BI__builtin_neon_vshrq_n_v:
1614 case NEON::BI__builtin_neon_vst1_v:
1615 case NEON::BI__builtin_neon_vst1q_v:
1616 case NEON::BI__builtin_neon_vst2_v:
1617 case NEON::BI__builtin_neon_vst2q_v:
1618 case NEON::BI__builtin_neon_vst3_v:
1619 case NEON::BI__builtin_neon_vst3q_v:
1620 case NEON::BI__builtin_neon_vst4_v:
1621 case NEON::BI__builtin_neon_vst4q_v:
1622 case NEON::BI__builtin_neon_vst2_lane_v:
1623 case NEON::BI__builtin_neon_vst2q_lane_v:
1624 case NEON::BI__builtin_neon_vst3_lane_v:
1625 case NEON::BI__builtin_neon_vst3q_lane_v:
1626 case NEON::BI__builtin_neon_vst4_lane_v:
1627 case NEON::BI__builtin_neon_vst4q_lane_v: {
1629 Ops.push_back(getAlignmentValue32(PtrOp0));
1632 case NEON::BI__builtin_neon_vsm3partw1q_u32:
1633 case NEON::BI__builtin_neon_vsm3partw2q_u32:
1634 case NEON::BI__builtin_neon_vsm3ss1q_u32:
1635 case NEON::BI__builtin_neon_vsm4ekeyq_u32:
1636 case NEON::BI__builtin_neon_vsm4eq_u32: {
1640 case NEON::BI__builtin_neon_vsm3tt1aq_u32:
1641 case NEON::BI__builtin_neon_vsm3tt1bq_u32:
1642 case NEON::BI__builtin_neon_vsm3tt2aq_u32:
1643 case NEON::BI__builtin_neon_vsm3tt2bq_u32: {
1648 case NEON::BI__builtin_neon_vst1_x2_v:
1649 case NEON::BI__builtin_neon_vst1q_x2_v:
1650 case NEON::BI__builtin_neon_vst1_x3_v:
1651 case NEON::BI__builtin_neon_vst1q_x3_v:
1652 case NEON::BI__builtin_neon_vst1_x4_v:
1653 case NEON::BI__builtin_neon_vst1q_x4_v: {
1656 if (
Arch == llvm::Triple::aarch64 ||
Arch == llvm::Triple::aarch64_be ||
1657 Arch == llvm::Triple::aarch64_32) {
1659 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end());
1665 case NEON::BI__builtin_neon_vsubhn_v: {
1666 llvm::FixedVectorType *SrcTy =
1667 llvm::FixedVectorType::getExtendedElementVectorType(VTy);
1670 Ops[0] =
Builder.CreateBitCast(Ops[0], SrcTy);
1671 Ops[1] =
Builder.CreateBitCast(Ops[1], SrcTy);
1672 Ops[0] =
Builder.CreateSub(Ops[0], Ops[1],
"vsubhn");
1676 ConstantInt::get(SrcTy, SrcTy->getScalarSizeInBits() / 2);
1677 Ops[0] =
Builder.CreateLShr(Ops[0], ShiftAmt,
"vsubhn");
1680 return Builder.CreateTrunc(Ops[0], VTy,
"vsubhn");
1682 case NEON::BI__builtin_neon_vtrn_v:
1683 case NEON::BI__builtin_neon_vtrnq_v: {
1684 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
1685 Ops[2] =
Builder.CreateBitCast(Ops[2], Ty);
1686 Value *SV =
nullptr;
1688 for (
unsigned vi = 0; vi != 2; ++vi) {
1690 for (
unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) {
1691 Indices.push_back(i+vi);
1692 Indices.push_back(i+e+vi);
1695 SV =
Builder.CreateShuffleVector(Ops[1], Ops[2], Indices,
"vtrn");
1700 case NEON::BI__builtin_neon_vtst_v:
1701 case NEON::BI__builtin_neon_vtstq_v: {
1702 Ops[0] =
Builder.CreateBitCast(Ops[0], Ty);
1703 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
1704 Ops[0] =
Builder.CreateAnd(Ops[0], Ops[1]);
1705 Ops[0] =
Builder.CreateICmp(ICmpInst::ICMP_NE, Ops[0],
1706 ConstantAggregateZero::get(Ty));
1707 return Builder.CreateSExt(Ops[0], Ty,
"vtst");
1709 case NEON::BI__builtin_neon_vuzp_v:
1710 case NEON::BI__builtin_neon_vuzpq_v: {
1711 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
1712 Ops[2] =
Builder.CreateBitCast(Ops[2], Ty);
1713 Value *SV =
nullptr;
1715 for (
unsigned vi = 0; vi != 2; ++vi) {
1717 for (
unsigned i = 0, e = VTy->getNumElements(); i != e; ++i)
1718 Indices.push_back(2*i+vi);
1721 SV =
Builder.CreateShuffleVector(Ops[1], Ops[2], Indices,
"vuzp");
1726 case NEON::BI__builtin_neon_vxarq_u64: {
1731 case NEON::BI__builtin_neon_vzip_v:
1732 case NEON::BI__builtin_neon_vzipq_v: {
1733 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
1734 Ops[2] =
Builder.CreateBitCast(Ops[2], Ty);
1735 Value *SV =
nullptr;
1737 for (
unsigned vi = 0; vi != 2; ++vi) {
1739 for (
unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) {
1740 Indices.push_back((i + vi*e) >> 1);
1741 Indices.push_back(((i + vi*e) >> 1)+e);
1744 SV =
Builder.CreateShuffleVector(Ops[1], Ops[2], Indices,
"vzip");
1749 case NEON::BI__builtin_neon_vdot_s32:
1750 case NEON::BI__builtin_neon_vdot_u32:
1751 case NEON::BI__builtin_neon_vdotq_s32:
1752 case NEON::BI__builtin_neon_vdotq_u32: {
1754 llvm::FixedVectorType::get(
Int8Ty, Ty->getPrimitiveSizeInBits() / 8);
1755 llvm::Type *Tys[2] = { Ty, InputTy };
1758 case NEON::BI__builtin_neon_vfmlal_low_f16:
1759 case NEON::BI__builtin_neon_vfmlalq_low_f16: {
1761 llvm::FixedVectorType::get(
HalfTy, Ty->getPrimitiveSizeInBits() / 16);
1762 llvm::Type *Tys[2] = { Ty, InputTy };
1765 case NEON::BI__builtin_neon_vfmlsl_low_f16:
1766 case NEON::BI__builtin_neon_vfmlslq_low_f16: {
1768 llvm::FixedVectorType::get(
HalfTy, Ty->getPrimitiveSizeInBits() / 16);
1769 llvm::Type *Tys[2] = { Ty, InputTy };
1772 case NEON::BI__builtin_neon_vfmlal_high_f16:
1773 case NEON::BI__builtin_neon_vfmlalq_high_f16: {
1775 llvm::FixedVectorType::get(
HalfTy, Ty->getPrimitiveSizeInBits() / 16);
1776 llvm::Type *Tys[2] = { Ty, InputTy };
1779 case NEON::BI__builtin_neon_vfmlsl_high_f16:
1780 case NEON::BI__builtin_neon_vfmlslq_high_f16: {
1782 llvm::FixedVectorType::get(
HalfTy, Ty->getPrimitiveSizeInBits() / 16);
1783 llvm::Type *Tys[2] = { Ty, InputTy };
1786 case NEON::BI__builtin_neon_vmmlaq_s32:
1787 case NEON::BI__builtin_neon_vmmlaq_u32: {
1789 llvm::FixedVectorType::get(
Int8Ty, Ty->getPrimitiveSizeInBits() / 8);
1790 llvm::Type *Tys[2] = { Ty, InputTy };
1791 return EmitNeonCall(
CGM.getIntrinsic(LLVMIntrinsic, Tys), Ops,
"vmmla");
1793 case NEON::BI__builtin_neon_vmmlaq_f16:
1794 case NEON::BI__builtin_neon_vmmlaq_f32_f16: {
1796 llvm::FixedVectorType::get(
HalfTy, Ty->getPrimitiveSizeInBits() / 16);
1797 llvm::Type *Tys[2] = {Ty, InputTy};
1800 case NEON::BI__builtin_neon_vusmmlaq_s32: {
1802 llvm::FixedVectorType::get(
Int8Ty, Ty->getPrimitiveSizeInBits() / 8);
1803 llvm::Type *Tys[2] = { Ty, InputTy };
1806 case NEON::BI__builtin_neon_vusdot_s32:
1807 case NEON::BI__builtin_neon_vusdotq_s32: {
1809 llvm::FixedVectorType::get(
Int8Ty, Ty->getPrimitiveSizeInBits() / 8);
1810 llvm::Type *Tys[2] = { Ty, InputTy };
1813 case NEON::BI__builtin_neon_vbfdot_f32:
1814 case NEON::BI__builtin_neon_vbfdotq_f32: {
1815 llvm::Type *InputTy =
1816 llvm::FixedVectorType::get(
BFloatTy, Ty->getPrimitiveSizeInBits() / 16);
1817 llvm::Type *Tys[2] = { Ty, InputTy };
1820 case NEON::BI__builtin_neon___a32_vcvt_bf16_f32: {
1821 llvm::Type *Tys[1] = { Ty };
1828 assert(Int &&
"Expected valid intrinsic number");
2103 llvm::Triple::ArchType
Arch) {
2104 if (
auto Hint = GetValueForARMHint(BuiltinID))
2107 if (BuiltinID == clang::ARM::BI__emit) {
2109 llvm::FunctionType *FTy =
2110 llvm::FunctionType::get(
VoidTy,
false);
2114 llvm_unreachable(
"Sema will ensure that the parameter is constant");
2117 uint64_t ZExtValue =
Value.zextOrTrunc(IsThumb ? 16 : 32).getZExtValue();
2119 llvm::InlineAsm *Emit =
2120 IsThumb ? InlineAsm::get(FTy,
".inst.n 0x" + utohexstr(ZExtValue),
"",
2122 : InlineAsm::get(FTy,
".inst 0x" + utohexstr(ZExtValue),
"",
2125 return Builder.CreateCall(Emit);
2128 if (BuiltinID == clang::ARM::BI__builtin_arm_dbg) {
2130 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::arm_dbg), Option);
2133 if (BuiltinID == clang::ARM::BI__builtin_arm_prefetch) {
2145 if (BuiltinID == clang::ARM::BI__builtin_arm_rbit) {
2148 CGM.getIntrinsic(Intrinsic::bitreverse, Arg->getType()), Arg,
"rbit");
2151 if (BuiltinID == clang::ARM::BI__builtin_arm_clz ||
2152 BuiltinID == clang::ARM::BI__builtin_arm_clz64) {
2154 Function *F =
CGM.getIntrinsic(Intrinsic::ctlz, Arg->getType());
2156 if (BuiltinID == clang::ARM::BI__builtin_arm_clz64)
2162 if (BuiltinID == clang::ARM::BI__builtin_arm_cls) {
2164 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::arm_cls), Arg,
"cls");
2166 if (BuiltinID == clang::ARM::BI__builtin_arm_cls64) {
2168 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::arm_cls64), Arg,
2172 if (BuiltinID == clang::ARM::BI__clear_cache) {
2173 assert(E->
getNumArgs() == 2 &&
"__clear_cache takes 2 arguments");
2176 for (
unsigned i = 0; i < 2; i++)
2178 llvm::Type *Ty =
CGM.getTypes().ConvertType(FD->
getType());
2180 StringRef Name = FD->
getName();
2184 if (BuiltinID == clang::ARM::BI__builtin_arm_mcrr ||
2185 BuiltinID == clang::ARM::BI__builtin_arm_mcrr2) {
2188 switch (BuiltinID) {
2189 default: llvm_unreachable(
"unexpected builtin");
2190 case clang::ARM::BI__builtin_arm_mcrr:
2191 F =
CGM.getIntrinsic(Intrinsic::arm_mcrr);
2193 case clang::ARM::BI__builtin_arm_mcrr2:
2194 F =
CGM.getIntrinsic(Intrinsic::arm_mcrr2);
2215 return Builder.CreateCall(F, {Coproc, Opc1, Rt, Rt2, CRm});
2218 if (BuiltinID == clang::ARM::BI__builtin_arm_mrrc ||
2219 BuiltinID == clang::ARM::BI__builtin_arm_mrrc2) {
2222 switch (BuiltinID) {
2223 default: llvm_unreachable(
"unexpected builtin");
2224 case clang::ARM::BI__builtin_arm_mrrc:
2225 F =
CGM.getIntrinsic(Intrinsic::arm_mrrc);
2227 case clang::ARM::BI__builtin_arm_mrrc2:
2228 F =
CGM.getIntrinsic(Intrinsic::arm_mrrc2);
2235 Value *RtAndRt2 =
Builder.CreateCall(F, {Coproc, Opc1, CRm});
2245 Value *ShiftCast = llvm::ConstantInt::get(
Int64Ty, 32);
2246 RtAndRt2 =
Builder.CreateShl(Rt, ShiftCast,
"shl",
true);
2247 RtAndRt2 =
Builder.CreateOr(RtAndRt2, Rt1);
2252 if (BuiltinID == clang::ARM::BI__builtin_arm_ldrexd ||
2253 ((BuiltinID == clang::ARM::BI__builtin_arm_ldrex ||
2254 BuiltinID == clang::ARM::BI__builtin_arm_ldaex) &&
2256 BuiltinID == clang::ARM::BI__ldrexd) {
2259 switch (BuiltinID) {
2260 default: llvm_unreachable(
"unexpected builtin");
2261 case clang::ARM::BI__builtin_arm_ldaex:
2262 F =
CGM.getIntrinsic(Intrinsic::arm_ldaexd);
2264 case clang::ARM::BI__builtin_arm_ldrexd:
2265 case clang::ARM::BI__builtin_arm_ldrex:
2266 case clang::ARM::BI__ldrexd:
2267 F =
CGM.getIntrinsic(Intrinsic::arm_ldrexd);
2280 Val =
Builder.CreateShl(Val0, ShiftCst,
"shl",
true );
2281 Val =
Builder.CreateOr(Val, Val1);
2285 if (BuiltinID == clang::ARM::BI__builtin_arm_ldrex ||
2286 BuiltinID == clang::ARM::BI__builtin_arm_ldaex) {
2295 BuiltinID == clang::ARM::BI__builtin_arm_ldaex ? Intrinsic::arm_ldaex
2296 : Intrinsic::arm_ldrex,
2298 CallInst *Val =
Builder.CreateCall(F, LoadAddr,
"ldrex");
2302 if (RealResTy->isPointerTy())
2303 return Builder.CreateIntToPtr(Val, RealResTy);
2305 llvm::Type *IntResTy = llvm::IntegerType::get(
2307 return Builder.CreateBitCast(
Builder.CreateTruncOrBitCast(Val, IntResTy),
2312 if (BuiltinID == clang::ARM::BI__builtin_arm_strexd ||
2313 ((BuiltinID == clang::ARM::BI__builtin_arm_stlex ||
2314 BuiltinID == clang::ARM::BI__builtin_arm_strex) &&
2317 BuiltinID == clang::ARM::BI__builtin_arm_stlex ? Intrinsic::arm_stlexd
2318 : Intrinsic::arm_strexd);
2323 Builder.CreateStore(Val, Tmp);
2326 Val =
Builder.CreateLoad(LdPtr);
2331 return Builder.CreateCall(F, {Arg0, Arg1, StPtr},
"strexd");
2334 if (BuiltinID == clang::ARM::BI__builtin_arm_strex ||
2335 BuiltinID == clang::ARM::BI__builtin_arm_stlex) {
2340 llvm::Type *StoreTy =
2343 if (StoreVal->
getType()->isPointerTy())
2346 llvm::Type *
IntTy = llvm::IntegerType::get(
2348 CGM.getDataLayout().getTypeSizeInBits(StoreVal->
getType()));
2354 BuiltinID == clang::ARM::BI__builtin_arm_stlex ? Intrinsic::arm_stlex
2355 : Intrinsic::arm_strex,
2358 CallInst *CI =
Builder.CreateCall(F, {StoreVal, StoreAddr},
"strex");
2360 1, Attribute::get(
getLLVMContext(), Attribute::ElementType, StoreTy));
2364 if (BuiltinID == clang::ARM::BI__builtin_arm_clrex) {
2365 Function *F =
CGM.getIntrinsic(Intrinsic::arm_clrex);
2370 Intrinsic::ID CRCIntrinsicID = Intrinsic::not_intrinsic;
2371 switch (BuiltinID) {
2372 case clang::ARM::BI__builtin_arm_crc32b:
2373 CRCIntrinsicID = Intrinsic::arm_crc32b;
break;
2374 case clang::ARM::BI__builtin_arm_crc32cb:
2375 CRCIntrinsicID = Intrinsic::arm_crc32cb;
break;
2376 case clang::ARM::BI__builtin_arm_crc32h:
2377 CRCIntrinsicID = Intrinsic::arm_crc32h;
break;
2378 case clang::ARM::BI__builtin_arm_crc32ch:
2379 CRCIntrinsicID = Intrinsic::arm_crc32ch;
break;
2380 case clang::ARM::BI__builtin_arm_crc32w:
2381 case clang::ARM::BI__builtin_arm_crc32d:
2382 CRCIntrinsicID = Intrinsic::arm_crc32w;
break;
2383 case clang::ARM::BI__builtin_arm_crc32cw:
2384 case clang::ARM::BI__builtin_arm_crc32cd:
2385 CRCIntrinsicID = Intrinsic::arm_crc32cw;
break;
2388 if (CRCIntrinsicID != Intrinsic::not_intrinsic) {
2394 if (BuiltinID == clang::ARM::BI__builtin_arm_crc32d ||
2395 BuiltinID == clang::ARM::BI__builtin_arm_crc32cd) {
2403 return Builder.CreateCall(F, {Res, Arg1b});
2408 return Builder.CreateCall(F, {Arg0, Arg1});
2412 if (BuiltinID == clang::ARM::BI__builtin_arm_rsr ||
2413 BuiltinID == clang::ARM::BI__builtin_arm_rsr64 ||
2414 BuiltinID == clang::ARM::BI__builtin_arm_rsrp ||
2415 BuiltinID == clang::ARM::BI__builtin_arm_wsr ||
2416 BuiltinID == clang::ARM::BI__builtin_arm_wsr64 ||
2417 BuiltinID == clang::ARM::BI__builtin_arm_wsrp) {
2420 if (BuiltinID == clang::ARM::BI__builtin_arm_rsr ||
2421 BuiltinID == clang::ARM::BI__builtin_arm_rsr64 ||
2422 BuiltinID == clang::ARM::BI__builtin_arm_rsrp)
2425 bool IsPointerBuiltin = BuiltinID == clang::ARM::BI__builtin_arm_rsrp ||
2426 BuiltinID == clang::ARM::BI__builtin_arm_wsrp;
2428 bool Is64Bit = BuiltinID == clang::ARM::BI__builtin_arm_rsr64 ||
2429 BuiltinID == clang::ARM::BI__builtin_arm_wsr64;
2431 llvm::Type *ValueType;
2433 if (IsPointerBuiltin) {
2436 }
else if (Is64Bit) {
2446 if (BuiltinID == ARM::BI__builtin_sponentry) {
2465 return P.first == BuiltinID;
2468 BuiltinID = It->second;
2472 unsigned ICEArguments = 0;
2477 auto getAlignmentValue32 = [&](
Address addr) ->
Value* {
2478 return Builder.getInt32(addr.getAlignment().getQuantity());
2485 unsigned NumArgs = E->
getNumArgs() - (HasExtraArg ? 1 : 0);
2486 for (
unsigned i = 0, e = NumArgs; i != e; i++) {
2488 switch (BuiltinID) {
2489 case NEON::BI__builtin_neon_vld1_v:
2490 case NEON::BI__builtin_neon_vld1q_v:
2491 case NEON::BI__builtin_neon_vld1q_lane_v:
2492 case NEON::BI__builtin_neon_vld1_lane_v:
2493 case NEON::BI__builtin_neon_vld1_dup_v:
2494 case NEON::BI__builtin_neon_vld1q_dup_v:
2495 case NEON::BI__builtin_neon_vst1_v:
2496 case NEON::BI__builtin_neon_vst1q_v:
2497 case NEON::BI__builtin_neon_vst1q_lane_v:
2498 case NEON::BI__builtin_neon_vst1_lane_v:
2499 case NEON::BI__builtin_neon_vst2_v:
2500 case NEON::BI__builtin_neon_vst2q_v:
2501 case NEON::BI__builtin_neon_vst2_lane_v:
2502 case NEON::BI__builtin_neon_vst2q_lane_v:
2503 case NEON::BI__builtin_neon_vst3_v:
2504 case NEON::BI__builtin_neon_vst3q_v:
2505 case NEON::BI__builtin_neon_vst3_lane_v:
2506 case NEON::BI__builtin_neon_vst3q_lane_v:
2507 case NEON::BI__builtin_neon_vst4_v:
2508 case NEON::BI__builtin_neon_vst4q_v:
2509 case NEON::BI__builtin_neon_vst4_lane_v:
2510 case NEON::BI__builtin_neon_vst4q_lane_v:
2519 switch (BuiltinID) {
2520 case NEON::BI__builtin_neon_vld2_v:
2521 case NEON::BI__builtin_neon_vld2q_v:
2522 case NEON::BI__builtin_neon_vld3_v:
2523 case NEON::BI__builtin_neon_vld3q_v:
2524 case NEON::BI__builtin_neon_vld4_v:
2525 case NEON::BI__builtin_neon_vld4q_v:
2526 case NEON::BI__builtin_neon_vld2_lane_v:
2527 case NEON::BI__builtin_neon_vld2q_lane_v:
2528 case NEON::BI__builtin_neon_vld3_lane_v:
2529 case NEON::BI__builtin_neon_vld3q_lane_v:
2530 case NEON::BI__builtin_neon_vld4_lane_v:
2531 case NEON::BI__builtin_neon_vld4q_lane_v:
2532 case NEON::BI__builtin_neon_vld2_dup_v:
2533 case NEON::BI__builtin_neon_vld2q_dup_v:
2534 case NEON::BI__builtin_neon_vld3_dup_v:
2535 case NEON::BI__builtin_neon_vld3q_dup_v:
2536 case NEON::BI__builtin_neon_vld4_dup_v:
2537 case NEON::BI__builtin_neon_vld4q_dup_v:
2549 switch (BuiltinID) {
2552 case NEON::BI__builtin_neon_vget_lane_i8:
2553 case NEON::BI__builtin_neon_vget_lane_i16:
2554 case NEON::BI__builtin_neon_vget_lane_i32:
2555 case NEON::BI__builtin_neon_vget_lane_i64:
2556 case NEON::BI__builtin_neon_vget_lane_bf16:
2557 case NEON::BI__builtin_neon_vget_lane_f32:
2558 case NEON::BI__builtin_neon_vgetq_lane_i8:
2559 case NEON::BI__builtin_neon_vgetq_lane_i16:
2560 case NEON::BI__builtin_neon_vgetq_lane_i32:
2561 case NEON::BI__builtin_neon_vgetq_lane_i64:
2562 case NEON::BI__builtin_neon_vgetq_lane_bf16:
2563 case NEON::BI__builtin_neon_vgetq_lane_f32:
2564 case NEON::BI__builtin_neon_vduph_lane_bf16:
2565 case NEON::BI__builtin_neon_vduph_laneq_bf16:
2566 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vget_lane");
2568 case NEON::BI__builtin_neon_vrndns_f32: {
2570 llvm::Type *Tys[] = {Arg->
getType()};
2571 Function *F =
CGM.getIntrinsic(Intrinsic::roundeven, Tys);
2572 return Builder.CreateCall(F, {Arg},
"vrndn"); }
2574 case NEON::BI__builtin_neon_vset_lane_i8:
2575 case NEON::BI__builtin_neon_vset_lane_i16:
2576 case NEON::BI__builtin_neon_vset_lane_i32:
2577 case NEON::BI__builtin_neon_vset_lane_i64:
2578 case NEON::BI__builtin_neon_vset_lane_bf16:
2579 case NEON::BI__builtin_neon_vset_lane_f32:
2580 case NEON::BI__builtin_neon_vsetq_lane_i8:
2581 case NEON::BI__builtin_neon_vsetq_lane_i16:
2582 case NEON::BI__builtin_neon_vsetq_lane_i32:
2583 case NEON::BI__builtin_neon_vsetq_lane_i64:
2584 case NEON::BI__builtin_neon_vsetq_lane_bf16:
2585 case NEON::BI__builtin_neon_vsetq_lane_f32:
2586 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2],
"vset_lane");
2588 case NEON::BI__builtin_neon_vsha1h_u32:
2591 case NEON::BI__builtin_neon_vsha1cq_u32:
2594 case NEON::BI__builtin_neon_vsha1pq_u32:
2597 case NEON::BI__builtin_neon_vsha1mq_u32:
2601 case NEON::BI__builtin_neon_vcvth_bf16_f32:
2602 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::arm_neon_vcvtbfp2bf), Ops,
2604 case NEON::BI__builtin_neon_vcvt_f16_f32:
2605 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::arm_neon_vcvtfp2hf), Ops,
2607 case NEON::BI__builtin_neon_vcvt_f32_f16:
2608 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::arm_neon_vcvthf2fp), Ops,
2613 case clang::ARM::BI_MoveToCoprocessor:
2614 case clang::ARM::BI_MoveToCoprocessor2: {
2615 Function *F =
CGM.getIntrinsic(BuiltinID == clang::ARM::BI_MoveToCoprocessor
2616 ? Intrinsic::arm_mcr
2617 : Intrinsic::arm_mcr2);
2618 return Builder.CreateCall(F, {Ops[1], Ops[2], Ops[0],
2619 Ops[3], Ops[4], Ops[5]});
2624 assert(HasExtraArg);
2626 std::optional<llvm::APSInt>
Result =
2631 if (BuiltinID == clang::ARM::BI__builtin_arm_vcvtr_f ||
2632 BuiltinID == clang::ARM::BI__builtin_arm_vcvtr_d) {
2635 if (BuiltinID == clang::ARM::BI__builtin_arm_vcvtr_f)
2641 bool usgn =
Result->getZExtValue() == 1;
2642 unsigned Int = usgn ? Intrinsic::arm_vcvtru : Intrinsic::arm_vcvtr;
2646 return Builder.CreateCall(F, Ops,
"vcvtr");
2651 bool usgn =
Type.isUnsigned();
2652 bool rightShift =
false;
2654 llvm::FixedVectorType *VTy =
2657 llvm::Type *Ty = VTy;
2672 switch (BuiltinID) {
2673 default:
return nullptr;
2674 case NEON::BI__builtin_neon_vld1q_lane_v:
2677 if (VTy->getElementType()->isIntegerTy(64)) {
2679 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
2681 Value *SV = llvm::ConstantVector::get(ConstantInt::get(
Int32Ty, 1-Lane));
2682 Ops[1] =
Builder.CreateShuffleVector(Ops[1], Ops[1], SV);
2684 Ty = llvm::FixedVectorType::get(VTy->getElementType(), 1);
2686 Function *F =
CGM.getIntrinsic(Intrinsic::arm_neon_vld1, Tys);
2687 Value *Align = getAlignmentValue32(PtrOp0);
2690 int Indices[] = {1 - Lane, Lane};
2691 return Builder.CreateShuffleVector(Ops[1], Ld, Indices,
"vld1q_lane");
2694 case NEON::BI__builtin_neon_vld1_lane_v: {
2695 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
2698 return Builder.CreateInsertElement(Ops[1], Ld, Ops[2],
"vld1_lane");
2700 case NEON::BI__builtin_neon_vqrshrn_n_v:
2702 usgn ? Intrinsic::arm_neon_vqrshiftnu : Intrinsic::arm_neon_vqrshiftns;
2705 case NEON::BI__builtin_neon_vqrshrun_n_v:
2706 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::arm_neon_vqrshiftnsu, Ty),
2707 Ops,
"vqrshrun_n", 1,
true);
2708 case NEON::BI__builtin_neon_vqshrn_n_v:
2709 Int = usgn ? Intrinsic::arm_neon_vqshiftnu : Intrinsic::arm_neon_vqshiftns;
2712 case NEON::BI__builtin_neon_vqshrun_n_v:
2713 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::arm_neon_vqshiftnsu, Ty),
2714 Ops,
"vqshrun_n", 1,
true);
2715 case NEON::BI__builtin_neon_vrecpe_v:
2716 case NEON::BI__builtin_neon_vrecpeq_v:
2719 case NEON::BI__builtin_neon_vrshrn_n_v:
2720 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::arm_neon_vrshiftn, Ty),
2721 Ops,
"vrshrn_n", 1,
true);
2722 case NEON::BI__builtin_neon_vrsra_n_v:
2723 case NEON::BI__builtin_neon_vrsraq_n_v:
2724 Ops[0] =
Builder.CreateBitCast(Ops[0], Ty);
2725 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
2727 Int = usgn ? Intrinsic::arm_neon_vrshiftu : Intrinsic::arm_neon_vrshifts;
2728 Ops[1] =
Builder.CreateCall(
CGM.getIntrinsic(Int, Ty), {Ops[1], Ops[2]});
2729 return Builder.CreateAdd(Ops[0], Ops[1],
"vrsra_n");
2730 case NEON::BI__builtin_neon_vsri_n_v:
2731 case NEON::BI__builtin_neon_vsriq_n_v:
2734 case NEON::BI__builtin_neon_vsli_n_v:
2735 case NEON::BI__builtin_neon_vsliq_n_v:
2737 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::arm_neon_vshiftins, Ty),
2739 case NEON::BI__builtin_neon_vsra_n_v:
2740 case NEON::BI__builtin_neon_vsraq_n_v:
2741 Ops[0] =
Builder.CreateBitCast(Ops[0], Ty);
2743 return Builder.CreateAdd(Ops[0], Ops[1]);
2744 case NEON::BI__builtin_neon_vst1q_lane_v:
2747 if (VTy->getElementType()->isIntegerTy(64)) {
2748 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
2750 Ops[1] =
Builder.CreateShuffleVector(Ops[1], Ops[1], SV);
2751 Ops[2] = getAlignmentValue32(PtrOp0);
2752 llvm::Type *Tys[] = {
Int8PtrTy, Ops[1]->getType()};
2753 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::arm_neon_vst1,
2757 case NEON::BI__builtin_neon_vst1_lane_v: {
2758 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
2759 Ops[1] =
Builder.CreateExtractElement(Ops[1], Ops[2]);
2760 return Builder.CreateStore(Ops[1],
2763 case NEON::BI__builtin_neon_vtbl1_v:
2766 case NEON::BI__builtin_neon_vtbl2_v:
2769 case NEON::BI__builtin_neon_vtbl3_v:
2772 case NEON::BI__builtin_neon_vtbl4_v:
2775 case NEON::BI__builtin_neon_vtbx1_v:
2778 case NEON::BI__builtin_neon_vtbx2_v:
2781 case NEON::BI__builtin_neon_vtbx3_v:
2784 case NEON::BI__builtin_neon_vtbx4_v:
4421 llvm::Triple::ArchType
Arch) {
4430 if (BuiltinID == Builtin::BI__builtin_cpu_supports)
4431 return EmitAArch64CpuSupports(E);
4433 unsigned HintID =
static_cast<unsigned>(-1);
4434 switch (BuiltinID) {
4436 case clang::AArch64::BI__builtin_arm_nop:
4439 case clang::AArch64::BI__builtin_arm_yield:
4440 case clang::AArch64::BI__yield:
4443 case clang::AArch64::BI__builtin_arm_wfe:
4444 case clang::AArch64::BI__wfe:
4447 case clang::AArch64::BI__builtin_arm_wfi:
4448 case clang::AArch64::BI__wfi:
4451 case clang::AArch64::BI__builtin_arm_sev:
4452 case clang::AArch64::BI__sev:
4455 case clang::AArch64::BI__builtin_arm_sevl:
4456 case clang::AArch64::BI__sevl:
4461 if (HintID !=
static_cast<unsigned>(-1)) {
4462 Function *F =
CGM.getIntrinsic(Intrinsic::aarch64_hint);
4463 return Builder.CreateCall(F, llvm::ConstantInt::get(
Int32Ty, HintID));
4466 if (BuiltinID == clang::AArch64::BI__builtin_arm_trap) {
4467 Function *F =
CGM.getIntrinsic(Intrinsic::aarch64_break);
4472 if (BuiltinID == clang::AArch64::BI__builtin_arm_get_sme_state) {
4475 llvm::FunctionType::get(StructType::get(
CGM.Int64Ty,
CGM.Int64Ty), {},
4477 "__arm_sme_state"));
4479 "aarch64_pstate_sm_compatible");
4480 CI->setAttributes(Attrs);
4483 AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2);
4490 if (BuiltinID == clang::AArch64::BI__builtin_arm_rbit) {
4492 "rbit of unusual size!");
4495 CGM.getIntrinsic(Intrinsic::bitreverse, Arg->getType()), Arg,
"rbit");
4497 if (BuiltinID == clang::AArch64::BI__builtin_arm_rbit64) {
4499 "rbit of unusual size!");
4502 CGM.getIntrinsic(Intrinsic::bitreverse, Arg->getType()), Arg,
"rbit");
4505 if (BuiltinID == clang::AArch64::BI__builtin_arm_clz ||
4506 BuiltinID == clang::AArch64::BI__builtin_arm_clz64) {
4508 Function *F =
CGM.getIntrinsic(Intrinsic::ctlz, Arg->getType());
4510 if (BuiltinID == clang::AArch64::BI__builtin_arm_clz64)
4515 if (BuiltinID == clang::AArch64::BI__builtin_arm_cls) {
4517 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::aarch64_cls), Arg,
4520 if (BuiltinID == clang::AArch64::BI__builtin_arm_cls64) {
4522 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::aarch64_cls64), Arg,
4526 if (BuiltinID == clang::AArch64::BI__builtin_arm_rint32zf ||
4527 BuiltinID == clang::AArch64::BI__builtin_arm_rint32z) {
4529 llvm::Type *Ty = Arg->getType();
4530 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::aarch64_frint32z, Ty),
4534 if (BuiltinID == clang::AArch64::BI__builtin_arm_rint64zf ||
4535 BuiltinID == clang::AArch64::BI__builtin_arm_rint64z) {
4537 llvm::Type *Ty = Arg->getType();
4538 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::aarch64_frint64z, Ty),
4542 if (BuiltinID == clang::AArch64::BI__builtin_arm_rint32xf ||
4543 BuiltinID == clang::AArch64::BI__builtin_arm_rint32x) {
4545 llvm::Type *Ty = Arg->getType();
4546 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::aarch64_frint32x, Ty),
4550 if (BuiltinID == clang::AArch64::BI__builtin_arm_rint64xf ||
4551 BuiltinID == clang::AArch64::BI__builtin_arm_rint64x) {
4553 llvm::Type *Ty = Arg->getType();
4554 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::aarch64_frint64x, Ty),
4558 if (BuiltinID == clang::AArch64::BI__builtin_arm_jcvt) {
4560 "__jcvt of unusual size!");
4563 CGM.getIntrinsic(Intrinsic::aarch64_fjcvtzs), Arg);
4566 if (BuiltinID == clang::AArch64::BI__builtin_arm_ld64b ||
4567 BuiltinID == clang::AArch64::BI__builtin_arm_st64b ||
4568 BuiltinID == clang::AArch64::BI__builtin_arm_st64bv ||
4569 BuiltinID == clang::AArch64::BI__builtin_arm_st64bv0) {
4573 if (BuiltinID == clang::AArch64::BI__builtin_arm_ld64b) {
4576 Function *F =
CGM.getIntrinsic(Intrinsic::aarch64_ld64b);
4577 llvm::Value *Val =
Builder.CreateCall(F, MemAddr);
4579 for (
size_t i = 0; i < 8; i++) {
4580 llvm::Value *ValOffsetPtr =
4592 Args.push_back(MemAddr);
4593 for (
size_t i = 0; i < 8; i++) {
4594 llvm::Value *ValOffsetPtr =
4600 auto Intr = (BuiltinID == clang::AArch64::BI__builtin_arm_st64b
4601 ? Intrinsic::aarch64_st64b
4602 : BuiltinID == clang::AArch64::BI__builtin_arm_st64bv
4603 ? Intrinsic::aarch64_st64bv
4604 : Intrinsic::aarch64_st64bv0);
4606 return Builder.CreateCall(F, Args);
4609 if (BuiltinID == clang::AArch64::BI__builtin_arm_rndr ||
4610 BuiltinID == clang::AArch64::BI__builtin_arm_rndrrs) {
4612 auto Intr = (BuiltinID == clang::AArch64::BI__builtin_arm_rndr
4613 ? Intrinsic::aarch64_rndr
4614 : Intrinsic::aarch64_rndrrs);
4616 llvm::Value *Val =
Builder.CreateCall(F);
4617 Value *RandomValue =
Builder.CreateExtractValue(Val, 0);
4621 Builder.CreateStore(RandomValue, MemAddress);
4626 if (BuiltinID == clang::AArch64::BI__clear_cache) {
4627 assert(E->
getNumArgs() == 2 &&
"__clear_cache takes 2 arguments");
4630 for (
unsigned i = 0; i < 2; i++)
4632 llvm::Type *Ty =
CGM.getTypes().ConvertType(FD->
getType());
4634 StringRef Name = FD->
getName();
4638 if ((BuiltinID == clang::AArch64::BI__builtin_arm_ldrex ||
4639 BuiltinID == clang::AArch64::BI__builtin_arm_ldaex) &&
4642 CGM.getIntrinsic(BuiltinID == clang::AArch64::BI__builtin_arm_ldaex
4643 ? Intrinsic::aarch64_ldaxp
4644 : Intrinsic::aarch64_ldxp);
4651 llvm::Type *Int128Ty = llvm::IntegerType::get(
getLLVMContext(), 128);
4652 Val0 =
Builder.CreateZExt(Val0, Int128Ty);
4653 Val1 =
Builder.CreateZExt(Val1, Int128Ty);
4655 Value *ShiftCst = llvm::ConstantInt::get(Int128Ty, 64);
4656 Val =
Builder.CreateShl(Val0, ShiftCst,
"shl",
true );
4657 Val =
Builder.CreateOr(Val, Val1);
4659 }
else if (BuiltinID == clang::AArch64::BI__builtin_arm_ldrex ||
4660 BuiltinID == clang::AArch64::BI__builtin_arm_ldaex) {
4669 CGM.getIntrinsic(BuiltinID == clang::AArch64::BI__builtin_arm_ldaex
4670 ? Intrinsic::aarch64_ldaxr
4671 : Intrinsic::aarch64_ldxr,
4673 CallInst *Val =
Builder.CreateCall(F, LoadAddr,
"ldxr");
4677 if (RealResTy->isPointerTy())
4678 return Builder.CreateIntToPtr(Val, RealResTy);
4680 llvm::Type *IntResTy = llvm::IntegerType::get(
4682 return Builder.CreateBitCast(
Builder.CreateTruncOrBitCast(Val, IntResTy),
4686 if ((BuiltinID == clang::AArch64::BI__builtin_arm_strex ||
4687 BuiltinID == clang::AArch64::BI__builtin_arm_stlex) &&
4690 CGM.getIntrinsic(BuiltinID == clang::AArch64::BI__builtin_arm_stlex
4691 ? Intrinsic::aarch64_stlxp
4692 : Intrinsic::aarch64_stxp);
4699 llvm::Value *Val =
Builder.CreateLoad(Tmp);
4704 return Builder.CreateCall(F, {Arg0, Arg1, StPtr},
"stxp");
4707 if (BuiltinID == clang::AArch64::BI__builtin_arm_strex ||
4708 BuiltinID == clang::AArch64::BI__builtin_arm_stlex) {
4713 llvm::Type *StoreTy =
4716 if (StoreVal->
getType()->isPointerTy())
4719 llvm::Type *
IntTy = llvm::IntegerType::get(
4721 CGM.getDataLayout().getTypeSizeInBits(StoreVal->
getType()));
4727 CGM.getIntrinsic(BuiltinID == clang::AArch64::BI__builtin_arm_stlex
4728 ? Intrinsic::aarch64_stlxr
4729 : Intrinsic::aarch64_stxr,
4731 CallInst *CI =
Builder.CreateCall(F, {StoreVal, StoreAddr},
"stxr");
4733 1, Attribute::get(
getLLVMContext(), Attribute::ElementType, StoreTy));
4737 if (BuiltinID == clang::AArch64::BI__getReg ||
4738 BuiltinID == clang::AArch64::BI__setReg) {
4741 llvm_unreachable(
"Sema will ensure that the parameter is constant");
4744 LLVMContext &Context =
CGM.getLLVMContext();
4747 llvm::Metadata *Ops[] = {llvm::MDString::get(Context, Reg)};
4748 llvm::MDNode *RegName = llvm::MDNode::get(Context, Ops);
4749 llvm::Value *Metadata = llvm::MetadataAsValue::get(Context, RegName);
4752 if (BuiltinID == clang::AArch64::BI__getReg) {
4754 CGM.getIntrinsic(Intrinsic::read_volatile_register, {
Int64Ty});
4755 CI =
Builder.CreateCall(F, Metadata);
4758 CGM.getIntrinsic(Intrinsic::write_volatile_register, {
Int64Ty});
4764 if (BuiltinID == clang::AArch64::BI__getRegFp ||
4765 BuiltinID == clang::AArch64::BI__setRegFp) {
4768 llvm_unreachable(
"Sema will ensure that the parameter is constant");
4771 LLVMContext &Context =
CGM.getLLVMContext();
4774 llvm::Metadata *Ops[] = {llvm::MDString::get(Context, Reg)};
4775 llvm::MDNode *RegName = llvm::MDNode::get(Context, Ops);
4776 llvm::Value *Metadata = llvm::MetadataAsValue::get(Context, RegName);
4779 if (BuiltinID == clang::AArch64::BI__getRegFp) {
4781 CGM.getIntrinsic(Intrinsic::read_volatile_register, {
Int64Ty});
4782 llvm::Value *Bits =
Builder.CreateCall(F, Metadata);
4783 Ret =
Builder.CreateBitCast(Bits, llvm::Type::getDoubleTy(Context));
4788 CGM.getIntrinsic(Intrinsic::write_volatile_register, {
Int64Ty});
4789 Ret =
Builder.CreateCall(F, {Metadata, Bits});
4794 if (BuiltinID == clang::AArch64::BI__break) {
4797 llvm_unreachable(
"Sema will ensure that the parameter is constant");
4799 llvm::Function *F =
CGM.getIntrinsic(Intrinsic::aarch64_break);
4803 if (BuiltinID == clang::AArch64::BI__builtin_arm_clrex) {
4804 Function *F =
CGM.getIntrinsic(Intrinsic::aarch64_clrex);
4808 if (BuiltinID == clang::AArch64::BI_ReadWriteBarrier)
4809 return Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent,
4810 llvm::SyncScope::SingleThread);
4813 Intrinsic::ID CRCIntrinsicID = Intrinsic::not_intrinsic;
4814 switch (BuiltinID) {
4815 case clang::AArch64::BI__builtin_arm_crc32b:
4816 CRCIntrinsicID = Intrinsic::aarch64_crc32b;
break;
4817 case clang::AArch64::BI__builtin_arm_crc32cb:
4818 CRCIntrinsicID = Intrinsic::aarch64_crc32cb;
break;
4819 case clang::AArch64::BI__builtin_arm_crc32h:
4820 CRCIntrinsicID = Intrinsic::aarch64_crc32h;
break;
4821 case clang::AArch64::BI__builtin_arm_crc32ch:
4822 CRCIntrinsicID = Intrinsic::aarch64_crc32ch;
break;
4823 case clang::AArch64::BI__builtin_arm_crc32w:
4824 CRCIntrinsicID = Intrinsic::aarch64_crc32w;
break;
4825 case clang::AArch64::BI__builtin_arm_crc32cw:
4826 CRCIntrinsicID = Intrinsic::aarch64_crc32cw;
break;
4827 case clang::AArch64::BI__builtin_arm_crc32d:
4828 CRCIntrinsicID = Intrinsic::aarch64_crc32x;
break;
4829 case clang::AArch64::BI__builtin_arm_crc32cd:
4830 CRCIntrinsicID = Intrinsic::aarch64_crc32cx;
break;
4833 if (CRCIntrinsicID != Intrinsic::not_intrinsic) {
4838 llvm::Type *DataTy = F->getFunctionType()->getParamType(1);
4839 Arg1 =
Builder.CreateZExtOrBitCast(Arg1, DataTy);
4841 return Builder.CreateCall(F, {Arg0, Arg1});
4845 if (BuiltinID == AArch64::BI__builtin_arm_mops_memset_tag) {
4852 CGM.getIntrinsic(Intrinsic::aarch64_mops_memset_tag), {Dst, Val, Size});
4855 if (BuiltinID == AArch64::BI__builtin_arm_range_prefetch ||
4856 BuiltinID == AArch64::BI__builtin_arm_range_prefetch_x)
4860 Intrinsic::ID MTEIntrinsicID = Intrinsic::not_intrinsic;
4861 switch (BuiltinID) {
4862 case clang::AArch64::BI__builtin_arm_irg:
4863 MTEIntrinsicID = Intrinsic::aarch64_irg;
break;
4864 case clang::AArch64::BI__builtin_arm_addg:
4865 MTEIntrinsicID = Intrinsic::aarch64_addg;
break;
4866 case clang::AArch64::BI__builtin_arm_gmi:
4867 MTEIntrinsicID = Intrinsic::aarch64_gmi;
break;
4868 case clang::AArch64::BI__builtin_arm_ldg:
4869 MTEIntrinsicID = Intrinsic::aarch64_ldg;
break;
4870 case clang::AArch64::BI__builtin_arm_stg:
4871 MTEIntrinsicID = Intrinsic::aarch64_stg;
break;
4872 case clang::AArch64::BI__builtin_arm_subp:
4873 MTEIntrinsicID = Intrinsic::aarch64_subp;
break;
4876 if (MTEIntrinsicID != Intrinsic::not_intrinsic) {
4877 if (MTEIntrinsicID == Intrinsic::aarch64_irg) {
4880 assert(Mask->
getType()->getScalarSizeInBits() == 64 &&
4881 "SemaARM::BuiltinARMMemoryTaggingCall() enforces this");
4882 return Builder.CreateCall(
CGM.getIntrinsic(MTEIntrinsicID),
4885 if (MTEIntrinsicID == Intrinsic::aarch64_addg) {
4890 return Builder.CreateCall(
CGM.getIntrinsic(MTEIntrinsicID),
4891 {Pointer, TagOffset});
4893 if (MTEIntrinsicID == Intrinsic::aarch64_gmi) {
4896 assert(ExcludedMask->
getType()->getScalarSizeInBits() == 64 &&
4897 "SemaARM::BuiltinARMMemoryTaggingCall() enforces this");
4898 return Builder.CreateCall(
CGM.getIntrinsic(MTEIntrinsicID),
4899 {Pointer, ExcludedMask});
4904 if (MTEIntrinsicID == Intrinsic::aarch64_ldg) {
4906 return Builder.CreateCall(
CGM.getIntrinsic(MTEIntrinsicID),
4907 {TagAddress, TagAddress});
4912 if (MTEIntrinsicID == Intrinsic::aarch64_stg) {
4914 return Builder.CreateCall(
CGM.getIntrinsic(MTEIntrinsicID),
4915 {TagAddress, TagAddress});
4917 if (MTEIntrinsicID == Intrinsic::aarch64_subp) {
4921 CGM.getIntrinsic(MTEIntrinsicID), {PointerA, PointerB});
4925 if (BuiltinID == clang::AArch64::BI__builtin_arm_rsr ||
4926 BuiltinID == clang::AArch64::BI__builtin_arm_rsr64 ||
4927 BuiltinID == clang::AArch64::BI__builtin_arm_rsr128 ||
4928 BuiltinID == clang::AArch64::BI__builtin_arm_rsrp ||
4929 BuiltinID == clang::AArch64::BI__builtin_arm_wsr ||
4930 BuiltinID == clang::AArch64::BI__builtin_arm_wsr64 ||
4931 BuiltinID == clang::AArch64::BI__builtin_arm_wsr128 ||
4932 BuiltinID == clang::AArch64::BI__builtin_arm_wsrp) {
4935 if (BuiltinID == clang::AArch64::BI__builtin_arm_rsr ||
4936 BuiltinID == clang::AArch64::BI__builtin_arm_rsr64 ||
4937 BuiltinID == clang::AArch64::BI__builtin_arm_rsr128 ||
4938 BuiltinID == clang::AArch64::BI__builtin_arm_rsrp)
4941 bool IsPointerBuiltin = BuiltinID == clang::AArch64::BI__builtin_arm_rsrp ||
4942 BuiltinID == clang::AArch64::BI__builtin_arm_wsrp;
4944 bool Is32Bit = BuiltinID == clang::AArch64::BI__builtin_arm_rsr ||
4945 BuiltinID == clang::AArch64::BI__builtin_arm_wsr;
4947 bool Is128Bit = BuiltinID == clang::AArch64::BI__builtin_arm_rsr128 ||
4948 BuiltinID == clang::AArch64::BI__builtin_arm_wsr128;
4950 llvm::Type *ValueType;
4954 }
else if (Is128Bit) {
4955 llvm::Type *Int128Ty =
4956 llvm::IntegerType::getInt128Ty(
CGM.getLLVMContext());
4957 ValueType = Int128Ty;
4959 }
else if (IsPointerBuiltin) {
4969 if (BuiltinID == clang::AArch64::BI_ReadStatusReg ||
4970 BuiltinID == clang::AArch64::BI_WriteStatusReg) {
4971 LLVMContext &Context =
CGM.getLLVMContext();
4976 std::string SysRegStr;
4977 llvm::raw_string_ostream(SysRegStr)
4978 << (0b10 | SysReg >> 14) <<
":" << ((SysReg >> 11) & 7) <<
":"
4979 << ((SysReg >> 7) & 15) <<
":" << ((SysReg >> 3) & 15) <<
":"
4982 llvm::Metadata *Ops[] = { llvm::MDString::get(Context, SysRegStr) };
4983 llvm::MDNode *RegName = llvm::MDNode::get(Context, Ops);
4984 llvm::Value *Metadata = llvm::MetadataAsValue::get(Context, RegName);
4989 if (BuiltinID == clang::AArch64::BI_ReadStatusReg) {
4990 llvm::Function *F =
CGM.getIntrinsic(Intrinsic::read_register, Types);
4992 return Builder.CreateCall(F, Metadata);
4995 llvm::Function *F =
CGM.getIntrinsic(Intrinsic::write_register, Types);
4997 llvm::Value *
Result =
Builder.CreateCall(F, {Metadata, ArgValue});
5002 if (BuiltinID == clang::AArch64::BI__sys) {
5005 const unsigned Op1 = SysReg >> 11;
5006 const unsigned CRn = (SysReg >> 7) & 0xf;
5007 const unsigned CRm = (SysReg >> 3) & 0xf;
5008 const unsigned Op2 = SysReg & 0x7;
5010 Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::aarch64_sys),
5011 {Builder.getInt32(Op1), Builder.getInt32(CRn),
5012 Builder.getInt32(CRm), Builder.getInt32(Op2),
5013 EmitScalarExpr(E->getArg(1))});
5017 return ConstantInt::get(
Builder.getInt32Ty(), 0);
5020 if (BuiltinID == clang::AArch64::BI_AddressOfReturnAddress) {
5026 if (BuiltinID == clang::AArch64::BI__builtin_sponentry) {
5031 if (BuiltinID == clang::AArch64::BI__mulh ||
5032 BuiltinID == clang::AArch64::BI__umulh) {
5034 llvm::Type *Int128Ty = llvm::IntegerType::get(
getLLVMContext(), 128);
5036 bool IsSigned = BuiltinID == clang::AArch64::BI__mulh;
5042 Value *MulResult, *HigherBits;
5044 MulResult =
Builder.CreateNSWMul(LHS, RHS);
5045 HigherBits =
Builder.CreateAShr(MulResult, 64);
5047 MulResult =
Builder.CreateNUWMul(LHS, RHS);
5048 HigherBits =
Builder.CreateLShr(MulResult, 64);
5050 HigherBits =
Builder.CreateIntCast(HigherBits, ResType, IsSigned);
5055 if (BuiltinID == AArch64::BI__writex18byte ||
5056 BuiltinID == AArch64::BI__writex18word ||
5057 BuiltinID == AArch64::BI__writex18dword ||
5058 BuiltinID == AArch64::BI__writex18qword) {
5074 if (BuiltinID == AArch64::BI__readx18byte ||
5075 BuiltinID == AArch64::BI__readx18word ||
5076 BuiltinID == AArch64::BI__readx18dword ||
5077 BuiltinID == AArch64::BI__readx18qword) {
5092 if (BuiltinID == AArch64::BI__addx18byte ||
5093 BuiltinID == AArch64::BI__addx18word ||
5094 BuiltinID == AArch64::BI__addx18dword ||
5095 BuiltinID == AArch64::BI__addx18qword ||
5096 BuiltinID == AArch64::BI__incx18byte ||
5097 BuiltinID == AArch64::BI__incx18word ||
5098 BuiltinID == AArch64::BI__incx18dword ||
5099 BuiltinID == AArch64::BI__incx18qword) {
5102 switch (BuiltinID) {
5103 case AArch64::BI__incx18byte:
5107 case AArch64::BI__incx18word:
5111 case AArch64::BI__incx18dword:
5115 case AArch64::BI__incx18qword:
5121 isIncrement =
false;
5146 if (BuiltinID == AArch64::BI_CopyDoubleFromInt64 ||
5147 BuiltinID == AArch64::BI_CopyFloatFromInt32 ||
5148 BuiltinID == AArch64::BI_CopyInt32FromFloat ||
5149 BuiltinID == AArch64::BI_CopyInt64FromDouble) {
5152 return Builder.CreateBitCast(Arg, RetTy);
5155 if (BuiltinID == AArch64::BI_CountLeadingOnes ||
5156 BuiltinID == AArch64::BI_CountLeadingOnes64 ||
5157 BuiltinID == AArch64::BI_CountLeadingZeros ||
5158 BuiltinID == AArch64::BI_CountLeadingZeros64) {
5162 if (BuiltinID == AArch64::BI_CountLeadingOnes ||
5163 BuiltinID == AArch64::BI_CountLeadingOnes64)
5164 Arg =
Builder.CreateXor(Arg, Constant::getAllOnesValue(
ArgType));
5169 if (BuiltinID == AArch64::BI_CountLeadingOnes64 ||
5170 BuiltinID == AArch64::BI_CountLeadingZeros64)
5175 if (BuiltinID == AArch64::BI_CountLeadingSigns ||
5176 BuiltinID == AArch64::BI_CountLeadingSigns64) {
5179 Function *F = (BuiltinID == AArch64::BI_CountLeadingSigns)
5180 ?
CGM.getIntrinsic(Intrinsic::aarch64_cls)
5181 :
CGM.getIntrinsic(Intrinsic::aarch64_cls64);
5184 if (BuiltinID == AArch64::BI_CountLeadingSigns64)
5189 if (BuiltinID == AArch64::BI_CountOneBits ||
5190 BuiltinID == AArch64::BI_CountOneBits64) {
5196 if (BuiltinID == AArch64::BI_CountOneBits64)
5201 if (BuiltinID == AArch64::BI_CountTrailingZeros ||
5202 BuiltinID == AArch64::BI_CountTrailingZeros64) {
5209 if (BuiltinID == AArch64::BI_CountTrailingZeros64)
5214 if (BuiltinID == AArch64::BI__prefetch) {
5223 if (BuiltinID == AArch64::BI__prefetch2) {
5231 uint64_t Op = PrfOp.getZExtValue();
5232 uint64_t
Type = (Op >> 3) & 0x3;
5233 uint64_t
Target = (Op >> 1) & 0x3;
5234 uint64_t Policy = Op & 0x1;
5239 Function *F =
CGM.getIntrinsic(Intrinsic::aarch64_prefetch);
5240 return Builder.CreateCall(F, {
Address, RW, Local, IsStream, IsData});
5243 if (BuiltinID == AArch64::BI__hlt) {
5244 Function *F =
CGM.getIntrinsic(Intrinsic::aarch64_hlt);
5250 return ConstantInt::get(
Builder.getInt32Ty(), 0);
5253 if (BuiltinID == AArch64::BI__hvc || BuiltinID == AArch64::BI__svc) {
5254 unsigned IID = BuiltinID == AArch64::BI__svc ? Intrinsic::aarch64_svc
5255 : Intrinsic::aarch64_hvc;
5263 for (
unsigned I = 1, N = E->
getNumArgs(); I < N; ++I) {
5265 llvm::Type *ArgTy = Arg->
getType();
5266 if (ArgTy->isPointerTy())
5268 else if (ArgTy->isFloatingPointTy())
5271 Arg =
Builder.CreateZExtOrTrunc(
5273 Arg,
Builder.getIntNTy(ArgTy->getPrimitiveSizeInBits())),
5278 Args.push_back(Arg);
5280 while (Args.size() < 5)
5281 Args.push_back(llvm::PoisonValue::get(
Int64Ty));
5287 if (BuiltinID == NEON::BI__builtin_neon_vcvth_bf16_f32)
5295 if (std::optional<MSVCIntrin> MsvcIntId =
5301 return P.first == BuiltinID;
5304 BuiltinID = It->second;
5310 bool IsSISD = (
Builtin !=
nullptr);
5314 unsigned ICEArguments = 0;
5325 unsigned NumArgs = E->
getNumArgs() - (HasExtraArg ? 1 : 0);
5326 for (
unsigned i = 0, e = NumArgs; i != e; i++) {
5328 switch (BuiltinID) {
5329 case NEON::BI__builtin_neon_vld1_v:
5330 case NEON::BI__builtin_neon_vld1q_v:
5331 case NEON::BI__builtin_neon_vld1_dup_v:
5332 case NEON::BI__builtin_neon_vld1q_dup_v:
5333 case NEON::BI__builtin_neon_vld1_lane_v:
5334 case NEON::BI__builtin_neon_vld1q_lane_v:
5335 case NEON::BI__builtin_neon_vst1_v:
5336 case NEON::BI__builtin_neon_vst1q_v:
5337 case NEON::BI__builtin_neon_vst1_lane_v:
5338 case NEON::BI__builtin_neon_vst1q_lane_v:
5339 case NEON::BI__builtin_neon_vldap1_lane_s64:
5340 case NEON::BI__builtin_neon_vldap1q_lane_s64:
5341 case NEON::BI__builtin_neon_vstl1_lane_s64:
5342 case NEON::BI__builtin_neon_vstl1q_lane_s64:
5355 assert(
Result &&
"SISD intrinsic should have been handled");
5361 if (std::optional<llvm::APSInt>
Result =
5366 bool usgn =
Type.isUnsigned();
5367 bool quad =
Type.isQuad();
5386 switch (BuiltinID) {
5388 case NEON::BI__builtin_neon_vabsh_f16:
5390 case NEON::BI__builtin_neon_vaddq_p128: {
5392 Ops[0] =
Builder.CreateBitCast(Ops[0], Ty);
5393 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
5394 Ops[0] =
Builder.CreateXor(Ops[0], Ops[1]);
5395 llvm::Type *Int128Ty = llvm::Type::getIntNTy(
getLLVMContext(), 128);
5396 return Builder.CreateBitCast(Ops[0], Int128Ty);
5398 case NEON::BI__builtin_neon_vldrq_p128: {
5399 llvm::Type *Int128Ty = llvm::Type::getIntNTy(
getLLVMContext(), 128);
5400 return Builder.CreateAlignedLoad(Int128Ty, Ops[0],
5403 case NEON::BI__builtin_neon_vstrq_p128: {
5404 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
5406 case NEON::BI__builtin_neon_vcvts_f32_u32:
5407 case NEON::BI__builtin_neon_vcvtd_f64_u64:
5410 case NEON::BI__builtin_neon_vcvts_f32_s32:
5411 case NEON::BI__builtin_neon_vcvtd_f64_s64: {
5412 bool Is64 = Ops[0]->getType()->getPrimitiveSizeInBits() == 64;
5415 Ops[0] =
Builder.CreateBitCast(Ops[0], InTy);
5417 return Builder.CreateUIToFP(Ops[0], FTy);
5418 return Builder.CreateSIToFP(Ops[0], FTy);
5420 case NEON::BI__builtin_neon_vcvth_f16_u16:
5421 case NEON::BI__builtin_neon_vcvth_f16_u32:
5422 case NEON::BI__builtin_neon_vcvth_f16_u64:
5425 case NEON::BI__builtin_neon_vcvth_f16_s16:
5426 case NEON::BI__builtin_neon_vcvth_f16_s32:
5427 case NEON::BI__builtin_neon_vcvth_f16_s64: {
5428 llvm::Type *FTy =
HalfTy;
5430 if (Ops[0]->
getType()->getPrimitiveSizeInBits() == 64)
5432 else if (Ops[0]->
getType()->getPrimitiveSizeInBits() == 32)
5436 Ops[0] =
Builder.CreateBitCast(Ops[0], InTy);
5438 return Builder.CreateUIToFP(Ops[0], FTy);
5439 return Builder.CreateSIToFP(Ops[0], FTy);
5441 case NEON::BI__builtin_neon_vcvtah_u16_f16:
5442 case NEON::BI__builtin_neon_vcvtmh_u16_f16:
5443 case NEON::BI__builtin_neon_vcvtnh_u16_f16:
5444 case NEON::BI__builtin_neon_vcvtph_u16_f16:
5445 case NEON::BI__builtin_neon_vcvtah_s16_f16:
5446 case NEON::BI__builtin_neon_vcvtmh_s16_f16:
5447 case NEON::BI__builtin_neon_vcvtnh_s16_f16:
5448 case NEON::BI__builtin_neon_vcvtph_s16_f16: {
5450 llvm::Type* FTy =
HalfTy;
5451 llvm::Type *Tys[2] = {InTy, FTy};
5452 switch (BuiltinID) {
5453 default: llvm_unreachable(
"missing builtin ID in switch!");
5454 case NEON::BI__builtin_neon_vcvtah_u16_f16:
5455 Int = Intrinsic::aarch64_neon_fcvtau;
break;
5456 case NEON::BI__builtin_neon_vcvtmh_u16_f16:
5457 Int = Intrinsic::aarch64_neon_fcvtmu;
break;
5458 case NEON::BI__builtin_neon_vcvtnh_u16_f16:
5459 Int = Intrinsic::aarch64_neon_fcvtnu;
break;
5460 case NEON::BI__builtin_neon_vcvtph_u16_f16:
5461 Int = Intrinsic::aarch64_neon_fcvtpu;
break;
5462 case NEON::BI__builtin_neon_vcvtah_s16_f16:
5463 Int = Intrinsic::aarch64_neon_fcvtas;
break;
5464 case NEON::BI__builtin_neon_vcvtmh_s16_f16:
5465 Int = Intrinsic::aarch64_neon_fcvtms;
break;
5466 case NEON::BI__builtin_neon_vcvtnh_s16_f16:
5467 Int = Intrinsic::aarch64_neon_fcvtns;
break;
5468 case NEON::BI__builtin_neon_vcvtph_s16_f16:
5469 Int = Intrinsic::aarch64_neon_fcvtps;
break;
5473 case NEON::BI__builtin_neon_vcaleh_f16:
5474 case NEON::BI__builtin_neon_vcalth_f16:
5475 case NEON::BI__builtin_neon_vcageh_f16:
5476 case NEON::BI__builtin_neon_vcagth_f16: {
5478 llvm::Type* FTy =
HalfTy;
5479 llvm::Type *Tys[2] = {InTy, FTy};
5480 switch (BuiltinID) {
5481 default: llvm_unreachable(
"missing builtin ID in switch!");
5482 case NEON::BI__builtin_neon_vcageh_f16:
5483 Int = Intrinsic::aarch64_neon_facge;
break;
5484 case NEON::BI__builtin_neon_vcagth_f16:
5485 Int = Intrinsic::aarch64_neon_facgt;
break;
5486 case NEON::BI__builtin_neon_vcaleh_f16:
5487 Int = Intrinsic::aarch64_neon_facge; std::swap(Ops[0], Ops[1]);
break;
5488 case NEON::BI__builtin_neon_vcalth_f16:
5489 Int = Intrinsic::aarch64_neon_facgt; std::swap(Ops[0], Ops[1]);
break;
5494 case NEON::BI__builtin_neon_vcvth_n_s16_f16:
5495 case NEON::BI__builtin_neon_vcvth_n_u16_f16: {
5497 llvm::Type* FTy =
HalfTy;
5498 llvm::Type *Tys[2] = {InTy, FTy};
5499 switch (BuiltinID) {
5500 default: llvm_unreachable(
"missing builtin ID in switch!");
5501 case NEON::BI__builtin_neon_vcvth_n_s16_f16:
5502 Int = Intrinsic::aarch64_neon_vcvtfp2fxs;
break;
5503 case NEON::BI__builtin_neon_vcvth_n_u16_f16:
5504 Int = Intrinsic::aarch64_neon_vcvtfp2fxu;
break;
5509 case NEON::BI__builtin_neon_vcvth_n_f16_s16:
5510 case NEON::BI__builtin_neon_vcvth_n_f16_u16: {
5511 llvm::Type* FTy =
HalfTy;
5513 llvm::Type *Tys[2] = {FTy, InTy};
5514 switch (BuiltinID) {
5515 default: llvm_unreachable(
"missing builtin ID in switch!");
5516 case NEON::BI__builtin_neon_vcvth_n_f16_s16:
5517 Int = Intrinsic::aarch64_neon_vcvtfxs2fp;
5518 Ops[0] =
Builder.CreateSExt(Ops[0], InTy,
"sext");
5520 case NEON::BI__builtin_neon_vcvth_n_f16_u16:
5521 Int = Intrinsic::aarch64_neon_vcvtfxu2fp;
5522 Ops[0] =
Builder.CreateZExt(Ops[0], InTy);
5527 case NEON::BI__builtin_neon_vpaddd_s64: {
5530 auto *Ty = llvm::FixedVectorType::get(
Int64Ty, 2);
5532 Ops[0] =
Builder.CreateBitCast(Ops[0], Ty,
"v2i64");
5533 llvm::Value *Idx0 = llvm::ConstantInt::get(
SizeTy, 0);
5534 llvm::Value *Idx1 = llvm::ConstantInt::get(
SizeTy, 1);
5535 Value *Op0 =
Builder.CreateExtractElement(Ops[0], Idx0,
"lane0");
5536 Value *Op1 =
Builder.CreateExtractElement(Ops[0], Idx1,
"lane1");
5538 return Builder.CreateAdd(Op0, Op1,
"vpaddd");
5540 case NEON::BI__builtin_neon_vpaddd_f64: {
5541 auto *Ty = llvm::FixedVectorType::get(
DoubleTy, 2);
5543 Ops[0] =
Builder.CreateBitCast(Ops[0], Ty,
"v2f64");
5544 llvm::Value *Idx0 = llvm::ConstantInt::get(
SizeTy, 0);
5545 llvm::Value *Idx1 = llvm::ConstantInt::get(
SizeTy, 1);
5546 Value *Op0 =
Builder.CreateExtractElement(Ops[0], Idx0,
"lane0");
5547 Value *Op1 =
Builder.CreateExtractElement(Ops[0], Idx1,
"lane1");
5549 return Builder.CreateFAdd(Op0, Op1,
"vpaddd");
5551 case NEON::BI__builtin_neon_vpadds_f32: {
5552 auto *Ty = llvm::FixedVectorType::get(
FloatTy, 2);
5554 Ops[0] =
Builder.CreateBitCast(Ops[0], Ty,
"v2f32");
5555 llvm::Value *Idx0 = llvm::ConstantInt::get(
SizeTy, 0);
5556 llvm::Value *Idx1 = llvm::ConstantInt::get(
SizeTy, 1);
5557 Value *Op0 =
Builder.CreateExtractElement(Ops[0], Idx0,
"lane0");
5558 Value *Op1 =
Builder.CreateExtractElement(Ops[0], Idx1,
"lane1");
5560 return Builder.CreateFAdd(Op0, Op1,
"vpaddd");
5562 case NEON::BI__builtin_neon_vceqzd_s64:
5565 ICmpInst::ICMP_EQ,
"vceqz");
5566 case NEON::BI__builtin_neon_vceqzd_f64:
5567 case NEON::BI__builtin_neon_vceqzs_f32:
5568 case NEON::BI__builtin_neon_vceqzh_f16:
5571 ICmpInst::FCMP_OEQ,
"vceqz");
5572 case NEON::BI__builtin_neon_vcgezd_s64:
5575 ICmpInst::ICMP_SGE,
"vcgez");
5576 case NEON::BI__builtin_neon_vcgezd_f64:
5577 case NEON::BI__builtin_neon_vcgezs_f32:
5578 case NEON::BI__builtin_neon_vcgezh_f16:
5581 ICmpInst::FCMP_OGE,
"vcgez");
5582 case NEON::BI__builtin_neon_vclezd_s64:
5585 ICmpInst::ICMP_SLE,
"vclez");
5586 case NEON::BI__builtin_neon_vclezd_f64:
5587 case NEON::BI__builtin_neon_vclezs_f32:
5588 case NEON::BI__builtin_neon_vclezh_f16:
5591 ICmpInst::FCMP_OLE,
"vclez");
5592 case NEON::BI__builtin_neon_vcgtzd_s64:
5595 ICmpInst::ICMP_SGT,
"vcgtz");
5596 case NEON::BI__builtin_neon_vcgtzd_f64:
5597 case NEON::BI__builtin_neon_vcgtzs_f32:
5598 case NEON::BI__builtin_neon_vcgtzh_f16:
5601 ICmpInst::FCMP_OGT,
"vcgtz");
5602 case NEON::BI__builtin_neon_vcltzd_s64:
5605 ICmpInst::ICMP_SLT,
"vcltz");
5607 case NEON::BI__builtin_neon_vcltzd_f64:
5608 case NEON::BI__builtin_neon_vcltzs_f32:
5609 case NEON::BI__builtin_neon_vcltzh_f16:
5612 ICmpInst::FCMP_OLT,
"vcltz");
5614 case NEON::BI__builtin_neon_vceqzd_u64: {
5617 ICmpInst::ICMP_EQ,
"vceqzd");
5619 case NEON::BI__builtin_neon_vceqd_f64:
5620 case NEON::BI__builtin_neon_vcled_f64:
5621 case NEON::BI__builtin_neon_vcltd_f64:
5622 case NEON::BI__builtin_neon_vcged_f64:
5623 case NEON::BI__builtin_neon_vcgtd_f64: {
5624 llvm::CmpInst::Predicate P;
5625 switch (BuiltinID) {
5626 default: llvm_unreachable(
"missing builtin ID in switch!");
5627 case NEON::BI__builtin_neon_vceqd_f64: P = llvm::FCmpInst::FCMP_OEQ;
break;
5628 case NEON::BI__builtin_neon_vcled_f64: P = llvm::FCmpInst::FCMP_OLE;
break;
5629 case NEON::BI__builtin_neon_vcltd_f64: P = llvm::FCmpInst::FCMP_OLT;
break;
5630 case NEON::BI__builtin_neon_vcged_f64: P = llvm::FCmpInst::FCMP_OGE;
break;
5631 case NEON::BI__builtin_neon_vcgtd_f64: P = llvm::FCmpInst::FCMP_OGT;
break;
5635 if (P == llvm::FCmpInst::FCMP_OEQ)
5636 Ops[0] =
Builder.CreateFCmp(P, Ops[0], Ops[1]);
5638 Ops[0] =
Builder.CreateFCmpS(P, Ops[0], Ops[1]);
5641 case NEON::BI__builtin_neon_vceqs_f32:
5642 case NEON::BI__builtin_neon_vcles_f32:
5643 case NEON::BI__builtin_neon_vclts_f32:
5644 case NEON::BI__builtin_neon_vcges_f32:
5645 case NEON::BI__builtin_neon_vcgts_f32: {
5646 llvm::CmpInst::Predicate P;
5647 switch (BuiltinID) {
5648 default: llvm_unreachable(
"missing builtin ID in switch!");
5649 case NEON::BI__builtin_neon_vceqs_f32: P = llvm::FCmpInst::FCMP_OEQ;
break;
5650 case NEON::BI__builtin_neon_vcles_f32: P = llvm::FCmpInst::FCMP_OLE;
break;
5651 case NEON::BI__builtin_neon_vclts_f32: P = llvm::FCmpInst::FCMP_OLT;
break;
5652 case NEON::BI__builtin_neon_vcges_f32: P = llvm::FCmpInst::FCMP_OGE;
break;
5653 case NEON::BI__builtin_neon_vcgts_f32: P = llvm::FCmpInst::FCMP_OGT;
break;
5657 if (P == llvm::FCmpInst::FCMP_OEQ)
5658 Ops[0] =
Builder.CreateFCmp(P, Ops[0], Ops[1]);
5660 Ops[0] =
Builder.CreateFCmpS(P, Ops[0], Ops[1]);
5663 case NEON::BI__builtin_neon_vceqh_f16:
5664 case NEON::BI__builtin_neon_vcleh_f16:
5665 case NEON::BI__builtin_neon_vclth_f16:
5666 case NEON::BI__builtin_neon_vcgeh_f16:
5667 case NEON::BI__builtin_neon_vcgth_f16: {
5668 llvm::CmpInst::Predicate P;
5669 switch (BuiltinID) {
5670 default: llvm_unreachable(
"missing builtin ID in switch!");
5671 case NEON::BI__builtin_neon_vceqh_f16: P = llvm::FCmpInst::FCMP_OEQ;
break;
5672 case NEON::BI__builtin_neon_vcleh_f16: P = llvm::FCmpInst::FCMP_OLE;
break;
5673 case NEON::BI__builtin_neon_vclth_f16: P = llvm::FCmpInst::FCMP_OLT;
break;
5674 case NEON::BI__builtin_neon_vcgeh_f16: P = llvm::FCmpInst::FCMP_OGE;
break;
5675 case NEON::BI__builtin_neon_vcgth_f16: P = llvm::FCmpInst::FCMP_OGT;
break;
5679 if (P == llvm::FCmpInst::FCMP_OEQ)
5680 Ops[0] =
Builder.CreateFCmp(P, Ops[0], Ops[1]);
5682 Ops[0] =
Builder.CreateFCmpS(P, Ops[0], Ops[1]);
5685 case NEON::BI__builtin_neon_vceqd_s64:
5686 case NEON::BI__builtin_neon_vceqd_u64:
5687 case NEON::BI__builtin_neon_vcgtd_s64:
5688 case NEON::BI__builtin_neon_vcgtd_u64:
5689 case NEON::BI__builtin_neon_vcltd_s64:
5690 case NEON::BI__builtin_neon_vcltd_u64:
5691 case NEON::BI__builtin_neon_vcged_u64:
5692 case NEON::BI__builtin_neon_vcged_s64:
5693 case NEON::BI__builtin_neon_vcled_u64:
5694 case NEON::BI__builtin_neon_vcled_s64: {
5695 llvm::CmpInst::Predicate P;
5696 switch (BuiltinID) {
5697 default: llvm_unreachable(
"missing builtin ID in switch!");
5698 case NEON::BI__builtin_neon_vceqd_s64:
5699 case NEON::BI__builtin_neon_vceqd_u64:P = llvm::ICmpInst::ICMP_EQ;
break;
5700 case NEON::BI__builtin_neon_vcgtd_s64:P = llvm::ICmpInst::ICMP_SGT;
break;
5701 case NEON::BI__builtin_neon_vcgtd_u64:P = llvm::ICmpInst::ICMP_UGT;
break;
5702 case NEON::BI__builtin_neon_vcltd_s64:P = llvm::ICmpInst::ICMP_SLT;
break;
5703 case NEON::BI__builtin_neon_vcltd_u64:P = llvm::ICmpInst::ICMP_ULT;
break;
5704 case NEON::BI__builtin_neon_vcged_u64:P = llvm::ICmpInst::ICMP_UGE;
break;
5705 case NEON::BI__builtin_neon_vcged_s64:P = llvm::ICmpInst::ICMP_SGE;
break;
5706 case NEON::BI__builtin_neon_vcled_u64:P = llvm::ICmpInst::ICMP_ULE;
break;
5707 case NEON::BI__builtin_neon_vcled_s64:P = llvm::ICmpInst::ICMP_SLE;
break;
5711 Ops[0] =
Builder.CreateICmp(P, Ops[0], Ops[1]);
5714 case NEON::BI__builtin_neon_vnegd_s64:
5715 return Builder.CreateNeg(Ops[0],
"vnegd");
5716 case NEON::BI__builtin_neon_vnegh_f16:
5717 return Builder.CreateFNeg(Ops[0],
"vnegh");
5718 case NEON::BI__builtin_neon_vtstd_s64:
5719 case NEON::BI__builtin_neon_vtstd_u64: {
5722 Ops[0] =
Builder.CreateAnd(Ops[0], Ops[1]);
5723 Ops[0] =
Builder.CreateICmp(ICmpInst::ICMP_NE, Ops[0],
5724 llvm::Constant::getNullValue(
Int64Ty));
5727 case NEON::BI__builtin_neon_vset_lane_i8:
5728 case NEON::BI__builtin_neon_vset_lane_i16:
5729 case NEON::BI__builtin_neon_vset_lane_i32:
5730 case NEON::BI__builtin_neon_vset_lane_i64:
5731 case NEON::BI__builtin_neon_vset_lane_bf16:
5732 case NEON::BI__builtin_neon_vset_lane_f32:
5733 case NEON::BI__builtin_neon_vsetq_lane_i8:
5734 case NEON::BI__builtin_neon_vsetq_lane_i16:
5735 case NEON::BI__builtin_neon_vsetq_lane_i32:
5736 case NEON::BI__builtin_neon_vsetq_lane_i64:
5737 case NEON::BI__builtin_neon_vsetq_lane_bf16:
5738 case NEON::BI__builtin_neon_vsetq_lane_f32:
5739 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2],
"vset_lane");
5740 case NEON::BI__builtin_neon_vset_lane_f64:
5743 Builder.CreateBitCast(Ops[1], llvm::FixedVectorType::get(
DoubleTy, 1));
5744 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2],
"vset_lane");
5745 case NEON::BI__builtin_neon_vset_lane_mf8:
5746 case NEON::BI__builtin_neon_vsetq_lane_mf8:
5750 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2],
"vset_lane");
5751 case NEON::BI__builtin_neon_vsetq_lane_f64:
5754 Builder.CreateBitCast(Ops[1], llvm::FixedVectorType::get(
DoubleTy, 2));
5755 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2],
"vset_lane");
5757 case NEON::BI__builtin_neon_vget_lane_i8:
5758 case NEON::BI__builtin_neon_vdupb_lane_i8:
5759 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vget_lane");
5760 case NEON::BI__builtin_neon_vgetq_lane_i8:
5761 case NEON::BI__builtin_neon_vdupb_laneq_i8:
5762 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vgetq_lane");
5763 case NEON::BI__builtin_neon_vget_lane_mf8:
5764 case NEON::BI__builtin_neon_vdupb_lane_mf8:
5765 case NEON::BI__builtin_neon_vgetq_lane_mf8:
5766 case NEON::BI__builtin_neon_vdupb_laneq_mf8:
5767 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vget_lane");
5768 case NEON::BI__builtin_neon_vget_lane_i16:
5769 case NEON::BI__builtin_neon_vduph_lane_i16:
5770 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vget_lane");
5771 case NEON::BI__builtin_neon_vgetq_lane_i16:
5772 case NEON::BI__builtin_neon_vduph_laneq_i16:
5773 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vgetq_lane");
5774 case NEON::BI__builtin_neon_vget_lane_i32:
5775 case NEON::BI__builtin_neon_vdups_lane_i32:
5776 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vget_lane");
5777 case NEON::BI__builtin_neon_vdups_lane_f32:
5778 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vdups_lane");
5779 case NEON::BI__builtin_neon_vgetq_lane_i32:
5780 case NEON::BI__builtin_neon_vdups_laneq_i32:
5781 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vgetq_lane");
5782 case NEON::BI__builtin_neon_vget_lane_i64:
5783 case NEON::BI__builtin_neon_vdupd_lane_i64:
5784 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vget_lane");
5785 case NEON::BI__builtin_neon_vdupd_lane_f64:
5786 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vdupd_lane");
5787 case NEON::BI__builtin_neon_vgetq_lane_i64:
5788 case NEON::BI__builtin_neon_vdupd_laneq_i64:
5789 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vgetq_lane");
5790 case NEON::BI__builtin_neon_vget_lane_f32:
5791 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vget_lane");
5792 case NEON::BI__builtin_neon_vget_lane_f64:
5793 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vget_lane");
5794 case NEON::BI__builtin_neon_vgetq_lane_f32:
5795 case NEON::BI__builtin_neon_vdups_laneq_f32:
5796 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vgetq_lane");
5797 case NEON::BI__builtin_neon_vgetq_lane_f64:
5798 case NEON::BI__builtin_neon_vdupd_laneq_f64:
5799 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vgetq_lane");
5800 case NEON::BI__builtin_neon_vaddh_f16:
5801 return Builder.CreateFAdd(Ops[0], Ops[1],
"vaddh");
5802 case NEON::BI__builtin_neon_vsubh_f16:
5803 return Builder.CreateFSub(Ops[0], Ops[1],
"vsubh");
5804 case NEON::BI__builtin_neon_vmulh_f16:
5805 return Builder.CreateFMul(Ops[0], Ops[1],
"vmulh");
5806 case NEON::BI__builtin_neon_vdivh_f16:
5807 return Builder.CreateFDiv(Ops[0], Ops[1],
"vdivh");
5808 case NEON::BI__builtin_neon_vfmah_f16:
5811 *
this, Intrinsic::fma, Intrinsic::experimental_constrained_fma,
HalfTy,
5812 {Ops[1], Ops[2], Ops[0]});
5813 case NEON::BI__builtin_neon_vfmsh_f16: {
5818 *
this, Intrinsic::fma, Intrinsic::experimental_constrained_fma,
HalfTy,
5819 {Neg, Ops[2], Ops[0]});
5821 case NEON::BI__builtin_neon_vaddd_s64:
5822 case NEON::BI__builtin_neon_vaddd_u64:
5823 return Builder.CreateAdd(Ops[0], Ops[1],
"vaddd");
5824 case NEON::BI__builtin_neon_vsubd_s64:
5825 case NEON::BI__builtin_neon_vsubd_u64:
5826 return Builder.CreateSub(Ops[0], Ops[1],
"vsubd");
5827 case NEON::BI__builtin_neon_vqdmlalh_s16:
5828 case NEON::BI__builtin_neon_vqdmlslh_s16: {
5832 auto *VTy = llvm::FixedVectorType::get(
Int32Ty, 4);
5833 Ops[1] =
EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmull, VTy),
5834 ProductOps,
"vqdmlXl");
5836 Ops[1] =
Builder.CreateExtractElement(Ops[1], CI,
"lane0");
5838 unsigned AccumInt = BuiltinID == NEON::BI__builtin_neon_vqdmlalh_s16
5839 ? Intrinsic::aarch64_neon_sqadd
5840 : Intrinsic::aarch64_neon_sqsub;
5845 case NEON::BI__builtin_neon_vqshlud_n_s64: {
5850 case NEON::BI__builtin_neon_vqshld_n_u64:
5851 case NEON::BI__builtin_neon_vqshld_n_s64: {
5852 Int = BuiltinID == NEON::BI__builtin_neon_vqshld_n_u64
5853 ? Intrinsic::aarch64_neon_uqshl
5854 : Intrinsic::aarch64_neon_sqshl;
5858 case NEON::BI__builtin_neon_vrshrd_n_u64:
5859 case NEON::BI__builtin_neon_vrshrd_n_s64: {
5860 Int = BuiltinID == NEON::BI__builtin_neon_vrshrd_n_u64
5861 ? Intrinsic::aarch64_neon_urshl
5862 : Intrinsic::aarch64_neon_srshl;
5864 Ops[1] = ConstantInt::get(
Int64Ty, -SV);
5867 case NEON::BI__builtin_neon_vrsrad_n_u64:
5868 case NEON::BI__builtin_neon_vrsrad_n_s64: {
5869 Int = BuiltinID == NEON::BI__builtin_neon_vrsrad_n_u64
5870 ? Intrinsic::aarch64_neon_urshl
5871 : Intrinsic::aarch64_neon_srshl;
5873 Ops[2] =
Builder.CreateNeg(Ops[2]);
5875 {Ops[1], Builder.CreateSExt(Ops[2], Int64Ty)});
5878 case NEON::BI__builtin_neon_vshld_n_s64:
5879 case NEON::BI__builtin_neon_vshld_n_u64: {
5882 Ops[0], ConstantInt::get(
Int64Ty, Amt->getZExtValue()),
"shld_n");
5884 case NEON::BI__builtin_neon_vshrd_n_s64: {
5887 Ops[0], ConstantInt::get(
Int64Ty, std::min(
static_cast<uint64_t
>(63),
5888 Amt->getZExtValue())),
5891 case NEON::BI__builtin_neon_vshrd_n_u64: {
5893 uint64_t ShiftAmt = Amt->getZExtValue();
5896 return ConstantInt::get(
Int64Ty, 0);
5897 return Builder.CreateLShr(Ops[0], ConstantInt::get(
Int64Ty, ShiftAmt),
5900 case NEON::BI__builtin_neon_vsrad_n_s64: {
5903 Ops[1], ConstantInt::get(
Int64Ty, std::min(
static_cast<uint64_t
>(63),
5904 Amt->getZExtValue())),
5906 return Builder.CreateAdd(Ops[0], Ops[1]);
5908 case NEON::BI__builtin_neon_vsrad_n_u64: {
5910 uint64_t ShiftAmt = Amt->getZExtValue();
5915 Ops[1] =
Builder.CreateLShr(Ops[1], ConstantInt::get(
Int64Ty, ShiftAmt),
5917 return Builder.CreateAdd(Ops[0], Ops[1]);
5919 case NEON::BI__builtin_neon_vqdmlalh_lane_s16:
5920 case NEON::BI__builtin_neon_vqdmlalh_laneq_s16:
5921 case NEON::BI__builtin_neon_vqdmlslh_lane_s16:
5922 case NEON::BI__builtin_neon_vqdmlslh_laneq_s16: {
5923 Ops[2] =
Builder.CreateExtractElement(Ops[2], Ops[3],
"lane");
5927 auto *VTy = llvm::FixedVectorType::get(
Int32Ty, 4);
5928 Ops[1] =
EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmull, VTy),
5929 ProductOps,
"vqdmlXl");
5931 Ops[1] =
Builder.CreateExtractElement(Ops[1], CI,
"lane0");
5936 unsigned AccInt = (BuiltinID == NEON::BI__builtin_neon_vqdmlalh_lane_s16 ||
5937 BuiltinID == NEON::BI__builtin_neon_vqdmlalh_laneq_s16)
5938 ? Intrinsic::aarch64_neon_sqadd
5939 : Intrinsic::aarch64_neon_sqsub;
5942 case NEON::BI__builtin_neon_vqdmlals_s32:
5943 case NEON::BI__builtin_neon_vqdmlsls_s32: {
5945 ProductOps.push_back(Ops[1]);
5946 ProductOps.push_back(Ops[2]);
5948 EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmulls_scalar),
5949 ProductOps,
"vqdmlXl");
5951 unsigned AccumInt = BuiltinID == NEON::BI__builtin_neon_vqdmlals_s32
5952 ? Intrinsic::aarch64_neon_sqadd
5953 : Intrinsic::aarch64_neon_sqsub;
5958 case NEON::BI__builtin_neon_vqdmlals_lane_s32:
5959 case NEON::BI__builtin_neon_vqdmlals_laneq_s32:
5960 case NEON::BI__builtin_neon_vqdmlsls_lane_s32:
5961 case NEON::BI__builtin_neon_vqdmlsls_laneq_s32: {
5962 Ops[2] =
Builder.CreateExtractElement(Ops[2], Ops[3],
"lane");
5964 ProductOps.push_back(Ops[1]);
5965 ProductOps.push_back(Ops[2]);
5967 EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmulls_scalar),
5968 ProductOps,
"vqdmlXl");
5973 unsigned AccInt = (BuiltinID == NEON::BI__builtin_neon_vqdmlals_lane_s32 ||
5974 BuiltinID == NEON::BI__builtin_neon_vqdmlals_laneq_s32)
5975 ? Intrinsic::aarch64_neon_sqadd
5976 : Intrinsic::aarch64_neon_sqsub;
5979 case NEON::BI__builtin_neon_vget_lane_bf16:
5980 case NEON::BI__builtin_neon_vduph_lane_bf16:
5981 case NEON::BI__builtin_neon_vduph_lane_f16: {
5982 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vget_lane");
5984 case NEON::BI__builtin_neon_vgetq_lane_bf16:
5985 case NEON::BI__builtin_neon_vduph_laneq_bf16:
5986 case NEON::BI__builtin_neon_vduph_laneq_f16: {
5987 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vgetq_lane");
5989 case NEON::BI__builtin_neon_vcvt_bf16_f32: {
5990 llvm::Type *V4F32 = FixedVectorType::get(
Builder.getFloatTy(), 4);
5991 llvm::Type *V4BF16 = FixedVectorType::get(
Builder.getBFloatTy(), 4);
5992 return Builder.CreateFPTrunc(
Builder.CreateBitCast(Ops[0], V4F32), V4BF16);
5994 case NEON::BI__builtin_neon_vcvtq_low_bf16_f32: {
5996 std::iota(ConcatMask.begin(), ConcatMask.end(), 0);
5997 llvm::Type *V4F32 = FixedVectorType::get(
Builder.getFloatTy(), 4);
5998 llvm::Type *V4BF16 = FixedVectorType::get(
Builder.getBFloatTy(), 4);
5999 llvm::Value *Trunc =
6000 Builder.CreateFPTrunc(
Builder.CreateBitCast(Ops[0], V4F32), V4BF16);
6001 return Builder.CreateShuffleVector(
6002 Trunc, ConstantAggregateZero::get(V4BF16), ConcatMask);
6004 case NEON::BI__builtin_neon_vcvtq_high_bf16_f32: {
6006 std::iota(ConcatMask.begin(), ConcatMask.end(), 0);
6008 std::iota(LoMask.begin(), LoMask.end(), 0);
6009 llvm::Type *V4F32 = FixedVectorType::get(
Builder.getFloatTy(), 4);
6010 llvm::Type *V4BF16 = FixedVectorType::get(
Builder.getBFloatTy(), 4);
6011 llvm::Type *V8BF16 = FixedVectorType::get(
Builder.getBFloatTy(), 8);
6012 llvm::Value *Inactive =
Builder.CreateShuffleVector(
6013 Builder.CreateBitCast(Ops[0], V8BF16), LoMask);
6014 llvm::Value *Trunc =
6015 Builder.CreateFPTrunc(
Builder.CreateBitCast(Ops[1], V4F32), V4BF16);
6016 return Builder.CreateShuffleVector(Inactive, Trunc, ConcatMask);
6018 case NEON::BI__builtin_neon_vcvt_f16_f32: {
6019 llvm::Type *V4F32 = FixedVectorType::get(
Builder.getFloatTy(), 4);
6020 llvm::Type *V4F16 = FixedVectorType::get(
Builder.getHalfTy(), 4);
6021 return Builder.CreateFPTrunc(
Builder.CreateBitCast(Ops[0], V4F32), V4F16);
6023 case NEON::BI__builtin_neon_vcvt_f32_f16: {
6024 llvm::Type *V4F32 = FixedVectorType::get(
Builder.getFloatTy(), 4);
6025 llvm::Type *V4F16 = FixedVectorType::get(
Builder.getHalfTy(), 4);
6026 return Builder.CreateFPExt(
Builder.CreateBitCast(Ops[0], V4F16), V4F32);
6029 case clang::AArch64::BI_InterlockedAdd:
6030 case clang::AArch64::BI_InterlockedAdd_acq:
6031 case clang::AArch64::BI_InterlockedAdd_rel:
6032 case clang::AArch64::BI_InterlockedAdd_nf:
6033 case clang::AArch64::BI_InterlockedAdd64:
6034 case clang::AArch64::BI_InterlockedAdd64_acq:
6035 case clang::AArch64::BI_InterlockedAdd64_rel:
6036 case clang::AArch64::BI_InterlockedAdd64_nf: {
6038 Value *Val = Ops[1];
6039 llvm::AtomicOrdering Ordering;
6040 switch (BuiltinID) {
6041 case clang::AArch64::BI_InterlockedAdd:
6042 case clang::AArch64::BI_InterlockedAdd64:
6043 Ordering = llvm::AtomicOrdering::SequentiallyConsistent;
6045 case clang::AArch64::BI_InterlockedAdd_acq:
6046 case clang::AArch64::BI_InterlockedAdd64_acq:
6047 Ordering = llvm::AtomicOrdering::Acquire;
6049 case clang::AArch64::BI_InterlockedAdd_rel:
6050 case clang::AArch64::BI_InterlockedAdd64_rel:
6051 Ordering = llvm::AtomicOrdering::Release;
6053 case clang::AArch64::BI_InterlockedAdd_nf:
6054 case clang::AArch64::BI_InterlockedAdd64_nf:
6055 Ordering = llvm::AtomicOrdering::Monotonic;
6058 llvm_unreachable(
"missing builtin ID in switch!");
6060 AtomicRMWInst *RMWI =
6061 Builder.CreateAtomicRMW(AtomicRMWInst::Add, DestAddr, Val, Ordering);
6062 return Builder.CreateAdd(RMWI, Val);
6067 llvm::Type *Ty = VTy;
6071 bool ExtractLow =
false;
6072 bool ExtendLaneArg =
false;
6073 switch (BuiltinID) {
6074 default:
return nullptr;
6075 case NEON::BI__builtin_neon_vbsl_v:
6076 case NEON::BI__builtin_neon_vbslq_v: {
6077 llvm::Type *BitTy = llvm::VectorType::getInteger(VTy);
6078 Ops[0] =
Builder.CreateBitCast(Ops[0], BitTy,
"vbsl");
6079 Ops[1] =
Builder.CreateBitCast(Ops[1], BitTy,
"vbsl");
6080 Ops[2] =
Builder.CreateBitCast(Ops[2], BitTy,
"vbsl");
6082 Ops[1] =
Builder.CreateAnd(Ops[0], Ops[1],
"vbsl");
6083 Ops[2] =
Builder.CreateAnd(
Builder.CreateNot(Ops[0]), Ops[2],
"vbsl");
6084 Ops[0] =
Builder.CreateOr(Ops[1], Ops[2],
"vbsl");
6085 return Builder.CreateBitCast(Ops[0], Ty);
6087 case NEON::BI__builtin_neon_vfma_lane_v:
6088 case NEON::BI__builtin_neon_vfmaq_lane_v: {
6091 Value *Addend = Ops[0];
6092 Value *Multiplicand = Ops[1];
6093 Value *LaneSource = Ops[2];
6094 Ops[0] = Multiplicand;
6095 Ops[1] = LaneSource;
6099 auto *SourceTy = BuiltinID == NEON::BI__builtin_neon_vfmaq_lane_v
6100 ? llvm::FixedVectorType::get(VTy->getElementType(),
6101 VTy->getNumElements() / 2)
6104 Value *SV = llvm::ConstantVector::getSplat(VTy->getElementCount(), cst);
6105 Ops[1] =
Builder.CreateBitCast(Ops[1], SourceTy);
6106 Ops[1] =
Builder.CreateShuffleVector(Ops[1], Ops[1], SV,
"lane");
6109 Int =
Builder.getIsFPConstrained() ? Intrinsic::experimental_constrained_fma
6113 case NEON::BI__builtin_neon_vfma_laneq_v: {
6116 if (VTy && VTy->getElementType() ==
DoubleTy) {
6119 llvm::FixedVectorType *VTy =
6121 Ops[2] =
Builder.CreateBitCast(Ops[2], VTy);
6122 Ops[2] =
Builder.CreateExtractElement(Ops[2], Ops[3],
"extract");
6125 *
this, Intrinsic::fma, Intrinsic::experimental_constrained_fma,
6126 DoubleTy, {Ops[1], Ops[2], Ops[0]});
6129 Ops[0] =
Builder.CreateBitCast(Ops[0], Ty);
6130 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
6132 auto *STy = llvm::FixedVectorType::get(VTy->getElementType(),
6133 VTy->getNumElements() * 2);
6134 Ops[2] =
Builder.CreateBitCast(Ops[2], STy);
6135 Value *SV = llvm::ConstantVector::getSplat(VTy->getElementCount(),
6137 Ops[2] =
Builder.CreateShuffleVector(Ops[2], Ops[2], SV,
"lane");
6140 *
this, Intrinsic::fma, Intrinsic::experimental_constrained_fma, Ty,
6141 {Ops[2], Ops[1], Ops[0]});
6143 case NEON::BI__builtin_neon_vfmaq_laneq_v: {
6144 Ops[0] =
Builder.CreateBitCast(Ops[0], Ty);
6145 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
6147 Ops[2] =
Builder.CreateBitCast(Ops[2], Ty);
6150 *
this, Intrinsic::fma, Intrinsic::experimental_constrained_fma, Ty,
6151 {Ops[2], Ops[1], Ops[0]});
6153 case NEON::BI__builtin_neon_vfmah_lane_f16:
6154 case NEON::BI__builtin_neon_vfmas_lane_f32:
6155 case NEON::BI__builtin_neon_vfmah_laneq_f16:
6156 case NEON::BI__builtin_neon_vfmas_laneq_f32:
6157 case NEON::BI__builtin_neon_vfmad_lane_f64:
6158 case NEON::BI__builtin_neon_vfmad_laneq_f64: {
6160 Ops[2] =
Builder.CreateExtractElement(Ops[2], Ops[3],
"extract");
6162 *
this, Intrinsic::fma, Intrinsic::experimental_constrained_fma, Ty,
6163 {Ops[1], Ops[2], Ops[0]});
6165 case NEON::BI__builtin_neon_vmull_v:
6167 Int = usgn ? Intrinsic::aarch64_neon_umull : Intrinsic::aarch64_neon_smull;
6168 if (
Type.isPoly()) Int = Intrinsic::aarch64_neon_pmull;
6170 case NEON::BI__builtin_neon_vmax_v:
6171 case NEON::BI__builtin_neon_vmaxq_v:
6173 Int = usgn ? Intrinsic::aarch64_neon_umax : Intrinsic::aarch64_neon_smax;
6174 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fmax;
6176 case NEON::BI__builtin_neon_vmaxh_f16: {
6177 Int = Intrinsic::aarch64_neon_fmax;
6180 case NEON::BI__builtin_neon_vmin_v:
6181 case NEON::BI__builtin_neon_vminq_v:
6183 Int = usgn ? Intrinsic::aarch64_neon_umin : Intrinsic::aarch64_neon_smin;
6184 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fmin;
6186 case NEON::BI__builtin_neon_vminh_f16: {
6187 Int = Intrinsic::aarch64_neon_fmin;
6190 case NEON::BI__builtin_neon_vabd_v:
6191 case NEON::BI__builtin_neon_vabdq_v:
6193 Int = usgn ? Intrinsic::aarch64_neon_uabd : Intrinsic::aarch64_neon_sabd;
6194 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fabd;
6196 case NEON::BI__builtin_neon_vpadal_v:
6197 case NEON::BI__builtin_neon_vpadalq_v: {
6198 unsigned ArgElts = VTy->getNumElements();
6200 unsigned BitWidth = EltTy->getBitWidth();
6201 auto *ArgTy = llvm::FixedVectorType::get(
6202 llvm::IntegerType::get(
getLLVMContext(), BitWidth / 2), 2 * ArgElts);
6203 llvm::Type* Tys[2] = { VTy, ArgTy };
6204 Int = usgn ? Intrinsic::aarch64_neon_uaddlp : Intrinsic::aarch64_neon_saddlp;
6206 TmpOps.push_back(Ops[1]);
6209 llvm::Value *addend =
Builder.CreateBitCast(Ops[0], tmp->getType());
6210 return Builder.CreateAdd(tmp, addend);
6212 case NEON::BI__builtin_neon_vpmin_v:
6213 case NEON::BI__builtin_neon_vpminq_v:
6215 Int = usgn ? Intrinsic::aarch64_neon_uminp : Intrinsic::aarch64_neon_sminp;
6216 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fminp;
6218 case NEON::BI__builtin_neon_vpmax_v:
6219 case NEON::BI__builtin_neon_vpmaxq_v:
6221 Int = usgn ? Intrinsic::aarch64_neon_umaxp : Intrinsic::aarch64_neon_smaxp;
6222 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fmaxp;
6224 case NEON::BI__builtin_neon_vminnm_v:
6225 case NEON::BI__builtin_neon_vminnmq_v:
6226 Int = Intrinsic::aarch64_neon_fminnm;
6228 case NEON::BI__builtin_neon_vminnmh_f16:
6229 Int = Intrinsic::aarch64_neon_fminnm;
6231 case NEON::BI__builtin_neon_vmaxnm_v:
6232 case NEON::BI__builtin_neon_vmaxnmq_v:
6233 Int = Intrinsic::aarch64_neon_fmaxnm;
6235 case NEON::BI__builtin_neon_vmaxnmh_f16:
6236 Int = Intrinsic::aarch64_neon_fmaxnm;
6238 case NEON::BI__builtin_neon_vrecpss_f32: {
6242 case NEON::BI__builtin_neon_vrecpsd_f64:
6245 case NEON::BI__builtin_neon_vrecpsh_f16:
6248 case NEON::BI__builtin_neon_vqshrun_n_v:
6249 Int = Intrinsic::aarch64_neon_sqshrun;
6251 case NEON::BI__builtin_neon_vqrshrun_n_v:
6252 Int = Intrinsic::aarch64_neon_sqrshrun;
6254 case NEON::BI__builtin_neon_vqshrn_n_v:
6255 Int = usgn ? Intrinsic::aarch64_neon_uqshrn : Intrinsic::aarch64_neon_sqshrn;
6257 case NEON::BI__builtin_neon_vrshrn_n_v:
6258 Int = Intrinsic::aarch64_neon_rshrn;
6260 case NEON::BI__builtin_neon_vqrshrn_n_v:
6261 Int = usgn ? Intrinsic::aarch64_neon_uqrshrn : Intrinsic::aarch64_neon_sqrshrn;
6263 case NEON::BI__builtin_neon_vrndah_f16: {
6264 Int =
Builder.getIsFPConstrained()
6265 ? Intrinsic::experimental_constrained_round
6269 case NEON::BI__builtin_neon_vrnda_v:
6270 case NEON::BI__builtin_neon_vrndaq_v: {
6271 Int =
Builder.getIsFPConstrained()
6272 ? Intrinsic::experimental_constrained_round
6276 case NEON::BI__builtin_neon_vrndih_f16: {
6277 Int =
Builder.getIsFPConstrained()
6278 ? Intrinsic::experimental_constrained_nearbyint
6279 : Intrinsic::nearbyint;
6282 case NEON::BI__builtin_neon_vrndmh_f16: {
6283 Int =
Builder.getIsFPConstrained()
6284 ? Intrinsic::experimental_constrained_floor
6288 case NEON::BI__builtin_neon_vrndm_v:
6289 case NEON::BI__builtin_neon_vrndmq_v: {
6290 Int =
Builder.getIsFPConstrained()
6291 ? Intrinsic::experimental_constrained_floor
6295 case NEON::BI__builtin_neon_vrndnh_f16: {
6296 Int =
Builder.getIsFPConstrained()
6297 ? Intrinsic::experimental_constrained_roundeven
6298 : Intrinsic::roundeven;
6301 case NEON::BI__builtin_neon_vrndn_v:
6302 case NEON::BI__builtin_neon_vrndnq_v: {
6303 Int =
Builder.getIsFPConstrained()
6304 ? Intrinsic::experimental_constrained_roundeven
6305 : Intrinsic::roundeven;
6308 case NEON::BI__builtin_neon_vrndns_f32: {
6309 Int =
Builder.getIsFPConstrained()
6310 ? Intrinsic::experimental_constrained_roundeven
6311 : Intrinsic::roundeven;
6314 case NEON::BI__builtin_neon_vrndph_f16: {
6315 Int =
Builder.getIsFPConstrained()
6316 ? Intrinsic::experimental_constrained_ceil
6320 case NEON::BI__builtin_neon_vrndp_v:
6321 case NEON::BI__builtin_neon_vrndpq_v: {
6322 Int =
Builder.getIsFPConstrained()
6323 ? Intrinsic::experimental_constrained_ceil
6327 case NEON::BI__builtin_neon_vrndxh_f16: {
6328 Int =
Builder.getIsFPConstrained()
6329 ? Intrinsic::experimental_constrained_rint
6333 case NEON::BI__builtin_neon_vrndx_v:
6334 case NEON::BI__builtin_neon_vrndxq_v: {
6335 Int =
Builder.getIsFPConstrained()
6336 ? Intrinsic::experimental_constrained_rint
6340 case NEON::BI__builtin_neon_vrndh_f16: {
6341 Int =
Builder.getIsFPConstrained()
6342 ? Intrinsic::experimental_constrained_trunc
6346 case NEON::BI__builtin_neon_vrnd_v:
6347 case NEON::BI__builtin_neon_vrndq_v: {
6348 Int =
Builder.getIsFPConstrained()
6349 ? Intrinsic::experimental_constrained_trunc
6353 case NEON::BI__builtin_neon_vcvt_f64_v:
6354 case NEON::BI__builtin_neon_vcvtq_f64_v:
6355 Ops[0] =
Builder.CreateBitCast(Ops[0], Ty);
6357 return usgn ?
Builder.CreateUIToFP(Ops[0], Ty,
"vcvt")
6358 :
Builder.CreateSIToFP(Ops[0], Ty,
"vcvt");
6359 case NEON::BI__builtin_neon_vcvt_f64_f32: {
6361 "unexpected vcvt_f64_f32 builtin");
6365 return Builder.CreateFPExt(Ops[0], Ty,
"vcvt");
6367 case NEON::BI__builtin_neon_vcvt_f32_f64: {
6369 "unexpected vcvt_f32_f64 builtin");
6373 return Builder.CreateFPTrunc(Ops[0], Ty,
"vcvt");
6375 case NEON::BI__builtin_neon_vcvta_s16_f16:
6376 case NEON::BI__builtin_neon_vcvta_u16_f16:
6377 case NEON::BI__builtin_neon_vcvta_s32_v:
6378 case NEON::BI__builtin_neon_vcvtaq_s16_f16:
6379 case NEON::BI__builtin_neon_vcvtaq_s32_v:
6380 case NEON::BI__builtin_neon_vcvta_u32_v:
6381 case NEON::BI__builtin_neon_vcvtaq_u16_f16:
6382 case NEON::BI__builtin_neon_vcvtaq_u32_v:
6383 case NEON::BI__builtin_neon_vcvta_s64_v:
6384 case NEON::BI__builtin_neon_vcvtaq_s64_v:
6385 case NEON::BI__builtin_neon_vcvta_u64_v:
6386 case NEON::BI__builtin_neon_vcvtaq_u64_v: {
6387 Int = usgn ? Intrinsic::aarch64_neon_fcvtau : Intrinsic::aarch64_neon_fcvtas;
6391 case NEON::BI__builtin_neon_vcvtm_s16_f16:
6392 case NEON::BI__builtin_neon_vcvtmq_s16_f16:
6393 case NEON::BI__builtin_neon_vcvtm_u16_f16:
6394 case NEON::BI__builtin_neon_vcvtmq_u16_f16:
6395 case NEON::BI__builtin_neon_vcvtm_s32_v:
6396 case NEON::BI__builtin_neon_vcvtmq_s32_v:
6397 case NEON::BI__builtin_neon_vcvtm_u32_v:
6398 case NEON::BI__builtin_neon_vcvtmq_u32_v:
6399 case NEON::BI__builtin_neon_vcvtm_s64_v:
6400 case NEON::BI__builtin_neon_vcvtmq_s64_v:
6401 case NEON::BI__builtin_neon_vcvtm_u64_v:
6402 case NEON::BI__builtin_neon_vcvtmq_u64_v: {
6403 Int = usgn ? Intrinsic::aarch64_neon_fcvtmu : Intrinsic::aarch64_neon_fcvtms;
6407 case NEON::BI__builtin_neon_vcvtn_s16_f16:
6408 case NEON::BI__builtin_neon_vcvtnq_s16_f16:
6409 case NEON::BI__builtin_neon_vcvtn_u16_f16:
6410 case NEON::BI__builtin_neon_vcvtnq_u16_f16:
6411 case NEON::BI__builtin_neon_vcvtn_s32_v:
6412 case NEON::BI__builtin_neon_vcvtnq_s32_v:
6413 case NEON::BI__builtin_neon_vcvtn_u32_v:
6414 case NEON::BI__builtin_neon_vcvtnq_u32_v:
6415 case NEON::BI__builtin_neon_vcvtn_s64_v:
6416 case NEON::BI__builtin_neon_vcvtnq_s64_v:
6417 case NEON::BI__builtin_neon_vcvtn_u64_v:
6418 case NEON::BI__builtin_neon_vcvtnq_u64_v: {
6419 Int = usgn ? Intrinsic::aarch64_neon_fcvtnu : Intrinsic::aarch64_neon_fcvtns;
6423 case NEON::BI__builtin_neon_vcvtp_s16_f16:
6424 case NEON::BI__builtin_neon_vcvtpq_s16_f16:
6425 case NEON::BI__builtin_neon_vcvtp_u16_f16:
6426 case NEON::BI__builtin_neon_vcvtpq_u16_f16:
6427 case NEON::BI__builtin_neon_vcvtp_s32_v:
6428 case NEON::BI__builtin_neon_vcvtpq_s32_v:
6429 case NEON::BI__builtin_neon_vcvtp_u32_v:
6430 case NEON::BI__builtin_neon_vcvtpq_u32_v:
6431 case NEON::BI__builtin_neon_vcvtp_s64_v:
6432 case NEON::BI__builtin_neon_vcvtpq_s64_v:
6433 case NEON::BI__builtin_neon_vcvtp_u64_v:
6434 case NEON::BI__builtin_neon_vcvtpq_u64_v: {
6435 Int = usgn ? Intrinsic::aarch64_neon_fcvtpu : Intrinsic::aarch64_neon_fcvtps;
6439 case NEON::BI__builtin_neon_vmulx_v:
6440 case NEON::BI__builtin_neon_vmulxq_v: {
6441 Int = Intrinsic::aarch64_neon_fmulx;
6444 case NEON::BI__builtin_neon_vmulxh_lane_f16:
6445 case NEON::BI__builtin_neon_vmulxh_laneq_f16: {
6448 Ops[1] =
Builder.CreateExtractElement(Ops[1], Ops[2],
"extract");
6450 Int = Intrinsic::aarch64_neon_fmulx;
6453 case NEON::BI__builtin_neon_vmul_lane_v:
6454 case NEON::BI__builtin_neon_vmul_laneq_v: {
6457 if (BuiltinID == NEON::BI__builtin_neon_vmul_laneq_v)
6460 llvm::FixedVectorType *VTy =
6462 Ops[1] =
Builder.CreateBitCast(Ops[1], VTy);
6463 Ops[1] =
Builder.CreateExtractElement(Ops[1], Ops[2],
"extract");
6467 case NEON::BI__builtin_neon_vpmaxnm_v:
6468 case NEON::BI__builtin_neon_vpmaxnmq_v: {
6469 Int = Intrinsic::aarch64_neon_fmaxnmp;
6472 case NEON::BI__builtin_neon_vpminnm_v:
6473 case NEON::BI__builtin_neon_vpminnmq_v: {
6474 Int = Intrinsic::aarch64_neon_fminnmp;
6477 case NEON::BI__builtin_neon_vsqrth_f16: {
6478 Int =
Builder.getIsFPConstrained()
6479 ? Intrinsic::experimental_constrained_sqrt
6483 case NEON::BI__builtin_neon_vsqrt_v:
6484 case NEON::BI__builtin_neon_vsqrtq_v: {
6485 Int =
Builder.getIsFPConstrained()
6486 ? Intrinsic::experimental_constrained_sqrt
6488 Ops[0] =
Builder.CreateBitCast(Ops[0], Ty);
6491 case NEON::BI__builtin_neon_vrbit_v:
6492 case NEON::BI__builtin_neon_vrbitq_v: {
6493 Int = Intrinsic::bitreverse;
6496 case NEON::BI__builtin_neon_vmaxv_f16: {
6497 Int = Intrinsic::aarch64_neon_fmaxv;
6499 VTy = llvm::FixedVectorType::get(
HalfTy, 4);
6500 llvm::Type *Tys[2] = {Ty, VTy};
6503 case NEON::BI__builtin_neon_vmaxvq_f16: {
6504 Int = Intrinsic::aarch64_neon_fmaxv;
6506 VTy = llvm::FixedVectorType::get(
HalfTy, 8);
6507 llvm::Type *Tys[2] = {Ty, VTy};
6510 case NEON::BI__builtin_neon_vminv_f16: {
6511 Int = Intrinsic::aarch64_neon_fminv;
6513 VTy = llvm::FixedVectorType::get(
HalfTy, 4);
6514 llvm::Type *Tys[2] = {Ty, VTy};
6517 case NEON::BI__builtin_neon_vminvq_f16: {
6518 Int = Intrinsic::aarch64_neon_fminv;
6520 VTy = llvm::FixedVectorType::get(
HalfTy, 8);
6521 llvm::Type *Tys[2] = {Ty, VTy};
6524 case NEON::BI__builtin_neon_vmaxnmv_f16: {
6525 Int = Intrinsic::aarch64_neon_fmaxnmv;
6527 VTy = llvm::FixedVectorType::get(
HalfTy, 4);
6528 llvm::Type *Tys[2] = {Ty, VTy};
6531 case NEON::BI__builtin_neon_vmaxnmvq_f16: {
6532 Int = Intrinsic::aarch64_neon_fmaxnmv;
6534 VTy = llvm::FixedVectorType::get(
HalfTy, 8);
6535 llvm::Type *Tys[2] = {Ty, VTy};
6538 case NEON::BI__builtin_neon_vminnmv_f16: {
6539 Int = Intrinsic::aarch64_neon_fminnmv;
6541 VTy = llvm::FixedVectorType::get(
HalfTy, 4);
6542 llvm::Type *Tys[2] = {Ty, VTy};
6545 case NEON::BI__builtin_neon_vminnmvq_f16: {
6546 Int = Intrinsic::aarch64_neon_fminnmv;
6548 VTy = llvm::FixedVectorType::get(
HalfTy, 8);
6549 llvm::Type *Tys[2] = {Ty, VTy};
6552 case NEON::BI__builtin_neon_vmul_n_f64: {
6555 return Builder.CreateFMul(Ops[0], RHS);
6557 case NEON::BI__builtin_neon_vaddlv_u8:
6558 case NEON::BI__builtin_neon_vaddlvq_u8:
6559 case NEON::BI__builtin_neon_vaddlv_u16:
6560 case NEON::BI__builtin_neon_vaddlvq_u16: {
6561 Int = Intrinsic::aarch64_neon_uaddlv;
6564 llvm::Type *Tys[2] = {Ty, VTy};
6566 if (VTy->getElementType()->getPrimitiveSizeInBits() == 8)
6570 case NEON::BI__builtin_neon_vaddlv_s8:
6571 case NEON::BI__builtin_neon_vaddlvq_s8:
6572 case NEON::BI__builtin_neon_vaddlv_s16:
6573 case NEON::BI__builtin_neon_vaddlvq_s16: {
6574 Int = Intrinsic::aarch64_neon_saddlv;
6577 llvm::Type *Tys[2] = {Ty, VTy};
6579 if (VTy->getElementType()->getPrimitiveSizeInBits() == 8)
6583 case NEON::BI__builtin_neon_vsri_n_v:
6584 case NEON::BI__builtin_neon_vsriq_n_v: {
6585 Int = Intrinsic::aarch64_neon_vsri;
6586 llvm::Function *Intrin =
CGM.getIntrinsic(Int, Ty);
6589 case NEON::BI__builtin_neon_vsli_n_v:
6590 case NEON::BI__builtin_neon_vsliq_n_v: {
6591 Int = Intrinsic::aarch64_neon_vsli;
6592 llvm::Function *Intrin =
CGM.getIntrinsic(Int, Ty);
6595 case NEON::BI__builtin_neon_vsra_n_v:
6596 case NEON::BI__builtin_neon_vsraq_n_v:
6597 Ops[0] =
Builder.CreateBitCast(Ops[0], Ty);
6599 return Builder.CreateAdd(Ops[0], Ops[1]);
6600 case NEON::BI__builtin_neon_vrsra_n_v:
6601 case NEON::BI__builtin_neon_vrsraq_n_v: {
6602 Int = usgn ? Intrinsic::aarch64_neon_urshl : Intrinsic::aarch64_neon_srshl;
6604 TmpOps.push_back(Ops[1]);
6605 TmpOps.push_back(Ops[2]);
6607 llvm::Value *tmp =
EmitNeonCall(F, TmpOps,
"vrshr_n", 1,
true);
6608 Ops[0] =
Builder.CreateBitCast(Ops[0], VTy);
6609 return Builder.CreateAdd(Ops[0], tmp);
6611 case NEON::BI__builtin_neon_vld1_v:
6612 case NEON::BI__builtin_neon_vld1q_v: {
6615 case NEON::BI__builtin_neon_vst1_v:
6616 case NEON::BI__builtin_neon_vst1q_v:
6617 Ops[1] =
Builder.CreateBitCast(Ops[1], VTy);
6619 case NEON::BI__builtin_neon_vld1_lane_v:
6620 case NEON::BI__builtin_neon_vld1q_lane_v: {
6621 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
6622 Ops[0] =
Builder.CreateAlignedLoad(VTy->getElementType(), Ops[0],
6624 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2],
"vld1_lane");
6626 case NEON::BI__builtin_neon_vldap1_lane_s64:
6627 case NEON::BI__builtin_neon_vldap1q_lane_s64: {
6628 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
6629 llvm::LoadInst *LI =
Builder.CreateAlignedLoad(
6631 LI->setAtomic(llvm::AtomicOrdering::Acquire);
6633 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2],
"vldap1_lane");
6635 case NEON::BI__builtin_neon_vld1_dup_v:
6636 case NEON::BI__builtin_neon_vld1q_dup_v: {
6637 Value *
V = PoisonValue::get(Ty);
6638 Ops[0] =
Builder.CreateAlignedLoad(VTy->getElementType(), Ops[0],
6640 llvm::Constant *CI = ConstantInt::get(
Int32Ty, 0);
6641 Ops[0] =
Builder.CreateInsertElement(
V, Ops[0], CI);
6644 case NEON::BI__builtin_neon_vst1_lane_v:
6645 case NEON::BI__builtin_neon_vst1q_lane_v:
6646 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
6647 Ops[1] =
Builder.CreateExtractElement(Ops[1], Ops[2]);
6649 case NEON::BI__builtin_neon_vstl1_lane_s64:
6650 case NEON::BI__builtin_neon_vstl1q_lane_s64: {
6651 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
6652 Ops[1] =
Builder.CreateExtractElement(Ops[1], Ops[2]);
6653 llvm::StoreInst *SI =
6655 SI->setAtomic(llvm::AtomicOrdering::Release);
6658 case NEON::BI__builtin_neon_vld2_v:
6659 case NEON::BI__builtin_neon_vld2q_v: {
6661 Function *F =
CGM.getIntrinsic(Intrinsic::aarch64_neon_ld2, Tys);
6662 Ops[1] =
Builder.CreateCall(F, Ops[1],
"vld2");
6663 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
6665 case NEON::BI__builtin_neon_vld3_v:
6666 case NEON::BI__builtin_neon_vld3q_v: {
6668 Function *F =
CGM.getIntrinsic(Intrinsic::aarch64_neon_ld3, Tys);
6669 Ops[1] =
Builder.CreateCall(F, Ops[1],
"vld3");
6670 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
6672 case NEON::BI__builtin_neon_vld4_v:
6673 case NEON::BI__builtin_neon_vld4q_v: {
6675 Function *F =
CGM.getIntrinsic(Intrinsic::aarch64_neon_ld4, Tys);
6676 Ops[1] =
Builder.CreateCall(F, Ops[1],
"vld4");
6677 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
6679 case NEON::BI__builtin_neon_vld2_dup_v:
6680 case NEON::BI__builtin_neon_vld2q_dup_v: {
6682 Function *F =
CGM.getIntrinsic(Intrinsic::aarch64_neon_ld2r, Tys);
6683 Ops[1] =
Builder.CreateCall(F, Ops[1],
"vld2");
6684 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
6686 case NEON::BI__builtin_neon_vld3_dup_v:
6687 case NEON::BI__builtin_neon_vld3q_dup_v: {
6689 Function *F =
CGM.getIntrinsic(Intrinsic::aarch64_neon_ld3r, Tys);
6690 Ops[1] =
Builder.CreateCall(F, Ops[1],
"vld3");
6691 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
6693 case NEON::BI__builtin_neon_vld4_dup_v:
6694 case NEON::BI__builtin_neon_vld4q_dup_v: {
6696 Function *F =
CGM.getIntrinsic(Intrinsic::aarch64_neon_ld4r, Tys);
6697 Ops[1] =
Builder.CreateCall(F, Ops[1],
"vld4");
6698 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
6700 case NEON::BI__builtin_neon_vld2_lane_v:
6701 case NEON::BI__builtin_neon_vld2q_lane_v: {
6702 llvm::Type *Tys[2] = { VTy, Ops[1]->getType() };
6703 Function *F =
CGM.getIntrinsic(Intrinsic::aarch64_neon_ld2lane, Tys);
6704 std::rotate(Ops.begin() + 1, Ops.begin() + 2, Ops.end());
6705 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
6706 Ops[2] =
Builder.CreateBitCast(Ops[2], Ty);
6709 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
6711 case NEON::BI__builtin_neon_vld3_lane_v:
6712 case NEON::BI__builtin_neon_vld3q_lane_v: {
6713 llvm::Type *Tys[2] = { VTy, Ops[1]->getType() };
6714 Function *F =
CGM.getIntrinsic(Intrinsic::aarch64_neon_ld3lane, Tys);
6715 std::rotate(Ops.begin() + 1, Ops.begin() + 2, Ops.end());
6716 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
6717 Ops[2] =
Builder.CreateBitCast(Ops[2], Ty);
6718 Ops[3] =
Builder.CreateBitCast(Ops[3], Ty);
6721 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
6723 case NEON::BI__builtin_neon_vld4_lane_v:
6724 case NEON::BI__builtin_neon_vld4q_lane_v: {
6725 llvm::Type *Tys[2] = { VTy, Ops[1]->getType() };
6726 Function *F =
CGM.getIntrinsic(Intrinsic::aarch64_neon_ld4lane, Tys);
6727 std::rotate(Ops.begin() + 1, Ops.begin() + 2, Ops.end());
6728 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
6729 Ops[2] =
Builder.CreateBitCast(Ops[2], Ty);
6730 Ops[3] =
Builder.CreateBitCast(Ops[3], Ty);
6731 Ops[4] =
Builder.CreateBitCast(Ops[4], Ty);
6734 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
6736 case NEON::BI__builtin_neon_vst2_v:
6737 case NEON::BI__builtin_neon_vst2q_v: {
6738 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end());
6739 llvm::Type *Tys[2] = { VTy, Ops[2]->getType() };
6740 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_st2, Tys),
6743 case NEON::BI__builtin_neon_vst2_lane_v:
6744 case NEON::BI__builtin_neon_vst2q_lane_v: {
6745 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end());
6747 llvm::Type *Tys[2] = { VTy, Ops[3]->getType() };
6748 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_st2lane, Tys),
6751 case NEON::BI__builtin_neon_vst3_v:
6752 case NEON::BI__builtin_neon_vst3q_v: {
6753 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end());
6754 llvm::Type *Tys[2] = { VTy, Ops[3]->getType() };
6755 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_st3, Tys),
6758 case NEON::BI__builtin_neon_vst3_lane_v:
6759 case NEON::BI__builtin_neon_vst3q_lane_v: {
6760 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end());
6762 llvm::Type *Tys[2] = { VTy, Ops[4]->getType() };
6763 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_st3lane, Tys),
6766 case NEON::BI__builtin_neon_vst4_v:
6767 case NEON::BI__builtin_neon_vst4q_v: {
6768 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end());
6769 llvm::Type *Tys[2] = { VTy, Ops[4]->getType() };
6770 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_st4, Tys),
6773 case NEON::BI__builtin_neon_vst4_lane_v:
6774 case NEON::BI__builtin_neon_vst4q_lane_v: {
6775 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end());
6777 llvm::Type *Tys[2] = { VTy, Ops[5]->getType() };
6778 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_st4lane, Tys),
6781 case NEON::BI__builtin_neon_vtrn_v:
6782 case NEON::BI__builtin_neon_vtrnq_v: {
6783 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
6784 Ops[2] =
Builder.CreateBitCast(Ops[2], Ty);
6785 Value *SV =
nullptr;
6787 for (
unsigned vi = 0; vi != 2; ++vi) {
6789 for (
unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) {
6790 Indices.push_back(i+vi);
6791 Indices.push_back(i+e+vi);
6794 SV =
Builder.CreateShuffleVector(Ops[1], Ops[2], Indices,
"vtrn");
6799 case NEON::BI__builtin_neon_vuzp_v:
6800 case NEON::BI__builtin_neon_vuzpq_v: {
6801 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
6802 Ops[2] =
Builder.CreateBitCast(Ops[2], Ty);
6803 Value *SV =
nullptr;
6805 for (
unsigned vi = 0; vi != 2; ++vi) {
6807 for (
unsigned i = 0, e = VTy->getNumElements(); i != e; ++i)
6808 Indices.push_back(2*i+vi);
6811 SV =
Builder.CreateShuffleVector(Ops[1], Ops[2], Indices,
"vuzp");
6816 case NEON::BI__builtin_neon_vzip_v:
6817 case NEON::BI__builtin_neon_vzipq_v: {
6818 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
6819 Ops[2] =
Builder.CreateBitCast(Ops[2], Ty);
6820 Value *SV =
nullptr;
6822 for (
unsigned vi = 0; vi != 2; ++vi) {
6824 for (
unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) {
6825 Indices.push_back((i + vi*e) >> 1);
6826 Indices.push_back(((i + vi*e) >> 1)+e);
6829 SV =
Builder.CreateShuffleVector(Ops[1], Ops[2], Indices,
"vzip");
6834 case NEON::BI__builtin_neon_vqtbl1q_v: {
6835 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl1, Ty),
6838 case NEON::BI__builtin_neon_vqtbl2q_v: {
6839 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl2, Ty),
6842 case NEON::BI__builtin_neon_vqtbl3q_v: {
6843 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl3, Ty),
6846 case NEON::BI__builtin_neon_vqtbl4q_v: {
6847 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl4, Ty),
6850 case NEON::BI__builtin_neon_vqtbx1q_v: {
6851 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx1, Ty),
6854 case NEON::BI__builtin_neon_vqtbx2q_v: {
6855 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx2, Ty),
6858 case NEON::BI__builtin_neon_vqtbx3q_v: {
6859 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx3, Ty),
6862 case NEON::BI__builtin_neon_vqtbx4q_v: {
6863 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx4, Ty),
6866 case NEON::BI__builtin_neon_vsqadd_v:
6867 case NEON::BI__builtin_neon_vsqaddq_v: {
6868 Int = Intrinsic::aarch64_neon_usqadd;
6871 case NEON::BI__builtin_neon_vuqadd_v:
6872 case NEON::BI__builtin_neon_vuqaddq_v: {
6873 Int = Intrinsic::aarch64_neon_suqadd;
6877 case NEON::BI__builtin_neon_vluti2_laneq_mf8:
6878 case NEON::BI__builtin_neon_vluti2_laneq_bf16:
6879 case NEON::BI__builtin_neon_vluti2_laneq_f16:
6880 case NEON::BI__builtin_neon_vluti2_laneq_p16:
6881 case NEON::BI__builtin_neon_vluti2_laneq_p8:
6882 case NEON::BI__builtin_neon_vluti2_laneq_s16:
6883 case NEON::BI__builtin_neon_vluti2_laneq_s8:
6884 case NEON::BI__builtin_neon_vluti2_laneq_u16:
6885 case NEON::BI__builtin_neon_vluti2_laneq_u8: {
6886 Int = Intrinsic::aarch64_neon_vluti2_laneq;
6893 case NEON::BI__builtin_neon_vluti2q_laneq_mf8:
6894 case NEON::BI__builtin_neon_vluti2q_laneq_bf16:
6895 case NEON::BI__builtin_neon_vluti2q_laneq_f16:
6896 case NEON::BI__builtin_neon_vluti2q_laneq_p16:
6897 case NEON::BI__builtin_neon_vluti2q_laneq_p8:
6898 case NEON::BI__builtin_neon_vluti2q_laneq_s16:
6899 case NEON::BI__builtin_neon_vluti2q_laneq_s8:
6900 case NEON::BI__builtin_neon_vluti2q_laneq_u16:
6901 case NEON::BI__builtin_neon_vluti2q_laneq_u8: {
6902 Int = Intrinsic::aarch64_neon_vluti2_laneq;
6909 case NEON::BI__builtin_neon_vluti2_lane_mf8:
6910 case NEON::BI__builtin_neon_vluti2_lane_bf16:
6911 case NEON::BI__builtin_neon_vluti2_lane_f16:
6912 case NEON::BI__builtin_neon_vluti2_lane_p16:
6913 case NEON::BI__builtin_neon_vluti2_lane_p8:
6914 case NEON::BI__builtin_neon_vluti2_lane_s16:
6915 case NEON::BI__builtin_neon_vluti2_lane_s8:
6916 case NEON::BI__builtin_neon_vluti2_lane_u16:
6917 case NEON::BI__builtin_neon_vluti2_lane_u8: {
6918 Int = Intrinsic::aarch64_neon_vluti2_lane;
6925 case NEON::BI__builtin_neon_vluti2q_lane_mf8:
6926 case NEON::BI__builtin_neon_vluti2q_lane_bf16:
6927 case NEON::BI__builtin_neon_vluti2q_lane_f16:
6928 case NEON::BI__builtin_neon_vluti2q_lane_p16:
6929 case NEON::BI__builtin_neon_vluti2q_lane_p8:
6930 case NEON::BI__builtin_neon_vluti2q_lane_s16:
6931 case NEON::BI__builtin_neon_vluti2q_lane_s8:
6932 case NEON::BI__builtin_neon_vluti2q_lane_u16:
6933 case NEON::BI__builtin_neon_vluti2q_lane_u8: {
6934 Int = Intrinsic::aarch64_neon_vluti2_lane;
6941 case NEON::BI__builtin_neon_vluti4q_lane_mf8:
6942 case NEON::BI__builtin_neon_vluti4q_lane_p8:
6943 case NEON::BI__builtin_neon_vluti4q_lane_s8:
6944 case NEON::BI__builtin_neon_vluti4q_lane_u8: {
6945 Int = Intrinsic::aarch64_neon_vluti4q_lane;
6948 case NEON::BI__builtin_neon_vluti4q_laneq_mf8:
6949 case NEON::BI__builtin_neon_vluti4q_laneq_p8:
6950 case NEON::BI__builtin_neon_vluti4q_laneq_s8:
6951 case NEON::BI__builtin_neon_vluti4q_laneq_u8: {
6952 Int = Intrinsic::aarch64_neon_vluti4q_laneq;
6955 case NEON::BI__builtin_neon_vluti4q_lane_bf16_x2:
6956 case NEON::BI__builtin_neon_vluti4q_lane_f16_x2:
6957 case NEON::BI__builtin_neon_vluti4q_lane_p16_x2:
6958 case NEON::BI__builtin_neon_vluti4q_lane_s16_x2:
6959 case NEON::BI__builtin_neon_vluti4q_lane_u16_x2: {
6960 Int = Intrinsic::aarch64_neon_vluti4q_lane_x2;
6961 return EmitNeonCall(
CGM.getIntrinsic(Int, Ty), Ops,
"vluti4q_lane_x2");
6963 case NEON::BI__builtin_neon_vluti4q_laneq_bf16_x2:
6964 case NEON::BI__builtin_neon_vluti4q_laneq_f16_x2:
6965 case NEON::BI__builtin_neon_vluti4q_laneq_p16_x2:
6966 case NEON::BI__builtin_neon_vluti4q_laneq_s16_x2:
6967 case NEON::BI__builtin_neon_vluti4q_laneq_u16_x2: {
6968 Int = Intrinsic::aarch64_neon_vluti4q_laneq_x2;
6969 return EmitNeonCall(
CGM.getIntrinsic(Int, Ty), Ops,
"vluti4q_laneq_x2");
6971 case NEON::BI__builtin_neon_vmmlaq_f16_mf8_fpm:
6973 {llvm::FixedVectorType::get(
HalfTy, 8),
6974 llvm::FixedVectorType::get(
Int8Ty, 16)},
6976 case NEON::BI__builtin_neon_vmmlaq_f32_mf8_fpm:
6978 {llvm::FixedVectorType::get(
FloatTy, 4),
6979 llvm::FixedVectorType::get(
Int8Ty, 16)},
6981 case NEON::BI__builtin_neon_vcvt1_low_bf16_mf8_fpm:
6984 case NEON::BI__builtin_neon_vcvt1_bf16_mf8_fpm:
6985 case NEON::BI__builtin_neon_vcvt1_high_bf16_mf8_fpm:
6987 llvm::FixedVectorType::get(
BFloatTy, 8),
6988 Ops[0]->
getType(), ExtractLow, Ops, E,
"vbfcvt1");
6989 case NEON::BI__builtin_neon_vcvt2_low_bf16_mf8_fpm:
6992 case NEON::BI__builtin_neon_vcvt2_bf16_mf8_fpm:
6993 case NEON::BI__builtin_neon_vcvt2_high_bf16_mf8_fpm:
6995 llvm::FixedVectorType::get(
BFloatTy, 8),
6996 Ops[0]->
getType(), ExtractLow, Ops, E,
"vbfcvt2");
6997 case NEON::BI__builtin_neon_vcvt1_low_f16_mf8_fpm:
7000 case NEON::BI__builtin_neon_vcvt1_f16_mf8_fpm:
7001 case NEON::BI__builtin_neon_vcvt1_high_f16_mf8_fpm:
7003 llvm::FixedVectorType::get(
HalfTy, 8),
7004 Ops[0]->
getType(), ExtractLow, Ops, E,
"vbfcvt1");
7005 case NEON::BI__builtin_neon_vcvt2_low_f16_mf8_fpm:
7008 case NEON::BI__builtin_neon_vcvt2_f16_mf8_fpm:
7009 case NEON::BI__builtin_neon_vcvt2_high_f16_mf8_fpm:
7011 llvm::FixedVectorType::get(
HalfTy, 8),
7012 Ops[0]->
getType(), ExtractLow, Ops, E,
"vbfcvt2");
7013 case NEON::BI__builtin_neon_vcvt_mf8_f32_fpm:
7015 llvm::FixedVectorType::get(
Int8Ty, 8),
7016 Ops[0]->
getType(),
false, Ops, E,
"vfcvtn");
7017 case NEON::BI__builtin_neon_vcvt_mf8_f16_fpm:
7019 llvm::FixedVectorType::get(
Int8Ty, 8),
7020 llvm::FixedVectorType::get(
HalfTy, 4),
false, Ops,
7022 case NEON::BI__builtin_neon_vcvtq_mf8_f16_fpm:
7024 llvm::FixedVectorType::get(
Int8Ty, 16),
7025 llvm::FixedVectorType::get(
HalfTy, 8),
false, Ops,
7027 case NEON::BI__builtin_neon_vcvt_high_mf8_f32_fpm: {
7028 llvm::Type *Ty = llvm::FixedVectorType::get(
Int8Ty, 16);
7029 Ops[0] =
Builder.CreateInsertVector(Ty, PoisonValue::get(Ty), Ops[0],
7032 Ops[1]->
getType(),
false, Ops, E,
"vfcvtn2");
7035 case NEON::BI__builtin_neon_vdot_f16_mf8_fpm:
7036 case NEON::BI__builtin_neon_vdotq_f16_mf8_fpm:
7039 case NEON::BI__builtin_neon_vdot_lane_f16_mf8_fpm:
7040 case NEON::BI__builtin_neon_vdotq_lane_f16_mf8_fpm:
7041 ExtendLaneArg =
true;
7043 case NEON::BI__builtin_neon_vdot_laneq_f16_mf8_fpm:
7044 case NEON::BI__builtin_neon_vdotq_laneq_f16_mf8_fpm:
7046 ExtendLaneArg,
HalfTy, Ops, E,
"fdot2_lane");
7047 case NEON::BI__builtin_neon_vdot_f32_mf8_fpm:
7048 case NEON::BI__builtin_neon_vdotq_f32_mf8_fpm:
7051 case NEON::BI__builtin_neon_vdot_lane_f32_mf8_fpm:
7052 case NEON::BI__builtin_neon_vdotq_lane_f32_mf8_fpm:
7053 ExtendLaneArg =
true;
7055 case NEON::BI__builtin_neon_vdot_laneq_f32_mf8_fpm:
7056 case NEON::BI__builtin_neon_vdotq_laneq_f32_mf8_fpm:
7058 ExtendLaneArg,
FloatTy, Ops, E,
"fdot4_lane");
7060 case NEON::BI__builtin_neon_vdot_f32_f16:
7061 case NEON::BI__builtin_neon_vdotq_f32_f16: {
7062 llvm::Type *InputTy =
7063 llvm::FixedVectorType::get(
HalfTy, Ty->getPrimitiveSizeInBits() / 16);
7064 llvm::Type *Tys[2] = {Ty, InputTy};
7065 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_fdot, Tys),
7069 case NEON::BI__builtin_neon_vdot_lane_f32_f16:
7070 case NEON::BI__builtin_neon_vdot_laneq_f32_f16:
7071 case NEON::BI__builtin_neon_vdotq_lane_f32_f16:
7072 case NEON::BI__builtin_neon_vdotq_laneq_f32_f16: {
7073 llvm::FixedVectorType *InputTy =
7074 llvm::FixedVectorType::get(
HalfTy, Ty->getPrimitiveSizeInBits() / 16);
7075 llvm::FixedVectorType *LaneTy = llvm::FixedVectorType::get(
7079 Ops[2] =
Builder.CreateBitCast(Ops[2], LaneTy);
7081 InputTy->getElementCount());
7082 llvm::Type *Tys[2] = {Ty, InputTy};
7084 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_fdot, Tys),
7088 case NEON::BI__builtin_neon_vmlalbq_f16_mf8_fpm:
7090 {llvm::FixedVectorType::get(
HalfTy, 8)}, Ops, E,
7092 case NEON::BI__builtin_neon_vmlaltq_f16_mf8_fpm:
7094 {llvm::FixedVectorType::get(
HalfTy, 8)}, Ops, E,
7096 case NEON::BI__builtin_neon_vmlallbbq_f32_mf8_fpm:
7098 {llvm::FixedVectorType::get(
FloatTy, 4)}, Ops, E,
7100 case NEON::BI__builtin_neon_vmlallbtq_f32_mf8_fpm:
7102 {llvm::FixedVectorType::get(
FloatTy, 4)}, Ops, E,
7104 case NEON::BI__builtin_neon_vmlalltbq_f32_mf8_fpm:
7106 {llvm::FixedVectorType::get(
FloatTy, 4)}, Ops, E,
7108 case NEON::BI__builtin_neon_vmlallttq_f32_mf8_fpm:
7110 {llvm::FixedVectorType::get(
FloatTy, 4)}, Ops, E,
7112 case NEON::BI__builtin_neon_vmlalbq_lane_f16_mf8_fpm:
7113 ExtendLaneArg =
true;
7115 case NEON::BI__builtin_neon_vmlalbq_laneq_f16_mf8_fpm:
7117 ExtendLaneArg,
HalfTy, Ops, E,
"vmlal_lane");
7118 case NEON::BI__builtin_neon_vmlaltq_lane_f16_mf8_fpm:
7119 ExtendLaneArg =
true;
7121 case NEON::BI__builtin_neon_vmlaltq_laneq_f16_mf8_fpm:
7123 ExtendLaneArg,
HalfTy, Ops, E,
"vmlal_lane");
7124 case NEON::BI__builtin_neon_vmlallbbq_lane_f32_mf8_fpm:
7125 ExtendLaneArg =
true;
7127 case NEON::BI__builtin_neon_vmlallbbq_laneq_f32_mf8_fpm:
7129 ExtendLaneArg,
FloatTy, Ops, E,
"vmlall_lane");
7130 case NEON::BI__builtin_neon_vmlallbtq_lane_f32_mf8_fpm:
7131 ExtendLaneArg =
true;
7133 case NEON::BI__builtin_neon_vmlallbtq_laneq_f32_mf8_fpm:
7135 ExtendLaneArg,
FloatTy, Ops, E,
"vmlall_lane");
7136 case NEON::BI__builtin_neon_vmlalltbq_lane_f32_mf8_fpm:
7137 ExtendLaneArg =
true;
7139 case NEON::BI__builtin_neon_vmlalltbq_laneq_f32_mf8_fpm:
7141 ExtendLaneArg,
FloatTy, Ops, E,
"vmlall_lane");
7142 case NEON::BI__builtin_neon_vmlallttq_lane_f32_mf8_fpm:
7143 ExtendLaneArg =
true;
7145 case NEON::BI__builtin_neon_vmlallttq_laneq_f32_mf8_fpm:
7147 ExtendLaneArg,
FloatTy, Ops, E,
"vmlall_lane");
7148 case NEON::BI__builtin_neon_vamin_f16:
7149 case NEON::BI__builtin_neon_vaminq_f16:
7150 case NEON::BI__builtin_neon_vamin_f32:
7151 case NEON::BI__builtin_neon_vaminq_f32:
7152 case NEON::BI__builtin_neon_vaminq_f64: {
7153 Int = Intrinsic::aarch64_neon_famin;
7156 case NEON::BI__builtin_neon_vamax_f16:
7157 case NEON::BI__builtin_neon_vamaxq_f16:
7158 case NEON::BI__builtin_neon_vamax_f32:
7159 case NEON::BI__builtin_neon_vamaxq_f32:
7160 case NEON::BI__builtin_neon_vamaxq_f64: {
7161 Int = Intrinsic::aarch64_neon_famax;
7164 case NEON::BI__builtin_neon_vscale_f16:
7165 case NEON::BI__builtin_neon_vscaleq_f16:
7166 case NEON::BI__builtin_neon_vscale_f32:
7167 case NEON::BI__builtin_neon_vscaleq_f32:
7168 case NEON::BI__builtin_neon_vscaleq_f64: {
7169 Int = Intrinsic::aarch64_neon_fp8_fscale;