542 NEONMAP1(__a32_vcvt_bf16_f32, arm_neon_vcvtfp2bf, 0),
550 NEONMAP1(vabsq_v, arm_neon_vabs, 0),
554 NEONMAP1(vaesdq_u8, arm_neon_aesd, 0),
555 NEONMAP1(vaeseq_u8, arm_neon_aese, 0),
556 NEONMAP1(vaesimcq_u8, arm_neon_aesimc, 0),
557 NEONMAP1(vaesmcq_u8, arm_neon_aesmc, 0),
558 NEONMAP1(vbfdot_f32, arm_neon_bfdot, 0),
559 NEONMAP1(vbfdotq_f32, arm_neon_bfdot, 0),
560 NEONMAP1(vbfmlalbq_f32, arm_neon_bfmlalb, 0),
561 NEONMAP1(vbfmlaltq_f32, arm_neon_bfmlalt, 0),
562 NEONMAP1(vbfmmlaq_f32, arm_neon_bfmmla, 0),
575 NEONMAP1(vcage_v, arm_neon_vacge, 0),
576 NEONMAP1(vcageq_v, arm_neon_vacge, 0),
577 NEONMAP1(vcagt_v, arm_neon_vacgt, 0),
578 NEONMAP1(vcagtq_v, arm_neon_vacgt, 0),
579 NEONMAP1(vcale_v, arm_neon_vacge, 0),
580 NEONMAP1(vcaleq_v, arm_neon_vacge, 0),
581 NEONMAP1(vcalt_v, arm_neon_vacgt, 0),
582 NEONMAP1(vcaltq_v, arm_neon_vacgt, 0),
602 NEONMAP1(vcvt_n_f16_s16, arm_neon_vcvtfxs2fp, 0),
603 NEONMAP1(vcvt_n_f16_u16, arm_neon_vcvtfxu2fp, 0),
604 NEONMAP2(vcvt_n_f32_v, arm_neon_vcvtfxu2fp, arm_neon_vcvtfxs2fp, 0),
605 NEONMAP1(vcvt_n_s16_f16, arm_neon_vcvtfp2fxs, 0),
606 NEONMAP1(vcvt_n_s32_v, arm_neon_vcvtfp2fxs, 0),
607 NEONMAP1(vcvt_n_s64_v, arm_neon_vcvtfp2fxs, 0),
608 NEONMAP1(vcvt_n_u16_f16, arm_neon_vcvtfp2fxu, 0),
609 NEONMAP1(vcvt_n_u32_v, arm_neon_vcvtfp2fxu, 0),
610 NEONMAP1(vcvt_n_u64_v, arm_neon_vcvtfp2fxu, 0),
617 NEONMAP1(vcvta_s16_f16, arm_neon_vcvtas, 0),
618 NEONMAP1(vcvta_s32_v, arm_neon_vcvtas, 0),
619 NEONMAP1(vcvta_s64_v, arm_neon_vcvtas, 0),
620 NEONMAP1(vcvta_u16_f16, arm_neon_vcvtau, 0),
621 NEONMAP1(vcvta_u32_v, arm_neon_vcvtau, 0),
622 NEONMAP1(vcvta_u64_v, arm_neon_vcvtau, 0),
623 NEONMAP1(vcvtaq_s16_f16, arm_neon_vcvtas, 0),
624 NEONMAP1(vcvtaq_s32_v, arm_neon_vcvtas, 0),
625 NEONMAP1(vcvtaq_s64_v, arm_neon_vcvtas, 0),
626 NEONMAP1(vcvtaq_u16_f16, arm_neon_vcvtau, 0),
627 NEONMAP1(vcvtaq_u32_v, arm_neon_vcvtau, 0),
628 NEONMAP1(vcvtaq_u64_v, arm_neon_vcvtau, 0),
629 NEONMAP1(vcvth_bf16_f32, arm_neon_vcvtbfp2bf, 0),
630 NEONMAP1(vcvtm_s16_f16, arm_neon_vcvtms, 0),
631 NEONMAP1(vcvtm_s32_v, arm_neon_vcvtms, 0),
632 NEONMAP1(vcvtm_s64_v, arm_neon_vcvtms, 0),
633 NEONMAP1(vcvtm_u16_f16, arm_neon_vcvtmu, 0),
634 NEONMAP1(vcvtm_u32_v, arm_neon_vcvtmu, 0),
635 NEONMAP1(vcvtm_u64_v, arm_neon_vcvtmu, 0),
636 NEONMAP1(vcvtmq_s16_f16, arm_neon_vcvtms, 0),
637 NEONMAP1(vcvtmq_s32_v, arm_neon_vcvtms, 0),
638 NEONMAP1(vcvtmq_s64_v, arm_neon_vcvtms, 0),
639 NEONMAP1(vcvtmq_u16_f16, arm_neon_vcvtmu, 0),
640 NEONMAP1(vcvtmq_u32_v, arm_neon_vcvtmu, 0),
641 NEONMAP1(vcvtmq_u64_v, arm_neon_vcvtmu, 0),
642 NEONMAP1(vcvtn_s16_f16, arm_neon_vcvtns, 0),
643 NEONMAP1(vcvtn_s32_v, arm_neon_vcvtns, 0),
644 NEONMAP1(vcvtn_s64_v, arm_neon_vcvtns, 0),
645 NEONMAP1(vcvtn_u16_f16, arm_neon_vcvtnu, 0),
646 NEONMAP1(vcvtn_u32_v, arm_neon_vcvtnu, 0),
647 NEONMAP1(vcvtn_u64_v, arm_neon_vcvtnu, 0),
648 NEONMAP1(vcvtnq_s16_f16, arm_neon_vcvtns, 0),
649 NEONMAP1(vcvtnq_s32_v, arm_neon_vcvtns, 0),
650 NEONMAP1(vcvtnq_s64_v, arm_neon_vcvtns, 0),
651 NEONMAP1(vcvtnq_u16_f16, arm_neon_vcvtnu, 0),
652 NEONMAP1(vcvtnq_u32_v, arm_neon_vcvtnu, 0),
653 NEONMAP1(vcvtnq_u64_v, arm_neon_vcvtnu, 0),
654 NEONMAP1(vcvtp_s16_f16, arm_neon_vcvtps, 0),
655 NEONMAP1(vcvtp_s32_v, arm_neon_vcvtps, 0),
656 NEONMAP1(vcvtp_s64_v, arm_neon_vcvtps, 0),
657 NEONMAP1(vcvtp_u16_f16, arm_neon_vcvtpu, 0),
658 NEONMAP1(vcvtp_u32_v, arm_neon_vcvtpu, 0),
659 NEONMAP1(vcvtp_u64_v, arm_neon_vcvtpu, 0),
660 NEONMAP1(vcvtpq_s16_f16, arm_neon_vcvtps, 0),
661 NEONMAP1(vcvtpq_s32_v, arm_neon_vcvtps, 0),
662 NEONMAP1(vcvtpq_s64_v, arm_neon_vcvtps, 0),
663 NEONMAP1(vcvtpq_u16_f16, arm_neon_vcvtpu, 0),
664 NEONMAP1(vcvtpq_u32_v, arm_neon_vcvtpu, 0),
665 NEONMAP1(vcvtpq_u64_v, arm_neon_vcvtpu, 0),
669 NEONMAP1(vcvtq_n_f16_s16, arm_neon_vcvtfxs2fp, 0),
670 NEONMAP1(vcvtq_n_f16_u16, arm_neon_vcvtfxu2fp, 0),
671 NEONMAP2(vcvtq_n_f32_v, arm_neon_vcvtfxu2fp, arm_neon_vcvtfxs2fp, 0),
672 NEONMAP1(vcvtq_n_s16_f16, arm_neon_vcvtfp2fxs, 0),
673 NEONMAP1(vcvtq_n_s32_v, arm_neon_vcvtfp2fxs, 0),
674 NEONMAP1(vcvtq_n_s64_v, arm_neon_vcvtfp2fxs, 0),
675 NEONMAP1(vcvtq_n_u16_f16, arm_neon_vcvtfp2fxu, 0),
676 NEONMAP1(vcvtq_n_u32_v, arm_neon_vcvtfp2fxu, 0),
677 NEONMAP1(vcvtq_n_u64_v, arm_neon_vcvtfp2fxu, 0),
684 NEONMAP1(vdot_s32, arm_neon_sdot, 0),
685 NEONMAP1(vdot_u32, arm_neon_udot, 0),
686 NEONMAP1(vdotq_s32, arm_neon_sdot, 0),
687 NEONMAP1(vdotq_u32, arm_neon_udot, 0),
698 NEONMAP1(vld1_x2_v, arm_neon_vld1x2, 0),
699 NEONMAP1(vld1_x3_v, arm_neon_vld1x3, 0),
700 NEONMAP1(vld1_x4_v, arm_neon_vld1x4, 0),
702 NEONMAP1(vld1q_v, arm_neon_vld1, 0),
703 NEONMAP1(vld1q_x2_v, arm_neon_vld1x2, 0),
704 NEONMAP1(vld1q_x3_v, arm_neon_vld1x3, 0),
705 NEONMAP1(vld1q_x4_v, arm_neon_vld1x4, 0),
706 NEONMAP1(vld2_dup_v, arm_neon_vld2dup, 0),
707 NEONMAP1(vld2_lane_v, arm_neon_vld2lane, 0),
709 NEONMAP1(vld2q_dup_v, arm_neon_vld2dup, 0),
710 NEONMAP1(vld2q_lane_v, arm_neon_vld2lane, 0),
711 NEONMAP1(vld2q_v, arm_neon_vld2, 0),
712 NEONMAP1(vld3_dup_v, arm_neon_vld3dup, 0),
713 NEONMAP1(vld3_lane_v, arm_neon_vld3lane, 0),
715 NEONMAP1(vld3q_dup_v, arm_neon_vld3dup, 0),
716 NEONMAP1(vld3q_lane_v, arm_neon_vld3lane, 0),
717 NEONMAP1(vld3q_v, arm_neon_vld3, 0),
718 NEONMAP1(vld4_dup_v, arm_neon_vld4dup, 0),
719 NEONMAP1(vld4_lane_v, arm_neon_vld4lane, 0),
721 NEONMAP1(vld4q_dup_v, arm_neon_vld4dup, 0),
722 NEONMAP1(vld4q_lane_v, arm_neon_vld4lane, 0),
723 NEONMAP1(vld4q_v, arm_neon_vld4, 0),
732 NEONMAP1(vmmlaq_s32, arm_neon_smmla, 0),
733 NEONMAP1(vmmlaq_u32, arm_neon_ummla, 0),
751 NEONMAP2(vqdmlal_v, arm_neon_vqdmull, sadd_sat, 0),
752 NEONMAP2(vqdmlsl_v, arm_neon_vqdmull, ssub_sat, 0),
776 NEONMAP1(vqshlu_n_v, arm_neon_vqshiftsu, 0),
777 NEONMAP1(vqshluq_n_v, arm_neon_vqshiftsu, 0),
781 NEONMAP2(vrecpe_v, arm_neon_vrecpe, arm_neon_vrecpe, 0),
782 NEONMAP2(vrecpeq_v, arm_neon_vrecpe, arm_neon_vrecpe, 0),
805 NEONMAP2(vrsqrte_v, arm_neon_vrsqrte, arm_neon_vrsqrte, 0),
806 NEONMAP2(vrsqrteq_v, arm_neon_vrsqrte, arm_neon_vrsqrte, 0),
810 NEONMAP1(vsha1su0q_u32, arm_neon_sha1su0, 0),
811 NEONMAP1(vsha1su1q_u32, arm_neon_sha1su1, 0),
812 NEONMAP1(vsha256h2q_u32, arm_neon_sha256h2, 0),
813 NEONMAP1(vsha256hq_u32, arm_neon_sha256h, 0),
814 NEONMAP1(vsha256su0q_u32, arm_neon_sha256su0, 0),
815 NEONMAP1(vsha256su1q_u32, arm_neon_sha256su1, 0),
825 NEONMAP1(vst1_x2_v, arm_neon_vst1x2, 0),
826 NEONMAP1(vst1_x3_v, arm_neon_vst1x3, 0),
827 NEONMAP1(vst1_x4_v, arm_neon_vst1x4, 0),
828 NEONMAP1(vst1q_v, arm_neon_vst1, 0),
829 NEONMAP1(vst1q_x2_v, arm_neon_vst1x2, 0),
830 NEONMAP1(vst1q_x3_v, arm_neon_vst1x3, 0),
831 NEONMAP1(vst1q_x4_v, arm_neon_vst1x4, 0),
832 NEONMAP1(vst2_lane_v, arm_neon_vst2lane, 0),
834 NEONMAP1(vst2q_lane_v, arm_neon_vst2lane, 0),
835 NEONMAP1(vst2q_v, arm_neon_vst2, 0),
836 NEONMAP1(vst3_lane_v, arm_neon_vst3lane, 0),
838 NEONMAP1(vst3q_lane_v, arm_neon_vst3lane, 0),
839 NEONMAP1(vst3q_v, arm_neon_vst3, 0),
840 NEONMAP1(vst4_lane_v, arm_neon_vst4lane, 0),
842 NEONMAP1(vst4q_lane_v, arm_neon_vst4lane, 0),
843 NEONMAP1(vst4q_v, arm_neon_vst4, 0),
849 NEONMAP1(vusdot_s32, arm_neon_usdot, 0),
850 NEONMAP1(vusdotq_s32, arm_neon_usdot, 0),
851 NEONMAP1(vusmmlaq_s32, arm_neon_usmmla, 0),
1122 unsigned BuiltinID,
unsigned LLVMIntrinsic,
unsigned AltLLVMIntrinsic,
1123 const char *NameHint,
unsigned Modifier,
const CallExpr *E,
1125 llvm::Triple::ArchType
Arch) {
1131 std::optional<llvm::APSInt> NeonTypeConst =
1138 const bool Usgn =
Type.isUnsigned();
1139 const bool Quad =
Type.isQuad();
1140 const bool Floating =
Type.isFloatingPoint();
1142 const bool AllowBFloatArgsAndRet =
1145 llvm::FixedVectorType *VTy =
1146 GetNeonType(
this,
Type, HasFastHalfType,
false, AllowBFloatArgsAndRet);
1147 llvm::Type *Ty = VTy;
1151 auto getAlignmentValue32 = [&](
Address addr) ->
Value* {
1152 return Builder.getInt32(addr.getAlignment().getQuantity());
1155 unsigned Int = LLVMIntrinsic;
1157 Int = AltLLVMIntrinsic;
1159 switch (BuiltinID) {
1161 case NEON::BI__builtin_neon_splat_lane_v:
1162 case NEON::BI__builtin_neon_splat_laneq_v:
1163 case NEON::BI__builtin_neon_splatq_lane_v:
1164 case NEON::BI__builtin_neon_splatq_laneq_v: {
1165 auto NumElements = VTy->getElementCount();
1166 if (BuiltinID == NEON::BI__builtin_neon_splatq_lane_v)
1167 NumElements = NumElements * 2;
1168 if (BuiltinID == NEON::BI__builtin_neon_splat_laneq_v)
1169 NumElements = NumElements.divideCoefficientBy(2);
1171 Ops[0] =
Builder.CreateBitCast(Ops[0], VTy);
1174 case NEON::BI__builtin_neon_vpadd_v:
1175 case NEON::BI__builtin_neon_vpaddq_v:
1177 if (VTy->getElementType()->isFloatingPointTy() &&
1178 Int == Intrinsic::aarch64_neon_addp)
1179 Int = Intrinsic::aarch64_neon_faddp;
1181 case NEON::BI__builtin_neon_vabs_v:
1182 case NEON::BI__builtin_neon_vabsq_v:
1183 if (VTy->getElementType()->isFloatingPointTy())
1184 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::fabs, Ty), Ops,
"vabs");
1185 return EmitNeonCall(
CGM.getIntrinsic(LLVMIntrinsic, Ty), Ops,
"vabs");
1186 case NEON::BI__builtin_neon_vadd_v:
1187 case NEON::BI__builtin_neon_vaddq_v: {
1188 llvm::Type *VTy = llvm::FixedVectorType::get(
Int8Ty, Quad ? 16 : 8);
1189 Ops[0] =
Builder.CreateBitCast(Ops[0], VTy);
1190 Ops[1] =
Builder.CreateBitCast(Ops[1], VTy);
1191 Ops[0] =
Builder.CreateXor(Ops[0], Ops[1]);
1192 return Builder.CreateBitCast(Ops[0], Ty);
1194 case NEON::BI__builtin_neon_vaddhn_v: {
1195 llvm::FixedVectorType *SrcTy =
1196 llvm::FixedVectorType::getExtendedElementVectorType(VTy);
1199 Ops[0] =
Builder.CreateBitCast(Ops[0], SrcTy);
1200 Ops[1] =
Builder.CreateBitCast(Ops[1], SrcTy);
1201 Ops[0] =
Builder.CreateAdd(Ops[0], Ops[1],
"vaddhn");
1205 ConstantInt::get(SrcTy, SrcTy->getScalarSizeInBits() / 2);
1206 Ops[0] =
Builder.CreateLShr(Ops[0], ShiftAmt,
"vaddhn");
1209 return Builder.CreateTrunc(Ops[0], VTy,
"vaddhn");
1211 case NEON::BI__builtin_neon_vcale_v:
1212 case NEON::BI__builtin_neon_vcaleq_v:
1213 case NEON::BI__builtin_neon_vcalt_v:
1214 case NEON::BI__builtin_neon_vcaltq_v:
1215 std::swap(Ops[0], Ops[1]);
1217 case NEON::BI__builtin_neon_vcage_v:
1218 case NEON::BI__builtin_neon_vcageq_v:
1219 case NEON::BI__builtin_neon_vcagt_v:
1220 case NEON::BI__builtin_neon_vcagtq_v: {
1222 switch (VTy->getScalarSizeInBits()) {
1223 default: llvm_unreachable(
"unexpected type");
1234 auto *VecFlt = llvm::FixedVectorType::get(Ty, VTy->getNumElements());
1235 llvm::Type *Tys[] = { VTy, VecFlt };
1236 Function *F =
CGM.getIntrinsic(LLVMIntrinsic, Tys);
1239 case NEON::BI__builtin_neon_vceqz_v:
1240 case NEON::BI__builtin_neon_vceqzq_v:
1242 Ops[0], Ty, Floating ? ICmpInst::FCMP_OEQ : ICmpInst::ICMP_EQ,
"vceqz");
1243 case NEON::BI__builtin_neon_vcgez_v:
1244 case NEON::BI__builtin_neon_vcgezq_v:
1246 Ops[0], Ty, Floating ? ICmpInst::FCMP_OGE : ICmpInst::ICMP_SGE,
1248 case NEON::BI__builtin_neon_vclez_v:
1249 case NEON::BI__builtin_neon_vclezq_v:
1251 Ops[0], Ty, Floating ? ICmpInst::FCMP_OLE : ICmpInst::ICMP_SLE,
1253 case NEON::BI__builtin_neon_vcgtz_v:
1254 case NEON::BI__builtin_neon_vcgtzq_v:
1256 Ops[0], Ty, Floating ? ICmpInst::FCMP_OGT : ICmpInst::ICMP_SGT,
1258 case NEON::BI__builtin_neon_vcltz_v:
1259 case NEON::BI__builtin_neon_vcltzq_v:
1261 Ops[0], Ty, Floating ? ICmpInst::FCMP_OLT : ICmpInst::ICMP_SLT,
1263 case NEON::BI__builtin_neon_vclz_v:
1264 case NEON::BI__builtin_neon_vclzq_v:
1269 case NEON::BI__builtin_neon_vcvt_f32_v:
1270 case NEON::BI__builtin_neon_vcvtq_f32_v:
1271 Ops[0] =
Builder.CreateBitCast(Ops[0], Ty);
1274 return Usgn ?
Builder.CreateUIToFP(Ops[0], Ty,
"vcvt")
1275 :
Builder.CreateSIToFP(Ops[0], Ty,
"vcvt");
1276 case NEON::BI__builtin_neon_vcvt_f16_s16:
1277 case NEON::BI__builtin_neon_vcvt_f16_u16:
1278 case NEON::BI__builtin_neon_vcvtq_f16_s16:
1279 case NEON::BI__builtin_neon_vcvtq_f16_u16:
1280 Ops[0] =
Builder.CreateBitCast(Ops[0], Ty);
1283 return Usgn ?
Builder.CreateUIToFP(Ops[0], Ty,
"vcvt")
1284 :
Builder.CreateSIToFP(Ops[0], Ty,
"vcvt");
1285 case NEON::BI__builtin_neon_vcvt_n_f16_s16:
1286 case NEON::BI__builtin_neon_vcvt_n_f16_u16:
1287 case NEON::BI__builtin_neon_vcvtq_n_f16_s16:
1288 case NEON::BI__builtin_neon_vcvtq_n_f16_u16: {
1293 case NEON::BI__builtin_neon_vcvt_n_f32_v:
1294 case NEON::BI__builtin_neon_vcvt_n_f64_v:
1295 case NEON::BI__builtin_neon_vcvtq_n_f32_v:
1296 case NEON::BI__builtin_neon_vcvtq_n_f64_v: {
1298 Int = Usgn ? LLVMIntrinsic : AltLLVMIntrinsic;
1302 case NEON::BI__builtin_neon_vcvt_n_s16_f16:
1303 case NEON::BI__builtin_neon_vcvt_n_s32_v:
1304 case NEON::BI__builtin_neon_vcvt_n_u16_f16:
1305 case NEON::BI__builtin_neon_vcvt_n_u32_v:
1306 case NEON::BI__builtin_neon_vcvt_n_s64_v:
1307 case NEON::BI__builtin_neon_vcvt_n_u64_v:
1308 case NEON::BI__builtin_neon_vcvtq_n_s16_f16:
1309 case NEON::BI__builtin_neon_vcvtq_n_s32_v:
1310 case NEON::BI__builtin_neon_vcvtq_n_u16_f16:
1311 case NEON::BI__builtin_neon_vcvtq_n_u32_v:
1312 case NEON::BI__builtin_neon_vcvtq_n_s64_v:
1313 case NEON::BI__builtin_neon_vcvtq_n_u64_v: {
1315 Function *F =
CGM.getIntrinsic(LLVMIntrinsic, Tys);
1318 case NEON::BI__builtin_neon_vcvt_s32_v:
1319 case NEON::BI__builtin_neon_vcvt_u32_v:
1320 case NEON::BI__builtin_neon_vcvt_s64_v:
1321 case NEON::BI__builtin_neon_vcvt_u64_v:
1322 case NEON::BI__builtin_neon_vcvt_s16_f16:
1323 case NEON::BI__builtin_neon_vcvt_u16_f16:
1324 case NEON::BI__builtin_neon_vcvtq_s32_v:
1325 case NEON::BI__builtin_neon_vcvtq_u32_v:
1326 case NEON::BI__builtin_neon_vcvtq_s64_v:
1327 case NEON::BI__builtin_neon_vcvtq_u64_v:
1328 case NEON::BI__builtin_neon_vcvtq_s16_f16:
1329 case NEON::BI__builtin_neon_vcvtq_u16_f16: {
1333 if (!
Builder.getIsFPConstrained())
1334 Int = Usgn ? Intrinsic::fptoui_sat : Intrinsic::fptosi_sat;
1335 llvm::Type *Tys[2] = {Ty, Ops[0]->getType()};
1340 return Usgn ?
Builder.CreateFPToUI(Ops[0], Ty,
"vcvt")
1341 :
Builder.CreateFPToSI(Ops[0], Ty,
"vcvt");
1343 case NEON::BI__builtin_neon_vcvta_s16_f16:
1344 case NEON::BI__builtin_neon_vcvta_s32_v:
1345 case NEON::BI__builtin_neon_vcvta_s64_v:
1346 case NEON::BI__builtin_neon_vcvta_u16_f16:
1347 case NEON::BI__builtin_neon_vcvta_u32_v:
1348 case NEON::BI__builtin_neon_vcvta_u64_v:
1349 case NEON::BI__builtin_neon_vcvtaq_s16_f16:
1350 case NEON::BI__builtin_neon_vcvtaq_s32_v:
1351 case NEON::BI__builtin_neon_vcvtaq_s64_v:
1352 case NEON::BI__builtin_neon_vcvtaq_u16_f16:
1353 case NEON::BI__builtin_neon_vcvtaq_u32_v:
1354 case NEON::BI__builtin_neon_vcvtaq_u64_v:
1355 case NEON::BI__builtin_neon_vcvtn_s16_f16:
1356 case NEON::BI__builtin_neon_vcvtn_s32_v:
1357 case NEON::BI__builtin_neon_vcvtn_s64_v:
1358 case NEON::BI__builtin_neon_vcvtn_u16_f16:
1359 case NEON::BI__builtin_neon_vcvtn_u32_v:
1360 case NEON::BI__builtin_neon_vcvtn_u64_v:
1361 case NEON::BI__builtin_neon_vcvtnq_s16_f16:
1362 case NEON::BI__builtin_neon_vcvtnq_s32_v:
1363 case NEON::BI__builtin_neon_vcvtnq_s64_v:
1364 case NEON::BI__builtin_neon_vcvtnq_u16_f16:
1365 case NEON::BI__builtin_neon_vcvtnq_u32_v:
1366 case NEON::BI__builtin_neon_vcvtnq_u64_v:
1367 case NEON::BI__builtin_neon_vcvtp_s16_f16:
1368 case NEON::BI__builtin_neon_vcvtp_s32_v:
1369 case NEON::BI__builtin_neon_vcvtp_s64_v:
1370 case NEON::BI__builtin_neon_vcvtp_u16_f16:
1371 case NEON::BI__builtin_neon_vcvtp_u32_v:
1372 case NEON::BI__builtin_neon_vcvtp_u64_v:
1373 case NEON::BI__builtin_neon_vcvtpq_s16_f16:
1374 case NEON::BI__builtin_neon_vcvtpq_s32_v:
1375 case NEON::BI__builtin_neon_vcvtpq_s64_v:
1376 case NEON::BI__builtin_neon_vcvtpq_u16_f16:
1377 case NEON::BI__builtin_neon_vcvtpq_u32_v:
1378 case NEON::BI__builtin_neon_vcvtpq_u64_v:
1379 case NEON::BI__builtin_neon_vcvtm_s16_f16:
1380 case NEON::BI__builtin_neon_vcvtm_s32_v:
1381 case NEON::BI__builtin_neon_vcvtm_s64_v:
1382 case NEON::BI__builtin_neon_vcvtm_u16_f16:
1383 case NEON::BI__builtin_neon_vcvtm_u32_v:
1384 case NEON::BI__builtin_neon_vcvtm_u64_v:
1385 case NEON::BI__builtin_neon_vcvtmq_s16_f16:
1386 case NEON::BI__builtin_neon_vcvtmq_s32_v:
1387 case NEON::BI__builtin_neon_vcvtmq_s64_v:
1388 case NEON::BI__builtin_neon_vcvtmq_u16_f16:
1389 case NEON::BI__builtin_neon_vcvtmq_u32_v:
1390 case NEON::BI__builtin_neon_vcvtmq_u64_v: {
1392 return EmitNeonCall(
CGM.getIntrinsic(LLVMIntrinsic, Tys), Ops, NameHint);
1394 case NEON::BI__builtin_neon_vcvtx_f32_v: {
1395 llvm::Type *Tys[2] = { VTy->getTruncatedElementVectorType(VTy), Ty};
1396 return EmitNeonCall(
CGM.getIntrinsic(LLVMIntrinsic, Tys), Ops, NameHint);
1399 case NEON::BI__builtin_neon_vext_v:
1400 case NEON::BI__builtin_neon_vextq_v: {
1403 for (
unsigned i = 0, e = VTy->getNumElements(); i != e; ++i)
1404 Indices.push_back(i+CV);
1406 Ops[0] =
Builder.CreateBitCast(Ops[0], Ty);
1407 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
1408 return Builder.CreateShuffleVector(Ops[0], Ops[1], Indices,
"vext");
1410 case NEON::BI__builtin_neon_vfma_v:
1411 case NEON::BI__builtin_neon_vfmaq_v: {
1412 Ops[0] =
Builder.CreateBitCast(Ops[0], Ty);
1413 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
1414 Ops[2] =
Builder.CreateBitCast(Ops[2], Ty);
1418 *
this, Intrinsic::fma, Intrinsic::experimental_constrained_fma, Ty,
1419 {Ops[1], Ops[2], Ops[0]});
1421 case NEON::BI__builtin_neon_vld1_x2_v:
1422 case NEON::BI__builtin_neon_vld1q_x2_v:
1423 case NEON::BI__builtin_neon_vld1_x3_v:
1424 case NEON::BI__builtin_neon_vld1q_x3_v:
1425 case NEON::BI__builtin_neon_vld1_x4_v:
1426 case NEON::BI__builtin_neon_vld1q_x4_v: {
1428 Function *F =
CGM.getIntrinsic(LLVMIntrinsic, Tys);
1429 Ops[1] =
Builder.CreateCall(F, Ops[1],
"vld1xN");
1430 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
1432 case NEON::BI__builtin_neon_vld1_v:
1433 case NEON::BI__builtin_neon_vld1q_v: {
1435 Ops.push_back(getAlignmentValue32(PtrOp0));
1436 return EmitNeonCall(
CGM.getIntrinsic(LLVMIntrinsic, Tys), Ops,
"vld1");
1438 case NEON::BI__builtin_neon_vld2_v:
1439 case NEON::BI__builtin_neon_vld2q_v:
1440 case NEON::BI__builtin_neon_vld3_v:
1441 case NEON::BI__builtin_neon_vld3q_v:
1442 case NEON::BI__builtin_neon_vld4_v:
1443 case NEON::BI__builtin_neon_vld4q_v:
1444 case NEON::BI__builtin_neon_vld2_dup_v:
1445 case NEON::BI__builtin_neon_vld2q_dup_v:
1446 case NEON::BI__builtin_neon_vld3_dup_v:
1447 case NEON::BI__builtin_neon_vld3q_dup_v:
1448 case NEON::BI__builtin_neon_vld4_dup_v:
1449 case NEON::BI__builtin_neon_vld4q_dup_v: {
1451 Function *F =
CGM.getIntrinsic(LLVMIntrinsic, Tys);
1452 Value *Align = getAlignmentValue32(PtrOp1);
1453 Ops[1] =
Builder.CreateCall(F, {Ops[1], Align}, NameHint);
1454 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
1456 case NEON::BI__builtin_neon_vld1_dup_v:
1457 case NEON::BI__builtin_neon_vld1q_dup_v: {
1458 Value *
V = PoisonValue::get(Ty);
1460 LoadInst *Ld =
Builder.CreateLoad(PtrOp0);
1461 llvm::Constant *CI = ConstantInt::get(
SizeTy, 0);
1462 Ops[0] =
Builder.CreateInsertElement(
V, Ld, CI);
1465 case NEON::BI__builtin_neon_vld2_lane_v:
1466 case NEON::BI__builtin_neon_vld2q_lane_v:
1467 case NEON::BI__builtin_neon_vld3_lane_v:
1468 case NEON::BI__builtin_neon_vld3q_lane_v:
1469 case NEON::BI__builtin_neon_vld4_lane_v:
1470 case NEON::BI__builtin_neon_vld4q_lane_v: {
1472 Function *F =
CGM.getIntrinsic(LLVMIntrinsic, Tys);
1473 for (
unsigned I = 2; I < Ops.size() - 1; ++I)
1474 Ops[I] =
Builder.CreateBitCast(Ops[I], Ty);
1475 Ops.push_back(getAlignmentValue32(PtrOp1));
1477 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
1479 case NEON::BI__builtin_neon_vmovl_v: {
1480 llvm::FixedVectorType *DTy =
1481 llvm::FixedVectorType::getTruncatedElementVectorType(VTy);
1482 Ops[0] =
Builder.CreateBitCast(Ops[0], DTy);
1484 return Builder.CreateZExt(Ops[0], Ty,
"vmovl");
1485 return Builder.CreateSExt(Ops[0], Ty,
"vmovl");
1487 case NEON::BI__builtin_neon_vmovn_v: {
1488 llvm::FixedVectorType *QTy =
1489 llvm::FixedVectorType::getExtendedElementVectorType(VTy);
1490 Ops[0] =
Builder.CreateBitCast(Ops[0], QTy);
1491 return Builder.CreateTrunc(Ops[0], Ty,
"vmovn");
1493 case NEON::BI__builtin_neon_vmull_v:
1499 Int = Usgn ? Intrinsic::arm_neon_vmullu : Intrinsic::arm_neon_vmulls;
1502 case NEON::BI__builtin_neon_vpadal_v:
1503 case NEON::BI__builtin_neon_vpadalq_v: {
1505 unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
1509 llvm::FixedVectorType::get(EltTy, VTy->getNumElements() * 2);
1510 llvm::Type *Tys[2] = { Ty, NarrowTy };
1513 case NEON::BI__builtin_neon_vpaddl_v:
1514 case NEON::BI__builtin_neon_vpaddlq_v: {
1516 unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
1517 llvm::Type *EltTy = llvm::IntegerType::get(
getLLVMContext(), EltBits / 2);
1519 llvm::FixedVectorType::get(EltTy, VTy->getNumElements() * 2);
1520 llvm::Type *Tys[2] = { Ty, NarrowTy };
1523 case NEON::BI__builtin_neon_vqdmlal_v:
1524 case NEON::BI__builtin_neon_vqdmlsl_v: {
1529 return EmitNeonCall(
CGM.getIntrinsic(AltLLVMIntrinsic, Ty), Ops, NameHint);
1531 case NEON::BI__builtin_neon_vqdmulhq_lane_v:
1532 case NEON::BI__builtin_neon_vqdmulh_lane_v:
1533 case NEON::BI__builtin_neon_vqrdmulhq_lane_v:
1534 case NEON::BI__builtin_neon_vqrdmulh_lane_v: {
1536 if (BuiltinID == NEON::BI__builtin_neon_vqdmulhq_lane_v ||
1537 BuiltinID == NEON::BI__builtin_neon_vqrdmulhq_lane_v)
1538 RTy = llvm::FixedVectorType::get(RTy->getElementType(),
1539 RTy->getNumElements() * 2);
1540 llvm::Type *Tys[2] = {
1545 case NEON::BI__builtin_neon_vqdmulhq_laneq_v:
1546 case NEON::BI__builtin_neon_vqdmulh_laneq_v:
1547 case NEON::BI__builtin_neon_vqrdmulhq_laneq_v:
1548 case NEON::BI__builtin_neon_vqrdmulh_laneq_v: {
1549 llvm::Type *Tys[2] = {
1554 case NEON::BI__builtin_neon_vqshl_n_v:
1555 case NEON::BI__builtin_neon_vqshlq_n_v:
1558 case NEON::BI__builtin_neon_vqshlu_n_v:
1559 case NEON::BI__builtin_neon_vqshluq_n_v:
1562 case NEON::BI__builtin_neon_vrecpe_v:
1563 case NEON::BI__builtin_neon_vrecpeq_v:
1564 case NEON::BI__builtin_neon_vrsqrte_v:
1565 case NEON::BI__builtin_neon_vrsqrteq_v:
1566 Int = Ty->isFPOrFPVectorTy() ? LLVMIntrinsic : AltLLVMIntrinsic;
1568 case NEON::BI__builtin_neon_vrndi_v:
1569 case NEON::BI__builtin_neon_vrndiq_v:
1571 ? Intrinsic::experimental_constrained_nearbyint
1572 : Intrinsic::nearbyint;
1574 case NEON::BI__builtin_neon_vrshr_n_v:
1575 case NEON::BI__builtin_neon_vrshrq_n_v:
1578 case NEON::BI__builtin_neon_vsha512hq_u64:
1579 case NEON::BI__builtin_neon_vsha512h2q_u64:
1580 case NEON::BI__builtin_neon_vsha512su0q_u64:
1581 case NEON::BI__builtin_neon_vsha512su1q_u64: {
1585 case NEON::BI__builtin_neon_vshl_n_v:
1586 case NEON::BI__builtin_neon_vshlq_n_v:
1588 return Builder.CreateShl(
Builder.CreateBitCast(Ops[0],Ty), Ops[1],
1590 case NEON::BI__builtin_neon_vshll_n_v: {
1591 llvm::FixedVectorType *SrcTy =
1592 llvm::FixedVectorType::getTruncatedElementVectorType(VTy);
1593 Ops[0] =
Builder.CreateBitCast(Ops[0], SrcTy);
1595 Ops[0] =
Builder.CreateZExt(Ops[0], VTy);
1597 Ops[0] =
Builder.CreateSExt(Ops[0], VTy);
1599 return Builder.CreateShl(Ops[0], Ops[1],
"vshll_n");
1601 case NEON::BI__builtin_neon_vshrn_n_v: {
1602 llvm::FixedVectorType *SrcTy =
1603 llvm::FixedVectorType::getExtendedElementVectorType(VTy);
1604 Ops[0] =
Builder.CreateBitCast(Ops[0], SrcTy);
1607 Ops[0] =
Builder.CreateLShr(Ops[0], Ops[1]);
1609 Ops[0] =
Builder.CreateAShr(Ops[0], Ops[1]);
1610 return Builder.CreateTrunc(Ops[0], Ty,
"vshrn_n");
1612 case NEON::BI__builtin_neon_vshr_n_v:
1613 case NEON::BI__builtin_neon_vshrq_n_v:
1615 case NEON::BI__builtin_neon_vst1_v:
1616 case NEON::BI__builtin_neon_vst1q_v:
1617 case NEON::BI__builtin_neon_vst2_v:
1618 case NEON::BI__builtin_neon_vst2q_v:
1619 case NEON::BI__builtin_neon_vst3_v:
1620 case NEON::BI__builtin_neon_vst3q_v:
1621 case NEON::BI__builtin_neon_vst4_v:
1622 case NEON::BI__builtin_neon_vst4q_v:
1623 case NEON::BI__builtin_neon_vst2_lane_v:
1624 case NEON::BI__builtin_neon_vst2q_lane_v:
1625 case NEON::BI__builtin_neon_vst3_lane_v:
1626 case NEON::BI__builtin_neon_vst3q_lane_v:
1627 case NEON::BI__builtin_neon_vst4_lane_v:
1628 case NEON::BI__builtin_neon_vst4q_lane_v: {
1630 Ops.push_back(getAlignmentValue32(PtrOp0));
1633 case NEON::BI__builtin_neon_vsm3partw1q_u32:
1634 case NEON::BI__builtin_neon_vsm3partw2q_u32:
1635 case NEON::BI__builtin_neon_vsm3ss1q_u32:
1636 case NEON::BI__builtin_neon_vsm4ekeyq_u32:
1637 case NEON::BI__builtin_neon_vsm4eq_u32: {
1641 case NEON::BI__builtin_neon_vsm3tt1aq_u32:
1642 case NEON::BI__builtin_neon_vsm3tt1bq_u32:
1643 case NEON::BI__builtin_neon_vsm3tt2aq_u32:
1644 case NEON::BI__builtin_neon_vsm3tt2bq_u32: {
1649 case NEON::BI__builtin_neon_vst1_x2_v:
1650 case NEON::BI__builtin_neon_vst1q_x2_v:
1651 case NEON::BI__builtin_neon_vst1_x3_v:
1652 case NEON::BI__builtin_neon_vst1q_x3_v:
1653 case NEON::BI__builtin_neon_vst1_x4_v:
1654 case NEON::BI__builtin_neon_vst1q_x4_v: {
1657 if (
Arch == llvm::Triple::aarch64 ||
Arch == llvm::Triple::aarch64_be ||
1658 Arch == llvm::Triple::aarch64_32) {
1660 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end());
1666 case NEON::BI__builtin_neon_vsubhn_v: {
1667 llvm::FixedVectorType *SrcTy =
1668 llvm::FixedVectorType::getExtendedElementVectorType(VTy);
1671 Ops[0] =
Builder.CreateBitCast(Ops[0], SrcTy);
1672 Ops[1] =
Builder.CreateBitCast(Ops[1], SrcTy);
1673 Ops[0] =
Builder.CreateSub(Ops[0], Ops[1],
"vsubhn");
1677 ConstantInt::get(SrcTy, SrcTy->getScalarSizeInBits() / 2);
1678 Ops[0] =
Builder.CreateLShr(Ops[0], ShiftAmt,
"vsubhn");
1681 return Builder.CreateTrunc(Ops[0], VTy,
"vsubhn");
1683 case NEON::BI__builtin_neon_vtrn_v:
1684 case NEON::BI__builtin_neon_vtrnq_v: {
1685 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
1686 Ops[2] =
Builder.CreateBitCast(Ops[2], Ty);
1687 Value *SV =
nullptr;
1689 for (
unsigned vi = 0; vi != 2; ++vi) {
1691 for (
unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) {
1692 Indices.push_back(i+vi);
1693 Indices.push_back(i+e+vi);
1696 SV =
Builder.CreateShuffleVector(Ops[1], Ops[2], Indices,
"vtrn");
1701 case NEON::BI__builtin_neon_vtst_v:
1702 case NEON::BI__builtin_neon_vtstq_v: {
1703 Ops[0] =
Builder.CreateBitCast(Ops[0], Ty);
1704 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
1705 Ops[0] =
Builder.CreateAnd(Ops[0], Ops[1]);
1706 Ops[0] =
Builder.CreateICmp(ICmpInst::ICMP_NE, Ops[0],
1707 ConstantAggregateZero::get(Ty));
1708 return Builder.CreateSExt(Ops[0], Ty,
"vtst");
1710 case NEON::BI__builtin_neon_vuzp_v:
1711 case NEON::BI__builtin_neon_vuzpq_v: {
1712 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
1713 Ops[2] =
Builder.CreateBitCast(Ops[2], Ty);
1714 Value *SV =
nullptr;
1716 for (
unsigned vi = 0; vi != 2; ++vi) {
1718 for (
unsigned i = 0, e = VTy->getNumElements(); i != e; ++i)
1719 Indices.push_back(2*i+vi);
1722 SV =
Builder.CreateShuffleVector(Ops[1], Ops[2], Indices,
"vuzp");
1727 case NEON::BI__builtin_neon_vxarq_u64: {
1732 case NEON::BI__builtin_neon_vzip_v:
1733 case NEON::BI__builtin_neon_vzipq_v: {
1734 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
1735 Ops[2] =
Builder.CreateBitCast(Ops[2], Ty);
1736 Value *SV =
nullptr;
1738 for (
unsigned vi = 0; vi != 2; ++vi) {
1740 for (
unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) {
1741 Indices.push_back((i + vi*e) >> 1);
1742 Indices.push_back(((i + vi*e) >> 1)+e);
1745 SV =
Builder.CreateShuffleVector(Ops[1], Ops[2], Indices,
"vzip");
1750 case NEON::BI__builtin_neon_vdot_s32:
1751 case NEON::BI__builtin_neon_vdot_u32:
1752 case NEON::BI__builtin_neon_vdotq_s32:
1753 case NEON::BI__builtin_neon_vdotq_u32: {
1755 llvm::FixedVectorType::get(
Int8Ty, Ty->getPrimitiveSizeInBits() / 8);
1756 llvm::Type *Tys[2] = { Ty, InputTy };
1759 case NEON::BI__builtin_neon_vfmlal_low_f16:
1760 case NEON::BI__builtin_neon_vfmlalq_low_f16: {
1762 llvm::FixedVectorType::get(
HalfTy, Ty->getPrimitiveSizeInBits() / 16);
1763 llvm::Type *Tys[2] = { Ty, InputTy };
1766 case NEON::BI__builtin_neon_vfmlsl_low_f16:
1767 case NEON::BI__builtin_neon_vfmlslq_low_f16: {
1769 llvm::FixedVectorType::get(
HalfTy, Ty->getPrimitiveSizeInBits() / 16);
1770 llvm::Type *Tys[2] = { Ty, InputTy };
1773 case NEON::BI__builtin_neon_vfmlal_high_f16:
1774 case NEON::BI__builtin_neon_vfmlalq_high_f16: {
1776 llvm::FixedVectorType::get(
HalfTy, Ty->getPrimitiveSizeInBits() / 16);
1777 llvm::Type *Tys[2] = { Ty, InputTy };
1780 case NEON::BI__builtin_neon_vfmlsl_high_f16:
1781 case NEON::BI__builtin_neon_vfmlslq_high_f16: {
1783 llvm::FixedVectorType::get(
HalfTy, Ty->getPrimitiveSizeInBits() / 16);
1784 llvm::Type *Tys[2] = { Ty, InputTy };
1787 case NEON::BI__builtin_neon_vmmlaq_s32:
1788 case NEON::BI__builtin_neon_vmmlaq_u32: {
1790 llvm::FixedVectorType::get(
Int8Ty, Ty->getPrimitiveSizeInBits() / 8);
1791 llvm::Type *Tys[2] = { Ty, InputTy };
1792 return EmitNeonCall(
CGM.getIntrinsic(LLVMIntrinsic, Tys), Ops,
"vmmla");
1794 case NEON::BI__builtin_neon_vmmlaq_f16:
1795 case NEON::BI__builtin_neon_vmmlaq_f32_f16: {
1797 llvm::FixedVectorType::get(
HalfTy, Ty->getPrimitiveSizeInBits() / 16);
1798 llvm::Type *Tys[2] = {Ty, InputTy};
1801 case NEON::BI__builtin_neon_vusmmlaq_s32: {
1803 llvm::FixedVectorType::get(
Int8Ty, Ty->getPrimitiveSizeInBits() / 8);
1804 llvm::Type *Tys[2] = { Ty, InputTy };
1807 case NEON::BI__builtin_neon_vusdot_s32:
1808 case NEON::BI__builtin_neon_vusdotq_s32: {
1810 llvm::FixedVectorType::get(
Int8Ty, Ty->getPrimitiveSizeInBits() / 8);
1811 llvm::Type *Tys[2] = { Ty, InputTy };
1814 case NEON::BI__builtin_neon_vbfdot_f32:
1815 case NEON::BI__builtin_neon_vbfdotq_f32: {
1816 llvm::Type *InputTy =
1817 llvm::FixedVectorType::get(
BFloatTy, Ty->getPrimitiveSizeInBits() / 16);
1818 llvm::Type *Tys[2] = { Ty, InputTy };
1821 case NEON::BI__builtin_neon___a32_vcvt_bf16_f32: {
1822 llvm::Type *Tys[1] = { Ty };
1829 assert(
Int &&
"Expected valid intrinsic number");
2165 llvm::Triple::ArchType
Arch) {
2166 if (
auto Hint = GetValueForARMHint(BuiltinID))
2169 if (BuiltinID == clang::ARM::BI__emit) {
2171 llvm::FunctionType *FTy =
2172 llvm::FunctionType::get(
VoidTy,
false);
2176 llvm_unreachable(
"Sema will ensure that the parameter is constant");
2179 uint64_t ZExtValue =
Value.zextOrTrunc(IsThumb ? 16 : 32).getZExtValue();
2181 llvm::InlineAsm *Emit =
2182 IsThumb ? InlineAsm::get(FTy,
".inst.n 0x" + utohexstr(ZExtValue),
"",
2184 : InlineAsm::get(FTy,
".inst 0x" + utohexstr(ZExtValue),
"",
2187 return Builder.CreateCall(Emit);
2190 if (BuiltinID == clang::ARM::BI__builtin_arm_dbg) {
2192 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::arm_dbg), Option);
2195 if (BuiltinID == clang::ARM::BI__builtin_arm_prefetch) {
2207 if (BuiltinID == clang::ARM::BI__builtin_arm_rbit) {
2210 CGM.getIntrinsic(Intrinsic::bitreverse, Arg->getType()), Arg,
"rbit");
2213 if (BuiltinID == clang::ARM::BI__builtin_arm_clz ||
2214 BuiltinID == clang::ARM::BI__builtin_arm_clz64) {
2216 Function *F =
CGM.getIntrinsic(Intrinsic::ctlz, Arg->getType());
2218 if (BuiltinID == clang::ARM::BI__builtin_arm_clz64)
2224 if (BuiltinID == clang::ARM::BI__builtin_arm_cls) {
2226 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::arm_cls), Arg,
"cls");
2228 if (BuiltinID == clang::ARM::BI__builtin_arm_cls64) {
2230 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::arm_cls64), Arg,
2234 if (BuiltinID == clang::ARM::BI__clear_cache) {
2237 Function *F =
CGM.getIntrinsic(Intrinsic::clear_cache, {
CGM.DefaultPtrTy});
2238 return Builder.CreateCall(F, {Begin, End});
2241 if (BuiltinID == clang::ARM::BI__builtin_arm_mcrr ||
2242 BuiltinID == clang::ARM::BI__builtin_arm_mcrr2) {
2245 switch (BuiltinID) {
2246 default: llvm_unreachable(
"unexpected builtin");
2247 case clang::ARM::BI__builtin_arm_mcrr:
2248 F =
CGM.getIntrinsic(Intrinsic::arm_mcrr);
2250 case clang::ARM::BI__builtin_arm_mcrr2:
2251 F =
CGM.getIntrinsic(Intrinsic::arm_mcrr2);
2272 return Builder.CreateCall(F, {Coproc, Opc1, Rt, Rt2, CRm});
2275 if (BuiltinID == clang::ARM::BI__builtin_arm_mrrc ||
2276 BuiltinID == clang::ARM::BI__builtin_arm_mrrc2) {
2279 switch (BuiltinID) {
2280 default: llvm_unreachable(
"unexpected builtin");
2281 case clang::ARM::BI__builtin_arm_mrrc:
2282 F =
CGM.getIntrinsic(Intrinsic::arm_mrrc);
2284 case clang::ARM::BI__builtin_arm_mrrc2:
2285 F =
CGM.getIntrinsic(Intrinsic::arm_mrrc2);
2292 Value *RtAndRt2 =
Builder.CreateCall(F, {Coproc, Opc1, CRm});
2302 Value *ShiftCast = llvm::ConstantInt::get(
Int64Ty, 32);
2303 RtAndRt2 =
Builder.CreateShl(Rt, ShiftCast,
"shl",
true);
2304 RtAndRt2 =
Builder.CreateOr(RtAndRt2, Rt1);
2309 if (BuiltinID == clang::ARM::BI__builtin_arm_ldrexd ||
2310 ((BuiltinID == clang::ARM::BI__builtin_arm_ldrex ||
2311 BuiltinID == clang::ARM::BI__builtin_arm_ldaex) &&
2313 BuiltinID == clang::ARM::BI__ldrexd) {
2316 switch (BuiltinID) {
2317 default: llvm_unreachable(
"unexpected builtin");
2318 case clang::ARM::BI__builtin_arm_ldaex:
2319 F =
CGM.getIntrinsic(Intrinsic::arm_ldaexd);
2321 case clang::ARM::BI__builtin_arm_ldrexd:
2322 case clang::ARM::BI__builtin_arm_ldrex:
2323 case clang::ARM::BI__ldrexd:
2324 F =
CGM.getIntrinsic(Intrinsic::arm_ldrexd);
2337 Val =
Builder.CreateShl(Val0, ShiftCst,
"shl",
true );
2338 Val =
Builder.CreateOr(Val, Val1);
2342 if (BuiltinID == clang::ARM::BI__builtin_arm_ldrex ||
2343 BuiltinID == clang::ARM::BI__builtin_arm_ldaex) {
2352 BuiltinID == clang::ARM::BI__builtin_arm_ldaex ? Intrinsic::arm_ldaex
2353 : Intrinsic::arm_ldrex,
2355 CallInst *Val =
Builder.CreateCall(F, LoadAddr,
"ldrex");
2359 if (RealResTy->isPointerTy())
2360 return Builder.CreateIntToPtr(Val, RealResTy);
2362 llvm::Type *IntResTy = llvm::IntegerType::get(
2364 return Builder.CreateBitCast(
Builder.CreateTruncOrBitCast(Val, IntResTy),
2369 if (BuiltinID == clang::ARM::BI__builtin_arm_strexd ||
2370 ((BuiltinID == clang::ARM::BI__builtin_arm_stlex ||
2371 BuiltinID == clang::ARM::BI__builtin_arm_strex) &&
2374 BuiltinID == clang::ARM::BI__builtin_arm_stlex ? Intrinsic::arm_stlexd
2375 : Intrinsic::arm_strexd);
2380 Builder.CreateStore(Val, Tmp);
2383 Val =
Builder.CreateLoad(LdPtr);
2388 return Builder.CreateCall(F, {Arg0, Arg1, StPtr},
"strexd");
2391 if (BuiltinID == clang::ARM::BI__builtin_arm_strex ||
2392 BuiltinID == clang::ARM::BI__builtin_arm_stlex) {
2397 llvm::Type *StoreTy =
2400 if (StoreVal->
getType()->isPointerTy())
2403 llvm::Type *
IntTy = llvm::IntegerType::get(
2405 CGM.getDataLayout().getTypeSizeInBits(StoreVal->
getType()));
2411 BuiltinID == clang::ARM::BI__builtin_arm_stlex ? Intrinsic::arm_stlex
2412 : Intrinsic::arm_strex,
2415 CallInst *CI =
Builder.CreateCall(F, {StoreVal, StoreAddr},
"strex");
2417 1, Attribute::get(
getLLVMContext(), Attribute::ElementType, StoreTy));
2421 if (BuiltinID == clang::ARM::BI__builtin_arm_clrex) {
2422 Function *F =
CGM.getIntrinsic(Intrinsic::arm_clrex);
2427 Intrinsic::ID CRCIntrinsicID = Intrinsic::not_intrinsic;
2428 switch (BuiltinID) {
2429 case clang::ARM::BI__builtin_arm_crc32b:
2430 CRCIntrinsicID = Intrinsic::arm_crc32b;
break;
2431 case clang::ARM::BI__builtin_arm_crc32cb:
2432 CRCIntrinsicID = Intrinsic::arm_crc32cb;
break;
2433 case clang::ARM::BI__builtin_arm_crc32h:
2434 CRCIntrinsicID = Intrinsic::arm_crc32h;
break;
2435 case clang::ARM::BI__builtin_arm_crc32ch:
2436 CRCIntrinsicID = Intrinsic::arm_crc32ch;
break;
2437 case clang::ARM::BI__builtin_arm_crc32w:
2438 case clang::ARM::BI__builtin_arm_crc32d:
2439 CRCIntrinsicID = Intrinsic::arm_crc32w;
break;
2440 case clang::ARM::BI__builtin_arm_crc32cw:
2441 case clang::ARM::BI__builtin_arm_crc32cd:
2442 CRCIntrinsicID = Intrinsic::arm_crc32cw;
break;
2445 if (CRCIntrinsicID != Intrinsic::not_intrinsic) {
2451 if (BuiltinID == clang::ARM::BI__builtin_arm_crc32d ||
2452 BuiltinID == clang::ARM::BI__builtin_arm_crc32cd) {
2460 return Builder.CreateCall(F, {Res, Arg1b});
2465 return Builder.CreateCall(F, {Arg0, Arg1});
2469 if (BuiltinID == clang::ARM::BI__builtin_arm_rsr ||
2470 BuiltinID == clang::ARM::BI__builtin_arm_rsr64 ||
2471 BuiltinID == clang::ARM::BI__builtin_arm_rsrp ||
2472 BuiltinID == clang::ARM::BI__builtin_arm_wsr ||
2473 BuiltinID == clang::ARM::BI__builtin_arm_wsr64 ||
2474 BuiltinID == clang::ARM::BI__builtin_arm_wsrp) {
2477 if (BuiltinID == clang::ARM::BI__builtin_arm_rsr ||
2478 BuiltinID == clang::ARM::BI__builtin_arm_rsr64 ||
2479 BuiltinID == clang::ARM::BI__builtin_arm_rsrp)
2482 bool IsPointerBuiltin = BuiltinID == clang::ARM::BI__builtin_arm_rsrp ||
2483 BuiltinID == clang::ARM::BI__builtin_arm_wsrp;
2485 bool Is64Bit = BuiltinID == clang::ARM::BI__builtin_arm_rsr64 ||
2486 BuiltinID == clang::ARM::BI__builtin_arm_wsr64;
2488 llvm::Type *ValueType;
2490 if (IsPointerBuiltin) {
2493 }
else if (Is64Bit) {
2503 if (BuiltinID == ARM::BI__builtin_sponentry) {
2522 return P.first == BuiltinID;
2525 BuiltinID = It->second;
2529 unsigned ICEArguments = 0;
2534 auto getAlignmentValue32 = [&](
Address addr) ->
Value* {
2535 return Builder.getInt32(addr.getAlignment().getQuantity());
2542 unsigned NumArgs = E->
getNumArgs() - (HasExtraArg ? 1 : 0);
2543 for (
unsigned i = 0, e = NumArgs; i != e; i++) {
2545 switch (BuiltinID) {
2546 case NEON::BI__builtin_neon_vld1_v:
2547 case NEON::BI__builtin_neon_vld1q_v:
2548 case NEON::BI__builtin_neon_vld1q_lane_v:
2549 case NEON::BI__builtin_neon_vld1_lane_v:
2550 case NEON::BI__builtin_neon_vld1_dup_v:
2551 case NEON::BI__builtin_neon_vld1q_dup_v:
2552 case NEON::BI__builtin_neon_vst1_v:
2553 case NEON::BI__builtin_neon_vst1q_v:
2554 case NEON::BI__builtin_neon_vst1q_lane_v:
2555 case NEON::BI__builtin_neon_vst1_lane_v:
2556 case NEON::BI__builtin_neon_vst2_v:
2557 case NEON::BI__builtin_neon_vst2q_v:
2558 case NEON::BI__builtin_neon_vst2_lane_v:
2559 case NEON::BI__builtin_neon_vst2q_lane_v:
2560 case NEON::BI__builtin_neon_vst3_v:
2561 case NEON::BI__builtin_neon_vst3q_v:
2562 case NEON::BI__builtin_neon_vst3_lane_v:
2563 case NEON::BI__builtin_neon_vst3q_lane_v:
2564 case NEON::BI__builtin_neon_vst4_v:
2565 case NEON::BI__builtin_neon_vst4q_v:
2566 case NEON::BI__builtin_neon_vst4_lane_v:
2567 case NEON::BI__builtin_neon_vst4q_lane_v:
2576 switch (BuiltinID) {
2577 case NEON::BI__builtin_neon_vld2_v:
2578 case NEON::BI__builtin_neon_vld2q_v:
2579 case NEON::BI__builtin_neon_vld3_v:
2580 case NEON::BI__builtin_neon_vld3q_v:
2581 case NEON::BI__builtin_neon_vld4_v:
2582 case NEON::BI__builtin_neon_vld4q_v:
2583 case NEON::BI__builtin_neon_vld2_lane_v:
2584 case NEON::BI__builtin_neon_vld2q_lane_v:
2585 case NEON::BI__builtin_neon_vld3_lane_v:
2586 case NEON::BI__builtin_neon_vld3q_lane_v:
2587 case NEON::BI__builtin_neon_vld4_lane_v:
2588 case NEON::BI__builtin_neon_vld4q_lane_v:
2589 case NEON::BI__builtin_neon_vld2_dup_v:
2590 case NEON::BI__builtin_neon_vld2q_dup_v:
2591 case NEON::BI__builtin_neon_vld3_dup_v:
2592 case NEON::BI__builtin_neon_vld3q_dup_v:
2593 case NEON::BI__builtin_neon_vld4_dup_v:
2594 case NEON::BI__builtin_neon_vld4q_dup_v:
2606 switch (BuiltinID) {
2609 case NEON::BI__builtin_neon_vget_lane_i8:
2610 case NEON::BI__builtin_neon_vget_lane_i16:
2611 case NEON::BI__builtin_neon_vget_lane_i32:
2612 case NEON::BI__builtin_neon_vget_lane_i64:
2613 case NEON::BI__builtin_neon_vget_lane_bf16:
2614 case NEON::BI__builtin_neon_vget_lane_f32:
2615 case NEON::BI__builtin_neon_vgetq_lane_i8:
2616 case NEON::BI__builtin_neon_vgetq_lane_i16:
2617 case NEON::BI__builtin_neon_vgetq_lane_i32:
2618 case NEON::BI__builtin_neon_vgetq_lane_i64:
2619 case NEON::BI__builtin_neon_vgetq_lane_bf16:
2620 case NEON::BI__builtin_neon_vgetq_lane_f32:
2621 case NEON::BI__builtin_neon_vduph_lane_bf16:
2622 case NEON::BI__builtin_neon_vduph_laneq_bf16:
2623 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vget_lane");
2625 case NEON::BI__builtin_neon_vrndns_f32: {
2627 llvm::Type *Tys[] = {Arg->
getType()};
2628 Function *F =
CGM.getIntrinsic(Intrinsic::roundeven, Tys);
2629 return Builder.CreateCall(F, {Arg},
"vrndn"); }
2631 case NEON::BI__builtin_neon_vset_lane_i8:
2632 case NEON::BI__builtin_neon_vset_lane_i16:
2633 case NEON::BI__builtin_neon_vset_lane_i32:
2634 case NEON::BI__builtin_neon_vset_lane_i64:
2635 case NEON::BI__builtin_neon_vset_lane_bf16:
2636 case NEON::BI__builtin_neon_vset_lane_f32:
2637 case NEON::BI__builtin_neon_vsetq_lane_i8:
2638 case NEON::BI__builtin_neon_vsetq_lane_i16:
2639 case NEON::BI__builtin_neon_vsetq_lane_i32:
2640 case NEON::BI__builtin_neon_vsetq_lane_i64:
2641 case NEON::BI__builtin_neon_vsetq_lane_bf16:
2642 case NEON::BI__builtin_neon_vsetq_lane_f32:
2643 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2],
"vset_lane");
2645 case NEON::BI__builtin_neon_vsha1h_u32:
2648 case NEON::BI__builtin_neon_vsha1cq_u32:
2651 case NEON::BI__builtin_neon_vsha1pq_u32:
2654 case NEON::BI__builtin_neon_vsha1mq_u32:
2658 case NEON::BI__builtin_neon_vcvth_bf16_f32:
2659 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::arm_neon_vcvtbfp2bf), Ops,
2661 case NEON::BI__builtin_neon_vcvt_f16_f32:
2662 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::arm_neon_vcvtfp2hf), Ops,
2664 case NEON::BI__builtin_neon_vcvt_f32_f16:
2665 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::arm_neon_vcvthf2fp), Ops,
2670 case clang::ARM::BI_MoveToCoprocessor:
2671 case clang::ARM::BI_MoveToCoprocessor2: {
2672 Function *F =
CGM.getIntrinsic(BuiltinID == clang::ARM::BI_MoveToCoprocessor
2673 ? Intrinsic::arm_mcr
2674 : Intrinsic::arm_mcr2);
2675 return Builder.CreateCall(F, {Ops[1], Ops[2], Ops[0],
2676 Ops[3], Ops[4], Ops[5]});
2681 assert(HasExtraArg);
2683 std::optional<llvm::APSInt>
Result =
2688 if (BuiltinID == clang::ARM::BI__builtin_arm_vcvtr_f ||
2689 BuiltinID == clang::ARM::BI__builtin_arm_vcvtr_d) {
2692 if (BuiltinID == clang::ARM::BI__builtin_arm_vcvtr_f)
2698 bool usgn =
Result->getZExtValue() == 1;
2699 unsigned Int = usgn ? Intrinsic::arm_vcvtru : Intrinsic::arm_vcvtr;
2703 return Builder.CreateCall(F, Ops,
"vcvtr");
2708 bool usgn =
Type.isUnsigned();
2709 bool rightShift =
false;
2711 llvm::FixedVectorType *VTy =
2714 llvm::Type *Ty = VTy;
2729 switch (BuiltinID) {
2730 default:
return nullptr;
2731 case NEON::BI__builtin_neon_vld1q_lane_v:
2734 if (VTy->getElementType()->isIntegerTy(64)) {
2736 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
2738 Value *SV = llvm::ConstantVector::get(ConstantInt::get(
Int32Ty, 1-Lane));
2739 Ops[1] =
Builder.CreateShuffleVector(Ops[1], Ops[1], SV);
2741 Ty = llvm::FixedVectorType::get(VTy->getElementType(), 1);
2743 Function *F =
CGM.getIntrinsic(Intrinsic::arm_neon_vld1, Tys);
2744 Value *Align = getAlignmentValue32(PtrOp0);
2747 int Indices[] = {1 - Lane, Lane};
2748 return Builder.CreateShuffleVector(Ops[1], Ld, Indices,
"vld1q_lane");
2751 case NEON::BI__builtin_neon_vld1_lane_v: {
2752 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
2755 return Builder.CreateInsertElement(Ops[1], Ld, Ops[2],
"vld1_lane");
2757 case NEON::BI__builtin_neon_vqrshrn_n_v:
2759 usgn ? Intrinsic::arm_neon_vqrshiftnu : Intrinsic::arm_neon_vqrshiftns;
2762 case NEON::BI__builtin_neon_vqrshrun_n_v:
2763 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::arm_neon_vqrshiftnsu, Ty),
2764 Ops,
"vqrshrun_n", 1,
true);
2765 case NEON::BI__builtin_neon_vqshrn_n_v:
2766 Int = usgn ? Intrinsic::arm_neon_vqshiftnu : Intrinsic::arm_neon_vqshiftns;
2769 case NEON::BI__builtin_neon_vqshrun_n_v:
2770 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::arm_neon_vqshiftnsu, Ty),
2771 Ops,
"vqshrun_n", 1,
true);
2772 case NEON::BI__builtin_neon_vrecpe_v:
2773 case NEON::BI__builtin_neon_vrecpeq_v:
2776 case NEON::BI__builtin_neon_vrshrn_n_v:
2777 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::arm_neon_vrshiftn, Ty),
2778 Ops,
"vrshrn_n", 1,
true);
2779 case NEON::BI__builtin_neon_vrsra_n_v:
2780 case NEON::BI__builtin_neon_vrsraq_n_v:
2781 Ops[0] =
Builder.CreateBitCast(Ops[0], Ty);
2782 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
2784 Int = usgn ? Intrinsic::arm_neon_vrshiftu : Intrinsic::arm_neon_vrshifts;
2785 Ops[1] =
Builder.CreateCall(
CGM.getIntrinsic(
Int, Ty), {Ops[1], Ops[2]});
2786 return Builder.CreateAdd(Ops[0], Ops[1],
"vrsra_n");
2787 case NEON::BI__builtin_neon_vsri_n_v:
2788 case NEON::BI__builtin_neon_vsriq_n_v:
2791 case NEON::BI__builtin_neon_vsli_n_v:
2792 case NEON::BI__builtin_neon_vsliq_n_v:
2794 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::arm_neon_vshiftins, Ty),
2796 case NEON::BI__builtin_neon_vsra_n_v:
2797 case NEON::BI__builtin_neon_vsraq_n_v:
2798 Ops[0] =
Builder.CreateBitCast(Ops[0], Ty);
2800 return Builder.CreateAdd(Ops[0], Ops[1]);
2801 case NEON::BI__builtin_neon_vst1q_lane_v:
2804 if (VTy->getElementType()->isIntegerTy(64)) {
2805 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
2807 Ops[1] =
Builder.CreateShuffleVector(Ops[1], Ops[1], SV);
2808 Ops[2] = getAlignmentValue32(PtrOp0);
2809 llvm::Type *Tys[] = {
Int8PtrTy, Ops[1]->getType()};
2810 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::arm_neon_vst1,
2814 case NEON::BI__builtin_neon_vst1_lane_v: {
2815 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
2816 Ops[1] =
Builder.CreateExtractElement(Ops[1], Ops[2]);
2817 return Builder.CreateStore(Ops[1],
2820 case NEON::BI__builtin_neon_vtbl1_v:
2823 case NEON::BI__builtin_neon_vtbl2_v:
2826 case NEON::BI__builtin_neon_vtbl3_v:
2829 case NEON::BI__builtin_neon_vtbl4_v:
2832 case NEON::BI__builtin_neon_vtbx1_v:
2835 case NEON::BI__builtin_neon_vtbx2_v:
2838 case NEON::BI__builtin_neon_vtbx3_v:
2841 case NEON::BI__builtin_neon_vtbx4_v:
4472 llvm::Triple::ArchType
Arch) {
4481 if (BuiltinID == Builtin::BI__builtin_cpu_supports)
4482 return EmitAArch64CpuSupports(E);
4484 unsigned HintID =
static_cast<unsigned>(-1);
4485 switch (BuiltinID) {
4487 case clang::AArch64::BI__builtin_arm_nop:
4490 case clang::AArch64::BI__builtin_arm_yield:
4491 case clang::AArch64::BI__yield:
4494 case clang::AArch64::BI__builtin_arm_wfe:
4495 case clang::AArch64::BI__wfe:
4498 case clang::AArch64::BI__builtin_arm_wfi:
4499 case clang::AArch64::BI__wfi:
4502 case clang::AArch64::BI__builtin_arm_sev:
4503 case clang::AArch64::BI__sev:
4506 case clang::AArch64::BI__builtin_arm_sevl:
4507 case clang::AArch64::BI__sevl:
4512 if (HintID !=
static_cast<unsigned>(-1)) {
4513 Function *F =
CGM.getIntrinsic(Intrinsic::aarch64_hint);
4514 return Builder.CreateCall(F, llvm::ConstantInt::get(
Int32Ty, HintID));
4517 if (BuiltinID == clang::AArch64::BI__builtin_arm_trap) {
4518 Function *F =
CGM.getIntrinsic(Intrinsic::aarch64_break);
4523 if (BuiltinID == clang::AArch64::BI__builtin_arm_get_sme_state) {
4526 llvm::FunctionType::get(StructType::get(
CGM.Int64Ty,
CGM.Int64Ty), {},
4528 "__arm_sme_state"));
4530 "aarch64_pstate_sm_compatible");
4531 CI->setAttributes(Attrs);
4534 AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2);
4541 if (BuiltinID == clang::AArch64::BI__builtin_arm_rbit) {
4543 "rbit of unusual size!");
4546 CGM.getIntrinsic(Intrinsic::bitreverse, Arg->getType()), Arg,
"rbit");
4548 if (BuiltinID == clang::AArch64::BI__builtin_arm_rbit64) {
4550 "rbit of unusual size!");
4553 CGM.getIntrinsic(Intrinsic::bitreverse, Arg->getType()), Arg,
"rbit");
4556 if (BuiltinID == clang::AArch64::BI__builtin_arm_clz ||
4557 BuiltinID == clang::AArch64::BI__builtin_arm_clz64) {
4559 Function *F =
CGM.getIntrinsic(Intrinsic::ctlz, Arg->getType());
4561 if (BuiltinID == clang::AArch64::BI__builtin_arm_clz64)
4566 if (BuiltinID == clang::AArch64::BI__builtin_arm_cls) {
4568 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::aarch64_cls), Arg,
4571 if (BuiltinID == clang::AArch64::BI__builtin_arm_cls64) {
4573 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::aarch64_cls64), Arg,
4577 if (BuiltinID == clang::AArch64::BI__builtin_arm_rint32zf ||
4578 BuiltinID == clang::AArch64::BI__builtin_arm_rint32z) {
4580 llvm::Type *Ty = Arg->getType();
4581 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::aarch64_frint32z, Ty),
4585 if (BuiltinID == clang::AArch64::BI__builtin_arm_rint64zf ||
4586 BuiltinID == clang::AArch64::BI__builtin_arm_rint64z) {
4588 llvm::Type *Ty = Arg->getType();
4589 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::aarch64_frint64z, Ty),
4593 if (BuiltinID == clang::AArch64::BI__builtin_arm_rint32xf ||
4594 BuiltinID == clang::AArch64::BI__builtin_arm_rint32x) {
4596 llvm::Type *Ty = Arg->getType();
4597 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::aarch64_frint32x, Ty),
4601 if (BuiltinID == clang::AArch64::BI__builtin_arm_rint64xf ||
4602 BuiltinID == clang::AArch64::BI__builtin_arm_rint64x) {
4604 llvm::Type *Ty = Arg->getType();
4605 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::aarch64_frint64x, Ty),
4609 if (BuiltinID == clang::AArch64::BI__builtin_arm_jcvt) {
4611 "__jcvt of unusual size!");
4614 CGM.getIntrinsic(Intrinsic::aarch64_fjcvtzs), Arg);
4617 if (BuiltinID == clang::AArch64::BI__builtin_arm_ld64b ||
4618 BuiltinID == clang::AArch64::BI__builtin_arm_st64b ||
4619 BuiltinID == clang::AArch64::BI__builtin_arm_st64bv ||
4620 BuiltinID == clang::AArch64::BI__builtin_arm_st64bv0) {
4624 if (BuiltinID == clang::AArch64::BI__builtin_arm_ld64b) {
4627 Function *F =
CGM.getIntrinsic(Intrinsic::aarch64_ld64b);
4628 llvm::Value *Val =
Builder.CreateCall(F, MemAddr);
4630 for (
size_t i = 0; i < 8; i++) {
4631 llvm::Value *ValOffsetPtr =
4643 Args.push_back(MemAddr);
4644 for (
size_t i = 0; i < 8; i++) {
4645 llvm::Value *ValOffsetPtr =
4651 auto Intr = (BuiltinID == clang::AArch64::BI__builtin_arm_st64b
4652 ? Intrinsic::aarch64_st64b
4653 : BuiltinID == clang::AArch64::BI__builtin_arm_st64bv
4654 ? Intrinsic::aarch64_st64bv
4655 : Intrinsic::aarch64_st64bv0);
4657 return Builder.CreateCall(F, Args);
4660 if (BuiltinID == clang::AArch64::BI__builtin_arm_rndr ||
4661 BuiltinID == clang::AArch64::BI__builtin_arm_rndrrs) {
4663 auto Intr = (BuiltinID == clang::AArch64::BI__builtin_arm_rndr
4664 ? Intrinsic::aarch64_rndr
4665 : Intrinsic::aarch64_rndrrs);
4667 llvm::Value *Val =
Builder.CreateCall(F);
4668 Value *RandomValue =
Builder.CreateExtractValue(Val, 0);
4672 Builder.CreateStore(RandomValue, MemAddress);
4677 if (BuiltinID == clang::AArch64::BI__clear_cache) {
4680 Function *F =
CGM.getIntrinsic(Intrinsic::clear_cache, {
CGM.DefaultPtrTy});
4681 return Builder.CreateCall(F, {Begin, End});
4684 if ((BuiltinID == clang::AArch64::BI__builtin_arm_ldrex ||
4685 BuiltinID == clang::AArch64::BI__builtin_arm_ldaex) &&
4688 CGM.getIntrinsic(BuiltinID == clang::AArch64::BI__builtin_arm_ldaex
4689 ? Intrinsic::aarch64_ldaxp
4690 : Intrinsic::aarch64_ldxp);
4697 llvm::Type *Int128Ty = llvm::IntegerType::get(
getLLVMContext(), 128);
4698 Val0 =
Builder.CreateZExt(Val0, Int128Ty);
4699 Val1 =
Builder.CreateZExt(Val1, Int128Ty);
4701 Value *ShiftCst = llvm::ConstantInt::get(Int128Ty, 64);
4702 Val =
Builder.CreateShl(Val0, ShiftCst,
"shl",
true );
4703 Val =
Builder.CreateOr(Val, Val1);
4705 }
else if (BuiltinID == clang::AArch64::BI__builtin_arm_ldrex ||
4706 BuiltinID == clang::AArch64::BI__builtin_arm_ldaex) {
4715 CGM.getIntrinsic(BuiltinID == clang::AArch64::BI__builtin_arm_ldaex
4716 ? Intrinsic::aarch64_ldaxr
4717 : Intrinsic::aarch64_ldxr,
4719 CallInst *Val =
Builder.CreateCall(F, LoadAddr,
"ldxr");
4723 if (RealResTy->isPointerTy())
4724 return Builder.CreateIntToPtr(Val, RealResTy);
4726 llvm::Type *IntResTy = llvm::IntegerType::get(
4728 return Builder.CreateBitCast(
Builder.CreateTruncOrBitCast(Val, IntResTy),
4732 if ((BuiltinID == clang::AArch64::BI__builtin_arm_strex ||
4733 BuiltinID == clang::AArch64::BI__builtin_arm_stlex) &&
4736 CGM.getIntrinsic(BuiltinID == clang::AArch64::BI__builtin_arm_stlex
4737 ? Intrinsic::aarch64_stlxp
4738 : Intrinsic::aarch64_stxp);
4745 llvm::Value *Val =
Builder.CreateLoad(Tmp);
4750 return Builder.CreateCall(F, {Arg0, Arg1, StPtr},
"stxp");
4753 if (BuiltinID == clang::AArch64::BI__builtin_arm_strex ||
4754 BuiltinID == clang::AArch64::BI__builtin_arm_stlex) {
4759 llvm::Type *StoreTy =
4762 if (StoreVal->
getType()->isPointerTy())
4765 llvm::Type *
IntTy = llvm::IntegerType::get(
4767 CGM.getDataLayout().getTypeSizeInBits(StoreVal->
getType()));
4773 CGM.getIntrinsic(BuiltinID == clang::AArch64::BI__builtin_arm_stlex
4774 ? Intrinsic::aarch64_stlxr
4775 : Intrinsic::aarch64_stxr,
4777 CallInst *CI =
Builder.CreateCall(F, {StoreVal, StoreAddr},
"stxr");
4779 1, Attribute::get(
getLLVMContext(), Attribute::ElementType, StoreTy));
4783 if (BuiltinID == clang::AArch64::BI__getReg ||
4784 BuiltinID == clang::AArch64::BI__setReg) {
4787 llvm_unreachable(
"Sema will ensure that the parameter is constant");
4790 LLVMContext &Context =
CGM.getLLVMContext();
4793 llvm::Metadata *Ops[] = {llvm::MDString::get(Context, Reg)};
4794 llvm::MDNode *RegName = llvm::MDNode::get(Context, Ops);
4795 llvm::Value *Metadata = llvm::MetadataAsValue::get(Context, RegName);
4798 if (BuiltinID == clang::AArch64::BI__getReg) {
4800 CGM.getIntrinsic(Intrinsic::read_volatile_register, {
Int64Ty});
4801 CI =
Builder.CreateCall(F, Metadata);
4804 CGM.getIntrinsic(Intrinsic::write_volatile_register, {
Int64Ty});
4810 if (BuiltinID == clang::AArch64::BI__getRegFp ||
4811 BuiltinID == clang::AArch64::BI__setRegFp) {
4814 llvm_unreachable(
"Sema will ensure that the parameter is constant");
4817 LLVMContext &Context =
CGM.getLLVMContext();
4820 llvm::Metadata *Ops[] = {llvm::MDString::get(Context, Reg)};
4821 llvm::MDNode *RegName = llvm::MDNode::get(Context, Ops);
4822 llvm::Value *Metadata = llvm::MetadataAsValue::get(Context, RegName);
4825 if (BuiltinID == clang::AArch64::BI__getRegFp) {
4827 CGM.getIntrinsic(Intrinsic::read_volatile_register, {
Int64Ty});
4828 llvm::Value *Bits =
Builder.CreateCall(F, Metadata);
4829 Ret =
Builder.CreateBitCast(Bits, llvm::Type::getDoubleTy(Context));
4834 CGM.getIntrinsic(Intrinsic::write_volatile_register, {
Int64Ty});
4835 Ret =
Builder.CreateCall(F, {Metadata, Bits});
4840 if (BuiltinID == clang::AArch64::BI__break) {
4843 llvm_unreachable(
"Sema will ensure that the parameter is constant");
4845 llvm::Function *F =
CGM.getIntrinsic(Intrinsic::aarch64_break);
4849 if (BuiltinID == clang::AArch64::BI__builtin_arm_clrex) {
4850 Function *F =
CGM.getIntrinsic(Intrinsic::aarch64_clrex);
4854 if (BuiltinID == clang::AArch64::BI_ReadWriteBarrier)
4855 return Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent,
4856 llvm::SyncScope::SingleThread);
4859 Intrinsic::ID CRCIntrinsicID = Intrinsic::not_intrinsic;
4860 switch (BuiltinID) {
4861 case clang::AArch64::BI__builtin_arm_crc32b:
4862 CRCIntrinsicID = Intrinsic::aarch64_crc32b;
break;
4863 case clang::AArch64::BI__builtin_arm_crc32cb:
4864 CRCIntrinsicID = Intrinsic::aarch64_crc32cb;
break;
4865 case clang::AArch64::BI__builtin_arm_crc32h:
4866 CRCIntrinsicID = Intrinsic::aarch64_crc32h;
break;
4867 case clang::AArch64::BI__builtin_arm_crc32ch:
4868 CRCIntrinsicID = Intrinsic::aarch64_crc32ch;
break;
4869 case clang::AArch64::BI__builtin_arm_crc32w:
4870 CRCIntrinsicID = Intrinsic::aarch64_crc32w;
break;
4871 case clang::AArch64::BI__builtin_arm_crc32cw:
4872 CRCIntrinsicID = Intrinsic::aarch64_crc32cw;
break;
4873 case clang::AArch64::BI__builtin_arm_crc32d:
4874 CRCIntrinsicID = Intrinsic::aarch64_crc32x;
break;
4875 case clang::AArch64::BI__builtin_arm_crc32cd:
4876 CRCIntrinsicID = Intrinsic::aarch64_crc32cx;
break;
4879 if (CRCIntrinsicID != Intrinsic::not_intrinsic) {
4884 llvm::Type *DataTy = F->getFunctionType()->getParamType(1);
4885 Arg1 =
Builder.CreateZExtOrBitCast(Arg1, DataTy);
4887 return Builder.CreateCall(F, {Arg0, Arg1});
4891 if (BuiltinID == AArch64::BI__builtin_arm_mops_memset_tag) {
4898 CGM.getIntrinsic(Intrinsic::aarch64_mops_memset_tag), {Dst, Val, Size});
4901 if (BuiltinID == AArch64::BI__builtin_arm_range_prefetch ||
4902 BuiltinID == AArch64::BI__builtin_arm_range_prefetch_x)
4905 if (BuiltinID == AArch64::BI__builtin_arm_atomic_store_with_hint)
4909 Intrinsic::ID MTEIntrinsicID = Intrinsic::not_intrinsic;
4910 switch (BuiltinID) {
4911 case clang::AArch64::BI__builtin_arm_irg:
4912 MTEIntrinsicID = Intrinsic::aarch64_irg;
break;
4913 case clang::AArch64::BI__builtin_arm_addg:
4914 MTEIntrinsicID = Intrinsic::aarch64_addg;
break;
4915 case clang::AArch64::BI__builtin_arm_gmi:
4916 MTEIntrinsicID = Intrinsic::aarch64_gmi;
break;
4917 case clang::AArch64::BI__builtin_arm_ldg:
4918 MTEIntrinsicID = Intrinsic::aarch64_ldg;
break;
4919 case clang::AArch64::BI__builtin_arm_stg:
4920 MTEIntrinsicID = Intrinsic::aarch64_stg;
break;
4921 case clang::AArch64::BI__builtin_arm_subp:
4922 MTEIntrinsicID = Intrinsic::aarch64_subp;
break;
4925 if (MTEIntrinsicID != Intrinsic::not_intrinsic) {
4926 if (MTEIntrinsicID == Intrinsic::aarch64_irg) {
4929 assert(Mask->
getType()->getScalarSizeInBits() == 64 &&
4930 "SemaARM::BuiltinARMMemoryTaggingCall() enforces this");
4931 return Builder.CreateCall(
CGM.getIntrinsic(MTEIntrinsicID),
4934 if (MTEIntrinsicID == Intrinsic::aarch64_addg) {
4939 return Builder.CreateCall(
CGM.getIntrinsic(MTEIntrinsicID),
4940 {Pointer, TagOffset});
4942 if (MTEIntrinsicID == Intrinsic::aarch64_gmi) {
4945 assert(ExcludedMask->
getType()->getScalarSizeInBits() == 64 &&
4946 "SemaARM::BuiltinARMMemoryTaggingCall() enforces this");
4947 return Builder.CreateCall(
CGM.getIntrinsic(MTEIntrinsicID),
4948 {Pointer, ExcludedMask});
4953 if (MTEIntrinsicID == Intrinsic::aarch64_ldg) {
4955 return Builder.CreateCall(
CGM.getIntrinsic(MTEIntrinsicID),
4956 {TagAddress, TagAddress});
4961 if (MTEIntrinsicID == Intrinsic::aarch64_stg) {
4963 return Builder.CreateCall(
CGM.getIntrinsic(MTEIntrinsicID),
4964 {TagAddress, TagAddress});
4966 if (MTEIntrinsicID == Intrinsic::aarch64_subp) {
4970 CGM.getIntrinsic(MTEIntrinsicID), {PointerA, PointerB});
4974 if (BuiltinID == clang::AArch64::BI__builtin_arm_rsr ||
4975 BuiltinID == clang::AArch64::BI__builtin_arm_rsr64 ||
4976 BuiltinID == clang::AArch64::BI__builtin_arm_rsr128 ||
4977 BuiltinID == clang::AArch64::BI__builtin_arm_rsrp ||
4978 BuiltinID == clang::AArch64::BI__builtin_arm_wsr ||
4979 BuiltinID == clang::AArch64::BI__builtin_arm_wsr64 ||
4980 BuiltinID == clang::AArch64::BI__builtin_arm_wsr128 ||
4981 BuiltinID == clang::AArch64::BI__builtin_arm_wsrp) {
4984 if (BuiltinID == clang::AArch64::BI__builtin_arm_rsr ||
4985 BuiltinID == clang::AArch64::BI__builtin_arm_rsr64 ||
4986 BuiltinID == clang::AArch64::BI__builtin_arm_rsr128 ||
4987 BuiltinID == clang::AArch64::BI__builtin_arm_rsrp)
4990 bool IsPointerBuiltin = BuiltinID == clang::AArch64::BI__builtin_arm_rsrp ||
4991 BuiltinID == clang::AArch64::BI__builtin_arm_wsrp;
4993 bool Is32Bit = BuiltinID == clang::AArch64::BI__builtin_arm_rsr ||
4994 BuiltinID == clang::AArch64::BI__builtin_arm_wsr;
4996 bool Is128Bit = BuiltinID == clang::AArch64::BI__builtin_arm_rsr128 ||
4997 BuiltinID == clang::AArch64::BI__builtin_arm_wsr128;
4999 llvm::Type *ValueType;
5003 }
else if (Is128Bit) {
5004 llvm::Type *Int128Ty =
5005 llvm::IntegerType::getInt128Ty(
CGM.getLLVMContext());
5006 ValueType = Int128Ty;
5008 }
else if (IsPointerBuiltin) {
5018 if (BuiltinID == clang::AArch64::BI_ReadStatusReg ||
5019 BuiltinID == clang::AArch64::BI_WriteStatusReg) {
5020 LLVMContext &Context =
CGM.getLLVMContext();
5025 std::string SysRegStr;
5026 llvm::raw_string_ostream(SysRegStr)
5027 << (0b10 | SysReg >> 14) <<
":" << ((SysReg >> 11) & 7) <<
":"
5028 << ((SysReg >> 7) & 15) <<
":" << ((SysReg >> 3) & 15) <<
":"
5031 llvm::Metadata *Ops[] = { llvm::MDString::get(Context, SysRegStr) };
5032 llvm::MDNode *RegName = llvm::MDNode::get(Context, Ops);
5033 llvm::Value *Metadata = llvm::MetadataAsValue::get(Context, RegName);
5038 if (BuiltinID == clang::AArch64::BI_ReadStatusReg) {
5039 llvm::Function *F =
CGM.getIntrinsic(Intrinsic::read_register, Types);
5041 return Builder.CreateCall(F, Metadata);
5044 llvm::Function *F =
CGM.getIntrinsic(Intrinsic::write_register, Types);
5046 llvm::Value *
Result =
Builder.CreateCall(F, {Metadata, ArgValue});
5051 if (BuiltinID == clang::AArch64::BI__sys) {
5054 const unsigned Op1 = SysReg >> 11;
5055 const unsigned CRn = (SysReg >> 7) & 0xf;
5056 const unsigned CRm = (SysReg >> 3) & 0xf;
5057 const unsigned Op2 = SysReg & 0x7;
5059 Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::aarch64_sys),
5060 {Builder.getInt32(Op1), Builder.getInt32(CRn),
5061 Builder.getInt32(CRm), Builder.getInt32(Op2),
5062 EmitScalarExpr(E->getArg(1))});
5066 return ConstantInt::get(
Builder.getInt32Ty(), 0);
5069 if (BuiltinID == clang::AArch64::BI_AddressOfReturnAddress) {
5075 if (BuiltinID == clang::AArch64::BI__builtin_sponentry) {
5080 if (BuiltinID == clang::AArch64::BI__mulh ||
5081 BuiltinID == clang::AArch64::BI__umulh) {
5083 llvm::Type *Int128Ty = llvm::IntegerType::get(
getLLVMContext(), 128);
5085 bool IsSigned = BuiltinID == clang::AArch64::BI__mulh;
5091 Value *MulResult, *HigherBits;
5093 MulResult =
Builder.CreateNSWMul(LHS, RHS);
5094 HigherBits =
Builder.CreateAShr(MulResult, 64);
5096 MulResult =
Builder.CreateNUWMul(LHS, RHS);
5097 HigherBits =
Builder.CreateLShr(MulResult, 64);
5099 HigherBits =
Builder.CreateIntCast(HigherBits, ResType, IsSigned);
5104 if (BuiltinID == AArch64::BI__writex18byte ||
5105 BuiltinID == AArch64::BI__writex18word ||
5106 BuiltinID == AArch64::BI__writex18dword ||
5107 BuiltinID == AArch64::BI__writex18qword) {
5123 if (BuiltinID == AArch64::BI__readx18byte ||
5124 BuiltinID == AArch64::BI__readx18word ||
5125 BuiltinID == AArch64::BI__readx18dword ||
5126 BuiltinID == AArch64::BI__readx18qword) {
5141 if (BuiltinID == AArch64::BI__addx18byte ||
5142 BuiltinID == AArch64::BI__addx18word ||
5143 BuiltinID == AArch64::BI__addx18dword ||
5144 BuiltinID == AArch64::BI__addx18qword ||
5145 BuiltinID == AArch64::BI__incx18byte ||
5146 BuiltinID == AArch64::BI__incx18word ||
5147 BuiltinID == AArch64::BI__incx18dword ||
5148 BuiltinID == AArch64::BI__incx18qword) {
5151 switch (BuiltinID) {
5152 case AArch64::BI__incx18byte:
5156 case AArch64::BI__incx18word:
5160 case AArch64::BI__incx18dword:
5164 case AArch64::BI__incx18qword:
5170 isIncrement =
false;
5195 if (BuiltinID == AArch64::BI_CopyDoubleFromInt64 ||
5196 BuiltinID == AArch64::BI_CopyFloatFromInt32 ||
5197 BuiltinID == AArch64::BI_CopyInt32FromFloat ||
5198 BuiltinID == AArch64::BI_CopyInt64FromDouble) {
5201 return Builder.CreateBitCast(Arg, RetTy);
5204 if (BuiltinID == AArch64::BI_CountLeadingOnes ||
5205 BuiltinID == AArch64::BI_CountLeadingOnes64 ||
5206 BuiltinID == AArch64::BI_CountLeadingZeros ||
5207 BuiltinID == AArch64::BI_CountLeadingZeros64) {
5211 if (BuiltinID == AArch64::BI_CountLeadingOnes ||
5212 BuiltinID == AArch64::BI_CountLeadingOnes64)
5213 Arg =
Builder.CreateXor(Arg, Constant::getAllOnesValue(
ArgType));
5218 if (BuiltinID == AArch64::BI_CountLeadingOnes64 ||
5219 BuiltinID == AArch64::BI_CountLeadingZeros64)
5224 if (BuiltinID == AArch64::BI_CountLeadingSigns ||
5225 BuiltinID == AArch64::BI_CountLeadingSigns64) {
5228 Function *F = (BuiltinID == AArch64::BI_CountLeadingSigns)
5229 ?
CGM.getIntrinsic(Intrinsic::aarch64_cls)
5230 :
CGM.getIntrinsic(Intrinsic::aarch64_cls64);
5233 if (BuiltinID == AArch64::BI_CountLeadingSigns64)
5238 if (BuiltinID == AArch64::BI_CountOneBits ||
5239 BuiltinID == AArch64::BI_CountOneBits64) {
5245 if (BuiltinID == AArch64::BI_CountOneBits64)
5250 if (BuiltinID == AArch64::BI_CountTrailingZeros ||
5251 BuiltinID == AArch64::BI_CountTrailingZeros64) {
5258 if (BuiltinID == AArch64::BI_CountTrailingZeros64)
5263 if (BuiltinID == AArch64::BI__prefetch) {
5272 if (BuiltinID == AArch64::BI__prefetch2) {
5280 uint64_t Op = PrfOp.getZExtValue();
5281 uint64_t
Type = (Op >> 3) & 0x3;
5282 uint64_t
Target = (Op >> 1) & 0x3;
5283 uint64_t Policy = Op & 0x1;
5288 Function *F =
CGM.getIntrinsic(Intrinsic::aarch64_prefetch);
5292 if (BuiltinID == AArch64::BI__hlt) {
5293 Function *F =
CGM.getIntrinsic(Intrinsic::aarch64_hlt);
5299 return ConstantInt::get(
Builder.getInt32Ty(), 0);
5302 if (BuiltinID == AArch64::BI__hvc || BuiltinID == AArch64::BI__svc) {
5303 unsigned IID = BuiltinID == AArch64::BI__svc ? Intrinsic::aarch64_svc
5304 : Intrinsic::aarch64_hvc;
5312 for (
unsigned I = 1, N = E->
getNumArgs(); I < N; ++I) {
5314 llvm::Type *ArgTy = Arg->
getType();
5315 if (ArgTy->isPointerTy())
5317 else if (ArgTy->isFloatingPointTy())
5320 Arg =
Builder.CreateZExtOrTrunc(
5322 Arg,
Builder.getIntNTy(ArgTy->getPrimitiveSizeInBits())),
5327 Args.push_back(Arg);
5329 while (Args.size() < 5)
5330 Args.push_back(llvm::PoisonValue::get(
Int64Ty));
5336 if (BuiltinID == NEON::BI__builtin_neon_vcvth_bf16_f32)
5344 if (std::optional<MSVCIntrin> MsvcIntId =
5350 return P.first == BuiltinID;
5353 BuiltinID = It->second;
5359 bool IsSISD = (
Builtin !=
nullptr);
5363 unsigned ICEArguments = 0;
5374 unsigned NumArgs = E->
getNumArgs() - (HasExtraArg ? 1 : 0);
5375 for (
unsigned i = 0, e = NumArgs; i != e; i++) {
5377 switch (BuiltinID) {
5378 case NEON::BI__builtin_neon_vld1_v:
5379 case NEON::BI__builtin_neon_vld1q_v:
5380 case NEON::BI__builtin_neon_vld1_dup_v:
5381 case NEON::BI__builtin_neon_vld1q_dup_v:
5382 case NEON::BI__builtin_neon_vld1_lane_v:
5383 case NEON::BI__builtin_neon_vld1q_lane_v:
5384 case NEON::BI__builtin_neon_vst1_v:
5385 case NEON::BI__builtin_neon_vst1q_v:
5386 case NEON::BI__builtin_neon_vst1_lane_v:
5387 case NEON::BI__builtin_neon_vst1q_lane_v:
5388 case NEON::BI__builtin_neon_vldap1_lane_s64:
5389 case NEON::BI__builtin_neon_vldap1q_lane_s64:
5390 case NEON::BI__builtin_neon_vstl1_lane_s64:
5391 case NEON::BI__builtin_neon_vstl1q_lane_s64:
5404 assert(
Result &&
"SISD intrinsic should have been handled");
5410 if (std::optional<llvm::APSInt>
Result =
5415 bool usgn =
Type.isUnsigned();
5416 bool quad =
Type.isQuad();
5435 switch (BuiltinID) {
5437 case NEON::BI__builtin_neon_vabsh_f16:
5439 case NEON::BI__builtin_neon_vaddq_p128: {
5441 Ops[0] =
Builder.CreateBitCast(Ops[0], Ty);
5442 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
5443 Ops[0] =
Builder.CreateXor(Ops[0], Ops[1]);
5444 llvm::Type *Int128Ty = llvm::Type::getIntNTy(
getLLVMContext(), 128);
5445 return Builder.CreateBitCast(Ops[0], Int128Ty);
5447 case NEON::BI__builtin_neon_vldrq_p128: {
5448 llvm::Type *Int128Ty = llvm::Type::getIntNTy(
getLLVMContext(), 128);
5449 return Builder.CreateAlignedLoad(Int128Ty, Ops[0],
5452 case NEON::BI__builtin_neon_vstrq_p128: {
5453 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
5455 case NEON::BI__builtin_neon_vcvts_f32_u32:
5456 case NEON::BI__builtin_neon_vcvtd_f64_u64:
5459 case NEON::BI__builtin_neon_vcvts_f32_s32:
5460 case NEON::BI__builtin_neon_vcvtd_f64_s64: {
5461 bool Is64 = Ops[0]->getType()->getPrimitiveSizeInBits() == 64;
5464 Ops[0] =
Builder.CreateBitCast(Ops[0], InTy);
5466 return Builder.CreateUIToFP(Ops[0], FTy);
5467 return Builder.CreateSIToFP(Ops[0], FTy);
5469 case NEON::BI__builtin_neon_vcvth_f16_u16:
5470 case NEON::BI__builtin_neon_vcvth_f16_u32:
5471 case NEON::BI__builtin_neon_vcvth_f16_u64:
5474 case NEON::BI__builtin_neon_vcvth_f16_s16:
5475 case NEON::BI__builtin_neon_vcvth_f16_s32:
5476 case NEON::BI__builtin_neon_vcvth_f16_s64: {
5477 llvm::Type *FTy =
HalfTy;
5479 if (Ops[0]->
getType()->getPrimitiveSizeInBits() == 64)
5481 else if (Ops[0]->
getType()->getPrimitiveSizeInBits() == 32)
5485 Ops[0] =
Builder.CreateBitCast(Ops[0], InTy);
5487 return Builder.CreateUIToFP(Ops[0], FTy);
5488 return Builder.CreateSIToFP(Ops[0], FTy);
5490 case NEON::BI__builtin_neon_vcvtah_u16_f16:
5491 case NEON::BI__builtin_neon_vcvtmh_u16_f16:
5492 case NEON::BI__builtin_neon_vcvtnh_u16_f16:
5493 case NEON::BI__builtin_neon_vcvtph_u16_f16:
5494 case NEON::BI__builtin_neon_vcvtah_s16_f16:
5495 case NEON::BI__builtin_neon_vcvtmh_s16_f16:
5496 case NEON::BI__builtin_neon_vcvtnh_s16_f16:
5497 case NEON::BI__builtin_neon_vcvtph_s16_f16: {
5499 llvm::Type* FTy =
HalfTy;
5500 llvm::Type *Tys[2] = {InTy, FTy};
5501 switch (BuiltinID) {
5502 default: llvm_unreachable(
"missing builtin ID in switch!");
5503 case NEON::BI__builtin_neon_vcvtah_u16_f16:
5504 Int = Intrinsic::aarch64_neon_fcvtau;
break;
5505 case NEON::BI__builtin_neon_vcvtmh_u16_f16:
5506 Int = Intrinsic::aarch64_neon_fcvtmu;
break;
5507 case NEON::BI__builtin_neon_vcvtnh_u16_f16:
5508 Int = Intrinsic::aarch64_neon_fcvtnu;
break;
5509 case NEON::BI__builtin_neon_vcvtph_u16_f16:
5510 Int = Intrinsic::aarch64_neon_fcvtpu;
break;
5511 case NEON::BI__builtin_neon_vcvtah_s16_f16:
5512 Int = Intrinsic::aarch64_neon_fcvtas;
break;
5513 case NEON::BI__builtin_neon_vcvtmh_s16_f16:
5514 Int = Intrinsic::aarch64_neon_fcvtms;
break;
5515 case NEON::BI__builtin_neon_vcvtnh_s16_f16:
5516 Int = Intrinsic::aarch64_neon_fcvtns;
break;
5517 case NEON::BI__builtin_neon_vcvtph_s16_f16:
5518 Int = Intrinsic::aarch64_neon_fcvtps;
break;
5522 case NEON::BI__builtin_neon_vcaleh_f16:
5523 case NEON::BI__builtin_neon_vcalth_f16:
5524 case NEON::BI__builtin_neon_vcageh_f16:
5525 case NEON::BI__builtin_neon_vcagth_f16: {
5527 llvm::Type* FTy =
HalfTy;
5528 llvm::Type *Tys[2] = {InTy, FTy};
5529 switch (BuiltinID) {
5530 default: llvm_unreachable(
"missing builtin ID in switch!");
5531 case NEON::BI__builtin_neon_vcageh_f16:
5532 Int = Intrinsic::aarch64_neon_facge;
break;
5533 case NEON::BI__builtin_neon_vcagth_f16:
5534 Int = Intrinsic::aarch64_neon_facgt;
break;
5535 case NEON::BI__builtin_neon_vcaleh_f16:
5536 Int = Intrinsic::aarch64_neon_facge; std::swap(Ops[0], Ops[1]);
break;
5537 case NEON::BI__builtin_neon_vcalth_f16:
5538 Int = Intrinsic::aarch64_neon_facgt; std::swap(Ops[0], Ops[1]);
break;
5543 case NEON::BI__builtin_neon_vcvth_n_s16_f16:
5544 case NEON::BI__builtin_neon_vcvth_n_u16_f16: {
5546 llvm::Type* FTy =
HalfTy;
5547 llvm::Type *Tys[2] = {InTy, FTy};
5548 switch (BuiltinID) {
5549 default: llvm_unreachable(
"missing builtin ID in switch!");
5550 case NEON::BI__builtin_neon_vcvth_n_s16_f16:
5551 Int = Intrinsic::aarch64_neon_vcvtfp2fxs;
break;
5552 case NEON::BI__builtin_neon_vcvth_n_u16_f16:
5553 Int = Intrinsic::aarch64_neon_vcvtfp2fxu;
break;
5558 case NEON::BI__builtin_neon_vcvth_n_f16_s16:
5559 case NEON::BI__builtin_neon_vcvth_n_f16_u16: {
5560 llvm::Type* FTy =
HalfTy;
5562 llvm::Type *Tys[2] = {FTy, InTy};
5563 switch (BuiltinID) {
5564 default: llvm_unreachable(
"missing builtin ID in switch!");
5565 case NEON::BI__builtin_neon_vcvth_n_f16_s16:
5566 Int = Intrinsic::aarch64_neon_vcvtfxs2fp;
5567 Ops[0] =
Builder.CreateSExt(Ops[0], InTy,
"sext");
5569 case NEON::BI__builtin_neon_vcvth_n_f16_u16:
5570 Int = Intrinsic::aarch64_neon_vcvtfxu2fp;
5571 Ops[0] =
Builder.CreateZExt(Ops[0], InTy);
5576 case NEON::BI__builtin_neon_vpaddd_s64: {
5579 auto *Ty = llvm::FixedVectorType::get(
Int64Ty, 2);
5581 Ops[0] =
Builder.CreateBitCast(Ops[0], Ty,
"v2i64");
5582 llvm::Value *Idx0 = llvm::ConstantInt::get(
SizeTy, 0);
5583 llvm::Value *Idx1 = llvm::ConstantInt::get(
SizeTy, 1);
5584 Value *Op0 =
Builder.CreateExtractElement(Ops[0], Idx0,
"lane0");
5585 Value *Op1 =
Builder.CreateExtractElement(Ops[0], Idx1,
"lane1");
5587 return Builder.CreateAdd(Op0, Op1,
"vpaddd");
5589 case NEON::BI__builtin_neon_vpaddd_f64: {
5590 auto *Ty = llvm::FixedVectorType::get(
DoubleTy, 2);
5592 Ops[0] =
Builder.CreateBitCast(Ops[0], Ty,
"v2f64");
5593 llvm::Value *Idx0 = llvm::ConstantInt::get(
SizeTy, 0);
5594 llvm::Value *Idx1 = llvm::ConstantInt::get(
SizeTy, 1);
5595 Value *Op0 =
Builder.CreateExtractElement(Ops[0], Idx0,
"lane0");
5596 Value *Op1 =
Builder.CreateExtractElement(Ops[0], Idx1,
"lane1");
5598 return Builder.CreateFAdd(Op0, Op1,
"vpaddd");
5600 case NEON::BI__builtin_neon_vpadds_f32: {
5601 auto *Ty = llvm::FixedVectorType::get(
FloatTy, 2);
5603 Ops[0] =
Builder.CreateBitCast(Ops[0], Ty,
"v2f32");
5604 llvm::Value *Idx0 = llvm::ConstantInt::get(
SizeTy, 0);
5605 llvm::Value *Idx1 = llvm::ConstantInt::get(
SizeTy, 1);
5606 Value *Op0 =
Builder.CreateExtractElement(Ops[0], Idx0,
"lane0");
5607 Value *Op1 =
Builder.CreateExtractElement(Ops[0], Idx1,
"lane1");
5609 return Builder.CreateFAdd(Op0, Op1,
"vpaddd");
5611 case NEON::BI__builtin_neon_vceqzd_s64:
5614 ICmpInst::ICMP_EQ,
"vceqz");
5615 case NEON::BI__builtin_neon_vceqzd_f64:
5616 case NEON::BI__builtin_neon_vceqzs_f32:
5617 case NEON::BI__builtin_neon_vceqzh_f16:
5620 ICmpInst::FCMP_OEQ,
"vceqz");
5621 case NEON::BI__builtin_neon_vcgezd_s64:
5624 ICmpInst::ICMP_SGE,
"vcgez");
5625 case NEON::BI__builtin_neon_vcgezd_f64:
5626 case NEON::BI__builtin_neon_vcgezs_f32:
5627 case NEON::BI__builtin_neon_vcgezh_f16:
5630 ICmpInst::FCMP_OGE,
"vcgez");
5631 case NEON::BI__builtin_neon_vclezd_s64:
5634 ICmpInst::ICMP_SLE,
"vclez");
5635 case NEON::BI__builtin_neon_vclezd_f64:
5636 case NEON::BI__builtin_neon_vclezs_f32:
5637 case NEON::BI__builtin_neon_vclezh_f16:
5640 ICmpInst::FCMP_OLE,
"vclez");
5641 case NEON::BI__builtin_neon_vcgtzd_s64:
5644 ICmpInst::ICMP_SGT,
"vcgtz");
5645 case NEON::BI__builtin_neon_vcgtzd_f64:
5646 case NEON::BI__builtin_neon_vcgtzs_f32:
5647 case NEON::BI__builtin_neon_vcgtzh_f16:
5650 ICmpInst::FCMP_OGT,
"vcgtz");
5651 case NEON::BI__builtin_neon_vcltzd_s64:
5654 ICmpInst::ICMP_SLT,
"vcltz");
5656 case NEON::BI__builtin_neon_vcltzd_f64:
5657 case NEON::BI__builtin_neon_vcltzs_f32:
5658 case NEON::BI__builtin_neon_vcltzh_f16:
5661 ICmpInst::FCMP_OLT,
"vcltz");
5663 case NEON::BI__builtin_neon_vceqzd_u64: {
5666 ICmpInst::ICMP_EQ,
"vceqzd");
5668 case NEON::BI__builtin_neon_vceqd_f64:
5669 case NEON::BI__builtin_neon_vcled_f64:
5670 case NEON::BI__builtin_neon_vcltd_f64:
5671 case NEON::BI__builtin_neon_vcged_f64:
5672 case NEON::BI__builtin_neon_vcgtd_f64: {
5673 llvm::CmpInst::Predicate P;
5674 switch (BuiltinID) {
5675 default: llvm_unreachable(
"missing builtin ID in switch!");
5676 case NEON::BI__builtin_neon_vceqd_f64: P = llvm::FCmpInst::FCMP_OEQ;
break;
5677 case NEON::BI__builtin_neon_vcled_f64: P = llvm::FCmpInst::FCMP_OLE;
break;
5678 case NEON::BI__builtin_neon_vcltd_f64: P = llvm::FCmpInst::FCMP_OLT;
break;
5679 case NEON::BI__builtin_neon_vcged_f64: P = llvm::FCmpInst::FCMP_OGE;
break;
5680 case NEON::BI__builtin_neon_vcgtd_f64: P = llvm::FCmpInst::FCMP_OGT;
break;
5684 if (P == llvm::FCmpInst::FCMP_OEQ)
5685 Ops[0] =
Builder.CreateFCmp(P, Ops[0], Ops[1]);
5687 Ops[0] =
Builder.CreateFCmpS(P, Ops[0], Ops[1]);
5690 case NEON::BI__builtin_neon_vceqs_f32:
5691 case NEON::BI__builtin_neon_vcles_f32:
5692 case NEON::BI__builtin_neon_vclts_f32:
5693 case NEON::BI__builtin_neon_vcges_f32:
5694 case NEON::BI__builtin_neon_vcgts_f32: {
5695 llvm::CmpInst::Predicate P;
5696 switch (BuiltinID) {
5697 default: llvm_unreachable(
"missing builtin ID in switch!");
5698 case NEON::BI__builtin_neon_vceqs_f32: P = llvm::FCmpInst::FCMP_OEQ;
break;
5699 case NEON::BI__builtin_neon_vcles_f32: P = llvm::FCmpInst::FCMP_OLE;
break;
5700 case NEON::BI__builtin_neon_vclts_f32: P = llvm::FCmpInst::FCMP_OLT;
break;
5701 case NEON::BI__builtin_neon_vcges_f32: P = llvm::FCmpInst::FCMP_OGE;
break;
5702 case NEON::BI__builtin_neon_vcgts_f32: P = llvm::FCmpInst::FCMP_OGT;
break;
5706 if (P == llvm::FCmpInst::FCMP_OEQ)
5707 Ops[0] =
Builder.CreateFCmp(P, Ops[0], Ops[1]);
5709 Ops[0] =
Builder.CreateFCmpS(P, Ops[0], Ops[1]);
5712 case NEON::BI__builtin_neon_vceqh_f16:
5713 case NEON::BI__builtin_neon_vcleh_f16:
5714 case NEON::BI__builtin_neon_vclth_f16:
5715 case NEON::BI__builtin_neon_vcgeh_f16:
5716 case NEON::BI__builtin_neon_vcgth_f16: {
5717 llvm::CmpInst::Predicate P;
5718 switch (BuiltinID) {
5719 default: llvm_unreachable(
"missing builtin ID in switch!");
5720 case NEON::BI__builtin_neon_vceqh_f16: P = llvm::FCmpInst::FCMP_OEQ;
break;
5721 case NEON::BI__builtin_neon_vcleh_f16: P = llvm::FCmpInst::FCMP_OLE;
break;
5722 case NEON::BI__builtin_neon_vclth_f16: P = llvm::FCmpInst::FCMP_OLT;
break;
5723 case NEON::BI__builtin_neon_vcgeh_f16: P = llvm::FCmpInst::FCMP_OGE;
break;
5724 case NEON::BI__builtin_neon_vcgth_f16: P = llvm::FCmpInst::FCMP_OGT;
break;
5728 if (P == llvm::FCmpInst::FCMP_OEQ)
5729 Ops[0] =
Builder.CreateFCmp(P, Ops[0], Ops[1]);
5731 Ops[0] =
Builder.CreateFCmpS(P, Ops[0], Ops[1]);
5734 case NEON::BI__builtin_neon_vceqd_s64:
5735 case NEON::BI__builtin_neon_vceqd_u64:
5736 case NEON::BI__builtin_neon_vcgtd_s64:
5737 case NEON::BI__builtin_neon_vcgtd_u64:
5738 case NEON::BI__builtin_neon_vcltd_s64:
5739 case NEON::BI__builtin_neon_vcltd_u64:
5740 case NEON::BI__builtin_neon_vcged_u64:
5741 case NEON::BI__builtin_neon_vcged_s64:
5742 case NEON::BI__builtin_neon_vcled_u64:
5743 case NEON::BI__builtin_neon_vcled_s64: {
5744 llvm::CmpInst::Predicate P;
5745 switch (BuiltinID) {
5746 default: llvm_unreachable(
"missing builtin ID in switch!");
5747 case NEON::BI__builtin_neon_vceqd_s64:
5748 case NEON::BI__builtin_neon_vceqd_u64:P = llvm::ICmpInst::ICMP_EQ;
break;
5749 case NEON::BI__builtin_neon_vcgtd_s64:P = llvm::ICmpInst::ICMP_SGT;
break;
5750 case NEON::BI__builtin_neon_vcgtd_u64:P = llvm::ICmpInst::ICMP_UGT;
break;
5751 case NEON::BI__builtin_neon_vcltd_s64:P = llvm::ICmpInst::ICMP_SLT;
break;
5752 case NEON::BI__builtin_neon_vcltd_u64:P = llvm::ICmpInst::ICMP_ULT;
break;
5753 case NEON::BI__builtin_neon_vcged_u64:P = llvm::ICmpInst::ICMP_UGE;
break;
5754 case NEON::BI__builtin_neon_vcged_s64:P = llvm::ICmpInst::ICMP_SGE;
break;
5755 case NEON::BI__builtin_neon_vcled_u64:P = llvm::ICmpInst::ICMP_ULE;
break;
5756 case NEON::BI__builtin_neon_vcled_s64:P = llvm::ICmpInst::ICMP_SLE;
break;
5760 Ops[0] =
Builder.CreateICmp(P, Ops[0], Ops[1]);
5763 case NEON::BI__builtin_neon_vnegd_s64:
5764 return Builder.CreateNeg(Ops[0],
"vnegd");
5765 case NEON::BI__builtin_neon_vnegh_f16:
5766 return Builder.CreateFNeg(Ops[0],
"vnegh");
5767 case NEON::BI__builtin_neon_vtstd_s64:
5768 case NEON::BI__builtin_neon_vtstd_u64: {
5771 Ops[0] =
Builder.CreateAnd(Ops[0], Ops[1]);
5772 Ops[0] =
Builder.CreateICmp(ICmpInst::ICMP_NE, Ops[0],
5773 llvm::Constant::getNullValue(
Int64Ty));
5776 case NEON::BI__builtin_neon_vset_lane_i8:
5777 case NEON::BI__builtin_neon_vset_lane_i16:
5778 case NEON::BI__builtin_neon_vset_lane_i32:
5779 case NEON::BI__builtin_neon_vset_lane_i64:
5780 case NEON::BI__builtin_neon_vset_lane_bf16:
5781 case NEON::BI__builtin_neon_vset_lane_f32:
5782 case NEON::BI__builtin_neon_vsetq_lane_i8:
5783 case NEON::BI__builtin_neon_vsetq_lane_i16:
5784 case NEON::BI__builtin_neon_vsetq_lane_i32:
5785 case NEON::BI__builtin_neon_vsetq_lane_i64:
5786 case NEON::BI__builtin_neon_vsetq_lane_bf16:
5787 case NEON::BI__builtin_neon_vsetq_lane_f32:
5788 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2],
"vset_lane");
5789 case NEON::BI__builtin_neon_vset_lane_f64:
5792 Builder.CreateBitCast(Ops[1], llvm::FixedVectorType::get(
DoubleTy, 1));
5793 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2],
"vset_lane");
5794 case NEON::BI__builtin_neon_vset_lane_mf8:
5795 case NEON::BI__builtin_neon_vsetq_lane_mf8:
5799 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2],
"vset_lane");
5800 case NEON::BI__builtin_neon_vsetq_lane_f64:
5803 Builder.CreateBitCast(Ops[1], llvm::FixedVectorType::get(
DoubleTy, 2));
5804 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2],
"vset_lane");
5806 case NEON::BI__builtin_neon_vget_lane_i8:
5807 case NEON::BI__builtin_neon_vdupb_lane_i8:
5808 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vget_lane");
5809 case NEON::BI__builtin_neon_vgetq_lane_i8:
5810 case NEON::BI__builtin_neon_vdupb_laneq_i8:
5811 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vgetq_lane");
5812 case NEON::BI__builtin_neon_vget_lane_mf8:
5813 case NEON::BI__builtin_neon_vdupb_lane_mf8:
5814 case NEON::BI__builtin_neon_vgetq_lane_mf8:
5815 case NEON::BI__builtin_neon_vdupb_laneq_mf8:
5816 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vget_lane");
5817 case NEON::BI__builtin_neon_vget_lane_i16:
5818 case NEON::BI__builtin_neon_vduph_lane_i16:
5819 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vget_lane");
5820 case NEON::BI__builtin_neon_vgetq_lane_i16:
5821 case NEON::BI__builtin_neon_vduph_laneq_i16:
5822 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vgetq_lane");
5823 case NEON::BI__builtin_neon_vget_lane_i32:
5824 case NEON::BI__builtin_neon_vdups_lane_i32:
5825 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vget_lane");
5826 case NEON::BI__builtin_neon_vdups_lane_f32:
5827 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vdups_lane");
5828 case NEON::BI__builtin_neon_vgetq_lane_i32:
5829 case NEON::BI__builtin_neon_vdups_laneq_i32:
5830 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vgetq_lane");
5831 case NEON::BI__builtin_neon_vget_lane_i64:
5832 case NEON::BI__builtin_neon_vdupd_lane_i64:
5833 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vget_lane");
5834 case NEON::BI__builtin_neon_vdupd_lane_f64:
5835 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vdupd_lane");
5836 case NEON::BI__builtin_neon_vgetq_lane_i64:
5837 case NEON::BI__builtin_neon_vdupd_laneq_i64:
5838 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vgetq_lane");
5839 case NEON::BI__builtin_neon_vget_lane_f32:
5840 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vget_lane");
5841 case NEON::BI__builtin_neon_vget_lane_f64:
5842 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vget_lane");
5843 case NEON::BI__builtin_neon_vgetq_lane_f32:
5844 case NEON::BI__builtin_neon_vdups_laneq_f32:
5845 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vgetq_lane");
5846 case NEON::BI__builtin_neon_vgetq_lane_f64:
5847 case NEON::BI__builtin_neon_vdupd_laneq_f64:
5848 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vgetq_lane");
5849 case NEON::BI__builtin_neon_vaddh_f16:
5850 return Builder.CreateFAdd(Ops[0], Ops[1],
"vaddh");
5851 case NEON::BI__builtin_neon_vsubh_f16:
5852 return Builder.CreateFSub(Ops[0], Ops[1],
"vsubh");
5853 case NEON::BI__builtin_neon_vmulh_f16:
5854 return Builder.CreateFMul(Ops[0], Ops[1],
"vmulh");
5855 case NEON::BI__builtin_neon_vdivh_f16:
5856 return Builder.CreateFDiv(Ops[0], Ops[1],
"vdivh");
5857 case NEON::BI__builtin_neon_vfmah_f16:
5860 *
this, Intrinsic::fma, Intrinsic::experimental_constrained_fma,
HalfTy,
5861 {Ops[1], Ops[2], Ops[0]});
5862 case NEON::BI__builtin_neon_vfmsh_f16: {
5867 *
this, Intrinsic::fma, Intrinsic::experimental_constrained_fma,
HalfTy,
5868 {Neg, Ops[2], Ops[0]});
5870 case NEON::BI__builtin_neon_vaddd_s64:
5871 case NEON::BI__builtin_neon_vaddd_u64:
5872 return Builder.CreateAdd(Ops[0], Ops[1],
"vaddd");
5873 case NEON::BI__builtin_neon_vsubd_s64:
5874 case NEON::BI__builtin_neon_vsubd_u64:
5875 return Builder.CreateSub(Ops[0], Ops[1],
"vsubd");
5876 case NEON::BI__builtin_neon_vqdmlalh_s16:
5877 case NEON::BI__builtin_neon_vqdmlslh_s16: {
5881 auto *VTy = llvm::FixedVectorType::get(
Int32Ty, 4);
5882 Ops[1] =
EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmull, VTy),
5883 ProductOps,
"vqdmlXl");
5885 Ops[1] =
Builder.CreateExtractElement(Ops[1], CI,
"lane0");
5887 unsigned AccumInt = BuiltinID == NEON::BI__builtin_neon_vqdmlalh_s16
5888 ? Intrinsic::aarch64_neon_sqadd
5889 : Intrinsic::aarch64_neon_sqsub;
5894 case NEON::BI__builtin_neon_vqshlud_n_s64: {
5899 case NEON::BI__builtin_neon_vqshld_n_u64:
5900 case NEON::BI__builtin_neon_vqshld_n_s64: {
5901 Int = BuiltinID == NEON::BI__builtin_neon_vqshld_n_u64
5902 ? Intrinsic::aarch64_neon_uqshl
5903 : Intrinsic::aarch64_neon_sqshl;
5907 case NEON::BI__builtin_neon_vrshrd_n_u64:
5908 case NEON::BI__builtin_neon_vrshrd_n_s64: {
5909 Int = BuiltinID == NEON::BI__builtin_neon_vrshrd_n_u64
5910 ? Intrinsic::aarch64_neon_urshl
5911 : Intrinsic::aarch64_neon_srshl;
5913 Ops[1] = ConstantInt::get(
Int64Ty, -SV);
5916 case NEON::BI__builtin_neon_vrsrad_n_u64:
5917 case NEON::BI__builtin_neon_vrsrad_n_s64: {
5918 Int = BuiltinID == NEON::BI__builtin_neon_vrsrad_n_u64
5919 ? Intrinsic::aarch64_neon_urshl
5920 : Intrinsic::aarch64_neon_srshl;
5922 Ops[2] =
Builder.CreateNeg(Ops[2]);
5924 {Ops[1], Builder.CreateSExt(Ops[2], Int64Ty)});
5927 case NEON::BI__builtin_neon_vshld_n_s64:
5928 case NEON::BI__builtin_neon_vshld_n_u64: {
5931 Ops[0], ConstantInt::get(
Int64Ty, Amt->getZExtValue()),
"shld_n");
5933 case NEON::BI__builtin_neon_vshrd_n_s64: {
5936 Ops[0], ConstantInt::get(
Int64Ty, std::min(
static_cast<uint64_t
>(63),
5937 Amt->getZExtValue())),
5940 case NEON::BI__builtin_neon_vshrd_n_u64: {
5942 uint64_t ShiftAmt = Amt->getZExtValue();
5945 return ConstantInt::get(
Int64Ty, 0);
5946 return Builder.CreateLShr(Ops[0], ConstantInt::get(
Int64Ty, ShiftAmt),
5949 case NEON::BI__builtin_neon_vsrad_n_s64: {
5952 Ops[1], ConstantInt::get(
Int64Ty, std::min(
static_cast<uint64_t
>(63),
5953 Amt->getZExtValue())),
5955 return Builder.CreateAdd(Ops[0], Ops[1]);
5957 case NEON::BI__builtin_neon_vsrad_n_u64: {
5959 uint64_t ShiftAmt = Amt->getZExtValue();
5964 Ops[1] =
Builder.CreateLShr(Ops[1], ConstantInt::get(
Int64Ty, ShiftAmt),
5966 return Builder.CreateAdd(Ops[0], Ops[1]);
5968 case NEON::BI__builtin_neon_vqdmlalh_lane_s16:
5969 case NEON::BI__builtin_neon_vqdmlalh_laneq_s16:
5970 case NEON::BI__builtin_neon_vqdmlslh_lane_s16:
5971 case NEON::BI__builtin_neon_vqdmlslh_laneq_s16: {
5972 Ops[2] =
Builder.CreateExtractElement(Ops[2], Ops[3],
"lane");
5976 auto *VTy = llvm::FixedVectorType::get(
Int32Ty, 4);
5977 Ops[1] =
EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmull, VTy),
5978 ProductOps,
"vqdmlXl");
5980 Ops[1] =
Builder.CreateExtractElement(Ops[1], CI,
"lane0");
5985 unsigned AccInt = (BuiltinID == NEON::BI__builtin_neon_vqdmlalh_lane_s16 ||
5986 BuiltinID == NEON::BI__builtin_neon_vqdmlalh_laneq_s16)
5987 ? Intrinsic::aarch64_neon_sqadd
5988 : Intrinsic::aarch64_neon_sqsub;
5991 case NEON::BI__builtin_neon_vqdmlals_s32:
5992 case NEON::BI__builtin_neon_vqdmlsls_s32: {
5994 ProductOps.push_back(Ops[1]);
5995 ProductOps.push_back(Ops[2]);
5997 EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmulls_scalar),
5998 ProductOps,
"vqdmlXl");
6000 unsigned AccumInt = BuiltinID == NEON::BI__builtin_neon_vqdmlals_s32
6001 ? Intrinsic::aarch64_neon_sqadd
6002 : Intrinsic::aarch64_neon_sqsub;
6007 case NEON::BI__builtin_neon_vqdmlals_lane_s32:
6008 case NEON::BI__builtin_neon_vqdmlals_laneq_s32:
6009 case NEON::BI__builtin_neon_vqdmlsls_lane_s32:
6010 case NEON::BI__builtin_neon_vqdmlsls_laneq_s32: {
6011 Ops[2] =
Builder.CreateExtractElement(Ops[2], Ops[3],
"lane");
6013 ProductOps.push_back(Ops[1]);
6014 ProductOps.push_back(Ops[2]);
6016 EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmulls_scalar),
6017 ProductOps,
"vqdmlXl");
6022 unsigned AccInt = (BuiltinID == NEON::BI__builtin_neon_vqdmlals_lane_s32 ||
6023 BuiltinID == NEON::BI__builtin_neon_vqdmlals_laneq_s32)
6024 ? Intrinsic::aarch64_neon_sqadd
6025 : Intrinsic::aarch64_neon_sqsub;
6028 case NEON::BI__builtin_neon_vget_lane_bf16:
6029 case NEON::BI__builtin_neon_vduph_lane_bf16:
6030 case NEON::BI__builtin_neon_vduph_lane_f16: {
6031 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vget_lane");
6033 case NEON::BI__builtin_neon_vgetq_lane_bf16:
6034 case NEON::BI__builtin_neon_vduph_laneq_bf16:
6035 case NEON::BI__builtin_neon_vduph_laneq_f16: {
6036 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vgetq_lane");
6038 case NEON::BI__builtin_neon_vcvt_bf16_f32: {
6039 llvm::Type *V4F32 = FixedVectorType::get(
Builder.getFloatTy(), 4);
6040 llvm::Type *V4BF16 = FixedVectorType::get(
Builder.getBFloatTy(), 4);
6041 return Builder.CreateFPTrunc(
Builder.CreateBitCast(Ops[0], V4F32), V4BF16);
6043 case NEON::BI__builtin_neon_vcvtq_low_bf16_f32: {
6045 std::iota(ConcatMask.begin(), ConcatMask.end(), 0);
6046 llvm::Type *V4F32 = FixedVectorType::get(
Builder.getFloatTy(), 4);
6047 llvm::Type *V4BF16 = FixedVectorType::get(
Builder.getBFloatTy(), 4);
6048 llvm::Value *Trunc =
6049 Builder.CreateFPTrunc(
Builder.CreateBitCast(Ops[0], V4F32), V4BF16);
6050 return Builder.CreateShuffleVector(
6051 Trunc, ConstantAggregateZero::get(V4BF16), ConcatMask);
6053 case NEON::BI__builtin_neon_vcvtq_high_bf16_f32: {
6055 std::iota(ConcatMask.begin(), ConcatMask.end(), 0);
6057 std::iota(LoMask.begin(), LoMask.end(), 0);
6058 llvm::Type *V4F32 = FixedVectorType::get(
Builder.getFloatTy(), 4);
6059 llvm::Type *V4BF16 = FixedVectorType::get(
Builder.getBFloatTy(), 4);
6060 llvm::Type *V8BF16 = FixedVectorType::get(
Builder.getBFloatTy(), 8);
6061 llvm::Value *Inactive =
Builder.CreateShuffleVector(
6062 Builder.CreateBitCast(Ops[0], V8BF16), LoMask);
6063 llvm::Value *Trunc =
6064 Builder.CreateFPTrunc(
Builder.CreateBitCast(Ops[1], V4F32), V4BF16);
6065 return Builder.CreateShuffleVector(Inactive, Trunc, ConcatMask);
6067 case NEON::BI__builtin_neon_vcvt_f16_f32: {
6068 llvm::Type *V4F32 = FixedVectorType::get(
Builder.getFloatTy(), 4);
6069 llvm::Type *V4F16 = FixedVectorType::get(
Builder.getHalfTy(), 4);
6070 return Builder.CreateFPTrunc(
Builder.CreateBitCast(Ops[0], V4F32), V4F16);
6072 case NEON::BI__builtin_neon_vcvt_f32_f16: {
6073 llvm::Type *V4F32 = FixedVectorType::get(
Builder.getFloatTy(), 4);
6074 llvm::Type *V4F16 = FixedVectorType::get(
Builder.getHalfTy(), 4);
6075 return Builder.CreateFPExt(
Builder.CreateBitCast(Ops[0], V4F16), V4F32);
6078 case clang::AArch64::BI_InterlockedAdd:
6079 case clang::AArch64::BI_InterlockedAdd_acq:
6080 case clang::AArch64::BI_InterlockedAdd_rel:
6081 case clang::AArch64::BI_InterlockedAdd_nf:
6082 case clang::AArch64::BI_InterlockedAdd64:
6083 case clang::AArch64::BI_InterlockedAdd64_acq:
6084 case clang::AArch64::BI_InterlockedAdd64_rel:
6085 case clang::AArch64::BI_InterlockedAdd64_nf: {
6087 Value *Val = Ops[1];
6088 llvm::AtomicOrdering Ordering;
6089 switch (BuiltinID) {
6090 case clang::AArch64::BI_InterlockedAdd:
6091 case clang::AArch64::BI_InterlockedAdd64:
6092 Ordering = llvm::AtomicOrdering::SequentiallyConsistent;
6094 case clang::AArch64::BI_InterlockedAdd_acq:
6095 case clang::AArch64::BI_InterlockedAdd64_acq:
6096 Ordering = llvm::AtomicOrdering::Acquire;
6098 case clang::AArch64::BI_InterlockedAdd_rel:
6099 case clang::AArch64::BI_InterlockedAdd64_rel:
6100 Ordering = llvm::AtomicOrdering::Release;
6102 case clang::AArch64::BI_InterlockedAdd_nf:
6103 case clang::AArch64::BI_InterlockedAdd64_nf:
6104 Ordering = llvm::AtomicOrdering::Monotonic;
6107 llvm_unreachable(
"missing builtin ID in switch!");
6109 AtomicRMWInst *RMWI =
6110 Builder.CreateAtomicRMW(AtomicRMWInst::Add, DestAddr, Val, Ordering);
6111 return Builder.CreateAdd(RMWI, Val);
6116 llvm::Type *Ty = VTy;
6120 bool ExtractLow =
false;
6121 bool ExtendLaneArg =
false;
6122 switch (BuiltinID) {
6123 default:
return nullptr;
6124 case NEON::BI__builtin_neon_vbsl_v:
6125 case NEON::BI__builtin_neon_vbslq_v: {
6126 llvm::Type *BitTy = llvm::VectorType::getInteger(VTy);
6127 Ops[0] =
Builder.CreateBitCast(Ops[0], BitTy,
"vbsl");
6128 Ops[1] =
Builder.CreateBitCast(Ops[1], BitTy,
"vbsl");
6129 Ops[2] =
Builder.CreateBitCast(Ops[2], BitTy,
"vbsl");
6131 Ops[1] =
Builder.CreateAnd(Ops[0], Ops[1],
"vbsl");
6132 Ops[2] =
Builder.CreateAnd(
Builder.CreateNot(Ops[0]), Ops[2],
"vbsl");
6133 Ops[0] =
Builder.CreateOr(Ops[1], Ops[2],
"vbsl");
6134 return Builder.CreateBitCast(Ops[0], Ty);
6136 case NEON::BI__builtin_neon_vfma_lane_v:
6137 case NEON::BI__builtin_neon_vfmaq_lane_v: {
6140 Value *Addend = Ops[0];
6141 Value *Multiplicand = Ops[1];
6142 Value *LaneSource = Ops[2];
6143 Ops[0] = Multiplicand;
6144 Ops[1] = LaneSource;
6148 auto *SourceTy = BuiltinID == NEON::BI__builtin_neon_vfmaq_lane_v
6149 ? llvm::FixedVectorType::get(VTy->getElementType(),
6150 VTy->getNumElements() / 2)
6153 Value *SV = llvm::ConstantVector::getSplat(VTy->getElementCount(), cst);
6154 Ops[1] =
Builder.CreateBitCast(Ops[1], SourceTy);
6155 Ops[1] =
Builder.CreateShuffleVector(Ops[1], Ops[1], SV,
"lane");
6158 Int =
Builder.getIsFPConstrained() ? Intrinsic::experimental_constrained_fma
6162 case NEON::BI__builtin_neon_vfma_laneq_v: {
6165 if (VTy && VTy->getElementType() ==
DoubleTy) {
6168 llvm::FixedVectorType *VTy =
6170 Ops[2] =
Builder.CreateBitCast(Ops[2], VTy);
6171 Ops[2] =
Builder.CreateExtractElement(Ops[2], Ops[3],
"extract");
6174 *
this, Intrinsic::fma, Intrinsic::experimental_constrained_fma,
6175 DoubleTy, {Ops[1], Ops[2], Ops[0]});
6178 Ops[0] =
Builder.CreateBitCast(Ops[0], Ty);
6179 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
6181 auto *STy = llvm::FixedVectorType::get(VTy->getElementType(),
6182 VTy->getNumElements() * 2);
6183 Ops[2] =
Builder.CreateBitCast(Ops[2], STy);
6184 Value *SV = llvm::ConstantVector::getSplat(VTy->getElementCount(),
6186 Ops[2] =
Builder.CreateShuffleVector(Ops[2], Ops[2], SV,
"lane");
6189 *
this, Intrinsic::fma, Intrinsic::experimental_constrained_fma, Ty,
6190 {Ops[2], Ops[1], Ops[0]});
6192 case NEON::BI__builtin_neon_vfmaq_laneq_v: {
6193 Ops[0] =
Builder.CreateBitCast(Ops[0], Ty);
6194 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
6196 Ops[2] =
Builder.CreateBitCast(Ops[2], Ty);
6199 *
this, Intrinsic::fma, Intrinsic::experimental_constrained_fma, Ty,
6200 {Ops[2], Ops[1], Ops[0]});
6202 case NEON::BI__builtin_neon_vfmah_lane_f16:
6203 case NEON::BI__builtin_neon_vfmas_lane_f32:
6204 case NEON::BI__builtin_neon_vfmah_laneq_f16:
6205 case NEON::BI__builtin_neon_vfmas_laneq_f32:
6206 case NEON::BI__builtin_neon_vfmad_lane_f64:
6207 case NEON::BI__builtin_neon_vfmad_laneq_f64: {
6209 Ops[2] =
Builder.CreateExtractElement(Ops[2], Ops[3],
"extract");
6211 *
this, Intrinsic::fma, Intrinsic::experimental_constrained_fma, Ty,
6212 {Ops[1], Ops[2], Ops[0]});
6214 case NEON::BI__builtin_neon_vmull_v:
6216 Int = usgn ? Intrinsic::aarch64_neon_umull : Intrinsic::aarch64_neon_smull;
6217 if (
Type.isPoly())
Int = Intrinsic::aarch64_neon_pmull;
6219 case NEON::BI__builtin_neon_vmax_v:
6220 case NEON::BI__builtin_neon_vmaxq_v:
6222 Int = usgn ? Intrinsic::umax : Intrinsic::smax;
6223 if (Ty->isFPOrFPVectorTy())
Int = Intrinsic::aarch64_neon_fmax;
6225 case NEON::BI__builtin_neon_vmaxh_f16: {
6226 Int = Intrinsic::aarch64_neon_fmax;
6229 case NEON::BI__builtin_neon_vmin_v:
6230 case NEON::BI__builtin_neon_vminq_v:
6232 Int = usgn ? Intrinsic::umin : Intrinsic::smin;
6233 if (Ty->isFPOrFPVectorTy())
Int = Intrinsic::aarch64_neon_fmin;
6235 case NEON::BI__builtin_neon_vminh_f16: {
6236 Int = Intrinsic::aarch64_neon_fmin;
6239 case NEON::BI__builtin_neon_vabd_v:
6240 case NEON::BI__builtin_neon_vabdq_v:
6242 Int = usgn ? Intrinsic::aarch64_neon_uabd : Intrinsic::aarch64_neon_sabd;
6243 if (Ty->isFPOrFPVectorTy())
Int = Intrinsic::aarch64_neon_fabd;
6245 case NEON::BI__builtin_neon_vpadal_v:
6246 case NEON::BI__builtin_neon_vpadalq_v: {
6247 unsigned ArgElts = VTy->getNumElements();
6249 unsigned BitWidth = EltTy->getBitWidth();
6250 auto *ArgTy = llvm::FixedVectorType::get(
6251 llvm::IntegerType::get(
getLLVMContext(), BitWidth / 2), 2 * ArgElts);
6252 llvm::Type* Tys[2] = { VTy, ArgTy };
6253 Int = usgn ? Intrinsic::aarch64_neon_uaddlp : Intrinsic::aarch64_neon_saddlp;
6255 TmpOps.push_back(Ops[1]);
6258 llvm::Value *addend =
Builder.CreateBitCast(Ops[0], tmp->getType());
6259 return Builder.CreateAdd(tmp, addend);
6261 case NEON::BI__builtin_neon_vpmin_v:
6262 case NEON::BI__builtin_neon_vpminq_v:
6264 Int = usgn ? Intrinsic::aarch64_neon_uminp : Intrinsic::aarch64_neon_sminp;
6265 if (Ty->isFPOrFPVectorTy())
Int = Intrinsic::aarch64_neon_fminp;
6267 case NEON::BI__builtin_neon_vpmax_v:
6268 case NEON::BI__builtin_neon_vpmaxq_v:
6270 Int = usgn ? Intrinsic::aarch64_neon_umaxp : Intrinsic::aarch64_neon_smaxp;
6271 if (Ty->isFPOrFPVectorTy())
Int = Intrinsic::aarch64_neon_fmaxp;
6273 case NEON::BI__builtin_neon_vminnm_v:
6274 case NEON::BI__builtin_neon_vminnmq_v:
6275 Int = Intrinsic::aarch64_neon_fminnm;
6277 case NEON::BI__builtin_neon_vminnmh_f16:
6278 Int = Intrinsic::aarch64_neon_fminnm;
6280 case NEON::BI__builtin_neon_vmaxnm_v:
6281 case NEON::BI__builtin_neon_vmaxnmq_v:
6282 Int = Intrinsic::aarch64_neon_fmaxnm;
6284 case NEON::BI__builtin_neon_vmaxnmh_f16:
6285 Int = Intrinsic::aarch64_neon_fmaxnm;
6287 case NEON::BI__builtin_neon_vrecpss_f32: {
6291 case NEON::BI__builtin_neon_vrecpsd_f64:
6294 case NEON::BI__builtin_neon_vrecpsh_f16:
6297 case NEON::BI__builtin_neon_vqshrun_n_v:
6298 Int = Intrinsic::aarch64_neon_sqshrun;
6300 case NEON::BI__builtin_neon_vqrshrun_n_v:
6301 Int = Intrinsic::aarch64_neon_sqrshrun;
6303 case NEON::BI__builtin_neon_vqshrn_n_v:
6304 Int = usgn ? Intrinsic::aarch64_neon_uqshrn : Intrinsic::aarch64_neon_sqshrn;
6306 case NEON::BI__builtin_neon_vrshrn_n_v:
6307 Int = Intrinsic::aarch64_neon_rshrn;
6309 case NEON::BI__builtin_neon_vqrshrn_n_v:
6310 Int = usgn ? Intrinsic::aarch64_neon_uqrshrn : Intrinsic::aarch64_neon_sqrshrn;
6312 case NEON::BI__builtin_neon_vrndah_f16: {
6314 ? Intrinsic::experimental_constrained_round
6318 case NEON::BI__builtin_neon_vrnda_v:
6319 case NEON::BI__builtin_neon_vrndaq_v: {
6321 ? Intrinsic::experimental_constrained_round
6325 case NEON::BI__builtin_neon_vrndih_f16: {
6327 ? Intrinsic::experimental_constrained_nearbyint
6328 : Intrinsic::nearbyint;
6331 case NEON::BI__builtin_neon_vrndmh_f16: {
6333 ? Intrinsic::experimental_constrained_floor
6337 case NEON::BI__builtin_neon_vrndm_v:
6338 case NEON::BI__builtin_neon_vrndmq_v: {
6340 ? Intrinsic::experimental_constrained_floor
6344 case NEON::BI__builtin_neon_vrndnh_f16: {
6346 ? Intrinsic::experimental_constrained_roundeven
6347 : Intrinsic::roundeven;
6350 case NEON::BI__builtin_neon_vrndn_v:
6351 case NEON::BI__builtin_neon_vrndnq_v: {
6353 ? Intrinsic::experimental_constrained_roundeven
6354 : Intrinsic::roundeven;
6357 case NEON::BI__builtin_neon_vrndns_f32: {
6359 ? Intrinsic::experimental_constrained_roundeven
6360 : Intrinsic::roundeven;
6363 case NEON::BI__builtin_neon_vrndph_f16: {
6365 ? Intrinsic::experimental_constrained_ceil
6369 case NEON::BI__builtin_neon_vrndp_v:
6370 case NEON::BI__builtin_neon_vrndpq_v: {
6372 ? Intrinsic::experimental_constrained_ceil
6376 case NEON::BI__builtin_neon_vrndxh_f16: {
6378 ? Intrinsic::experimental_constrained_rint
6382 case NEON::BI__builtin_neon_vrndx_v:
6383 case NEON::BI__builtin_neon_vrndxq_v: {
6385 ? Intrinsic::experimental_constrained_rint
6389 case NEON::BI__builtin_neon_vrndh_f16: {
6391 ? Intrinsic::experimental_constrained_trunc
6395 case NEON::BI__builtin_neon_vrnd_v:
6396 case NEON::BI__builtin_neon_vrndq_v: {
6398 ? Intrinsic::experimental_constrained_trunc
6402 case NEON::BI__builtin_neon_vcvt_f64_v:
6403 case NEON::BI__builtin_neon_vcvtq_f64_v:
6404 Ops[0] =
Builder.CreateBitCast(Ops[0], Ty);
6406 return usgn ?
Builder.CreateUIToFP(Ops[0], Ty,
"vcvt")
6407 :
Builder.CreateSIToFP(Ops[0], Ty,
"vcvt");
6408 case NEON::BI__builtin_neon_vcvt_f64_f32: {
6410 "unexpected vcvt_f64_f32 builtin");
6414 return Builder.CreateFPExt(Ops[0], Ty,
"vcvt");
6416 case NEON::BI__builtin_neon_vcvt_f32_f64: {
6418 "unexpected vcvt_f32_f64 builtin");
6422 return Builder.CreateFPTrunc(Ops[0], Ty,
"vcvt");
6424 case NEON::BI__builtin_neon_vcvta_s16_f16:
6425 case NEON::BI__builtin_neon_vcvta_u16_f16:
6426 case NEON::BI__builtin_neon_vcvta_s32_v:
6427 case NEON::BI__builtin_neon_vcvtaq_s16_f16:
6428 case NEON::BI__builtin_neon_vcvtaq_s32_v:
6429 case NEON::BI__builtin_neon_vcvta_u32_v:
6430 case NEON::BI__builtin_neon_vcvtaq_u16_f16:
6431 case NEON::BI__builtin_neon_vcvtaq_u32_v:
6432 case NEON::BI__builtin_neon_vcvta_s64_v:
6433 case NEON::BI__builtin_neon_vcvtaq_s64_v:
6434 case NEON::BI__builtin_neon_vcvta_u64_v:
6435 case NEON::BI__builtin_neon_vcvtaq_u64_v: {
6436 Int = usgn ? Intrinsic::aarch64_neon_fcvtau : Intrinsic::aarch64_neon_fcvtas;
6440 case NEON::BI__builtin_neon_vcvtm_s16_f16:
6441 case NEON::BI__builtin_neon_vcvtmq_s16_f16:
6442 case NEON::BI__builtin_neon_vcvtm_u16_f16:
6443 case NEON::BI__builtin_neon_vcvtmq_u16_f16:
6444 case NEON::BI__builtin_neon_vcvtm_s32_v:
6445 case NEON::BI__builtin_neon_vcvtmq_s32_v:
6446 case NEON::BI__builtin_neon_vcvtm_u32_v:
6447 case NEON::BI__builtin_neon_vcvtmq_u32_v:
6448 case NEON::BI__builtin_neon_vcvtm_s64_v:
6449 case NEON::BI__builtin_neon_vcvtmq_s64_v:
6450 case NEON::BI__builtin_neon_vcvtm_u64_v:
6451 case NEON::BI__builtin_neon_vcvtmq_u64_v: {
6452 Int = usgn ? Intrinsic::aarch64_neon_fcvtmu : Intrinsic::aarch64_neon_fcvtms;
6456 case NEON::BI__builtin_neon_vcvtn_s16_f16:
6457 case NEON::BI__builtin_neon_vcvtnq_s16_f16:
6458 case NEON::BI__builtin_neon_vcvtn_u16_f16:
6459 case NEON::BI__builtin_neon_vcvtnq_u16_f16:
6460 case NEON::BI__builtin_neon_vcvtn_s32_v:
6461 case NEON::BI__builtin_neon_vcvtnq_s32_v:
6462 case NEON::BI__builtin_neon_vcvtn_u32_v:
6463 case NEON::BI__builtin_neon_vcvtnq_u32_v:
6464 case NEON::BI__builtin_neon_vcvtn_s64_v:
6465 case NEON::BI__builtin_neon_vcvtnq_s64_v:
6466 case NEON::BI__builtin_neon_vcvtn_u64_v:
6467 case NEON::BI__builtin_neon_vcvtnq_u64_v: {
6468 Int = usgn ? Intrinsic::aarch64_neon_fcvtnu : Intrinsic::aarch64_neon_fcvtns;
6472 case NEON::BI__builtin_neon_vcvtp_s16_f16:
6473 case NEON::BI__builtin_neon_vcvtpq_s16_f16:
6474 case NEON::BI__builtin_neon_vcvtp_u16_f16:
6475 case NEON::BI__builtin_neon_vcvtpq_u16_f16:
6476 case NEON::BI__builtin_neon_vcvtp_s32_v:
6477 case NEON::BI__builtin_neon_vcvtpq_s32_v:
6478 case NEON::BI__builtin_neon_vcvtp_u32_v:
6479 case NEON::BI__builtin_neon_vcvtpq_u32_v:
6480 case NEON::BI__builtin_neon_vcvtp_s64_v:
6481 case NEON::BI__builtin_neon_vcvtpq_s64_v:
6482 case NEON::BI__builtin_neon_vcvtp_u64_v:
6483 case NEON::BI__builtin_neon_vcvtpq_u64_v: {
6484 Int = usgn ? Intrinsic::aarch64_neon_fcvtpu : Intrinsic::aarch64_neon_fcvtps;
6488 case NEON::BI__builtin_neon_vmulx_v:
6489 case NEON::BI__builtin_neon_vmulxq_v: {
6490 Int = Intrinsic::aarch64_neon_fmulx;
6493 case NEON::BI__builtin_neon_vmulxh_lane_f16:
6494 case NEON::BI__builtin_neon_vmulxh_laneq_f16: {
6497 Ops[1] =
Builder.CreateExtractElement(Ops[1], Ops[2],
"extract");
6499 Int = Intrinsic::aarch64_neon_fmulx;
6502 case NEON::BI__builtin_neon_vmul_lane_v:
6503 case NEON::BI__builtin_neon_vmul_laneq_v: {
6506 if (BuiltinID == NEON::BI__builtin_neon_vmul_laneq_v)
6509 llvm::FixedVectorType *VTy =
6511 Ops[1] =
Builder.CreateBitCast(Ops[1], VTy);
6512 Ops[1] =
Builder.CreateExtractElement(Ops[1], Ops[2],
"extract");
6516 case NEON::BI__builtin_neon_vpmaxnm_v:
6517 case NEON::BI__builtin_neon_vpmaxnmq_v: {
6518 Int = Intrinsic::aarch64_neon_fmaxnmp;
6521 case NEON::BI__builtin_neon_vpminnm_v:
6522 case NEON::BI__builtin_neon_vpminnmq_v: {
6523 Int = Intrinsic::aarch64_neon_fminnmp;
6526 case NEON::BI__builtin_neon_vsqrth_f16: {
6528 ? Intrinsic::experimental_constrained_sqrt
6532 case NEON::BI__builtin_neon_vsqrt_v:
6533 case NEON::BI__builtin_neon_vsqrtq_v: {
6535 ? Intrinsic::experimental_constrained_sqrt
6537 Ops[0] =
Builder.CreateBitCast(Ops[0], Ty);
6540 case NEON::BI__builtin_neon_vrbit_v:
6541 case NEON::BI__builtin_neon_vrbitq_v: {
6542 Int = Intrinsic::bitreverse;
6545 case NEON::BI__builtin_neon_vmaxv_f16: {
6546 Int = Intrinsic::aarch64_neon_fmaxv;
6548 VTy = llvm::FixedVectorType::get(
HalfTy, 4);
6549 llvm::Type *Tys[2] = {Ty, VTy};
6552 case NEON::BI__builtin_neon_vmaxvq_f16: {
6553 Int = Intrinsic::aarch64_neon_fmaxv;
6555 VTy = llvm::FixedVectorType::get(
HalfTy, 8);
6556 llvm::Type *Tys[2] = {Ty, VTy};
6559 case NEON::BI__builtin_neon_vminv_f16: {
6560 Int = Intrinsic::aarch64_neon_fminv;
6562 VTy = llvm::FixedVectorType::get(
HalfTy, 4);
6563 llvm::Type *Tys[2] = {Ty, VTy};
6566 case NEON::BI__builtin_neon_vminvq_f16: {
6567 Int = Intrinsic::aarch64_neon_fminv;
6569 VTy = llvm::FixedVectorType::get(
HalfTy, 8);
6570 llvm::Type *Tys[2] = {Ty, VTy};
6573 case NEON::BI__builtin_neon_vmaxnmv_f16: {
6574 Int = Intrinsic::aarch64_neon_fmaxnmv;
6576 VTy = llvm::FixedVectorType::get(
HalfTy, 4);
6577 llvm::Type *Tys[2] = {Ty, VTy};
6580 case NEON::BI__builtin_neon_vmaxnmvq_f16: {
6581 Int = Intrinsic::aarch64_neon_fmaxnmv;
6583 VTy = llvm::FixedVectorType::get(
HalfTy, 8);
6584 llvm::Type *Tys[2] = {Ty, VTy};
6587 case NEON::BI__builtin_neon_vminnmv_f16: {
6588 Int = Intrinsic::aarch64_neon_fminnmv;
6590 VTy = llvm::FixedVectorType::get(
HalfTy, 4);
6591 llvm::Type *Tys[2] = {Ty, VTy};
6594 case NEON::BI__builtin_neon_vminnmvq_f16: {
6595 Int = Intrinsic::aarch64_neon_fminnmv;
6597 VTy = llvm::FixedVectorType::get(
HalfTy, 8);
6598 llvm::Type *Tys[2] = {Ty, VTy};
6601 case NEON::BI__builtin_neon_vmul_n_f64: {
6604 return Builder.CreateFMul(Ops[0], RHS);
6606 case NEON::BI__builtin_neon_vaddlv_u8:
6607 case NEON::BI__builtin_neon_vaddlvq_u8:
6608 case NEON::BI__builtin_neon_vaddlv_u16:
6609 case NEON::BI__builtin_neon_vaddlvq_u16: {
6610 Int = Intrinsic::aarch64_neon_uaddlv;
6613 llvm::Type *Tys[2] = {Ty, VTy};
6615 if (VTy->getElementType()->getPrimitiveSizeInBits() == 8)
6619 case NEON::BI__builtin_neon_vaddlv_s8:
6620 case NEON::BI__builtin_neon_vaddlvq_s8:
6621 case NEON::BI__builtin_neon_vaddlv_s16:
6622 case NEON::BI__builtin_neon_vaddlvq_s16: {
6623 Int = Intrinsic::aarch64_neon_saddlv;
6626 llvm::Type *Tys[2] = {Ty, VTy};
6628 if (VTy->getElementType()->getPrimitiveSizeInBits() == 8)
6632 case NEON::BI__builtin_neon_vsri_n_v:
6633 case NEON::BI__builtin_neon_vsriq_n_v: {
6634 Int = Intrinsic::aarch64_neon_vsri;
6635 llvm::Function *Intrin =
CGM.getIntrinsic(
Int, Ty);
6638 case NEON::BI__builtin_neon_vsli_n_v:
6639 case NEON::BI__builtin_neon_vsliq_n_v: {
6640 Int = Intrinsic::aarch64_neon_vsli;
6641 llvm::Function *Intrin =
CGM.getIntrinsic(
Int, Ty);
6644 case NEON::BI__builtin_neon_vsra_n_v:
6645 case NEON::BI__builtin_neon_vsraq_n_v:
6646 Ops[0] =
Builder.CreateBitCast(Ops[0], Ty);
6648 return Builder.CreateAdd(Ops[0], Ops[1]);
6649 case NEON::BI__builtin_neon_vrsra_n_v:
6650 case NEON::BI__builtin_neon_vrsraq_n_v: {
6651 Int = usgn ? Intrinsic::aarch64_neon_urshl : Intrinsic::aarch64_neon_srshl;
6653 TmpOps.push_back(Ops[1]);
6654 TmpOps.push_back(Ops[2]);
6656 llvm::Value *tmp =
EmitNeonCall(F, TmpOps,
"vrshr_n", 1,
true);
6657 Ops[0] =
Builder.CreateBitCast(Ops[0], VTy);
6658 return Builder.CreateAdd(Ops[0], tmp);
6660 case NEON::BI__builtin_neon_vld1_v:
6661 case NEON::BI__builtin_neon_vld1q_v: {
6664 case NEON::BI__builtin_neon_vst1_v:
6665 case NEON::BI__builtin_neon_vst1q_v:
6666 Ops[1] =
Builder.CreateBitCast(Ops[1], VTy);
6668 case NEON::BI__builtin_neon_vld1_lane_v:
6669 case NEON::BI__builtin_neon_vld1q_lane_v: {
6670 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
6671 Ops[0] =
Builder.CreateAlignedLoad(VTy->getElementType(), Ops[0],
6673 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2],
"vld1_lane");
6675 case NEON::BI__builtin_neon_vldap1_lane_s64:
6676 case NEON::BI__builtin_neon_vldap1q_lane_s64: {
6677 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
6678 llvm::LoadInst *LI =
Builder.CreateAlignedLoad(
6680 LI->setAtomic(llvm::AtomicOrdering::Acquire);
6682 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2],
"vldap1_lane");
6684 case NEON::BI__builtin_neon_vld1_dup_v:
6685 case NEON::BI__builtin_neon_vld1q_dup_v: {
6686 Value *
V = PoisonValue::get(Ty);
6687 Ops[0] =
Builder.CreateAlignedLoad(VTy->getElementType(), Ops[0],
6689 llvm::Constant *CI = ConstantInt::get(
Int32Ty, 0);
6690 Ops[0] =
Builder.CreateInsertElement(
V, Ops[0], CI);
6693 case NEON::BI__builtin_neon_vst1_lane_v:
6694 case NEON::BI__builtin_neon_vst1q_lane_v:
6695 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
6696 Ops[1] =
Builder.CreateExtractElement(Ops[1], Ops[2]);
6698 case NEON::BI__builtin_neon_vstl1_lane_s64:
6699 case NEON::BI__builtin_neon_vstl1q_lane_s64: {
6700 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
6701 Ops[1] =
Builder.CreateExtractElement(Ops[1], Ops[2]);
6702 llvm::StoreInst *SI =
6704 SI->setAtomic(llvm::AtomicOrdering::Release);
6707 case NEON::BI__builtin_neon_vld2_v:
6708 case NEON::BI__builtin_neon_vld2q_v: {
6710 Function *F =
CGM.getIntrinsic(Intrinsic::aarch64_neon_ld2, Tys);
6711 Ops[1] =
Builder.CreateCall(F, Ops[1],
"vld2");
6712 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
6714 case NEON::BI__builtin_neon_vld3_v:
6715 case NEON::BI__builtin_neon_vld3q_v: {
6717 Function *F =
CGM.getIntrinsic(Intrinsic::aarch64_neon_ld3, Tys);
6718 Ops[1] =
Builder.CreateCall(F, Ops[1],
"vld3");
6719 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
6721 case NEON::BI__builtin_neon_vld4_v:
6722 case NEON::BI__builtin_neon_vld4q_v: {
6724 Function *F =
CGM.getIntrinsic(Intrinsic::aarch64_neon_ld4, Tys);
6725 Ops[1] =
Builder.CreateCall(F, Ops[1],
"vld4");
6726 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
6728 case NEON::BI__builtin_neon_vld2_dup_v:
6729 case NEON::BI__builtin_neon_vld2q_dup_v: {
6731 Function *F =
CGM.getIntrinsic(Intrinsic::aarch64_neon_ld2r, Tys);
6732 Ops[1] =
Builder.CreateCall(F, Ops[1],
"vld2");
6733 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
6735 case NEON::BI__builtin_neon_vld3_dup_v:
6736 case NEON::BI__builtin_neon_vld3q_dup_v: {
6738 Function *F =
CGM.getIntrinsic(Intrinsic::aarch64_neon_ld3r, Tys);
6739 Ops[1] =
Builder.CreateCall(F, Ops[1],
"vld3");
6740 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
6742 case NEON::BI__builtin_neon_vld4_dup_v:
6743 case NEON::BI__builtin_neon_vld4q_dup_v: {
6745 Function *F =
CGM.getIntrinsic(Intrinsic::aarch64_neon_ld4r, Tys);
6746 Ops[1] =
Builder.CreateCall(F, Ops[1],
"vld4");
6747 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
6749 case NEON::BI__builtin_neon_vld2_lane_v:
6750 case NEON::BI__builtin_neon_vld2q_lane_v: {
6751 llvm::Type *Tys[2] = { VTy, Ops[1]->getType() };
6752 Function *F =
CGM.getIntrinsic(Intrinsic::aarch64_neon_ld2lane, Tys);
6753 std::rotate(Ops.begin() + 1, Ops.begin() + 2, Ops.end());
6754 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
6755 Ops[2] =
Builder.CreateBitCast(Ops[2], Ty);
6758 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
6760 case NEON::BI__builtin_neon_vld3_lane_v:
6761 case NEON::BI__builtin_neon_vld3q_lane_v: {
6762 llvm::Type *Tys[2] = { VTy, Ops[1]->getType() };
6763 Function *F =
CGM.getIntrinsic(Intrinsic::aarch64_neon_ld3lane, Tys);
6764 std::rotate(Ops.begin() + 1, Ops.begin() + 2, Ops.end());
6765 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
6766 Ops[2] =
Builder.CreateBitCast(Ops[2], Ty);
6767 Ops[3] =
Builder.CreateBitCast(Ops[3], Ty);
6770 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
6772 case NEON::BI__builtin_neon_vld4_lane_v:
6773 case NEON::BI__builtin_neon_vld4q_lane_v: {
6774 llvm::Type *Tys[2] = { VTy, Ops[1]->getType() };
6775 Function *F =
CGM.getIntrinsic(Intrinsic::aarch64_neon_ld4lane, Tys);
6776 std::rotate(Ops.begin() + 1, Ops.begin() + 2, Ops.end());
6777 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
6778 Ops[2] =
Builder.CreateBitCast(Ops[2], Ty);
6779 Ops[3] =
Builder.CreateBitCast(Ops[3], Ty);
6780 Ops[4] =
Builder.CreateBitCast(Ops[4], Ty);
6783 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
6785 case NEON::BI__builtin_neon_vst2_v:
6786 case NEON::BI__builtin_neon_vst2q_v: {
6787 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end());
6788 llvm::Type *Tys[2] = { VTy, Ops[2]->getType() };
6789 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_st2, Tys),
6792 case NEON::BI__builtin_neon_vst2_lane_v:
6793 case NEON::BI__builtin_neon_vst2q_lane_v: {
6794 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end());
6796 llvm::Type *Tys[2] = { VTy, Ops[3]->getType() };
6797 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_st2lane, Tys),
6800 case NEON::BI__builtin_neon_vst3_v:
6801 case NEON::BI__builtin_neon_vst3q_v: {
6802 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end());
6803 llvm::Type *Tys[2] = { VTy, Ops[3]->getType() };
6804 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_st3, Tys),
6807 case NEON::BI__builtin_neon_vst3_lane_v:
6808 case NEON::BI__builtin_neon_vst3q_lane_v: {
6809 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end());
6811 llvm::Type *Tys[2] = { VTy, Ops[4]->getType() };
6812 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_st3lane, Tys),
6815 case NEON::BI__builtin_neon_vst4_v:
6816 case NEON::BI__builtin_neon_vst4q_v: {
6817 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end());
6818 llvm::Type *Tys[2] = { VTy, Ops[4]->getType() };
6819 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_st4, Tys),
6822 case NEON::BI__builtin_neon_vst4_lane_v:
6823 case NEON::BI__builtin_neon_vst4q_lane_v: {
6824 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end());
6826 llvm::Type *Tys[2] = { VTy, Ops[5]->getType() };
6827 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_st4lane, Tys),
6830 case NEON::BI__builtin_neon_vtrn_v:
6831 case NEON::BI__builtin_neon_vtrnq_v: {
6832 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
6833 Ops[2] =
Builder.CreateBitCast(Ops[2], Ty);
6834 Value *SV =
nullptr;
6836 for (
unsigned vi = 0; vi != 2; ++vi) {
6838 for (
unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) {
6839 Indices.push_back(i+vi);
6840 Indices.push_back(i+e+vi);
6843 SV =
Builder.CreateShuffleVector(Ops[1], Ops[2], Indices,
"vtrn");
6848 case NEON::BI__builtin_neon_vuzp_v:
6849 case NEON::BI__builtin_neon_vuzpq_v: {
6850 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
6851 Ops[2] =
Builder.CreateBitCast(Ops[2], Ty);
6852 Value *SV =
nullptr;
6854 for (
unsigned vi = 0; vi != 2; ++vi) {
6856 for (
unsigned i = 0, e = VTy->getNumElements(); i != e; ++i)
6857 Indices.push_back(2*i+vi);
6860 SV =
Builder.CreateShuffleVector(Ops[1], Ops[2], Indices,
"vuzp");
6865 case NEON::BI__builtin_neon_vzip_v:
6866 case NEON::BI__builtin_neon_vzipq_v: {
6867 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
6868 Ops[2] =
Builder.CreateBitCast(Ops[2], Ty);
6869 Value *SV =
nullptr;
6871 for (
unsigned vi = 0; vi != 2; ++vi) {
6873 for (
unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) {
6874 Indices.push_back((i + vi*e) >> 1);
6875 Indices.push_back(((i + vi*e) >> 1)+e);
6878 SV =
Builder.CreateShuffleVector(Ops[1], Ops[2], Indices,
"vzip");
6883 case NEON::BI__builtin_neon_vqtbl1q_v: {
6884 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl1, Ty),
6887 case NEON::BI__builtin_neon_vqtbl2q_v: {
6888 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl2, Ty),
6891 case NEON::BI__builtin_neon_vqtbl3q_v: {
6892 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl3, Ty),
6895 case NEON::BI__builtin_neon_vqtbl4q_v: {
6896 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl4, Ty),
6899 case NEON::BI__builtin_neon_vqtbx1q_v: {
6900 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx1, Ty),
6903 case NEON::BI__builtin_neon_vqtbx2q_v: {
6904 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx2, Ty),
6907 case NEON::BI__builtin_neon_vqtbx3q_v: {
6908 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx3, Ty),
6911 case NEON::BI__builtin_neon_vqtbx4q_v: {
6912 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx4, Ty),
6915 case NEON::BI__builtin_neon_vsqadd_v:
6916 case NEON::BI__builtin_neon_vsqaddq_v: {
6917 Int = Intrinsic::aarch64_neon_usqadd;
6920 case NEON::BI__builtin_neon_vuqadd_v:
6921 case NEON::BI__builtin_neon_vuqaddq_v: {
6922 Int = Intrinsic::aarch64_neon_suqadd;
6926 case NEON::BI__builtin_neon_vluti2_laneq_mf8:
6927 case NEON::BI__builtin_neon_vluti2_laneq_bf16:
6928 case NEON::BI__builtin_neon_vluti2_laneq_f16:
6929 case NEON::BI__builtin_neon_vluti2_laneq_p16:
6930 case NEON::BI__builtin_neon_vluti2_laneq_p8:
6931 case NEON::BI__builtin_neon_vluti2_laneq_s16:
6932 case NEON::BI__builtin_neon_vluti2_laneq_s8:
6933 case NEON::BI__builtin_neon_vluti2_laneq_u16:
6934 case NEON::BI__builtin_neon_vluti2_laneq_u8: {
6935 Int = Intrinsic::aarch64_neon_vluti2_laneq;
6942 case NEON::BI__builtin_neon_vluti2q_laneq_mf8:
6943 case NEON::BI__builtin_neon_vluti2q_laneq_bf16:
6944 case NEON::BI__builtin_neon_vluti2q_laneq_f16:
6945 case NEON::BI__builtin_neon_vluti2q_laneq_p16:
6946 case NEON::BI__builtin_neon_vluti2q_laneq_p8:
6947 case NEON::BI__builtin_neon_vluti2q_laneq_s16:
6948 case NEON::BI__builtin_neon_vluti2q_laneq_s8:
6949 case NEON::BI__builtin_neon_vluti2q_laneq_u16:
6950 case NEON::BI__builtin_neon_vluti2q_laneq_u8: {
6951 Int = Intrinsic::aarch64_neon_vluti2_laneq;
6958 case NEON::BI__builtin_neon_vluti2_lane_mf8:
6959 case NEON::BI__builtin_neon_vluti2_lane_bf16:
6960 case NEON::BI__builtin_neon_vluti2_lane_f16:
6961 case NEON::BI__builtin_neon_vluti2_lane_p16:
6962 case NEON::BI__builtin_neon_vluti2_lane_p8:
6963 case NEON::BI__builtin_neon_vluti2_lane_s16:
6964 case NEON::BI__builtin_neon_vluti2_lane_s8:
6965 case NEON::BI__builtin_neon_vluti2_lane_u16:
6966 case NEON::BI__builtin_neon_vluti2_lane_u8: {
6967 Int = Intrinsic::aarch64_neon_vluti2_lane;
6974 case NEON::BI__builtin_neon_vluti2q_lane_mf8:
6975 case NEON::BI__builtin_neon_vluti2q_lane_bf16:
6976 case NEON::BI__builtin_neon_vluti2q_lane_f16:
6977 case NEON::BI__builtin_neon_vluti2q_lane_p16:
6978 case NEON::BI__builtin_neon_vluti2q_lane_p8:
6979 case NEON::BI__builtin_neon_vluti2q_lane_s16:
6980 case NEON::BI__builtin_neon_vluti2q_lane_s8:
6981 case NEON::BI__builtin_neon_vluti2q_lane_u16:
6982 case NEON::BI__builtin_neon_vluti2q_lane_u8: {
6983 Int = Intrinsic::aarch64_neon_vluti2_lane;
6990 case NEON::BI__builtin_neon_vluti4q_lane_mf8:
6991 case NEON::BI__builtin_neon_vluti4q_lane_p8:
6992 case NEON::BI__builtin_neon_vluti4q_lane_s8:
6993 case NEON::BI__builtin_neon_vluti4q_lane_u8: {
6994 Int = Intrinsic::aarch64_neon_vluti4q_lane;
6997 case NEON::BI__builtin_neon_vluti4q_laneq_mf8:
6998 case NEON::BI__builtin_neon_vluti4q_laneq_p8:
6999 case NEON::BI__builtin_neon_vluti4q_laneq_s8:
7000 case NEON::BI__builtin_neon_vluti4q_laneq_u8: {
7001 Int = Intrinsic::aarch64_neon_vluti4q_laneq;
7004 case NEON::BI__builtin_neon_vluti4q_lane_bf16_x2:
7005 case NEON::BI__builtin_neon_vluti4q_lane_f16_x2:
7006 case NEON::BI__builtin_neon_vluti4q_lane_p16_x2:
7007 case NEON::BI__builtin_neon_vluti4q_lane_s16_x2:
7008 case NEON::BI__builtin_neon_vluti4q_lane_u16_x2: {
7009 Int = Intrinsic::aarch64_neon_vluti4q_lane_x2;
7012 case NEON::BI__builtin_neon_vluti4q_laneq_bf16_x2:
7013 case NEON::BI__builtin_neon_vluti4q_laneq_f16_x2:
7014 case NEON::BI__builtin_neon_vluti4q_laneq_p16_x2:
7015 case NEON::BI__builtin_neon_vluti4q_laneq_s16_x2:
7016 case NEON::BI__builtin_neon_vluti4q_laneq_u16_x2: {
7017 Int = Intrinsic::aarch64_neon_vluti4q_laneq_x2;
7020 case NEON::BI__builtin_neon_vmmlaq_f16_mf8_fpm:
7022 {llvm::FixedVectorType::get(
HalfTy, 8),
7023 llvm::FixedVectorType::get(
Int8Ty, 16)},
7025 case NEON::BI__builtin_neon_vmmlaq_f32_mf8_fpm:
7027 {llvm::FixedVectorType::get(
FloatTy, 4),
7028 llvm::FixedVectorType::get(
Int8Ty, 16)},
7030 case NEON::BI__builtin_neon_vcvt1_low_bf16_mf8_fpm:
7033 case NEON::BI__builtin_neon_vcvt1_bf16_mf8_fpm:
7034 case NEON::BI__builtin_neon_vcvt1_high_bf16_mf8_fpm:
7036 llvm::FixedVectorType::get(
BFloatTy, 8),
7037 Ops[0]->
getType(), ExtractLow, Ops, E,
"vbfcvt1");
7038 case NEON::BI__builtin_neon_vcvt2_low_bf16_mf8_fpm:
7041 case NEON::BI__builtin_neon_vcvt2_bf16_mf8_fpm:
7042 case NEON::BI__builtin_neon_vcvt2_high_bf16_mf8_fpm:
7044 llvm::FixedVectorType::get(
BFloatTy, 8),
7045 Ops[0]->
getType(), ExtractLow, Ops, E,
"vbfcvt2");
7046 case NEON::BI__builtin_neon_vcvt1_low_f16_mf8_fpm:
7049 case NEON::BI__builtin_neon_vcvt1_f16_mf8_fpm:
7050 case NEON::BI__builtin_neon_vcvt1_high_f16_mf8_fpm:
7052 llvm::FixedVectorType::get(
HalfTy, 8),
7053 Ops[0]->
getType(), ExtractLow, Ops, E,
"vbfcvt1");
7054 case NEON::BI__builtin_neon_vcvt2_low_f16_mf8_fpm:
7057 case NEON::BI__builtin_neon_vcvt2_f16_mf8_fpm:
7058 case NEON::BI__builtin_neon_vcvt2_high_f16_mf8_fpm:
7060 llvm::FixedVectorType::get(
HalfTy, 8),
7061 Ops[0]->
getType(), ExtractLow, Ops, E,
"vbfcvt2");
7062 case NEON::BI__builtin_neon_vcvt_mf8_f32_fpm:
7064 llvm::FixedVectorType::get(
Int8Ty, 8),
7065 Ops[0]->
getType(),
false, Ops, E,
"vfcvtn");
7066 case NEON::BI__builtin_neon_vcvt_mf8_f16_fpm:
7068 llvm::FixedVectorType::get(
Int8Ty, 8),
7069 llvm::FixedVectorType::get(
HalfTy, 4),
false, Ops,
7071 case NEON::BI__builtin_neon_vcvtq_mf8_f16_fpm:
7073 llvm::FixedVectorType::get(
Int8Ty, 16),
7074 llvm::FixedVectorType::get(
HalfTy, 8),
false, Ops,
7076 case NEON::BI__builtin_neon_vcvt_high_mf8_f32_fpm: {
7077 llvm::Type *Ty = llvm::FixedVectorType::get(
Int8Ty, 16);
7078 Ops[0] =
Builder.CreateInsertVector(Ty, PoisonValue::get(Ty), Ops[0],
7081 Ops[1]->
getType(),
false, Ops, E,
"vfcvtn2");
7084 case NEON::BI__builtin_neon_vdot_f16_mf8_fpm:
7085 case NEON::BI__builtin_neon_vdotq_f16_mf8_fpm:
7088 case NEON::BI__builtin_neon_vdot_lane_f16_mf8_fpm:
7089 case NEON::BI__builtin_neon_vdotq_lane_f16_mf8_fpm:
7090 ExtendLaneArg =
true;
7092 case NEON::BI__builtin_neon_vdot_laneq_f16_mf8_fpm:
7093 case NEON::BI__builtin_neon_vdotq_laneq_f16_mf8_fpm:
7095 ExtendLaneArg,
HalfTy, Ops, E,
"fdot2_lane");
7096 case NEON::BI__builtin_neon_vdot_f32_mf8_fpm:
7097 case NEON::BI__builtin_neon_vdotq_f32_mf8_fpm:
7100 case NEON::BI__builtin_neon_vdot_lane_f32_mf8_fpm:
7101 case NEON::BI__builtin_neon_vdotq_lane_f32_mf8_fpm:
7102 ExtendLaneArg =
true;
7104 case NEON::BI__builtin_neon_vdot_laneq_f32_mf8_fpm:
7105 case NEON::BI__builtin_neon_vdotq_laneq_f32_mf8_fpm:
7107 ExtendLaneArg,
FloatTy, Ops, E,
"fdot4_lane");
7109 case NEON::BI__builtin_neon_vdot_f32_f16:
7110 case NEON::BI__builtin_neon_vdotq_f32_f16: {
7111 llvm::Type *InputTy =
7112 llvm::FixedVectorType::get(
HalfTy, Ty->getPrimitiveSizeInBits() / 16);
7113 llvm::Type *Tys[2] = {Ty, InputTy};
7114 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_fdot, Tys),
7118 case NEON::BI__builtin_neon_vdot_lane_f32_f16:
7119 case NEON::BI__builtin_neon_vdot_laneq_f32_f16:
7120 case NEON::BI__builtin_neon_vdotq_lane_f32_f16:
7121 case NEON::BI__builtin_neon_vdotq_laneq_f32_f16: {
7122 llvm::FixedVectorType *InputTy =
7123 llvm::FixedVectorType::get(
HalfTy, Ty->getPrimitiveSizeInBits() / 16);
7124 llvm::FixedVectorType *LaneTy = llvm::FixedVectorType::get(
7128 Ops[2] =
Builder.CreateBitCast(Ops[2], LaneTy);
7130 InputTy->getElementCount());
7131 llvm::Type *Tys[2] = {Ty, InputTy};
7133 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_fdot, Tys),
7137 case NEON::BI__builtin_neon_vmlalbq_f16_mf8_fpm:
7139 {llvm::FixedVectorType::get(
HalfTy, 8)}, Ops, E,
7141 case NEON::BI__builtin_neon_vmlaltq_f16_mf8_fpm:
7143 {llvm::FixedVectorType::get(
HalfTy, 8)}, Ops, E,
7145 case NEON::BI__builtin_neon_vmlallbbq_f32_mf8_fpm:
7147 {llvm::FixedVectorType::get(
FloatTy, 4)}, Ops, E,
7149 case NEON::BI__builtin_neon_vmlallbtq_f32_mf8_fpm:
7151 {llvm::FixedVectorType::get(
FloatTy, 4)}, Ops, E,
7153 case NEON::BI__builtin_neon_vmlalltbq_f32_mf8_fpm:
7155 {llvm::FixedVectorType::get(
FloatTy, 4)}, Ops, E,
7157 case NEON::BI__builtin_neon_vmlallttq_f32_mf8_fpm:
7159 {llvm::FixedVectorType::get(
FloatTy, 4)}, Ops, E,
7161 case NEON::BI__builtin_neon_vmlalbq_lane_f16_mf8_fpm:
7162 ExtendLaneArg =
true;
7164 case NEON::BI__builtin_neon_vmlalbq_laneq_f16_mf8_fpm:
7166 ExtendLaneArg,
HalfTy, Ops, E,
"vmlal_lane");
7167 case NEON::BI__builtin_neon_vmlaltq_lane_f16_mf8_fpm:
7168 ExtendLaneArg =
true;
7170 case NEON::BI__builtin_neon_vmlaltq_laneq_f16_mf8_fpm:
7172 ExtendLaneArg,
HalfTy, Ops, E,
"vmlal_lane");
7173 case NEON::BI__builtin_neon_vmlallbbq_lane_f32_mf8_fpm:
7174 ExtendLaneArg =
true;
7176 case NEON::BI__builtin_neon_vmlallbbq_laneq_f32_mf8_fpm:
7178 ExtendLaneArg,
FloatTy, Ops, E,
"vmlall_lane");
7179 case NEON::BI__builtin_neon_vmlallbtq_lane_f32_mf8_fpm:
7180 ExtendLaneArg =
true;
7182 case NEON::BI__builtin_neon_vmlallbtq_laneq_f32_mf8_fpm:
7184 ExtendLaneArg,
FloatTy, Ops, E,
"vmlall_lane");
7185 case NEON::BI__builtin_neon_vmlalltbq_lane_f32_mf8_fpm:
7186 ExtendLaneArg =
true;
7188 case NEON::BI__builtin_neon_vmlalltbq_laneq_f32_mf8_fpm:
7190 ExtendLaneArg,
FloatTy, Ops, E,
"vmlall_lane");
7191 case NEON::BI__builtin_neon_vmlallttq_lane_f32_mf8_fpm:
7192 ExtendLaneArg =
true;
7194 case NEON::BI__builtin_neon_vmlallttq_laneq_f32_mf8_fpm:
7196 ExtendLaneArg,
FloatTy, Ops, E,
"vmlall_lane");
7197 case NEON::BI__builtin_neon_vamin_f16:
7198 case NEON::BI__builtin_neon_vaminq_f16:
7199 case NEON::BI__builtin_neon_vamin_f32:
7200 case NEON::BI__builtin_neon_vaminq_f32:
7201 case NEON::BI__builtin_neon_vaminq_f64: {
7202 Int = Intrinsic::aarch64_neon_famin;
7205 case NEON::BI__builtin_neon_vamax_f16:
7206 case NEON::BI__builtin_neon_vamaxq_f16:
7207 case NEON::BI__builtin_neon_vamax_f32:
7208 case NEON::BI__builtin_neon_vamaxq_f32:
7209 case NEON::BI__builtin_neon_vamaxq_f64: {
7210 Int = Intrinsic::aarch64_neon_famax;
7213 case NEON::BI__builtin_neon_vscale_f16:
7214 case NEON::BI__builtin_neon_vscaleq_f16:
7215 case NEON::BI__builtin_neon_vscale_f32:
7216 case NEON::BI__builtin_neon_vscaleq_f32:
7217 case NEON::BI__builtin_neon_vscaleq_f64: {
7218 Int = Intrinsic::aarch64_neon_fp8_fscale;