543 NEONMAP1(__a32_vcvt_bf16_f32, arm_neon_vcvtfp2bf, 0),
551 NEONMAP1(vabsq_v, arm_neon_vabs, 0),
555 NEONMAP1(vaesdq_u8, arm_neon_aesd, 0),
556 NEONMAP1(vaeseq_u8, arm_neon_aese, 0),
557 NEONMAP1(vaesimcq_u8, arm_neon_aesimc, 0),
558 NEONMAP1(vaesmcq_u8, arm_neon_aesmc, 0),
559 NEONMAP1(vbfdot_f32, arm_neon_bfdot, 0),
560 NEONMAP1(vbfdotq_f32, arm_neon_bfdot, 0),
561 NEONMAP1(vbfmlalbq_f32, arm_neon_bfmlalb, 0),
562 NEONMAP1(vbfmlaltq_f32, arm_neon_bfmlalt, 0),
563 NEONMAP1(vbfmmlaq_f32, arm_neon_bfmmla, 0),
576 NEONMAP1(vcage_v, arm_neon_vacge, 0),
577 NEONMAP1(vcageq_v, arm_neon_vacge, 0),
578 NEONMAP1(vcagt_v, arm_neon_vacgt, 0),
579 NEONMAP1(vcagtq_v, arm_neon_vacgt, 0),
580 NEONMAP1(vcale_v, arm_neon_vacge, 0),
581 NEONMAP1(vcaleq_v, arm_neon_vacge, 0),
582 NEONMAP1(vcalt_v, arm_neon_vacgt, 0),
583 NEONMAP1(vcaltq_v, arm_neon_vacgt, 0),
603 NEONMAP1(vcvt_n_f16_s16, arm_neon_vcvtfxs2fp, 0),
604 NEONMAP1(vcvt_n_f16_u16, arm_neon_vcvtfxu2fp, 0),
605 NEONMAP2(vcvt_n_f32_v, arm_neon_vcvtfxu2fp, arm_neon_vcvtfxs2fp, 0),
606 NEONMAP1(vcvt_n_s16_f16, arm_neon_vcvtfp2fxs, 0),
607 NEONMAP1(vcvt_n_s32_v, arm_neon_vcvtfp2fxs, 0),
608 NEONMAP1(vcvt_n_s64_v, arm_neon_vcvtfp2fxs, 0),
609 NEONMAP1(vcvt_n_u16_f16, arm_neon_vcvtfp2fxu, 0),
610 NEONMAP1(vcvt_n_u32_v, arm_neon_vcvtfp2fxu, 0),
611 NEONMAP1(vcvt_n_u64_v, arm_neon_vcvtfp2fxu, 0),
618 NEONMAP1(vcvta_s16_f16, arm_neon_vcvtas, 0),
619 NEONMAP1(vcvta_s32_v, arm_neon_vcvtas, 0),
620 NEONMAP1(vcvta_s64_v, arm_neon_vcvtas, 0),
621 NEONMAP1(vcvta_u16_f16, arm_neon_vcvtau, 0),
622 NEONMAP1(vcvta_u32_v, arm_neon_vcvtau, 0),
623 NEONMAP1(vcvta_u64_v, arm_neon_vcvtau, 0),
624 NEONMAP1(vcvtaq_s16_f16, arm_neon_vcvtas, 0),
625 NEONMAP1(vcvtaq_s32_v, arm_neon_vcvtas, 0),
626 NEONMAP1(vcvtaq_s64_v, arm_neon_vcvtas, 0),
627 NEONMAP1(vcvtaq_u16_f16, arm_neon_vcvtau, 0),
628 NEONMAP1(vcvtaq_u32_v, arm_neon_vcvtau, 0),
629 NEONMAP1(vcvtaq_u64_v, arm_neon_vcvtau, 0),
630 NEONMAP1(vcvth_bf16_f32, arm_neon_vcvtbfp2bf, 0),
631 NEONMAP1(vcvtm_s16_f16, arm_neon_vcvtms, 0),
632 NEONMAP1(vcvtm_s32_v, arm_neon_vcvtms, 0),
633 NEONMAP1(vcvtm_s64_v, arm_neon_vcvtms, 0),
634 NEONMAP1(vcvtm_u16_f16, arm_neon_vcvtmu, 0),
635 NEONMAP1(vcvtm_u32_v, arm_neon_vcvtmu, 0),
636 NEONMAP1(vcvtm_u64_v, arm_neon_vcvtmu, 0),
637 NEONMAP1(vcvtmq_s16_f16, arm_neon_vcvtms, 0),
638 NEONMAP1(vcvtmq_s32_v, arm_neon_vcvtms, 0),
639 NEONMAP1(vcvtmq_s64_v, arm_neon_vcvtms, 0),
640 NEONMAP1(vcvtmq_u16_f16, arm_neon_vcvtmu, 0),
641 NEONMAP1(vcvtmq_u32_v, arm_neon_vcvtmu, 0),
642 NEONMAP1(vcvtmq_u64_v, arm_neon_vcvtmu, 0),
643 NEONMAP1(vcvtn_s16_f16, arm_neon_vcvtns, 0),
644 NEONMAP1(vcvtn_s32_v, arm_neon_vcvtns, 0),
645 NEONMAP1(vcvtn_s64_v, arm_neon_vcvtns, 0),
646 NEONMAP1(vcvtn_u16_f16, arm_neon_vcvtnu, 0),
647 NEONMAP1(vcvtn_u32_v, arm_neon_vcvtnu, 0),
648 NEONMAP1(vcvtn_u64_v, arm_neon_vcvtnu, 0),
649 NEONMAP1(vcvtnq_s16_f16, arm_neon_vcvtns, 0),
650 NEONMAP1(vcvtnq_s32_v, arm_neon_vcvtns, 0),
651 NEONMAP1(vcvtnq_s64_v, arm_neon_vcvtns, 0),
652 NEONMAP1(vcvtnq_u16_f16, arm_neon_vcvtnu, 0),
653 NEONMAP1(vcvtnq_u32_v, arm_neon_vcvtnu, 0),
654 NEONMAP1(vcvtnq_u64_v, arm_neon_vcvtnu, 0),
655 NEONMAP1(vcvtp_s16_f16, arm_neon_vcvtps, 0),
656 NEONMAP1(vcvtp_s32_v, arm_neon_vcvtps, 0),
657 NEONMAP1(vcvtp_s64_v, arm_neon_vcvtps, 0),
658 NEONMAP1(vcvtp_u16_f16, arm_neon_vcvtpu, 0),
659 NEONMAP1(vcvtp_u32_v, arm_neon_vcvtpu, 0),
660 NEONMAP1(vcvtp_u64_v, arm_neon_vcvtpu, 0),
661 NEONMAP1(vcvtpq_s16_f16, arm_neon_vcvtps, 0),
662 NEONMAP1(vcvtpq_s32_v, arm_neon_vcvtps, 0),
663 NEONMAP1(vcvtpq_s64_v, arm_neon_vcvtps, 0),
664 NEONMAP1(vcvtpq_u16_f16, arm_neon_vcvtpu, 0),
665 NEONMAP1(vcvtpq_u32_v, arm_neon_vcvtpu, 0),
666 NEONMAP1(vcvtpq_u64_v, arm_neon_vcvtpu, 0),
670 NEONMAP1(vcvtq_n_f16_s16, arm_neon_vcvtfxs2fp, 0),
671 NEONMAP1(vcvtq_n_f16_u16, arm_neon_vcvtfxu2fp, 0),
672 NEONMAP2(vcvtq_n_f32_v, arm_neon_vcvtfxu2fp, arm_neon_vcvtfxs2fp, 0),
673 NEONMAP1(vcvtq_n_s16_f16, arm_neon_vcvtfp2fxs, 0),
674 NEONMAP1(vcvtq_n_s32_v, arm_neon_vcvtfp2fxs, 0),
675 NEONMAP1(vcvtq_n_s64_v, arm_neon_vcvtfp2fxs, 0),
676 NEONMAP1(vcvtq_n_u16_f16, arm_neon_vcvtfp2fxu, 0),
677 NEONMAP1(vcvtq_n_u32_v, arm_neon_vcvtfp2fxu, 0),
678 NEONMAP1(vcvtq_n_u64_v, arm_neon_vcvtfp2fxu, 0),
685 NEONMAP1(vdot_s32, arm_neon_sdot, 0),
686 NEONMAP1(vdot_u32, arm_neon_udot, 0),
687 NEONMAP1(vdotq_s32, arm_neon_sdot, 0),
688 NEONMAP1(vdotq_u32, arm_neon_udot, 0),
699 NEONMAP1(vld1_x2_v, arm_neon_vld1x2, 0),
700 NEONMAP1(vld1_x3_v, arm_neon_vld1x3, 0),
701 NEONMAP1(vld1_x4_v, arm_neon_vld1x4, 0),
703 NEONMAP1(vld1q_v, arm_neon_vld1, 0),
704 NEONMAP1(vld1q_x2_v, arm_neon_vld1x2, 0),
705 NEONMAP1(vld1q_x3_v, arm_neon_vld1x3, 0),
706 NEONMAP1(vld1q_x4_v, arm_neon_vld1x4, 0),
707 NEONMAP1(vld2_dup_v, arm_neon_vld2dup, 0),
708 NEONMAP1(vld2_lane_v, arm_neon_vld2lane, 0),
710 NEONMAP1(vld2q_dup_v, arm_neon_vld2dup, 0),
711 NEONMAP1(vld2q_lane_v, arm_neon_vld2lane, 0),
712 NEONMAP1(vld2q_v, arm_neon_vld2, 0),
713 NEONMAP1(vld3_dup_v, arm_neon_vld3dup, 0),
714 NEONMAP1(vld3_lane_v, arm_neon_vld3lane, 0),
716 NEONMAP1(vld3q_dup_v, arm_neon_vld3dup, 0),
717 NEONMAP1(vld3q_lane_v, arm_neon_vld3lane, 0),
718 NEONMAP1(vld3q_v, arm_neon_vld3, 0),
719 NEONMAP1(vld4_dup_v, arm_neon_vld4dup, 0),
720 NEONMAP1(vld4_lane_v, arm_neon_vld4lane, 0),
722 NEONMAP1(vld4q_dup_v, arm_neon_vld4dup, 0),
723 NEONMAP1(vld4q_lane_v, arm_neon_vld4lane, 0),
724 NEONMAP1(vld4q_v, arm_neon_vld4, 0),
733 NEONMAP1(vmmlaq_s32, arm_neon_smmla, 0),
734 NEONMAP1(vmmlaq_u32, arm_neon_ummla, 0),
752 NEONMAP2(vqdmlal_v, arm_neon_vqdmull, sadd_sat, 0),
753 NEONMAP2(vqdmlsl_v, arm_neon_vqdmull, ssub_sat, 0),
777 NEONMAP1(vqshlu_n_v, arm_neon_vqshiftsu, 0),
778 NEONMAP1(vqshluq_n_v, arm_neon_vqshiftsu, 0),
782 NEONMAP2(vrecpe_v, arm_neon_vrecpe, arm_neon_vrecpe, 0),
783 NEONMAP2(vrecpeq_v, arm_neon_vrecpe, arm_neon_vrecpe, 0),
806 NEONMAP2(vrsqrte_v, arm_neon_vrsqrte, arm_neon_vrsqrte, 0),
807 NEONMAP2(vrsqrteq_v, arm_neon_vrsqrte, arm_neon_vrsqrte, 0),
811 NEONMAP1(vsha1su0q_u32, arm_neon_sha1su0, 0),
812 NEONMAP1(vsha1su1q_u32, arm_neon_sha1su1, 0),
813 NEONMAP1(vsha256h2q_u32, arm_neon_sha256h2, 0),
814 NEONMAP1(vsha256hq_u32, arm_neon_sha256h, 0),
815 NEONMAP1(vsha256su0q_u32, arm_neon_sha256su0, 0),
816 NEONMAP1(vsha256su1q_u32, arm_neon_sha256su1, 0),
826 NEONMAP1(vst1_x2_v, arm_neon_vst1x2, 0),
827 NEONMAP1(vst1_x3_v, arm_neon_vst1x3, 0),
828 NEONMAP1(vst1_x4_v, arm_neon_vst1x4, 0),
829 NEONMAP1(vst1q_v, arm_neon_vst1, 0),
830 NEONMAP1(vst1q_x2_v, arm_neon_vst1x2, 0),
831 NEONMAP1(vst1q_x3_v, arm_neon_vst1x3, 0),
832 NEONMAP1(vst1q_x4_v, arm_neon_vst1x4, 0),
833 NEONMAP1(vst2_lane_v, arm_neon_vst2lane, 0),
835 NEONMAP1(vst2q_lane_v, arm_neon_vst2lane, 0),
836 NEONMAP1(vst2q_v, arm_neon_vst2, 0),
837 NEONMAP1(vst3_lane_v, arm_neon_vst3lane, 0),
839 NEONMAP1(vst3q_lane_v, arm_neon_vst3lane, 0),
840 NEONMAP1(vst3q_v, arm_neon_vst3, 0),
841 NEONMAP1(vst4_lane_v, arm_neon_vst4lane, 0),
843 NEONMAP1(vst4q_lane_v, arm_neon_vst4lane, 0),
844 NEONMAP1(vst4q_v, arm_neon_vst4, 0),
850 NEONMAP1(vusdot_s32, arm_neon_usdot, 0),
851 NEONMAP1(vusdotq_s32, arm_neon_usdot, 0),
852 NEONMAP1(vusmmlaq_s32, arm_neon_usmmla, 0),
1123 unsigned BuiltinID,
unsigned LLVMIntrinsic,
unsigned AltLLVMIntrinsic,
1124 const char *NameHint,
unsigned Modifier,
const CallExpr *E,
1126 llvm::Triple::ArchType
Arch) {
1132 std::optional<llvm::APSInt> NeonTypeConst =
1139 const bool Usgn =
Type.isUnsigned();
1140 const bool Quad =
Type.isQuad();
1141 const bool Floating =
Type.isFloatingPoint();
1143 const bool AllowBFloatArgsAndRet =
1146 llvm::FixedVectorType *VTy =
1147 GetNeonType(
this,
Type, HasFastHalfType,
false, AllowBFloatArgsAndRet);
1148 llvm::Type *Ty = VTy;
1152 auto getAlignmentValue32 = [&](
Address addr) ->
Value* {
1153 return Builder.getInt32(addr.getAlignment().getQuantity());
1156 unsigned Int = LLVMIntrinsic;
1158 Int = AltLLVMIntrinsic;
1160 switch (BuiltinID) {
1162 case NEON::BI__builtin_neon_splat_lane_v:
1163 case NEON::BI__builtin_neon_splat_laneq_v:
1164 case NEON::BI__builtin_neon_splatq_lane_v:
1165 case NEON::BI__builtin_neon_splatq_laneq_v: {
1166 auto NumElements = VTy->getElementCount();
1167 if (BuiltinID == NEON::BI__builtin_neon_splatq_lane_v)
1168 NumElements = NumElements * 2;
1169 if (BuiltinID == NEON::BI__builtin_neon_splat_laneq_v)
1170 NumElements = NumElements.divideCoefficientBy(2);
1172 Ops[0] =
Builder.CreateBitCast(Ops[0], VTy);
1175 case NEON::BI__builtin_neon_vpadd_v:
1176 case NEON::BI__builtin_neon_vpaddq_v:
1178 if (VTy->getElementType()->isFloatingPointTy() &&
1179 Int == Intrinsic::aarch64_neon_addp)
1180 Int = Intrinsic::aarch64_neon_faddp;
1182 case NEON::BI__builtin_neon_vabs_v:
1183 case NEON::BI__builtin_neon_vabsq_v:
1184 if (VTy->getElementType()->isFloatingPointTy())
1185 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::fabs, Ty), Ops,
"vabs");
1186 return EmitNeonCall(
CGM.getIntrinsic(LLVMIntrinsic, Ty), Ops,
"vabs");
1187 case NEON::BI__builtin_neon_vadd_v:
1188 case NEON::BI__builtin_neon_vaddq_v: {
1189 llvm::Type *VTy = llvm::FixedVectorType::get(
Int8Ty, Quad ? 16 : 8);
1190 Ops[0] =
Builder.CreateBitCast(Ops[0], VTy);
1191 Ops[1] =
Builder.CreateBitCast(Ops[1], VTy);
1192 Ops[0] =
Builder.CreateXor(Ops[0], Ops[1]);
1193 return Builder.CreateBitCast(Ops[0], Ty);
1195 case NEON::BI__builtin_neon_vaddhn_v: {
1196 llvm::FixedVectorType *SrcTy =
1197 llvm::FixedVectorType::getExtendedElementVectorType(VTy);
1200 Ops[0] =
Builder.CreateBitCast(Ops[0], SrcTy);
1201 Ops[1] =
Builder.CreateBitCast(Ops[1], SrcTy);
1202 Ops[0] =
Builder.CreateAdd(Ops[0], Ops[1],
"vaddhn");
1206 ConstantInt::get(SrcTy, SrcTy->getScalarSizeInBits() / 2);
1207 Ops[0] =
Builder.CreateLShr(Ops[0], ShiftAmt,
"vaddhn");
1210 return Builder.CreateTrunc(Ops[0], VTy,
"vaddhn");
1212 case NEON::BI__builtin_neon_vcale_v:
1213 case NEON::BI__builtin_neon_vcaleq_v:
1214 case NEON::BI__builtin_neon_vcalt_v:
1215 case NEON::BI__builtin_neon_vcaltq_v:
1216 std::swap(Ops[0], Ops[1]);
1218 case NEON::BI__builtin_neon_vcage_v:
1219 case NEON::BI__builtin_neon_vcageq_v:
1220 case NEON::BI__builtin_neon_vcagt_v:
1221 case NEON::BI__builtin_neon_vcagtq_v: {
1223 switch (VTy->getScalarSizeInBits()) {
1224 default: llvm_unreachable(
"unexpected type");
1235 auto *VecFlt = llvm::FixedVectorType::get(Ty, VTy->getNumElements());
1236 llvm::Type *Tys[] = { VTy, VecFlt };
1237 Function *F =
CGM.getIntrinsic(LLVMIntrinsic, Tys);
1240 case NEON::BI__builtin_neon_vceqz_v:
1241 case NEON::BI__builtin_neon_vceqzq_v:
1243 Ops[0], Ty, Floating ? ICmpInst::FCMP_OEQ : ICmpInst::ICMP_EQ,
"vceqz");
1244 case NEON::BI__builtin_neon_vcgez_v:
1245 case NEON::BI__builtin_neon_vcgezq_v:
1247 Ops[0], Ty, Floating ? ICmpInst::FCMP_OGE : ICmpInst::ICMP_SGE,
1249 case NEON::BI__builtin_neon_vclez_v:
1250 case NEON::BI__builtin_neon_vclezq_v:
1252 Ops[0], Ty, Floating ? ICmpInst::FCMP_OLE : ICmpInst::ICMP_SLE,
1254 case NEON::BI__builtin_neon_vcgtz_v:
1255 case NEON::BI__builtin_neon_vcgtzq_v:
1257 Ops[0], Ty, Floating ? ICmpInst::FCMP_OGT : ICmpInst::ICMP_SGT,
1259 case NEON::BI__builtin_neon_vcltz_v:
1260 case NEON::BI__builtin_neon_vcltzq_v:
1262 Ops[0], Ty, Floating ? ICmpInst::FCMP_OLT : ICmpInst::ICMP_SLT,
1264 case NEON::BI__builtin_neon_vclz_v:
1265 case NEON::BI__builtin_neon_vclzq_v:
1270 case NEON::BI__builtin_neon_vcvt_f32_v:
1271 case NEON::BI__builtin_neon_vcvtq_f32_v:
1272 Ops[0] =
Builder.CreateBitCast(Ops[0], Ty);
1275 return Usgn ?
Builder.CreateUIToFP(Ops[0], Ty,
"vcvt")
1276 :
Builder.CreateSIToFP(Ops[0], Ty,
"vcvt");
1277 case NEON::BI__builtin_neon_vcvt_f16_s16:
1278 case NEON::BI__builtin_neon_vcvt_f16_u16:
1279 case NEON::BI__builtin_neon_vcvtq_f16_s16:
1280 case NEON::BI__builtin_neon_vcvtq_f16_u16:
1281 Ops[0] =
Builder.CreateBitCast(Ops[0], Ty);
1284 return Usgn ?
Builder.CreateUIToFP(Ops[0], Ty,
"vcvt")
1285 :
Builder.CreateSIToFP(Ops[0], Ty,
"vcvt");
1286 case NEON::BI__builtin_neon_vcvt_n_f16_s16:
1287 case NEON::BI__builtin_neon_vcvt_n_f16_u16:
1288 case NEON::BI__builtin_neon_vcvtq_n_f16_s16:
1289 case NEON::BI__builtin_neon_vcvtq_n_f16_u16: {
1294 case NEON::BI__builtin_neon_vcvt_n_f32_v:
1295 case NEON::BI__builtin_neon_vcvt_n_f64_v:
1296 case NEON::BI__builtin_neon_vcvtq_n_f32_v:
1297 case NEON::BI__builtin_neon_vcvtq_n_f64_v: {
1299 Int = Usgn ? LLVMIntrinsic : AltLLVMIntrinsic;
1303 case NEON::BI__builtin_neon_vcvt_n_s16_f16:
1304 case NEON::BI__builtin_neon_vcvt_n_s32_v:
1305 case NEON::BI__builtin_neon_vcvt_n_u16_f16:
1306 case NEON::BI__builtin_neon_vcvt_n_u32_v:
1307 case NEON::BI__builtin_neon_vcvt_n_s64_v:
1308 case NEON::BI__builtin_neon_vcvt_n_u64_v:
1309 case NEON::BI__builtin_neon_vcvtq_n_s16_f16:
1310 case NEON::BI__builtin_neon_vcvtq_n_s32_v:
1311 case NEON::BI__builtin_neon_vcvtq_n_u16_f16:
1312 case NEON::BI__builtin_neon_vcvtq_n_u32_v:
1313 case NEON::BI__builtin_neon_vcvtq_n_s64_v:
1314 case NEON::BI__builtin_neon_vcvtq_n_u64_v: {
1316 Function *F =
CGM.getIntrinsic(LLVMIntrinsic, Tys);
1319 case NEON::BI__builtin_neon_vcvt_s32_v:
1320 case NEON::BI__builtin_neon_vcvt_u32_v:
1321 case NEON::BI__builtin_neon_vcvt_s64_v:
1322 case NEON::BI__builtin_neon_vcvt_u64_v:
1323 case NEON::BI__builtin_neon_vcvt_s16_f16:
1324 case NEON::BI__builtin_neon_vcvt_u16_f16:
1325 case NEON::BI__builtin_neon_vcvtq_s32_v:
1326 case NEON::BI__builtin_neon_vcvtq_u32_v:
1327 case NEON::BI__builtin_neon_vcvtq_s64_v:
1328 case NEON::BI__builtin_neon_vcvtq_u64_v:
1329 case NEON::BI__builtin_neon_vcvtq_s16_f16:
1330 case NEON::BI__builtin_neon_vcvtq_u16_f16: {
1334 if (!
Builder.getIsFPConstrained())
1335 Int = Usgn ? Intrinsic::fptoui_sat : Intrinsic::fptosi_sat;
1336 llvm::Type *Tys[2] = {Ty, Ops[0]->getType()};
1341 return Usgn ?
Builder.CreateFPToUI(Ops[0], Ty,
"vcvt")
1342 :
Builder.CreateFPToSI(Ops[0], Ty,
"vcvt");
1344 case NEON::BI__builtin_neon_vcvta_s16_f16:
1345 case NEON::BI__builtin_neon_vcvta_s32_v:
1346 case NEON::BI__builtin_neon_vcvta_s64_v:
1347 case NEON::BI__builtin_neon_vcvta_u16_f16:
1348 case NEON::BI__builtin_neon_vcvta_u32_v:
1349 case NEON::BI__builtin_neon_vcvta_u64_v:
1350 case NEON::BI__builtin_neon_vcvtaq_s16_f16:
1351 case NEON::BI__builtin_neon_vcvtaq_s32_v:
1352 case NEON::BI__builtin_neon_vcvtaq_s64_v:
1353 case NEON::BI__builtin_neon_vcvtaq_u16_f16:
1354 case NEON::BI__builtin_neon_vcvtaq_u32_v:
1355 case NEON::BI__builtin_neon_vcvtaq_u64_v:
1356 case NEON::BI__builtin_neon_vcvtn_s16_f16:
1357 case NEON::BI__builtin_neon_vcvtn_s32_v:
1358 case NEON::BI__builtin_neon_vcvtn_s64_v:
1359 case NEON::BI__builtin_neon_vcvtn_u16_f16:
1360 case NEON::BI__builtin_neon_vcvtn_u32_v:
1361 case NEON::BI__builtin_neon_vcvtn_u64_v:
1362 case NEON::BI__builtin_neon_vcvtnq_s16_f16:
1363 case NEON::BI__builtin_neon_vcvtnq_s32_v:
1364 case NEON::BI__builtin_neon_vcvtnq_s64_v:
1365 case NEON::BI__builtin_neon_vcvtnq_u16_f16:
1366 case NEON::BI__builtin_neon_vcvtnq_u32_v:
1367 case NEON::BI__builtin_neon_vcvtnq_u64_v:
1368 case NEON::BI__builtin_neon_vcvtp_s16_f16:
1369 case NEON::BI__builtin_neon_vcvtp_s32_v:
1370 case NEON::BI__builtin_neon_vcvtp_s64_v:
1371 case NEON::BI__builtin_neon_vcvtp_u16_f16:
1372 case NEON::BI__builtin_neon_vcvtp_u32_v:
1373 case NEON::BI__builtin_neon_vcvtp_u64_v:
1374 case NEON::BI__builtin_neon_vcvtpq_s16_f16:
1375 case NEON::BI__builtin_neon_vcvtpq_s32_v:
1376 case NEON::BI__builtin_neon_vcvtpq_s64_v:
1377 case NEON::BI__builtin_neon_vcvtpq_u16_f16:
1378 case NEON::BI__builtin_neon_vcvtpq_u32_v:
1379 case NEON::BI__builtin_neon_vcvtpq_u64_v:
1380 case NEON::BI__builtin_neon_vcvtm_s16_f16:
1381 case NEON::BI__builtin_neon_vcvtm_s32_v:
1382 case NEON::BI__builtin_neon_vcvtm_s64_v:
1383 case NEON::BI__builtin_neon_vcvtm_u16_f16:
1384 case NEON::BI__builtin_neon_vcvtm_u32_v:
1385 case NEON::BI__builtin_neon_vcvtm_u64_v:
1386 case NEON::BI__builtin_neon_vcvtmq_s16_f16:
1387 case NEON::BI__builtin_neon_vcvtmq_s32_v:
1388 case NEON::BI__builtin_neon_vcvtmq_s64_v:
1389 case NEON::BI__builtin_neon_vcvtmq_u16_f16:
1390 case NEON::BI__builtin_neon_vcvtmq_u32_v:
1391 case NEON::BI__builtin_neon_vcvtmq_u64_v: {
1393 return EmitNeonCall(
CGM.getIntrinsic(LLVMIntrinsic, Tys), Ops, NameHint);
1395 case NEON::BI__builtin_neon_vcvtx_f32_v: {
1396 llvm::Type *Tys[2] = { VTy->getTruncatedElementVectorType(VTy), Ty};
1397 return EmitNeonCall(
CGM.getIntrinsic(LLVMIntrinsic, Tys), Ops, NameHint);
1400 case NEON::BI__builtin_neon_vext_v:
1401 case NEON::BI__builtin_neon_vextq_v: {
1404 for (
unsigned i = 0, e = VTy->getNumElements(); i != e; ++i)
1405 Indices.push_back(i+CV);
1407 Ops[0] =
Builder.CreateBitCast(Ops[0], Ty);
1408 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
1409 return Builder.CreateShuffleVector(Ops[0], Ops[1], Indices,
"vext");
1411 case NEON::BI__builtin_neon_vfma_v:
1412 case NEON::BI__builtin_neon_vfmaq_v: {
1413 Ops[0] =
Builder.CreateBitCast(Ops[0], Ty);
1414 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
1415 Ops[2] =
Builder.CreateBitCast(Ops[2], Ty);
1419 *
this, Intrinsic::fma, Intrinsic::experimental_constrained_fma, Ty,
1420 {Ops[1], Ops[2], Ops[0]});
1422 case NEON::BI__builtin_neon_vld1_x2_v:
1423 case NEON::BI__builtin_neon_vld1q_x2_v:
1424 case NEON::BI__builtin_neon_vld1_x3_v:
1425 case NEON::BI__builtin_neon_vld1q_x3_v:
1426 case NEON::BI__builtin_neon_vld1_x4_v:
1427 case NEON::BI__builtin_neon_vld1q_x4_v: {
1429 Function *F =
CGM.getIntrinsic(LLVMIntrinsic, Tys);
1430 Ops[1] =
Builder.CreateCall(F, Ops[1],
"vld1xN");
1431 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
1433 case NEON::BI__builtin_neon_vld1_v:
1434 case NEON::BI__builtin_neon_vld1q_v: {
1436 Ops.push_back(getAlignmentValue32(PtrOp0));
1437 return EmitNeonCall(
CGM.getIntrinsic(LLVMIntrinsic, Tys), Ops,
"vld1");
1439 case NEON::BI__builtin_neon_vld2_v:
1440 case NEON::BI__builtin_neon_vld2q_v:
1441 case NEON::BI__builtin_neon_vld3_v:
1442 case NEON::BI__builtin_neon_vld3q_v:
1443 case NEON::BI__builtin_neon_vld4_v:
1444 case NEON::BI__builtin_neon_vld4q_v:
1445 case NEON::BI__builtin_neon_vld2_dup_v:
1446 case NEON::BI__builtin_neon_vld2q_dup_v:
1447 case NEON::BI__builtin_neon_vld3_dup_v:
1448 case NEON::BI__builtin_neon_vld3q_dup_v:
1449 case NEON::BI__builtin_neon_vld4_dup_v:
1450 case NEON::BI__builtin_neon_vld4q_dup_v: {
1452 Function *F =
CGM.getIntrinsic(LLVMIntrinsic, Tys);
1453 Value *Align = getAlignmentValue32(PtrOp1);
1454 Ops[1] =
Builder.CreateCall(F, {Ops[1], Align}, NameHint);
1455 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
1457 case NEON::BI__builtin_neon_vld1_dup_v:
1458 case NEON::BI__builtin_neon_vld1q_dup_v: {
1459 Value *
V = PoisonValue::get(Ty);
1461 LoadInst *Ld =
Builder.CreateLoad(PtrOp0);
1462 llvm::Constant *CI = ConstantInt::get(
SizeTy, 0);
1463 Ops[0] =
Builder.CreateInsertElement(
V, Ld, CI);
1466 case NEON::BI__builtin_neon_vld2_lane_v:
1467 case NEON::BI__builtin_neon_vld2q_lane_v:
1468 case NEON::BI__builtin_neon_vld3_lane_v:
1469 case NEON::BI__builtin_neon_vld3q_lane_v:
1470 case NEON::BI__builtin_neon_vld4_lane_v:
1471 case NEON::BI__builtin_neon_vld4q_lane_v: {
1473 Function *F =
CGM.getIntrinsic(LLVMIntrinsic, Tys);
1474 for (
unsigned I = 2; I < Ops.size() - 1; ++I)
1475 Ops[I] =
Builder.CreateBitCast(Ops[I], Ty);
1476 Ops.push_back(getAlignmentValue32(PtrOp1));
1478 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
1480 case NEON::BI__builtin_neon_vmovl_v: {
1481 llvm::FixedVectorType *DTy =
1482 llvm::FixedVectorType::getTruncatedElementVectorType(VTy);
1483 Ops[0] =
Builder.CreateBitCast(Ops[0], DTy);
1485 return Builder.CreateZExt(Ops[0], Ty,
"vmovl");
1486 return Builder.CreateSExt(Ops[0], Ty,
"vmovl");
1488 case NEON::BI__builtin_neon_vmovn_v: {
1489 llvm::FixedVectorType *QTy =
1490 llvm::FixedVectorType::getExtendedElementVectorType(VTy);
1491 Ops[0] =
Builder.CreateBitCast(Ops[0], QTy);
1492 return Builder.CreateTrunc(Ops[0], Ty,
"vmovn");
1494 case NEON::BI__builtin_neon_vmull_v:
1500 Int = Usgn ? Intrinsic::arm_neon_vmullu : Intrinsic::arm_neon_vmulls;
1503 case NEON::BI__builtin_neon_vpadal_v:
1504 case NEON::BI__builtin_neon_vpadalq_v: {
1506 unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
1510 llvm::FixedVectorType::get(EltTy, VTy->getNumElements() * 2);
1511 llvm::Type *Tys[2] = { Ty, NarrowTy };
1514 case NEON::BI__builtin_neon_vpaddl_v:
1515 case NEON::BI__builtin_neon_vpaddlq_v: {
1517 unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
1518 llvm::Type *EltTy = llvm::IntegerType::get(
getLLVMContext(), EltBits / 2);
1520 llvm::FixedVectorType::get(EltTy, VTy->getNumElements() * 2);
1521 llvm::Type *Tys[2] = { Ty, NarrowTy };
1524 case NEON::BI__builtin_neon_vqdmlal_v:
1525 case NEON::BI__builtin_neon_vqdmlsl_v: {
1530 return EmitNeonCall(
CGM.getIntrinsic(AltLLVMIntrinsic, Ty), Ops, NameHint);
1532 case NEON::BI__builtin_neon_vqdmulhq_lane_v:
1533 case NEON::BI__builtin_neon_vqdmulh_lane_v:
1534 case NEON::BI__builtin_neon_vqrdmulhq_lane_v:
1535 case NEON::BI__builtin_neon_vqrdmulh_lane_v: {
1537 if (BuiltinID == NEON::BI__builtin_neon_vqdmulhq_lane_v ||
1538 BuiltinID == NEON::BI__builtin_neon_vqrdmulhq_lane_v)
1539 RTy = llvm::FixedVectorType::get(RTy->getElementType(),
1540 RTy->getNumElements() * 2);
1541 llvm::Type *Tys[2] = {
1546 case NEON::BI__builtin_neon_vqdmulhq_laneq_v:
1547 case NEON::BI__builtin_neon_vqdmulh_laneq_v:
1548 case NEON::BI__builtin_neon_vqrdmulhq_laneq_v:
1549 case NEON::BI__builtin_neon_vqrdmulh_laneq_v: {
1550 llvm::Type *Tys[2] = {
1555 case NEON::BI__builtin_neon_vqshl_n_v:
1556 case NEON::BI__builtin_neon_vqshlq_n_v:
1559 case NEON::BI__builtin_neon_vqshlu_n_v:
1560 case NEON::BI__builtin_neon_vqshluq_n_v:
1563 case NEON::BI__builtin_neon_vrecpe_v:
1564 case NEON::BI__builtin_neon_vrecpeq_v:
1565 case NEON::BI__builtin_neon_vrsqrte_v:
1566 case NEON::BI__builtin_neon_vrsqrteq_v:
1567 Int = Ty->isFPOrFPVectorTy() ? LLVMIntrinsic : AltLLVMIntrinsic;
1569 case NEON::BI__builtin_neon_vrndi_v:
1570 case NEON::BI__builtin_neon_vrndiq_v:
1572 ? Intrinsic::experimental_constrained_nearbyint
1573 : Intrinsic::nearbyint;
1575 case NEON::BI__builtin_neon_vrshr_n_v:
1576 case NEON::BI__builtin_neon_vrshrq_n_v:
1579 case NEON::BI__builtin_neon_vsha512hq_u64:
1580 case NEON::BI__builtin_neon_vsha512h2q_u64:
1581 case NEON::BI__builtin_neon_vsha512su0q_u64:
1582 case NEON::BI__builtin_neon_vsha512su1q_u64: {
1586 case NEON::BI__builtin_neon_vshl_n_v:
1587 case NEON::BI__builtin_neon_vshlq_n_v:
1589 return Builder.CreateShl(
Builder.CreateBitCast(Ops[0],Ty), Ops[1],
1591 case NEON::BI__builtin_neon_vshll_n_v: {
1592 llvm::FixedVectorType *SrcTy =
1593 llvm::FixedVectorType::getTruncatedElementVectorType(VTy);
1594 Ops[0] =
Builder.CreateBitCast(Ops[0], SrcTy);
1596 Ops[0] =
Builder.CreateZExt(Ops[0], VTy);
1598 Ops[0] =
Builder.CreateSExt(Ops[0], VTy);
1600 return Builder.CreateShl(Ops[0], Ops[1],
"vshll_n");
1602 case NEON::BI__builtin_neon_vshrn_n_v: {
1603 llvm::FixedVectorType *SrcTy =
1604 llvm::FixedVectorType::getExtendedElementVectorType(VTy);
1605 Ops[0] =
Builder.CreateBitCast(Ops[0], SrcTy);
1608 Ops[0] =
Builder.CreateLShr(Ops[0], Ops[1]);
1610 Ops[0] =
Builder.CreateAShr(Ops[0], Ops[1]);
1611 return Builder.CreateTrunc(Ops[0], Ty,
"vshrn_n");
1613 case NEON::BI__builtin_neon_vshr_n_v:
1614 case NEON::BI__builtin_neon_vshrq_n_v:
1616 case NEON::BI__builtin_neon_vst1_v:
1617 case NEON::BI__builtin_neon_vst1q_v:
1618 case NEON::BI__builtin_neon_vst2_v:
1619 case NEON::BI__builtin_neon_vst2q_v:
1620 case NEON::BI__builtin_neon_vst3_v:
1621 case NEON::BI__builtin_neon_vst3q_v:
1622 case NEON::BI__builtin_neon_vst4_v:
1623 case NEON::BI__builtin_neon_vst4q_v:
1624 case NEON::BI__builtin_neon_vst2_lane_v:
1625 case NEON::BI__builtin_neon_vst2q_lane_v:
1626 case NEON::BI__builtin_neon_vst3_lane_v:
1627 case NEON::BI__builtin_neon_vst3q_lane_v:
1628 case NEON::BI__builtin_neon_vst4_lane_v:
1629 case NEON::BI__builtin_neon_vst4q_lane_v: {
1631 Ops.push_back(getAlignmentValue32(PtrOp0));
1634 case NEON::BI__builtin_neon_vsm3partw1q_u32:
1635 case NEON::BI__builtin_neon_vsm3partw2q_u32:
1636 case NEON::BI__builtin_neon_vsm3ss1q_u32:
1637 case NEON::BI__builtin_neon_vsm4ekeyq_u32:
1638 case NEON::BI__builtin_neon_vsm4eq_u32: {
1642 case NEON::BI__builtin_neon_vsm3tt1aq_u32:
1643 case NEON::BI__builtin_neon_vsm3tt1bq_u32:
1644 case NEON::BI__builtin_neon_vsm3tt2aq_u32:
1645 case NEON::BI__builtin_neon_vsm3tt2bq_u32: {
1650 case NEON::BI__builtin_neon_vst1_x2_v:
1651 case NEON::BI__builtin_neon_vst1q_x2_v:
1652 case NEON::BI__builtin_neon_vst1_x3_v:
1653 case NEON::BI__builtin_neon_vst1q_x3_v:
1654 case NEON::BI__builtin_neon_vst1_x4_v:
1655 case NEON::BI__builtin_neon_vst1q_x4_v: {
1658 if (
Arch == llvm::Triple::aarch64 ||
Arch == llvm::Triple::aarch64_be ||
1659 Arch == llvm::Triple::aarch64_32) {
1661 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end());
1667 case NEON::BI__builtin_neon_vsubhn_v: {
1668 llvm::FixedVectorType *SrcTy =
1669 llvm::FixedVectorType::getExtendedElementVectorType(VTy);
1672 Ops[0] =
Builder.CreateBitCast(Ops[0], SrcTy);
1673 Ops[1] =
Builder.CreateBitCast(Ops[1], SrcTy);
1674 Ops[0] =
Builder.CreateSub(Ops[0], Ops[1],
"vsubhn");
1678 ConstantInt::get(SrcTy, SrcTy->getScalarSizeInBits() / 2);
1679 Ops[0] =
Builder.CreateLShr(Ops[0], ShiftAmt,
"vsubhn");
1682 return Builder.CreateTrunc(Ops[0], VTy,
"vsubhn");
1684 case NEON::BI__builtin_neon_vtrn_v:
1685 case NEON::BI__builtin_neon_vtrnq_v: {
1686 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
1687 Ops[2] =
Builder.CreateBitCast(Ops[2], Ty);
1688 Value *SV =
nullptr;
1690 for (
unsigned vi = 0; vi != 2; ++vi) {
1692 for (
unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) {
1693 Indices.push_back(i+vi);
1694 Indices.push_back(i+e+vi);
1697 SV =
Builder.CreateShuffleVector(Ops[1], Ops[2], Indices,
"vtrn");
1702 case NEON::BI__builtin_neon_vtst_v:
1703 case NEON::BI__builtin_neon_vtstq_v: {
1704 Ops[0] =
Builder.CreateBitCast(Ops[0], Ty);
1705 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
1706 Ops[0] =
Builder.CreateAnd(Ops[0], Ops[1]);
1707 Ops[0] =
Builder.CreateICmp(ICmpInst::ICMP_NE, Ops[0],
1708 ConstantAggregateZero::get(Ty));
1709 return Builder.CreateSExt(Ops[0], Ty,
"vtst");
1711 case NEON::BI__builtin_neon_vuzp_v:
1712 case NEON::BI__builtin_neon_vuzpq_v: {
1713 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
1714 Ops[2] =
Builder.CreateBitCast(Ops[2], Ty);
1715 Value *SV =
nullptr;
1717 for (
unsigned vi = 0; vi != 2; ++vi) {
1719 for (
unsigned i = 0, e = VTy->getNumElements(); i != e; ++i)
1720 Indices.push_back(2*i+vi);
1723 SV =
Builder.CreateShuffleVector(Ops[1], Ops[2], Indices,
"vuzp");
1728 case NEON::BI__builtin_neon_vxarq_u64: {
1733 case NEON::BI__builtin_neon_vzip_v:
1734 case NEON::BI__builtin_neon_vzipq_v: {
1735 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
1736 Ops[2] =
Builder.CreateBitCast(Ops[2], Ty);
1737 Value *SV =
nullptr;
1739 for (
unsigned vi = 0; vi != 2; ++vi) {
1741 for (
unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) {
1742 Indices.push_back((i + vi*e) >> 1);
1743 Indices.push_back(((i + vi*e) >> 1)+e);
1746 SV =
Builder.CreateShuffleVector(Ops[1], Ops[2], Indices,
"vzip");
1751 case NEON::BI__builtin_neon_vdot_s32:
1752 case NEON::BI__builtin_neon_vdot_u32:
1753 case NEON::BI__builtin_neon_vdotq_s32:
1754 case NEON::BI__builtin_neon_vdotq_u32: {
1756 llvm::FixedVectorType::get(
Int8Ty, Ty->getPrimitiveSizeInBits() / 8);
1757 llvm::Type *Tys[2] = { Ty, InputTy };
1760 case NEON::BI__builtin_neon_vfmlal_low_f16:
1761 case NEON::BI__builtin_neon_vfmlalq_low_f16: {
1763 llvm::FixedVectorType::get(
HalfTy, Ty->getPrimitiveSizeInBits() / 16);
1764 llvm::Type *Tys[2] = { Ty, InputTy };
1767 case NEON::BI__builtin_neon_vfmlsl_low_f16:
1768 case NEON::BI__builtin_neon_vfmlslq_low_f16: {
1770 llvm::FixedVectorType::get(
HalfTy, Ty->getPrimitiveSizeInBits() / 16);
1771 llvm::Type *Tys[2] = { Ty, InputTy };
1774 case NEON::BI__builtin_neon_vfmlal_high_f16:
1775 case NEON::BI__builtin_neon_vfmlalq_high_f16: {
1777 llvm::FixedVectorType::get(
HalfTy, Ty->getPrimitiveSizeInBits() / 16);
1778 llvm::Type *Tys[2] = { Ty, InputTy };
1781 case NEON::BI__builtin_neon_vfmlsl_high_f16:
1782 case NEON::BI__builtin_neon_vfmlslq_high_f16: {
1784 llvm::FixedVectorType::get(
HalfTy, Ty->getPrimitiveSizeInBits() / 16);
1785 llvm::Type *Tys[2] = { Ty, InputTy };
1788 case NEON::BI__builtin_neon_vmmlaq_s32:
1789 case NEON::BI__builtin_neon_vmmlaq_u32: {
1791 llvm::FixedVectorType::get(
Int8Ty, Ty->getPrimitiveSizeInBits() / 8);
1792 llvm::Type *Tys[2] = { Ty, InputTy };
1793 return EmitNeonCall(
CGM.getIntrinsic(LLVMIntrinsic, Tys), Ops,
"vmmla");
1795 case NEON::BI__builtin_neon_vmmlaq_f16:
1796 case NEON::BI__builtin_neon_vmmlaq_f32_f16: {
1798 llvm::FixedVectorType::get(
HalfTy, Ty->getPrimitiveSizeInBits() / 16);
1799 llvm::Type *Tys[2] = {Ty, InputTy};
1802 case NEON::BI__builtin_neon_vusmmlaq_s32: {
1804 llvm::FixedVectorType::get(
Int8Ty, Ty->getPrimitiveSizeInBits() / 8);
1805 llvm::Type *Tys[2] = { Ty, InputTy };
1808 case NEON::BI__builtin_neon_vusdot_s32:
1809 case NEON::BI__builtin_neon_vusdotq_s32: {
1811 llvm::FixedVectorType::get(
Int8Ty, Ty->getPrimitiveSizeInBits() / 8);
1812 llvm::Type *Tys[2] = { Ty, InputTy };
1815 case NEON::BI__builtin_neon_vbfdot_f32:
1816 case NEON::BI__builtin_neon_vbfdotq_f32: {
1817 llvm::Type *InputTy =
1818 llvm::FixedVectorType::get(
BFloatTy, Ty->getPrimitiveSizeInBits() / 16);
1819 llvm::Type *Tys[2] = { Ty, InputTy };
1822 case NEON::BI__builtin_neon___a32_vcvt_bf16_f32: {
1823 llvm::Type *Tys[1] = { Ty };
1830 assert(
Int &&
"Expected valid intrinsic number");
2186 llvm::Triple::ArchType
Arch) {
2187 if (
auto Hint = GetValueForARMHint(BuiltinID))
2190 if (BuiltinID == clang::ARM::BI__emit) {
2192 llvm::FunctionType *FTy =
2193 llvm::FunctionType::get(
VoidTy,
false);
2197 llvm_unreachable(
"Sema will ensure that the parameter is constant");
2200 uint64_t ZExtValue =
Value.zextOrTrunc(IsThumb ? 16 : 32).getZExtValue();
2202 llvm::InlineAsm *Emit =
2203 IsThumb ? InlineAsm::get(FTy,
".inst.n 0x" + utohexstr(ZExtValue),
"",
2205 : InlineAsm::get(FTy,
".inst 0x" + utohexstr(ZExtValue),
"",
2208 return Builder.CreateCall(Emit);
2211 if (BuiltinID == clang::ARM::BI__builtin_arm_dbg) {
2213 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::arm_dbg), Option);
2216 if (BuiltinID == clang::ARM::BI__builtin_arm_prefetch) {
2228 if (BuiltinID == clang::ARM::BI__builtin_arm_rbit) {
2231 CGM.getIntrinsic(Intrinsic::bitreverse, Arg->getType()), Arg,
"rbit");
2234 if (BuiltinID == clang::ARM::BI__builtin_arm_clz ||
2235 BuiltinID == clang::ARM::BI__builtin_arm_clz64) {
2237 Function *F =
CGM.getIntrinsic(Intrinsic::ctlz, Arg->getType());
2239 if (BuiltinID == clang::ARM::BI__builtin_arm_clz64)
2245 if (BuiltinID == clang::ARM::BI__builtin_arm_cls) {
2247 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::arm_cls), Arg,
"cls");
2249 if (BuiltinID == clang::ARM::BI__builtin_arm_cls64) {
2251 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::arm_cls64), Arg,
2255 if (BuiltinID == clang::ARM::BI__clear_cache) {
2258 Function *F =
CGM.getIntrinsic(Intrinsic::clear_cache, {
CGM.DefaultPtrTy});
2259 return Builder.CreateCall(F, {Begin, End});
2262 if (BuiltinID == clang::ARM::BI__builtin_arm_mcrr ||
2263 BuiltinID == clang::ARM::BI__builtin_arm_mcrr2) {
2266 switch (BuiltinID) {
2267 default: llvm_unreachable(
"unexpected builtin");
2268 case clang::ARM::BI__builtin_arm_mcrr:
2269 F =
CGM.getIntrinsic(Intrinsic::arm_mcrr);
2271 case clang::ARM::BI__builtin_arm_mcrr2:
2272 F =
CGM.getIntrinsic(Intrinsic::arm_mcrr2);
2293 return Builder.CreateCall(F, {Coproc, Opc1, Rt, Rt2, CRm});
2296 if (BuiltinID == clang::ARM::BI__builtin_arm_mrrc ||
2297 BuiltinID == clang::ARM::BI__builtin_arm_mrrc2) {
2300 switch (BuiltinID) {
2301 default: llvm_unreachable(
"unexpected builtin");
2302 case clang::ARM::BI__builtin_arm_mrrc:
2303 F =
CGM.getIntrinsic(Intrinsic::arm_mrrc);
2305 case clang::ARM::BI__builtin_arm_mrrc2:
2306 F =
CGM.getIntrinsic(Intrinsic::arm_mrrc2);
2313 Value *RtAndRt2 =
Builder.CreateCall(F, {Coproc, Opc1, CRm});
2323 Value *ShiftCast = llvm::ConstantInt::get(
Int64Ty, 32);
2324 RtAndRt2 =
Builder.CreateShl(Rt, ShiftCast,
"shl",
true);
2325 RtAndRt2 =
Builder.CreateOr(RtAndRt2, Rt1);
2330 if (BuiltinID == clang::ARM::BI__builtin_arm_ldrexd ||
2331 ((BuiltinID == clang::ARM::BI__builtin_arm_ldrex ||
2332 BuiltinID == clang::ARM::BI__builtin_arm_ldaex) &&
2334 BuiltinID == clang::ARM::BI__ldrexd) {
2337 switch (BuiltinID) {
2338 default: llvm_unreachable(
"unexpected builtin");
2339 case clang::ARM::BI__builtin_arm_ldaex:
2340 F =
CGM.getIntrinsic(Intrinsic::arm_ldaexd);
2342 case clang::ARM::BI__builtin_arm_ldrexd:
2343 case clang::ARM::BI__builtin_arm_ldrex:
2344 case clang::ARM::BI__ldrexd:
2345 F =
CGM.getIntrinsic(Intrinsic::arm_ldrexd);
2358 Val =
Builder.CreateShl(Val0, ShiftCst,
"shl",
true );
2359 Val =
Builder.CreateOr(Val, Val1);
2363 if (BuiltinID == clang::ARM::BI__builtin_arm_ldrex ||
2364 BuiltinID == clang::ARM::BI__builtin_arm_ldaex) {
2373 BuiltinID == clang::ARM::BI__builtin_arm_ldaex ? Intrinsic::arm_ldaex
2374 : Intrinsic::arm_ldrex,
2376 CallInst *Val =
Builder.CreateCall(F, LoadAddr,
"ldrex");
2380 if (RealResTy->isPointerTy())
2381 return Builder.CreateIntToPtr(Val, RealResTy);
2383 llvm::Type *IntResTy = llvm::IntegerType::get(
2385 return Builder.CreateBitCast(
Builder.CreateTruncOrBitCast(Val, IntResTy),
2390 if (BuiltinID == clang::ARM::BI__builtin_arm_strexd ||
2391 ((BuiltinID == clang::ARM::BI__builtin_arm_stlex ||
2392 BuiltinID == clang::ARM::BI__builtin_arm_strex) &&
2395 BuiltinID == clang::ARM::BI__builtin_arm_stlex ? Intrinsic::arm_stlexd
2396 : Intrinsic::arm_strexd);
2401 Builder.CreateStore(Val, Tmp);
2404 Val =
Builder.CreateLoad(LdPtr);
2409 return Builder.CreateCall(F, {Arg0, Arg1, StPtr},
"strexd");
2412 if (BuiltinID == clang::ARM::BI__builtin_arm_strex ||
2413 BuiltinID == clang::ARM::BI__builtin_arm_stlex) {
2418 llvm::Type *StoreTy =
2421 if (StoreVal->
getType()->isPointerTy())
2424 llvm::Type *
IntTy = llvm::IntegerType::get(
2426 CGM.getDataLayout().getTypeSizeInBits(StoreVal->
getType()));
2432 BuiltinID == clang::ARM::BI__builtin_arm_stlex ? Intrinsic::arm_stlex
2433 : Intrinsic::arm_strex,
2436 CallInst *CI =
Builder.CreateCall(F, {StoreVal, StoreAddr},
"strex");
2438 1, Attribute::get(
getLLVMContext(), Attribute::ElementType, StoreTy));
2442 if (BuiltinID == clang::ARM::BI__builtin_arm_clrex) {
2443 Function *F =
CGM.getIntrinsic(Intrinsic::arm_clrex);
2448 Intrinsic::ID CRCIntrinsicID = Intrinsic::not_intrinsic;
2449 switch (BuiltinID) {
2450 case clang::ARM::BI__builtin_arm_crc32b:
2451 CRCIntrinsicID = Intrinsic::arm_crc32b;
break;
2452 case clang::ARM::BI__builtin_arm_crc32cb:
2453 CRCIntrinsicID = Intrinsic::arm_crc32cb;
break;
2454 case clang::ARM::BI__builtin_arm_crc32h:
2455 CRCIntrinsicID = Intrinsic::arm_crc32h;
break;
2456 case clang::ARM::BI__builtin_arm_crc32ch:
2457 CRCIntrinsicID = Intrinsic::arm_crc32ch;
break;
2458 case clang::ARM::BI__builtin_arm_crc32w:
2459 case clang::ARM::BI__builtin_arm_crc32d:
2460 CRCIntrinsicID = Intrinsic::arm_crc32w;
break;
2461 case clang::ARM::BI__builtin_arm_crc32cw:
2462 case clang::ARM::BI__builtin_arm_crc32cd:
2463 CRCIntrinsicID = Intrinsic::arm_crc32cw;
break;
2466 if (CRCIntrinsicID != Intrinsic::not_intrinsic) {
2472 if (BuiltinID == clang::ARM::BI__builtin_arm_crc32d ||
2473 BuiltinID == clang::ARM::BI__builtin_arm_crc32cd) {
2481 return Builder.CreateCall(F, {Res, Arg1b});
2486 return Builder.CreateCall(F, {Arg0, Arg1});
2490 if (BuiltinID == clang::ARM::BI__builtin_arm_rsr ||
2491 BuiltinID == clang::ARM::BI__builtin_arm_rsr64 ||
2492 BuiltinID == clang::ARM::BI__builtin_arm_rsrp ||
2493 BuiltinID == clang::ARM::BI__builtin_arm_wsr ||
2494 BuiltinID == clang::ARM::BI__builtin_arm_wsr64 ||
2495 BuiltinID == clang::ARM::BI__builtin_arm_wsrp) {
2498 if (BuiltinID == clang::ARM::BI__builtin_arm_rsr ||
2499 BuiltinID == clang::ARM::BI__builtin_arm_rsr64 ||
2500 BuiltinID == clang::ARM::BI__builtin_arm_rsrp)
2503 bool IsPointerBuiltin = BuiltinID == clang::ARM::BI__builtin_arm_rsrp ||
2504 BuiltinID == clang::ARM::BI__builtin_arm_wsrp;
2506 bool Is64Bit = BuiltinID == clang::ARM::BI__builtin_arm_rsr64 ||
2507 BuiltinID == clang::ARM::BI__builtin_arm_wsr64;
2509 llvm::Type *ValueType;
2511 if (IsPointerBuiltin) {
2514 }
else if (Is64Bit) {
2524 if (BuiltinID == ARM::BI__builtin_sponentry) {
2543 return P.first == BuiltinID;
2546 BuiltinID = It->second;
2550 unsigned ICEArguments = 0;
2555 auto getAlignmentValue32 = [&](
Address addr) ->
Value* {
2556 return Builder.getInt32(addr.getAlignment().getQuantity());
2563 unsigned NumArgs = E->
getNumArgs() - (HasExtraArg ? 1 : 0);
2564 for (
unsigned i = 0, e = NumArgs; i != e; i++) {
2566 switch (BuiltinID) {
2567 case NEON::BI__builtin_neon_vld1_v:
2568 case NEON::BI__builtin_neon_vld1q_v:
2569 case NEON::BI__builtin_neon_vld1q_lane_v:
2570 case NEON::BI__builtin_neon_vld1_lane_v:
2571 case NEON::BI__builtin_neon_vld1_dup_v:
2572 case NEON::BI__builtin_neon_vld1q_dup_v:
2573 case NEON::BI__builtin_neon_vst1_v:
2574 case NEON::BI__builtin_neon_vst1q_v:
2575 case NEON::BI__builtin_neon_vst1q_lane_v:
2576 case NEON::BI__builtin_neon_vst1_lane_v:
2577 case NEON::BI__builtin_neon_vst2_v:
2578 case NEON::BI__builtin_neon_vst2q_v:
2579 case NEON::BI__builtin_neon_vst2_lane_v:
2580 case NEON::BI__builtin_neon_vst2q_lane_v:
2581 case NEON::BI__builtin_neon_vst3_v:
2582 case NEON::BI__builtin_neon_vst3q_v:
2583 case NEON::BI__builtin_neon_vst3_lane_v:
2584 case NEON::BI__builtin_neon_vst3q_lane_v:
2585 case NEON::BI__builtin_neon_vst4_v:
2586 case NEON::BI__builtin_neon_vst4q_v:
2587 case NEON::BI__builtin_neon_vst4_lane_v:
2588 case NEON::BI__builtin_neon_vst4q_lane_v:
2597 switch (BuiltinID) {
2598 case NEON::BI__builtin_neon_vld2_v:
2599 case NEON::BI__builtin_neon_vld2q_v:
2600 case NEON::BI__builtin_neon_vld3_v:
2601 case NEON::BI__builtin_neon_vld3q_v:
2602 case NEON::BI__builtin_neon_vld4_v:
2603 case NEON::BI__builtin_neon_vld4q_v:
2604 case NEON::BI__builtin_neon_vld2_lane_v:
2605 case NEON::BI__builtin_neon_vld2q_lane_v:
2606 case NEON::BI__builtin_neon_vld3_lane_v:
2607 case NEON::BI__builtin_neon_vld3q_lane_v:
2608 case NEON::BI__builtin_neon_vld4_lane_v:
2609 case NEON::BI__builtin_neon_vld4q_lane_v:
2610 case NEON::BI__builtin_neon_vld2_dup_v:
2611 case NEON::BI__builtin_neon_vld2q_dup_v:
2612 case NEON::BI__builtin_neon_vld3_dup_v:
2613 case NEON::BI__builtin_neon_vld3q_dup_v:
2614 case NEON::BI__builtin_neon_vld4_dup_v:
2615 case NEON::BI__builtin_neon_vld4q_dup_v:
2627 switch (BuiltinID) {
2630 case NEON::BI__builtin_neon_vget_lane_i8:
2631 case NEON::BI__builtin_neon_vget_lane_i16:
2632 case NEON::BI__builtin_neon_vget_lane_i32:
2633 case NEON::BI__builtin_neon_vget_lane_i64:
2634 case NEON::BI__builtin_neon_vget_lane_bf16:
2635 case NEON::BI__builtin_neon_vget_lane_f32:
2636 case NEON::BI__builtin_neon_vgetq_lane_i8:
2637 case NEON::BI__builtin_neon_vgetq_lane_i16:
2638 case NEON::BI__builtin_neon_vgetq_lane_i32:
2639 case NEON::BI__builtin_neon_vgetq_lane_i64:
2640 case NEON::BI__builtin_neon_vgetq_lane_bf16:
2641 case NEON::BI__builtin_neon_vgetq_lane_f32:
2642 case NEON::BI__builtin_neon_vduph_lane_bf16:
2643 case NEON::BI__builtin_neon_vduph_laneq_bf16:
2644 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vget_lane");
2646 case NEON::BI__builtin_neon_vrndns_f32: {
2648 llvm::Type *Tys[] = {Arg->
getType()};
2649 Function *F =
CGM.getIntrinsic(Intrinsic::roundeven, Tys);
2650 return Builder.CreateCall(F, {Arg},
"vrndn"); }
2652 case NEON::BI__builtin_neon_vset_lane_i8:
2653 case NEON::BI__builtin_neon_vset_lane_i16:
2654 case NEON::BI__builtin_neon_vset_lane_i32:
2655 case NEON::BI__builtin_neon_vset_lane_i64:
2656 case NEON::BI__builtin_neon_vset_lane_bf16:
2657 case NEON::BI__builtin_neon_vset_lane_f32:
2658 case NEON::BI__builtin_neon_vsetq_lane_i8:
2659 case NEON::BI__builtin_neon_vsetq_lane_i16:
2660 case NEON::BI__builtin_neon_vsetq_lane_i32:
2661 case NEON::BI__builtin_neon_vsetq_lane_i64:
2662 case NEON::BI__builtin_neon_vsetq_lane_bf16:
2663 case NEON::BI__builtin_neon_vsetq_lane_f32:
2664 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2],
"vset_lane");
2666 case NEON::BI__builtin_neon_vsha1h_u32:
2669 case NEON::BI__builtin_neon_vsha1cq_u32:
2672 case NEON::BI__builtin_neon_vsha1pq_u32:
2675 case NEON::BI__builtin_neon_vsha1mq_u32:
2679 case NEON::BI__builtin_neon_vcvth_bf16_f32:
2680 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::arm_neon_vcvtbfp2bf), Ops,
2682 case NEON::BI__builtin_neon_vcvt_f16_f32:
2683 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::arm_neon_vcvtfp2hf), Ops,
2685 case NEON::BI__builtin_neon_vcvt_f32_f16:
2686 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::arm_neon_vcvthf2fp), Ops,
2691 case clang::ARM::BI_MoveToCoprocessor:
2692 case clang::ARM::BI_MoveToCoprocessor2: {
2693 Function *F =
CGM.getIntrinsic(BuiltinID == clang::ARM::BI_MoveToCoprocessor
2694 ? Intrinsic::arm_mcr
2695 : Intrinsic::arm_mcr2);
2696 return Builder.CreateCall(F, {Ops[1], Ops[2], Ops[0],
2697 Ops[3], Ops[4], Ops[5]});
2702 assert(HasExtraArg);
2704 std::optional<llvm::APSInt>
Result =
2709 if (BuiltinID == clang::ARM::BI__builtin_arm_vcvtr_f ||
2710 BuiltinID == clang::ARM::BI__builtin_arm_vcvtr_d) {
2713 if (BuiltinID == clang::ARM::BI__builtin_arm_vcvtr_f)
2719 bool usgn =
Result->getZExtValue() == 1;
2720 unsigned Int = usgn ? Intrinsic::arm_vcvtru : Intrinsic::arm_vcvtr;
2724 return Builder.CreateCall(F, Ops,
"vcvtr");
2729 bool usgn =
Type.isUnsigned();
2730 bool rightShift =
false;
2732 llvm::FixedVectorType *VTy =
2735 llvm::Type *Ty = VTy;
2750 switch (BuiltinID) {
2751 default:
return nullptr;
2752 case NEON::BI__builtin_neon_vld1q_lane_v:
2755 if (VTy->getElementType()->isIntegerTy(64)) {
2757 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
2759 Value *SV = llvm::ConstantVector::get(ConstantInt::get(
Int32Ty, 1-Lane));
2760 Ops[1] =
Builder.CreateShuffleVector(Ops[1], Ops[1], SV);
2762 Ty = llvm::FixedVectorType::get(VTy->getElementType(), 1);
2764 Function *F =
CGM.getIntrinsic(Intrinsic::arm_neon_vld1, Tys);
2765 Value *Align = getAlignmentValue32(PtrOp0);
2768 int Indices[] = {1 - Lane, Lane};
2769 return Builder.CreateShuffleVector(Ops[1], Ld, Indices,
"vld1q_lane");
2772 case NEON::BI__builtin_neon_vld1_lane_v: {
2773 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
2776 return Builder.CreateInsertElement(Ops[1], Ld, Ops[2],
"vld1_lane");
2778 case NEON::BI__builtin_neon_vqrshrn_n_v:
2780 usgn ? Intrinsic::arm_neon_vqrshiftnu : Intrinsic::arm_neon_vqrshiftns;
2783 case NEON::BI__builtin_neon_vqrshrun_n_v:
2784 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::arm_neon_vqrshiftnsu, Ty),
2785 Ops,
"vqrshrun_n", 1,
true);
2786 case NEON::BI__builtin_neon_vqshrn_n_v:
2787 Int = usgn ? Intrinsic::arm_neon_vqshiftnu : Intrinsic::arm_neon_vqshiftns;
2790 case NEON::BI__builtin_neon_vqshrun_n_v:
2791 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::arm_neon_vqshiftnsu, Ty),
2792 Ops,
"vqshrun_n", 1,
true);
2793 case NEON::BI__builtin_neon_vrecpe_v:
2794 case NEON::BI__builtin_neon_vrecpeq_v:
2797 case NEON::BI__builtin_neon_vrshrn_n_v:
2798 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::arm_neon_vrshiftn, Ty),
2799 Ops,
"vrshrn_n", 1,
true);
2800 case NEON::BI__builtin_neon_vrsra_n_v:
2801 case NEON::BI__builtin_neon_vrsraq_n_v:
2802 Ops[0] =
Builder.CreateBitCast(Ops[0], Ty);
2803 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
2805 Int = usgn ? Intrinsic::arm_neon_vrshiftu : Intrinsic::arm_neon_vrshifts;
2806 Ops[1] =
Builder.CreateCall(
CGM.getIntrinsic(
Int, Ty), {Ops[1], Ops[2]});
2807 return Builder.CreateAdd(Ops[0], Ops[1],
"vrsra_n");
2808 case NEON::BI__builtin_neon_vsri_n_v:
2809 case NEON::BI__builtin_neon_vsriq_n_v:
2812 case NEON::BI__builtin_neon_vsli_n_v:
2813 case NEON::BI__builtin_neon_vsliq_n_v:
2815 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::arm_neon_vshiftins, Ty),
2817 case NEON::BI__builtin_neon_vsra_n_v:
2818 case NEON::BI__builtin_neon_vsraq_n_v:
2819 Ops[0] =
Builder.CreateBitCast(Ops[0], Ty);
2821 return Builder.CreateAdd(Ops[0], Ops[1]);
2822 case NEON::BI__builtin_neon_vst1q_lane_v:
2825 if (VTy->getElementType()->isIntegerTy(64)) {
2826 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
2828 Ops[1] =
Builder.CreateShuffleVector(Ops[1], Ops[1], SV);
2829 Ops[2] = getAlignmentValue32(PtrOp0);
2830 llvm::Type *Tys[] = {
Int8PtrTy, Ops[1]->getType()};
2831 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::arm_neon_vst1,
2835 case NEON::BI__builtin_neon_vst1_lane_v: {
2836 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
2837 Ops[1] =
Builder.CreateExtractElement(Ops[1], Ops[2]);
2838 return Builder.CreateStore(Ops[1],
2841 case NEON::BI__builtin_neon_vtbl1_v:
2844 case NEON::BI__builtin_neon_vtbl2_v:
2847 case NEON::BI__builtin_neon_vtbl3_v:
2850 case NEON::BI__builtin_neon_vtbl4_v:
2853 case NEON::BI__builtin_neon_vtbx1_v:
2856 case NEON::BI__builtin_neon_vtbx2_v:
2859 case NEON::BI__builtin_neon_vtbx3_v:
2862 case NEON::BI__builtin_neon_vtbx4_v:
4493 llvm::Triple::ArchType
Arch) {
4502 if (BuiltinID == Builtin::BI__builtin_cpu_supports)
4503 return EmitAArch64CpuSupports(E);
4505 unsigned HintID =
static_cast<unsigned>(-1);
4506 switch (BuiltinID) {
4508 case clang::AArch64::BI__builtin_arm_nop:
4511 case clang::AArch64::BI__builtin_arm_yield:
4512 case clang::AArch64::BI__yield:
4515 case clang::AArch64::BI__builtin_arm_wfe:
4516 case clang::AArch64::BI__wfe:
4519 case clang::AArch64::BI__builtin_arm_wfi:
4520 case clang::AArch64::BI__wfi:
4523 case clang::AArch64::BI__builtin_arm_sev:
4524 case clang::AArch64::BI__sev:
4527 case clang::AArch64::BI__builtin_arm_sevl:
4528 case clang::AArch64::BI__sevl:
4533 if (HintID !=
static_cast<unsigned>(-1)) {
4534 Function *F =
CGM.getIntrinsic(Intrinsic::aarch64_hint);
4535 return Builder.CreateCall(F, llvm::ConstantInt::get(
Int32Ty, HintID));
4538 if (BuiltinID == clang::AArch64::BI__builtin_arm_trap) {
4539 Function *F =
CGM.getIntrinsic(Intrinsic::aarch64_break);
4544 if (BuiltinID == clang::AArch64::BI__builtin_arm_get_sme_state) {
4547 llvm::FunctionType::get(StructType::get(
CGM.Int64Ty,
CGM.Int64Ty), {},
4549 "__arm_sme_state"));
4551 "aarch64_pstate_sm_compatible");
4552 CI->setAttributes(Attrs);
4555 AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2);
4562 if (BuiltinID == clang::AArch64::BI__builtin_arm_rbit) {
4564 "rbit of unusual size!");
4567 CGM.getIntrinsic(Intrinsic::bitreverse, Arg->getType()), Arg,
"rbit");
4569 if (BuiltinID == clang::AArch64::BI__builtin_arm_rbit64) {
4571 "rbit of unusual size!");
4574 CGM.getIntrinsic(Intrinsic::bitreverse, Arg->getType()), Arg,
"rbit");
4577 if (BuiltinID == clang::AArch64::BI__builtin_arm_clz ||
4578 BuiltinID == clang::AArch64::BI__builtin_arm_clz64) {
4580 Function *F =
CGM.getIntrinsic(Intrinsic::ctlz, Arg->getType());
4582 if (BuiltinID == clang::AArch64::BI__builtin_arm_clz64)
4587 if (BuiltinID == clang::AArch64::BI__builtin_arm_cls) {
4589 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::aarch64_cls), Arg,
4592 if (BuiltinID == clang::AArch64::BI__builtin_arm_cls64) {
4594 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::aarch64_cls64), Arg,
4598 if (BuiltinID == clang::AArch64::BI__builtin_arm_rint32zf ||
4599 BuiltinID == clang::AArch64::BI__builtin_arm_rint32z) {
4601 llvm::Type *Ty = Arg->getType();
4602 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::aarch64_frint32z, Ty),
4606 if (BuiltinID == clang::AArch64::BI__builtin_arm_rint64zf ||
4607 BuiltinID == clang::AArch64::BI__builtin_arm_rint64z) {
4609 llvm::Type *Ty = Arg->getType();
4610 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::aarch64_frint64z, Ty),
4614 if (BuiltinID == clang::AArch64::BI__builtin_arm_rint32xf ||
4615 BuiltinID == clang::AArch64::BI__builtin_arm_rint32x) {
4617 llvm::Type *Ty = Arg->getType();
4618 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::aarch64_frint32x, Ty),
4622 if (BuiltinID == clang::AArch64::BI__builtin_arm_rint64xf ||
4623 BuiltinID == clang::AArch64::BI__builtin_arm_rint64x) {
4625 llvm::Type *Ty = Arg->getType();
4626 return Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::aarch64_frint64x, Ty),
4630 if (BuiltinID == clang::AArch64::BI__builtin_arm_jcvt) {
4632 "__jcvt of unusual size!");
4635 CGM.getIntrinsic(Intrinsic::aarch64_fjcvtzs), Arg);
4638 if (BuiltinID == clang::AArch64::BI__builtin_arm_ld64b ||
4639 BuiltinID == clang::AArch64::BI__builtin_arm_st64b ||
4640 BuiltinID == clang::AArch64::BI__builtin_arm_st64bv ||
4641 BuiltinID == clang::AArch64::BI__builtin_arm_st64bv0) {
4645 if (BuiltinID == clang::AArch64::BI__builtin_arm_ld64b) {
4648 Function *F =
CGM.getIntrinsic(Intrinsic::aarch64_ld64b);
4649 llvm::Value *Val =
Builder.CreateCall(F, MemAddr);
4651 for (
size_t i = 0; i < 8; i++) {
4652 llvm::Value *ValOffsetPtr =
4664 Args.push_back(MemAddr);
4665 for (
size_t i = 0; i < 8; i++) {
4666 llvm::Value *ValOffsetPtr =
4672 auto Intr = (BuiltinID == clang::AArch64::BI__builtin_arm_st64b
4673 ? Intrinsic::aarch64_st64b
4674 : BuiltinID == clang::AArch64::BI__builtin_arm_st64bv
4675 ? Intrinsic::aarch64_st64bv
4676 : Intrinsic::aarch64_st64bv0);
4678 return Builder.CreateCall(F, Args);
4681 if (BuiltinID == clang::AArch64::BI__builtin_arm_rndr ||
4682 BuiltinID == clang::AArch64::BI__builtin_arm_rndrrs) {
4684 auto Intr = (BuiltinID == clang::AArch64::BI__builtin_arm_rndr
4685 ? Intrinsic::aarch64_rndr
4686 : Intrinsic::aarch64_rndrrs);
4688 llvm::Value *Val =
Builder.CreateCall(F);
4689 Value *RandomValue =
Builder.CreateExtractValue(Val, 0);
4693 Builder.CreateStore(RandomValue, MemAddress);
4698 if (BuiltinID == clang::AArch64::BI__clear_cache) {
4701 Function *F =
CGM.getIntrinsic(Intrinsic::clear_cache, {
CGM.DefaultPtrTy});
4702 return Builder.CreateCall(F, {Begin, End});
4705 if ((BuiltinID == clang::AArch64::BI__builtin_arm_ldrex ||
4706 BuiltinID == clang::AArch64::BI__builtin_arm_ldaex) &&
4709 CGM.getIntrinsic(BuiltinID == clang::AArch64::BI__builtin_arm_ldaex
4710 ? Intrinsic::aarch64_ldaxp
4711 : Intrinsic::aarch64_ldxp);
4718 llvm::Type *Int128Ty = llvm::IntegerType::get(
getLLVMContext(), 128);
4719 Val0 =
Builder.CreateZExt(Val0, Int128Ty);
4720 Val1 =
Builder.CreateZExt(Val1, Int128Ty);
4722 Value *ShiftCst = llvm::ConstantInt::get(Int128Ty, 64);
4723 Val =
Builder.CreateShl(Val0, ShiftCst,
"shl",
true );
4724 Val =
Builder.CreateOr(Val, Val1);
4726 }
else if (BuiltinID == clang::AArch64::BI__builtin_arm_ldrex ||
4727 BuiltinID == clang::AArch64::BI__builtin_arm_ldaex) {
4736 CGM.getIntrinsic(BuiltinID == clang::AArch64::BI__builtin_arm_ldaex
4737 ? Intrinsic::aarch64_ldaxr
4738 : Intrinsic::aarch64_ldxr,
4740 CallInst *Val =
Builder.CreateCall(F, LoadAddr,
"ldxr");
4744 if (RealResTy->isPointerTy())
4745 return Builder.CreateIntToPtr(Val, RealResTy);
4747 llvm::Type *IntResTy = llvm::IntegerType::get(
4749 return Builder.CreateBitCast(
Builder.CreateTruncOrBitCast(Val, IntResTy),
4753 if ((BuiltinID == clang::AArch64::BI__builtin_arm_strex ||
4754 BuiltinID == clang::AArch64::BI__builtin_arm_stlex) &&
4757 CGM.getIntrinsic(BuiltinID == clang::AArch64::BI__builtin_arm_stlex
4758 ? Intrinsic::aarch64_stlxp
4759 : Intrinsic::aarch64_stxp);
4766 llvm::Value *Val =
Builder.CreateLoad(Tmp);
4771 return Builder.CreateCall(F, {Arg0, Arg1, StPtr},
"stxp");
4774 if (BuiltinID == clang::AArch64::BI__builtin_arm_strex ||
4775 BuiltinID == clang::AArch64::BI__builtin_arm_stlex) {
4780 llvm::Type *StoreTy =
4783 if (StoreVal->
getType()->isPointerTy())
4786 llvm::Type *
IntTy = llvm::IntegerType::get(
4788 CGM.getDataLayout().getTypeSizeInBits(StoreVal->
getType()));
4794 CGM.getIntrinsic(BuiltinID == clang::AArch64::BI__builtin_arm_stlex
4795 ? Intrinsic::aarch64_stlxr
4796 : Intrinsic::aarch64_stxr,
4798 CallInst *CI =
Builder.CreateCall(F, {StoreVal, StoreAddr},
"stxr");
4800 1, Attribute::get(
getLLVMContext(), Attribute::ElementType, StoreTy));
4804 if (BuiltinID == clang::AArch64::BI__getReg ||
4805 BuiltinID == clang::AArch64::BI__setReg) {
4808 llvm_unreachable(
"Sema will ensure that the parameter is constant");
4811 LLVMContext &Context =
CGM.getLLVMContext();
4814 llvm::Metadata *Ops[] = {llvm::MDString::get(Context, Reg)};
4815 llvm::MDNode *RegName = llvm::MDNode::get(Context, Ops);
4816 llvm::Value *Metadata = llvm::MetadataAsValue::get(Context, RegName);
4819 if (BuiltinID == clang::AArch64::BI__getReg) {
4821 CGM.getIntrinsic(Intrinsic::read_volatile_register, {
Int64Ty});
4822 CI =
Builder.CreateCall(F, Metadata);
4825 CGM.getIntrinsic(Intrinsic::write_volatile_register, {
Int64Ty});
4831 if (BuiltinID == clang::AArch64::BI__getRegFp ||
4832 BuiltinID == clang::AArch64::BI__setRegFp) {
4835 llvm_unreachable(
"Sema will ensure that the parameter is constant");
4838 LLVMContext &Context =
CGM.getLLVMContext();
4841 llvm::Metadata *Ops[] = {llvm::MDString::get(Context, Reg)};
4842 llvm::MDNode *RegName = llvm::MDNode::get(Context, Ops);
4843 llvm::Value *Metadata = llvm::MetadataAsValue::get(Context, RegName);
4846 if (BuiltinID == clang::AArch64::BI__getRegFp) {
4848 CGM.getIntrinsic(Intrinsic::read_volatile_register, {
Int64Ty});
4849 llvm::Value *Bits =
Builder.CreateCall(F, Metadata);
4850 Ret =
Builder.CreateBitCast(Bits, llvm::Type::getDoubleTy(Context));
4855 CGM.getIntrinsic(Intrinsic::write_volatile_register, {
Int64Ty});
4856 Ret =
Builder.CreateCall(F, {Metadata, Bits});
4861 if (BuiltinID == clang::AArch64::BI__break) {
4864 llvm_unreachable(
"Sema will ensure that the parameter is constant");
4866 llvm::Function *F =
CGM.getIntrinsic(Intrinsic::aarch64_break);
4870 if (BuiltinID == clang::AArch64::BI__builtin_arm_clrex) {
4871 Function *F =
CGM.getIntrinsic(Intrinsic::aarch64_clrex);
4875 if (BuiltinID == clang::AArch64::BI_ReadWriteBarrier)
4876 return Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent,
4877 llvm::SyncScope::SingleThread);
4880 Intrinsic::ID CRCIntrinsicID = Intrinsic::not_intrinsic;
4881 switch (BuiltinID) {
4882 case clang::AArch64::BI__builtin_arm_crc32b:
4883 CRCIntrinsicID = Intrinsic::aarch64_crc32b;
break;
4884 case clang::AArch64::BI__builtin_arm_crc32cb:
4885 CRCIntrinsicID = Intrinsic::aarch64_crc32cb;
break;
4886 case clang::AArch64::BI__builtin_arm_crc32h:
4887 CRCIntrinsicID = Intrinsic::aarch64_crc32h;
break;
4888 case clang::AArch64::BI__builtin_arm_crc32ch:
4889 CRCIntrinsicID = Intrinsic::aarch64_crc32ch;
break;
4890 case clang::AArch64::BI__builtin_arm_crc32w:
4891 CRCIntrinsicID = Intrinsic::aarch64_crc32w;
break;
4892 case clang::AArch64::BI__builtin_arm_crc32cw:
4893 CRCIntrinsicID = Intrinsic::aarch64_crc32cw;
break;
4894 case clang::AArch64::BI__builtin_arm_crc32d:
4895 CRCIntrinsicID = Intrinsic::aarch64_crc32x;
break;
4896 case clang::AArch64::BI__builtin_arm_crc32cd:
4897 CRCIntrinsicID = Intrinsic::aarch64_crc32cx;
break;
4900 if (CRCIntrinsicID != Intrinsic::not_intrinsic) {
4905 llvm::Type *DataTy = F->getFunctionType()->getParamType(1);
4906 Arg1 =
Builder.CreateZExtOrBitCast(Arg1, DataTy);
4908 return Builder.CreateCall(F, {Arg0, Arg1});
4912 if (BuiltinID == AArch64::BI__builtin_arm_mops_memset_tag) {
4919 CGM.getIntrinsic(Intrinsic::aarch64_mops_memset_tag), {Dst, Val, Size});
4922 if (BuiltinID == AArch64::BI__builtin_arm_range_prefetch ||
4923 BuiltinID == AArch64::BI__builtin_arm_range_prefetch_x)
4926 switch (BuiltinID) {
4929 case AArch64::BI__builtin_arm_atomic_store_with_hint:
4931 case AArch64::BI__builtin_arm_atomic_fetch_add_with_hint:
4933 case AArch64::BI__builtin_arm_atomic_fetch_sub_with_hint:
4935 case AArch64::BI__builtin_arm_atomic_fetch_and_with_hint:
4937 case AArch64::BI__builtin_arm_atomic_fetch_xor_with_hint:
4939 case AArch64::BI__builtin_arm_atomic_fetch_or_with_hint:
4944 Intrinsic::ID MTEIntrinsicID = Intrinsic::not_intrinsic;
4945 switch (BuiltinID) {
4946 case clang::AArch64::BI__builtin_arm_irg:
4947 MTEIntrinsicID = Intrinsic::aarch64_irg;
break;
4948 case clang::AArch64::BI__builtin_arm_addg:
4949 MTEIntrinsicID = Intrinsic::aarch64_addg;
break;
4950 case clang::AArch64::BI__builtin_arm_gmi:
4951 MTEIntrinsicID = Intrinsic::aarch64_gmi;
break;
4952 case clang::AArch64::BI__builtin_arm_ldg:
4953 MTEIntrinsicID = Intrinsic::aarch64_ldg;
break;
4954 case clang::AArch64::BI__builtin_arm_stg:
4955 MTEIntrinsicID = Intrinsic::aarch64_stg;
break;
4956 case clang::AArch64::BI__builtin_arm_subp:
4957 MTEIntrinsicID = Intrinsic::aarch64_subp;
break;
4960 if (BuiltinID == clang::AArch64::BI__arm_set_fpm_lscale) {
4968 return Builder.CreateOr(MaskedFPM, ShiftedScale);
4970 if (BuiltinID == clang::AArch64::BI__arm_set_fpm_nscale) {
4978 return Builder.CreateOr(MaskedFPM, ShiftedScale);
4980 if (BuiltinID == clang::AArch64::BI__arm_set_fpm_lscale2) {
4988 return Builder.CreateOr(LowFPM, ShiftedScale);
4991 if (MTEIntrinsicID != Intrinsic::not_intrinsic) {
4992 if (MTEIntrinsicID == Intrinsic::aarch64_irg) {
4995 assert(Mask->
getType()->getScalarSizeInBits() == 64 &&
4996 "SemaARM::BuiltinARMMemoryTaggingCall() enforces this");
4997 return Builder.CreateCall(
CGM.getIntrinsic(MTEIntrinsicID),
5000 if (MTEIntrinsicID == Intrinsic::aarch64_addg) {
5005 return Builder.CreateCall(
CGM.getIntrinsic(MTEIntrinsicID),
5006 {Pointer, TagOffset});
5008 if (MTEIntrinsicID == Intrinsic::aarch64_gmi) {
5011 assert(ExcludedMask->
getType()->getScalarSizeInBits() == 64 &&
5012 "SemaARM::BuiltinARMMemoryTaggingCall() enforces this");
5013 return Builder.CreateCall(
CGM.getIntrinsic(MTEIntrinsicID),
5014 {Pointer, ExcludedMask});
5019 if (MTEIntrinsicID == Intrinsic::aarch64_ldg) {
5021 return Builder.CreateCall(
CGM.getIntrinsic(MTEIntrinsicID),
5022 {TagAddress, TagAddress});
5027 if (MTEIntrinsicID == Intrinsic::aarch64_stg) {
5029 return Builder.CreateCall(
CGM.getIntrinsic(MTEIntrinsicID),
5030 {TagAddress, TagAddress});
5032 if (MTEIntrinsicID == Intrinsic::aarch64_subp) {
5036 CGM.getIntrinsic(MTEIntrinsicID), {PointerA, PointerB});
5040 if (BuiltinID == clang::AArch64::BI__builtin_arm_rsr ||
5041 BuiltinID == clang::AArch64::BI__builtin_arm_rsr64 ||
5042 BuiltinID == clang::AArch64::BI__builtin_arm_rsr128 ||
5043 BuiltinID == clang::AArch64::BI__builtin_arm_rsrp ||
5044 BuiltinID == clang::AArch64::BI__builtin_arm_wsr ||
5045 BuiltinID == clang::AArch64::BI__builtin_arm_wsr64 ||
5046 BuiltinID == clang::AArch64::BI__builtin_arm_wsr128 ||
5047 BuiltinID == clang::AArch64::BI__builtin_arm_wsrp) {
5050 if (BuiltinID == clang::AArch64::BI__builtin_arm_rsr ||
5051 BuiltinID == clang::AArch64::BI__builtin_arm_rsr64 ||
5052 BuiltinID == clang::AArch64::BI__builtin_arm_rsr128 ||
5053 BuiltinID == clang::AArch64::BI__builtin_arm_rsrp)
5056 bool IsPointerBuiltin = BuiltinID == clang::AArch64::BI__builtin_arm_rsrp ||
5057 BuiltinID == clang::AArch64::BI__builtin_arm_wsrp;
5059 bool Is32Bit = BuiltinID == clang::AArch64::BI__builtin_arm_rsr ||
5060 BuiltinID == clang::AArch64::BI__builtin_arm_wsr;
5062 bool Is128Bit = BuiltinID == clang::AArch64::BI__builtin_arm_rsr128 ||
5063 BuiltinID == clang::AArch64::BI__builtin_arm_wsr128;
5065 llvm::Type *ValueType;
5069 }
else if (Is128Bit) {
5070 llvm::Type *Int128Ty =
5071 llvm::IntegerType::getInt128Ty(
CGM.getLLVMContext());
5072 ValueType = Int128Ty;
5074 }
else if (IsPointerBuiltin) {
5084 if (BuiltinID == clang::AArch64::BI_ReadStatusReg ||
5085 BuiltinID == clang::AArch64::BI_WriteStatusReg) {
5086 LLVMContext &Context =
CGM.getLLVMContext();
5091 std::string SysRegStr;
5092 llvm::raw_string_ostream(SysRegStr)
5093 << (0b10 | SysReg >> 14) <<
":" << ((SysReg >> 11) & 7) <<
":"
5094 << ((SysReg >> 7) & 15) <<
":" << ((SysReg >> 3) & 15) <<
":"
5097 llvm::Metadata *Ops[] = { llvm::MDString::get(Context, SysRegStr) };
5098 llvm::MDNode *RegName = llvm::MDNode::get(Context, Ops);
5099 llvm::Value *Metadata = llvm::MetadataAsValue::get(Context, RegName);
5104 if (BuiltinID == clang::AArch64::BI_ReadStatusReg) {
5105 llvm::Function *F =
CGM.getIntrinsic(Intrinsic::read_register, Types);
5107 return Builder.CreateCall(F, Metadata);
5110 llvm::Function *F =
CGM.getIntrinsic(Intrinsic::write_register, Types);
5112 llvm::Value *
Result =
Builder.CreateCall(F, {Metadata, ArgValue});
5117 if (BuiltinID == clang::AArch64::BI__sys) {
5120 const unsigned Op1 = SysReg >> 11;
5121 const unsigned CRn = (SysReg >> 7) & 0xf;
5122 const unsigned CRm = (SysReg >> 3) & 0xf;
5123 const unsigned Op2 = SysReg & 0x7;
5125 Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::aarch64_sys),
5126 {Builder.getInt32(Op1), Builder.getInt32(CRn),
5127 Builder.getInt32(CRm), Builder.getInt32(Op2),
5128 EmitScalarExpr(E->getArg(1))});
5132 return ConstantInt::get(
Builder.getInt32Ty(), 0);
5135 if (BuiltinID == clang::AArch64::BI_AddressOfReturnAddress) {
5141 if (BuiltinID == clang::AArch64::BI__builtin_sponentry) {
5146 if (BuiltinID == clang::AArch64::BI__mulh ||
5147 BuiltinID == clang::AArch64::BI__umulh) {
5149 llvm::Type *Int128Ty = llvm::IntegerType::get(
getLLVMContext(), 128);
5151 bool IsSigned = BuiltinID == clang::AArch64::BI__mulh;
5157 Value *MulResult, *HigherBits;
5159 MulResult =
Builder.CreateNSWMul(LHS, RHS);
5160 HigherBits =
Builder.CreateAShr(MulResult, 64);
5162 MulResult =
Builder.CreateNUWMul(LHS, RHS);
5163 HigherBits =
Builder.CreateLShr(MulResult, 64);
5165 HigherBits =
Builder.CreateIntCast(HigherBits, ResType, IsSigned);
5170 if (BuiltinID == AArch64::BI__writex18byte ||
5171 BuiltinID == AArch64::BI__writex18word ||
5172 BuiltinID == AArch64::BI__writex18dword ||
5173 BuiltinID == AArch64::BI__writex18qword) {
5189 if (BuiltinID == AArch64::BI__readx18byte ||
5190 BuiltinID == AArch64::BI__readx18word ||
5191 BuiltinID == AArch64::BI__readx18dword ||
5192 BuiltinID == AArch64::BI__readx18qword) {
5207 if (BuiltinID == AArch64::BI__addx18byte ||
5208 BuiltinID == AArch64::BI__addx18word ||
5209 BuiltinID == AArch64::BI__addx18dword ||
5210 BuiltinID == AArch64::BI__addx18qword ||
5211 BuiltinID == AArch64::BI__incx18byte ||
5212 BuiltinID == AArch64::BI__incx18word ||
5213 BuiltinID == AArch64::BI__incx18dword ||
5214 BuiltinID == AArch64::BI__incx18qword) {
5217 switch (BuiltinID) {
5218 case AArch64::BI__incx18byte:
5222 case AArch64::BI__incx18word:
5226 case AArch64::BI__incx18dword:
5230 case AArch64::BI__incx18qword:
5236 isIncrement =
false;
5261 if (BuiltinID == AArch64::BI_CopyDoubleFromInt64 ||
5262 BuiltinID == AArch64::BI_CopyFloatFromInt32 ||
5263 BuiltinID == AArch64::BI_CopyInt32FromFloat ||
5264 BuiltinID == AArch64::BI_CopyInt64FromDouble) {
5267 return Builder.CreateBitCast(Arg, RetTy);
5270 if (BuiltinID == AArch64::BI_CountLeadingOnes ||
5271 BuiltinID == AArch64::BI_CountLeadingOnes64 ||
5272 BuiltinID == AArch64::BI_CountLeadingZeros ||
5273 BuiltinID == AArch64::BI_CountLeadingZeros64) {
5277 if (BuiltinID == AArch64::BI_CountLeadingOnes ||
5278 BuiltinID == AArch64::BI_CountLeadingOnes64)
5279 Arg =
Builder.CreateXor(Arg, Constant::getAllOnesValue(
ArgType));
5284 if (BuiltinID == AArch64::BI_CountLeadingOnes64 ||
5285 BuiltinID == AArch64::BI_CountLeadingZeros64)
5290 if (BuiltinID == AArch64::BI_CountLeadingSigns ||
5291 BuiltinID == AArch64::BI_CountLeadingSigns64) {
5294 Function *F = (BuiltinID == AArch64::BI_CountLeadingSigns)
5295 ?
CGM.getIntrinsic(Intrinsic::aarch64_cls)
5296 :
CGM.getIntrinsic(Intrinsic::aarch64_cls64);
5299 if (BuiltinID == AArch64::BI_CountLeadingSigns64)
5304 if (BuiltinID == AArch64::BI_CountOneBits ||
5305 BuiltinID == AArch64::BI_CountOneBits64) {
5311 if (BuiltinID == AArch64::BI_CountOneBits64)
5316 if (BuiltinID == AArch64::BI_CountTrailingZeros ||
5317 BuiltinID == AArch64::BI_CountTrailingZeros64) {
5324 if (BuiltinID == AArch64::BI_CountTrailingZeros64)
5329 if (BuiltinID == AArch64::BI__prefetch) {
5338 if (BuiltinID == AArch64::BI__prefetch2) {
5346 uint64_t Op = PrfOp.getZExtValue();
5347 uint64_t
Type = (Op >> 3) & 0x3;
5348 uint64_t
Target = (Op >> 1) & 0x3;
5349 uint64_t Policy = Op & 0x1;
5354 Function *F =
CGM.getIntrinsic(Intrinsic::aarch64_prefetch);
5358 if (BuiltinID == AArch64::BI__hlt) {
5359 Function *F =
CGM.getIntrinsic(Intrinsic::aarch64_hlt);
5365 return ConstantInt::get(
Builder.getInt32Ty(), 0);
5368 if (BuiltinID == AArch64::BI__hvc || BuiltinID == AArch64::BI__svc) {
5369 unsigned IID = BuiltinID == AArch64::BI__svc ? Intrinsic::aarch64_svc
5370 : Intrinsic::aarch64_hvc;
5378 for (
unsigned I = 1, N = E->
getNumArgs(); I < N; ++I) {
5380 llvm::Type *ArgTy = Arg->
getType();
5381 if (ArgTy->isPointerTy())
5383 else if (ArgTy->isFloatingPointTy())
5386 Arg =
Builder.CreateZExtOrTrunc(
5388 Arg,
Builder.getIntNTy(ArgTy->getPrimitiveSizeInBits())),
5393 Args.push_back(Arg);
5395 while (Args.size() < 5)
5396 Args.push_back(llvm::PoisonValue::get(
Int64Ty));
5402 if (BuiltinID == NEON::BI__builtin_neon_vcvth_bf16_f32)
5410 if (std::optional<MSVCIntrin> MsvcIntId =
5416 return P.first == BuiltinID;
5419 BuiltinID = It->second;
5425 bool IsSISD = (
Builtin !=
nullptr);
5429 unsigned ICEArguments = 0;
5440 unsigned NumArgs = E->
getNumArgs() - (HasExtraArg ? 1 : 0);
5441 for (
unsigned i = 0, e = NumArgs; i != e; i++) {
5443 switch (BuiltinID) {
5444 case NEON::BI__builtin_neon_vld1_v:
5445 case NEON::BI__builtin_neon_vld1q_v:
5446 case NEON::BI__builtin_neon_vld1_dup_v:
5447 case NEON::BI__builtin_neon_vld1q_dup_v:
5448 case NEON::BI__builtin_neon_vld1_lane_v:
5449 case NEON::BI__builtin_neon_vld1q_lane_v:
5450 case NEON::BI__builtin_neon_vst1_v:
5451 case NEON::BI__builtin_neon_vst1q_v:
5452 case NEON::BI__builtin_neon_vst1_lane_v:
5453 case NEON::BI__builtin_neon_vst1q_lane_v:
5454 case NEON::BI__builtin_neon_vldap1_lane_s64:
5455 case NEON::BI__builtin_neon_vldap1q_lane_s64:
5456 case NEON::BI__builtin_neon_vstl1_lane_s64:
5457 case NEON::BI__builtin_neon_vstl1q_lane_s64:
5470 assert(
Result &&
"SISD intrinsic should have been handled");
5476 if (std::optional<llvm::APSInt>
Result =
5481 bool usgn =
Type.isUnsigned();
5482 bool quad =
Type.isQuad();
5501 switch (BuiltinID) {
5503 case NEON::BI__builtin_neon_vabsh_f16:
5505 case NEON::BI__builtin_neon_vaddq_p128: {
5507 Ops[0] =
Builder.CreateBitCast(Ops[0], Ty);
5508 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
5509 Ops[0] =
Builder.CreateXor(Ops[0], Ops[1]);
5510 llvm::Type *Int128Ty = llvm::Type::getIntNTy(
getLLVMContext(), 128);
5511 return Builder.CreateBitCast(Ops[0], Int128Ty);
5513 case NEON::BI__builtin_neon_vldrq_p128: {
5514 llvm::Type *Int128Ty = llvm::Type::getIntNTy(
getLLVMContext(), 128);
5515 return Builder.CreateAlignedLoad(Int128Ty, Ops[0],
5518 case NEON::BI__builtin_neon_vstrq_p128: {
5519 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
5521 case NEON::BI__builtin_neon_vcvts_f32_u32:
5522 case NEON::BI__builtin_neon_vcvtd_f64_u64:
5525 case NEON::BI__builtin_neon_vcvts_f32_s32:
5526 case NEON::BI__builtin_neon_vcvtd_f64_s64: {
5527 bool Is64 = Ops[0]->getType()->getPrimitiveSizeInBits() == 64;
5530 Ops[0] =
Builder.CreateBitCast(Ops[0], InTy);
5532 return Builder.CreateUIToFP(Ops[0], FTy);
5533 return Builder.CreateSIToFP(Ops[0], FTy);
5535 case NEON::BI__builtin_neon_vcvth_f16_u16:
5536 case NEON::BI__builtin_neon_vcvth_f16_u32:
5537 case NEON::BI__builtin_neon_vcvth_f16_u64:
5540 case NEON::BI__builtin_neon_vcvth_f16_s16:
5541 case NEON::BI__builtin_neon_vcvth_f16_s32:
5542 case NEON::BI__builtin_neon_vcvth_f16_s64: {
5543 llvm::Type *FTy =
HalfTy;
5545 if (Ops[0]->
getType()->getPrimitiveSizeInBits() == 64)
5547 else if (Ops[0]->
getType()->getPrimitiveSizeInBits() == 32)
5551 Ops[0] =
Builder.CreateBitCast(Ops[0], InTy);
5553 return Builder.CreateUIToFP(Ops[0], FTy);
5554 return Builder.CreateSIToFP(Ops[0], FTy);
5556 case NEON::BI__builtin_neon_vcvtah_u16_f16:
5557 case NEON::BI__builtin_neon_vcvtmh_u16_f16:
5558 case NEON::BI__builtin_neon_vcvtnh_u16_f16:
5559 case NEON::BI__builtin_neon_vcvtph_u16_f16:
5560 case NEON::BI__builtin_neon_vcvtah_s16_f16:
5561 case NEON::BI__builtin_neon_vcvtmh_s16_f16:
5562 case NEON::BI__builtin_neon_vcvtnh_s16_f16:
5563 case NEON::BI__builtin_neon_vcvtph_s16_f16: {
5565 llvm::Type* FTy =
HalfTy;
5566 llvm::Type *Tys[2] = {InTy, FTy};
5567 switch (BuiltinID) {
5568 default: llvm_unreachable(
"missing builtin ID in switch!");
5569 case NEON::BI__builtin_neon_vcvtah_u16_f16:
5570 Int = Intrinsic::aarch64_neon_fcvtau;
break;
5571 case NEON::BI__builtin_neon_vcvtmh_u16_f16:
5572 Int = Intrinsic::aarch64_neon_fcvtmu;
break;
5573 case NEON::BI__builtin_neon_vcvtnh_u16_f16:
5574 Int = Intrinsic::aarch64_neon_fcvtnu;
break;
5575 case NEON::BI__builtin_neon_vcvtph_u16_f16:
5576 Int = Intrinsic::aarch64_neon_fcvtpu;
break;
5577 case NEON::BI__builtin_neon_vcvtah_s16_f16:
5578 Int = Intrinsic::aarch64_neon_fcvtas;
break;
5579 case NEON::BI__builtin_neon_vcvtmh_s16_f16:
5580 Int = Intrinsic::aarch64_neon_fcvtms;
break;
5581 case NEON::BI__builtin_neon_vcvtnh_s16_f16:
5582 Int = Intrinsic::aarch64_neon_fcvtns;
break;
5583 case NEON::BI__builtin_neon_vcvtph_s16_f16:
5584 Int = Intrinsic::aarch64_neon_fcvtps;
break;
5588 case NEON::BI__builtin_neon_vcaleh_f16:
5589 case NEON::BI__builtin_neon_vcalth_f16:
5590 case NEON::BI__builtin_neon_vcageh_f16:
5591 case NEON::BI__builtin_neon_vcagth_f16: {
5593 llvm::Type* FTy =
HalfTy;
5594 llvm::Type *Tys[2] = {InTy, FTy};
5595 switch (BuiltinID) {
5596 default: llvm_unreachable(
"missing builtin ID in switch!");
5597 case NEON::BI__builtin_neon_vcageh_f16:
5598 Int = Intrinsic::aarch64_neon_facge;
break;
5599 case NEON::BI__builtin_neon_vcagth_f16:
5600 Int = Intrinsic::aarch64_neon_facgt;
break;
5601 case NEON::BI__builtin_neon_vcaleh_f16:
5602 Int = Intrinsic::aarch64_neon_facge; std::swap(Ops[0], Ops[1]);
break;
5603 case NEON::BI__builtin_neon_vcalth_f16:
5604 Int = Intrinsic::aarch64_neon_facgt; std::swap(Ops[0], Ops[1]);
break;
5609 case NEON::BI__builtin_neon_vcvth_n_s16_f16:
5610 case NEON::BI__builtin_neon_vcvth_n_u16_f16: {
5612 llvm::Type* FTy =
HalfTy;
5613 llvm::Type *Tys[2] = {InTy, FTy};
5614 switch (BuiltinID) {
5615 default: llvm_unreachable(
"missing builtin ID in switch!");
5616 case NEON::BI__builtin_neon_vcvth_n_s16_f16:
5617 Int = Intrinsic::aarch64_neon_vcvtfp2fxs;
break;
5618 case NEON::BI__builtin_neon_vcvth_n_u16_f16:
5619 Int = Intrinsic::aarch64_neon_vcvtfp2fxu;
break;
5624 case NEON::BI__builtin_neon_vcvth_n_f16_s16:
5625 case NEON::BI__builtin_neon_vcvth_n_f16_u16: {
5626 llvm::Type* FTy =
HalfTy;
5628 llvm::Type *Tys[2] = {FTy, InTy};
5629 switch (BuiltinID) {
5630 default: llvm_unreachable(
"missing builtin ID in switch!");
5631 case NEON::BI__builtin_neon_vcvth_n_f16_s16:
5632 Int = Intrinsic::aarch64_neon_vcvtfxs2fp;
5633 Ops[0] =
Builder.CreateSExt(Ops[0], InTy,
"sext");
5635 case NEON::BI__builtin_neon_vcvth_n_f16_u16:
5636 Int = Intrinsic::aarch64_neon_vcvtfxu2fp;
5637 Ops[0] =
Builder.CreateZExt(Ops[0], InTy);
5642 case NEON::BI__builtin_neon_vpaddd_s64: {
5645 auto *Ty = llvm::FixedVectorType::get(
Int64Ty, 2);
5647 Ops[0] =
Builder.CreateBitCast(Ops[0], Ty,
"v2i64");
5648 llvm::Value *Idx0 = llvm::ConstantInt::get(
SizeTy, 0);
5649 llvm::Value *Idx1 = llvm::ConstantInt::get(
SizeTy, 1);
5650 Value *Op0 =
Builder.CreateExtractElement(Ops[0], Idx0,
"lane0");
5651 Value *Op1 =
Builder.CreateExtractElement(Ops[0], Idx1,
"lane1");
5653 return Builder.CreateAdd(Op0, Op1,
"vpaddd");
5655 case NEON::BI__builtin_neon_vpaddd_f64: {
5656 auto *Ty = llvm::FixedVectorType::get(
DoubleTy, 2);
5658 Ops[0] =
Builder.CreateBitCast(Ops[0], Ty,
"v2f64");
5659 llvm::Value *Idx0 = llvm::ConstantInt::get(
SizeTy, 0);
5660 llvm::Value *Idx1 = llvm::ConstantInt::get(
SizeTy, 1);
5661 Value *Op0 =
Builder.CreateExtractElement(Ops[0], Idx0,
"lane0");
5662 Value *Op1 =
Builder.CreateExtractElement(Ops[0], Idx1,
"lane1");
5664 return Builder.CreateFAdd(Op0, Op1,
"vpaddd");
5666 case NEON::BI__builtin_neon_vpadds_f32: {
5667 auto *Ty = llvm::FixedVectorType::get(
FloatTy, 2);
5669 Ops[0] =
Builder.CreateBitCast(Ops[0], Ty,
"v2f32");
5670 llvm::Value *Idx0 = llvm::ConstantInt::get(
SizeTy, 0);
5671 llvm::Value *Idx1 = llvm::ConstantInt::get(
SizeTy, 1);
5672 Value *Op0 =
Builder.CreateExtractElement(Ops[0], Idx0,
"lane0");
5673 Value *Op1 =
Builder.CreateExtractElement(Ops[0], Idx1,
"lane1");
5675 return Builder.CreateFAdd(Op0, Op1,
"vpaddd");
5677 case NEON::BI__builtin_neon_vceqzd_s64:
5680 ICmpInst::ICMP_EQ,
"vceqz");
5681 case NEON::BI__builtin_neon_vceqzd_f64:
5682 case NEON::BI__builtin_neon_vceqzs_f32:
5683 case NEON::BI__builtin_neon_vceqzh_f16:
5686 ICmpInst::FCMP_OEQ,
"vceqz");
5687 case NEON::BI__builtin_neon_vcgezd_s64:
5690 ICmpInst::ICMP_SGE,
"vcgez");
5691 case NEON::BI__builtin_neon_vcgezd_f64:
5692 case NEON::BI__builtin_neon_vcgezs_f32:
5693 case NEON::BI__builtin_neon_vcgezh_f16:
5696 ICmpInst::FCMP_OGE,
"vcgez");
5697 case NEON::BI__builtin_neon_vclezd_s64:
5700 ICmpInst::ICMP_SLE,
"vclez");
5701 case NEON::BI__builtin_neon_vclezd_f64:
5702 case NEON::BI__builtin_neon_vclezs_f32:
5703 case NEON::BI__builtin_neon_vclezh_f16:
5706 ICmpInst::FCMP_OLE,
"vclez");
5707 case NEON::BI__builtin_neon_vcgtzd_s64:
5710 ICmpInst::ICMP_SGT,
"vcgtz");
5711 case NEON::BI__builtin_neon_vcgtzd_f64:
5712 case NEON::BI__builtin_neon_vcgtzs_f32:
5713 case NEON::BI__builtin_neon_vcgtzh_f16:
5716 ICmpInst::FCMP_OGT,
"vcgtz");
5717 case NEON::BI__builtin_neon_vcltzd_s64:
5720 ICmpInst::ICMP_SLT,
"vcltz");
5722 case NEON::BI__builtin_neon_vcltzd_f64:
5723 case NEON::BI__builtin_neon_vcltzs_f32:
5724 case NEON::BI__builtin_neon_vcltzh_f16:
5727 ICmpInst::FCMP_OLT,
"vcltz");
5729 case NEON::BI__builtin_neon_vceqzd_u64: {
5732 ICmpInst::ICMP_EQ,
"vceqzd");
5734 case NEON::BI__builtin_neon_vceqd_f64:
5735 case NEON::BI__builtin_neon_vcled_f64:
5736 case NEON::BI__builtin_neon_vcltd_f64:
5737 case NEON::BI__builtin_neon_vcged_f64:
5738 case NEON::BI__builtin_neon_vcgtd_f64: {
5739 llvm::CmpInst::Predicate P;
5740 switch (BuiltinID) {
5741 default: llvm_unreachable(
"missing builtin ID in switch!");
5742 case NEON::BI__builtin_neon_vceqd_f64: P = llvm::FCmpInst::FCMP_OEQ;
break;
5743 case NEON::BI__builtin_neon_vcled_f64: P = llvm::FCmpInst::FCMP_OLE;
break;
5744 case NEON::BI__builtin_neon_vcltd_f64: P = llvm::FCmpInst::FCMP_OLT;
break;
5745 case NEON::BI__builtin_neon_vcged_f64: P = llvm::FCmpInst::FCMP_OGE;
break;
5746 case NEON::BI__builtin_neon_vcgtd_f64: P = llvm::FCmpInst::FCMP_OGT;
break;
5750 if (P == llvm::FCmpInst::FCMP_OEQ)
5751 Ops[0] =
Builder.CreateFCmp(P, Ops[0], Ops[1]);
5753 Ops[0] =
Builder.CreateFCmpS(P, Ops[0], Ops[1]);
5756 case NEON::BI__builtin_neon_vceqs_f32:
5757 case NEON::BI__builtin_neon_vcles_f32:
5758 case NEON::BI__builtin_neon_vclts_f32:
5759 case NEON::BI__builtin_neon_vcges_f32:
5760 case NEON::BI__builtin_neon_vcgts_f32: {
5761 llvm::CmpInst::Predicate P;
5762 switch (BuiltinID) {
5763 default: llvm_unreachable(
"missing builtin ID in switch!");
5764 case NEON::BI__builtin_neon_vceqs_f32: P = llvm::FCmpInst::FCMP_OEQ;
break;
5765 case NEON::BI__builtin_neon_vcles_f32: P = llvm::FCmpInst::FCMP_OLE;
break;
5766 case NEON::BI__builtin_neon_vclts_f32: P = llvm::FCmpInst::FCMP_OLT;
break;
5767 case NEON::BI__builtin_neon_vcges_f32: P = llvm::FCmpInst::FCMP_OGE;
break;
5768 case NEON::BI__builtin_neon_vcgts_f32: P = llvm::FCmpInst::FCMP_OGT;
break;
5772 if (P == llvm::FCmpInst::FCMP_OEQ)
5773 Ops[0] =
Builder.CreateFCmp(P, Ops[0], Ops[1]);
5775 Ops[0] =
Builder.CreateFCmpS(P, Ops[0], Ops[1]);
5778 case NEON::BI__builtin_neon_vceqh_f16:
5779 case NEON::BI__builtin_neon_vcleh_f16:
5780 case NEON::BI__builtin_neon_vclth_f16:
5781 case NEON::BI__builtin_neon_vcgeh_f16:
5782 case NEON::BI__builtin_neon_vcgth_f16: {
5783 llvm::CmpInst::Predicate P;
5784 switch (BuiltinID) {
5785 default: llvm_unreachable(
"missing builtin ID in switch!");
5786 case NEON::BI__builtin_neon_vceqh_f16: P = llvm::FCmpInst::FCMP_OEQ;
break;
5787 case NEON::BI__builtin_neon_vcleh_f16: P = llvm::FCmpInst::FCMP_OLE;
break;
5788 case NEON::BI__builtin_neon_vclth_f16: P = llvm::FCmpInst::FCMP_OLT;
break;
5789 case NEON::BI__builtin_neon_vcgeh_f16: P = llvm::FCmpInst::FCMP_OGE;
break;
5790 case NEON::BI__builtin_neon_vcgth_f16: P = llvm::FCmpInst::FCMP_OGT;
break;
5794 if (P == llvm::FCmpInst::FCMP_OEQ)
5795 Ops[0] =
Builder.CreateFCmp(P, Ops[0], Ops[1]);
5797 Ops[0] =
Builder.CreateFCmpS(P, Ops[0], Ops[1]);
5800 case NEON::BI__builtin_neon_vceqd_s64:
5801 case NEON::BI__builtin_neon_vceqd_u64:
5802 case NEON::BI__builtin_neon_vcgtd_s64:
5803 case NEON::BI__builtin_neon_vcgtd_u64:
5804 case NEON::BI__builtin_neon_vcltd_s64:
5805 case NEON::BI__builtin_neon_vcltd_u64:
5806 case NEON::BI__builtin_neon_vcged_u64:
5807 case NEON::BI__builtin_neon_vcged_s64:
5808 case NEON::BI__builtin_neon_vcled_u64:
5809 case NEON::BI__builtin_neon_vcled_s64: {
5810 llvm::CmpInst::Predicate P;
5811 switch (BuiltinID) {
5812 default: llvm_unreachable(
"missing builtin ID in switch!");
5813 case NEON::BI__builtin_neon_vceqd_s64:
5814 case NEON::BI__builtin_neon_vceqd_u64:P = llvm::ICmpInst::ICMP_EQ;
break;
5815 case NEON::BI__builtin_neon_vcgtd_s64:P = llvm::ICmpInst::ICMP_SGT;
break;
5816 case NEON::BI__builtin_neon_vcgtd_u64:P = llvm::ICmpInst::ICMP_UGT;
break;
5817 case NEON::BI__builtin_neon_vcltd_s64:P = llvm::ICmpInst::ICMP_SLT;
break;
5818 case NEON::BI__builtin_neon_vcltd_u64:P = llvm::ICmpInst::ICMP_ULT;
break;
5819 case NEON::BI__builtin_neon_vcged_u64:P = llvm::ICmpInst::ICMP_UGE;
break;
5820 case NEON::BI__builtin_neon_vcged_s64:P = llvm::ICmpInst::ICMP_SGE;
break;
5821 case NEON::BI__builtin_neon_vcled_u64:P = llvm::ICmpInst::ICMP_ULE;
break;
5822 case NEON::BI__builtin_neon_vcled_s64:P = llvm::ICmpInst::ICMP_SLE;
break;
5826 Ops[0] =
Builder.CreateICmp(P, Ops[0], Ops[1]);
5829 case NEON::BI__builtin_neon_vnegd_s64:
5830 return Builder.CreateNeg(Ops[0],
"vnegd");
5831 case NEON::BI__builtin_neon_vnegh_f16:
5832 return Builder.CreateFNeg(Ops[0],
"vnegh");
5833 case NEON::BI__builtin_neon_vtstd_s64:
5834 case NEON::BI__builtin_neon_vtstd_u64: {
5837 Ops[0] =
Builder.CreateAnd(Ops[0], Ops[1]);
5838 Ops[0] =
Builder.CreateICmp(ICmpInst::ICMP_NE, Ops[0],
5839 llvm::Constant::getNullValue(
Int64Ty));
5842 case NEON::BI__builtin_neon_vset_lane_i8:
5843 case NEON::BI__builtin_neon_vset_lane_i16:
5844 case NEON::BI__builtin_neon_vset_lane_i32:
5845 case NEON::BI__builtin_neon_vset_lane_i64:
5846 case NEON::BI__builtin_neon_vset_lane_bf16:
5847 case NEON::BI__builtin_neon_vset_lane_f32:
5848 case NEON::BI__builtin_neon_vsetq_lane_i8:
5849 case NEON::BI__builtin_neon_vsetq_lane_i16:
5850 case NEON::BI__builtin_neon_vsetq_lane_i32:
5851 case NEON::BI__builtin_neon_vsetq_lane_i64:
5852 case NEON::BI__builtin_neon_vsetq_lane_bf16:
5853 case NEON::BI__builtin_neon_vsetq_lane_f32:
5854 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2],
"vset_lane");
5855 case NEON::BI__builtin_neon_vset_lane_f64:
5858 Builder.CreateBitCast(Ops[1], llvm::FixedVectorType::get(
DoubleTy, 1));
5859 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2],
"vset_lane");
5860 case NEON::BI__builtin_neon_vset_lane_mf8:
5861 case NEON::BI__builtin_neon_vsetq_lane_mf8:
5865 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2],
"vset_lane");
5866 case NEON::BI__builtin_neon_vsetq_lane_f64:
5869 Builder.CreateBitCast(Ops[1], llvm::FixedVectorType::get(
DoubleTy, 2));
5870 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2],
"vset_lane");
5872 case NEON::BI__builtin_neon_vget_lane_i8:
5873 case NEON::BI__builtin_neon_vdupb_lane_i8:
5874 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vget_lane");
5875 case NEON::BI__builtin_neon_vgetq_lane_i8:
5876 case NEON::BI__builtin_neon_vdupb_laneq_i8:
5877 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vgetq_lane");
5878 case NEON::BI__builtin_neon_vget_lane_mf8:
5879 case NEON::BI__builtin_neon_vdupb_lane_mf8:
5880 case NEON::BI__builtin_neon_vgetq_lane_mf8:
5881 case NEON::BI__builtin_neon_vdupb_laneq_mf8:
5882 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vget_lane");
5883 case NEON::BI__builtin_neon_vget_lane_i16:
5884 case NEON::BI__builtin_neon_vduph_lane_i16:
5885 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vget_lane");
5886 case NEON::BI__builtin_neon_vgetq_lane_i16:
5887 case NEON::BI__builtin_neon_vduph_laneq_i16:
5888 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vgetq_lane");
5889 case NEON::BI__builtin_neon_vget_lane_i32:
5890 case NEON::BI__builtin_neon_vdups_lane_i32:
5891 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vget_lane");
5892 case NEON::BI__builtin_neon_vdups_lane_f32:
5893 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vdups_lane");
5894 case NEON::BI__builtin_neon_vgetq_lane_i32:
5895 case NEON::BI__builtin_neon_vdups_laneq_i32:
5896 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vgetq_lane");
5897 case NEON::BI__builtin_neon_vget_lane_i64:
5898 case NEON::BI__builtin_neon_vdupd_lane_i64:
5899 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vget_lane");
5900 case NEON::BI__builtin_neon_vdupd_lane_f64:
5901 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vdupd_lane");
5902 case NEON::BI__builtin_neon_vgetq_lane_i64:
5903 case NEON::BI__builtin_neon_vdupd_laneq_i64:
5904 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vgetq_lane");
5905 case NEON::BI__builtin_neon_vget_lane_f32:
5906 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vget_lane");
5907 case NEON::BI__builtin_neon_vget_lane_f64:
5908 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vget_lane");
5909 case NEON::BI__builtin_neon_vgetq_lane_f32:
5910 case NEON::BI__builtin_neon_vdups_laneq_f32:
5911 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vgetq_lane");
5912 case NEON::BI__builtin_neon_vgetq_lane_f64:
5913 case NEON::BI__builtin_neon_vdupd_laneq_f64:
5914 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vgetq_lane");
5915 case NEON::BI__builtin_neon_vaddh_f16:
5916 return Builder.CreateFAdd(Ops[0], Ops[1],
"vaddh");
5917 case NEON::BI__builtin_neon_vsubh_f16:
5918 return Builder.CreateFSub(Ops[0], Ops[1],
"vsubh");
5919 case NEON::BI__builtin_neon_vmulh_f16:
5920 return Builder.CreateFMul(Ops[0], Ops[1],
"vmulh");
5921 case NEON::BI__builtin_neon_vdivh_f16:
5922 return Builder.CreateFDiv(Ops[0], Ops[1],
"vdivh");
5923 case NEON::BI__builtin_neon_vfmah_f16:
5926 *
this, Intrinsic::fma, Intrinsic::experimental_constrained_fma,
HalfTy,
5927 {Ops[1], Ops[2], Ops[0]});
5928 case NEON::BI__builtin_neon_vfmsh_f16: {
5933 *
this, Intrinsic::fma, Intrinsic::experimental_constrained_fma,
HalfTy,
5934 {Neg, Ops[2], Ops[0]});
5936 case NEON::BI__builtin_neon_vaddd_s64:
5937 case NEON::BI__builtin_neon_vaddd_u64:
5938 return Builder.CreateAdd(Ops[0], Ops[1],
"vaddd");
5939 case NEON::BI__builtin_neon_vsubd_s64:
5940 case NEON::BI__builtin_neon_vsubd_u64:
5941 return Builder.CreateSub(Ops[0], Ops[1],
"vsubd");
5942 case NEON::BI__builtin_neon_vqdmlalh_s16:
5943 case NEON::BI__builtin_neon_vqdmlslh_s16: {
5947 auto *VTy = llvm::FixedVectorType::get(
Int32Ty, 4);
5948 Ops[1] =
EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmull, VTy),
5949 ProductOps,
"vqdmlXl");
5951 Ops[1] =
Builder.CreateExtractElement(Ops[1], CI,
"lane0");
5953 unsigned AccumInt = BuiltinID == NEON::BI__builtin_neon_vqdmlalh_s16
5954 ? Intrinsic::aarch64_neon_sqadd
5955 : Intrinsic::aarch64_neon_sqsub;
5960 case NEON::BI__builtin_neon_vqshlud_n_s64: {
5965 case NEON::BI__builtin_neon_vqshld_n_u64:
5966 case NEON::BI__builtin_neon_vqshld_n_s64: {
5967 Int = BuiltinID == NEON::BI__builtin_neon_vqshld_n_u64
5968 ? Intrinsic::aarch64_neon_uqshl
5969 : Intrinsic::aarch64_neon_sqshl;
5973 case NEON::BI__builtin_neon_vrshrd_n_u64:
5974 case NEON::BI__builtin_neon_vrshrd_n_s64: {
5975 Int = BuiltinID == NEON::BI__builtin_neon_vrshrd_n_u64
5976 ? Intrinsic::aarch64_neon_urshl
5977 : Intrinsic::aarch64_neon_srshl;
5979 Ops[1] = ConstantInt::get(
Int64Ty, -SV);
5982 case NEON::BI__builtin_neon_vrsrad_n_u64:
5983 case NEON::BI__builtin_neon_vrsrad_n_s64: {
5984 Int = BuiltinID == NEON::BI__builtin_neon_vrsrad_n_u64
5985 ? Intrinsic::aarch64_neon_urshl
5986 : Intrinsic::aarch64_neon_srshl;
5988 Ops[2] =
Builder.CreateNeg(Ops[2]);
5990 {Ops[1], Builder.CreateSExt(Ops[2], Int64Ty)});
5993 case NEON::BI__builtin_neon_vshld_n_s64:
5994 case NEON::BI__builtin_neon_vshld_n_u64: {
5997 Ops[0], ConstantInt::get(
Int64Ty, Amt->getZExtValue()),
"shld_n");
5999 case NEON::BI__builtin_neon_vshrd_n_s64: {
6002 Ops[0], ConstantInt::get(
Int64Ty, std::min(
static_cast<uint64_t
>(63),
6003 Amt->getZExtValue())),
6006 case NEON::BI__builtin_neon_vshrd_n_u64: {
6008 uint64_t ShiftAmt = Amt->getZExtValue();
6011 return ConstantInt::get(
Int64Ty, 0);
6012 return Builder.CreateLShr(Ops[0], ConstantInt::get(
Int64Ty, ShiftAmt),
6015 case NEON::BI__builtin_neon_vsrad_n_s64: {
6018 Ops[1], ConstantInt::get(
Int64Ty, std::min(
static_cast<uint64_t
>(63),
6019 Amt->getZExtValue())),
6021 return Builder.CreateAdd(Ops[0], Ops[1]);
6023 case NEON::BI__builtin_neon_vsrad_n_u64: {
6025 uint64_t ShiftAmt = Amt->getZExtValue();
6030 Ops[1] =
Builder.CreateLShr(Ops[1], ConstantInt::get(
Int64Ty, ShiftAmt),
6032 return Builder.CreateAdd(Ops[0], Ops[1]);
6034 case NEON::BI__builtin_neon_vqdmlalh_lane_s16:
6035 case NEON::BI__builtin_neon_vqdmlalh_laneq_s16:
6036 case NEON::BI__builtin_neon_vqdmlslh_lane_s16:
6037 case NEON::BI__builtin_neon_vqdmlslh_laneq_s16: {
6038 Ops[2] =
Builder.CreateExtractElement(Ops[2], Ops[3],
"lane");
6042 auto *VTy = llvm::FixedVectorType::get(
Int32Ty, 4);
6043 Ops[1] =
EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmull, VTy),
6044 ProductOps,
"vqdmlXl");
6046 Ops[1] =
Builder.CreateExtractElement(Ops[1], CI,
"lane0");
6051 unsigned AccInt = (BuiltinID == NEON::BI__builtin_neon_vqdmlalh_lane_s16 ||
6052 BuiltinID == NEON::BI__builtin_neon_vqdmlalh_laneq_s16)
6053 ? Intrinsic::aarch64_neon_sqadd
6054 : Intrinsic::aarch64_neon_sqsub;
6057 case NEON::BI__builtin_neon_vqdmlals_s32:
6058 case NEON::BI__builtin_neon_vqdmlsls_s32: {
6060 ProductOps.push_back(Ops[1]);
6061 ProductOps.push_back(Ops[2]);
6063 EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmulls_scalar),
6064 ProductOps,
"vqdmlXl");
6066 unsigned AccumInt = BuiltinID == NEON::BI__builtin_neon_vqdmlals_s32
6067 ? Intrinsic::aarch64_neon_sqadd
6068 : Intrinsic::aarch64_neon_sqsub;
6073 case NEON::BI__builtin_neon_vqdmlals_lane_s32:
6074 case NEON::BI__builtin_neon_vqdmlals_laneq_s32:
6075 case NEON::BI__builtin_neon_vqdmlsls_lane_s32:
6076 case NEON::BI__builtin_neon_vqdmlsls_laneq_s32: {
6077 Ops[2] =
Builder.CreateExtractElement(Ops[2], Ops[3],
"lane");
6079 ProductOps.push_back(Ops[1]);
6080 ProductOps.push_back(Ops[2]);
6082 EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmulls_scalar),
6083 ProductOps,
"vqdmlXl");
6088 unsigned AccInt = (BuiltinID == NEON::BI__builtin_neon_vqdmlals_lane_s32 ||
6089 BuiltinID == NEON::BI__builtin_neon_vqdmlals_laneq_s32)
6090 ? Intrinsic::aarch64_neon_sqadd
6091 : Intrinsic::aarch64_neon_sqsub;
6094 case NEON::BI__builtin_neon_vget_lane_bf16:
6095 case NEON::BI__builtin_neon_vduph_lane_bf16:
6096 case NEON::BI__builtin_neon_vduph_lane_f16: {
6097 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vget_lane");
6099 case NEON::BI__builtin_neon_vgetq_lane_bf16:
6100 case NEON::BI__builtin_neon_vduph_laneq_bf16:
6101 case NEON::BI__builtin_neon_vduph_laneq_f16: {
6102 return Builder.CreateExtractElement(Ops[0], Ops[1],
"vgetq_lane");
6104 case NEON::BI__builtin_neon_vcvt_bf16_f32: {
6105 llvm::Type *V4F32 = FixedVectorType::get(
Builder.getFloatTy(), 4);
6106 llvm::Type *V4BF16 = FixedVectorType::get(
Builder.getBFloatTy(), 4);
6107 return Builder.CreateFPTrunc(
Builder.CreateBitCast(Ops[0], V4F32), V4BF16);
6109 case NEON::BI__builtin_neon_vcvtq_low_bf16_f32: {
6111 std::iota(ConcatMask.begin(), ConcatMask.end(), 0);
6112 llvm::Type *V4F32 = FixedVectorType::get(
Builder.getFloatTy(), 4);
6113 llvm::Type *V4BF16 = FixedVectorType::get(
Builder.getBFloatTy(), 4);
6114 llvm::Value *Trunc =
6115 Builder.CreateFPTrunc(
Builder.CreateBitCast(Ops[0], V4F32), V4BF16);
6116 return Builder.CreateShuffleVector(
6117 Trunc, ConstantAggregateZero::get(V4BF16), ConcatMask);
6119 case NEON::BI__builtin_neon_vcvtq_high_bf16_f32: {
6121 std::iota(ConcatMask.begin(), ConcatMask.end(), 0);
6123 std::iota(LoMask.begin(), LoMask.end(), 0);
6124 llvm::Type *V4F32 = FixedVectorType::get(
Builder.getFloatTy(), 4);
6125 llvm::Type *V4BF16 = FixedVectorType::get(
Builder.getBFloatTy(), 4);
6126 llvm::Type *V8BF16 = FixedVectorType::get(
Builder.getBFloatTy(), 8);
6127 llvm::Value *Inactive =
Builder.CreateShuffleVector(
6128 Builder.CreateBitCast(Ops[0], V8BF16), LoMask);
6129 llvm::Value *Trunc =
6130 Builder.CreateFPTrunc(
Builder.CreateBitCast(Ops[1], V4F32), V4BF16);
6131 return Builder.CreateShuffleVector(Inactive, Trunc, ConcatMask);
6133 case NEON::BI__builtin_neon_vcvt_f16_f32: {
6134 llvm::Type *V4F32 = FixedVectorType::get(
Builder.getFloatTy(), 4);
6135 llvm::Type *V4F16 = FixedVectorType::get(
Builder.getHalfTy(), 4);
6136 return Builder.CreateFPTrunc(
Builder.CreateBitCast(Ops[0], V4F32), V4F16);
6138 case NEON::BI__builtin_neon_vcvt_f32_f16: {
6139 llvm::Type *V4F32 = FixedVectorType::get(
Builder.getFloatTy(), 4);
6140 llvm::Type *V4F16 = FixedVectorType::get(
Builder.getHalfTy(), 4);
6141 return Builder.CreateFPExt(
Builder.CreateBitCast(Ops[0], V4F16), V4F32);
6144 case clang::AArch64::BI_InterlockedAdd:
6145 case clang::AArch64::BI_InterlockedAdd_acq:
6146 case clang::AArch64::BI_InterlockedAdd_rel:
6147 case clang::AArch64::BI_InterlockedAdd_nf:
6148 case clang::AArch64::BI_InterlockedAdd64:
6149 case clang::AArch64::BI_InterlockedAdd64_acq:
6150 case clang::AArch64::BI_InterlockedAdd64_rel:
6151 case clang::AArch64::BI_InterlockedAdd64_nf: {
6153 Value *Val = Ops[1];
6154 llvm::AtomicOrdering Ordering;
6155 switch (BuiltinID) {
6156 case clang::AArch64::BI_InterlockedAdd:
6157 case clang::AArch64::BI_InterlockedAdd64:
6158 Ordering = llvm::AtomicOrdering::SequentiallyConsistent;
6160 case clang::AArch64::BI_InterlockedAdd_acq:
6161 case clang::AArch64::BI_InterlockedAdd64_acq:
6162 Ordering = llvm::AtomicOrdering::Acquire;
6164 case clang::AArch64::BI_InterlockedAdd_rel:
6165 case clang::AArch64::BI_InterlockedAdd64_rel:
6166 Ordering = llvm::AtomicOrdering::Release;
6168 case clang::AArch64::BI_InterlockedAdd_nf:
6169 case clang::AArch64::BI_InterlockedAdd64_nf:
6170 Ordering = llvm::AtomicOrdering::Monotonic;
6173 llvm_unreachable(
"missing builtin ID in switch!");
6175 AtomicRMWInst *RMWI =
6176 Builder.CreateAtomicRMW(AtomicRMWInst::Add, DestAddr, Val, Ordering);
6177 return Builder.CreateAdd(RMWI, Val);
6182 llvm::Type *Ty = VTy;
6186 bool ExtractLow =
false;
6187 bool ExtendLaneArg =
false;
6188 switch (BuiltinID) {
6189 default:
return nullptr;
6190 case NEON::BI__builtin_neon_vbsl_v:
6191 case NEON::BI__builtin_neon_vbslq_v: {
6192 llvm::Type *BitTy = llvm::VectorType::getInteger(VTy);
6193 Ops[0] =
Builder.CreateBitCast(Ops[0], BitTy,
"vbsl");
6194 Ops[1] =
Builder.CreateBitCast(Ops[1], BitTy,
"vbsl");
6195 Ops[2] =
Builder.CreateBitCast(Ops[2], BitTy,
"vbsl");
6197 Ops[1] =
Builder.CreateAnd(Ops[0], Ops[1],
"vbsl");
6198 Ops[2] =
Builder.CreateAnd(
Builder.CreateNot(Ops[0]), Ops[2],
"vbsl");
6199 Ops[0] =
Builder.CreateOr(Ops[1], Ops[2],
"vbsl");
6200 return Builder.CreateBitCast(Ops[0], Ty);
6202 case NEON::BI__builtin_neon_vfma_lane_v:
6203 case NEON::BI__builtin_neon_vfmaq_lane_v: {
6206 Value *Addend = Ops[0];
6207 Value *Multiplicand = Ops[1];
6208 Value *LaneSource = Ops[2];
6209 Ops[0] = Multiplicand;
6210 Ops[1] = LaneSource;
6214 auto *SourceTy = BuiltinID == NEON::BI__builtin_neon_vfmaq_lane_v
6215 ? llvm::FixedVectorType::get(VTy->getElementType(),
6216 VTy->getNumElements() / 2)
6219 Value *SV = llvm::ConstantVector::getSplat(VTy->getElementCount(), cst);
6220 Ops[1] =
Builder.CreateBitCast(Ops[1], SourceTy);
6221 Ops[1] =
Builder.CreateShuffleVector(Ops[1], Ops[1], SV,
"lane");
6224 Int =
Builder.getIsFPConstrained() ? Intrinsic::experimental_constrained_fma
6228 case NEON::BI__builtin_neon_vfma_laneq_v: {
6231 if (VTy && VTy->getElementType() ==
DoubleTy) {
6234 llvm::FixedVectorType *VTy =
6236 Ops[2] =
Builder.CreateBitCast(Ops[2], VTy);
6237 Ops[2] =
Builder.CreateExtractElement(Ops[2], Ops[3],
"extract");
6240 *
this, Intrinsic::fma, Intrinsic::experimental_constrained_fma,
6241 DoubleTy, {Ops[1], Ops[2], Ops[0]});
6244 Ops[0] =
Builder.CreateBitCast(Ops[0], Ty);
6245 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
6247 auto *STy = llvm::FixedVectorType::get(VTy->getElementType(),
6248 VTy->getNumElements() * 2);
6249 Ops[2] =
Builder.CreateBitCast(Ops[2], STy);
6250 Value *SV = llvm::ConstantVector::getSplat(VTy->getElementCount(),
6252 Ops[2] =
Builder.CreateShuffleVector(Ops[2], Ops[2], SV,
"lane");
6255 *
this, Intrinsic::fma, Intrinsic::experimental_constrained_fma, Ty,
6256 {Ops[2], Ops[1], Ops[0]});
6258 case NEON::BI__builtin_neon_vfmaq_laneq_v: {
6259 Ops[0] =
Builder.CreateBitCast(Ops[0], Ty);
6260 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
6262 Ops[2] =
Builder.CreateBitCast(Ops[2], Ty);
6265 *
this, Intrinsic::fma, Intrinsic::experimental_constrained_fma, Ty,
6266 {Ops[2], Ops[1], Ops[0]});
6268 case NEON::BI__builtin_neon_vfmah_lane_f16:
6269 case NEON::BI__builtin_neon_vfmas_lane_f32:
6270 case NEON::BI__builtin_neon_vfmah_laneq_f16:
6271 case NEON::BI__builtin_neon_vfmas_laneq_f32:
6272 case NEON::BI__builtin_neon_vfmad_lane_f64:
6273 case NEON::BI__builtin_neon_vfmad_laneq_f64: {
6275 Ops[2] =
Builder.CreateExtractElement(Ops[2], Ops[3],
"extract");
6277 *
this, Intrinsic::fma, Intrinsic::experimental_constrained_fma, Ty,
6278 {Ops[1], Ops[2], Ops[0]});
6280 case NEON::BI__builtin_neon_vmull_v:
6282 Int = usgn ? Intrinsic::aarch64_neon_umull : Intrinsic::aarch64_neon_smull;
6283 if (
Type.isPoly())
Int = Intrinsic::aarch64_neon_pmull;
6285 case NEON::BI__builtin_neon_vmax_v:
6286 case NEON::BI__builtin_neon_vmaxq_v:
6288 Int = usgn ? Intrinsic::umax : Intrinsic::smax;
6289 if (Ty->isFPOrFPVectorTy())
Int = Intrinsic::aarch64_neon_fmax;
6291 case NEON::BI__builtin_neon_vmaxh_f16: {
6292 Int = Intrinsic::aarch64_neon_fmax;
6295 case NEON::BI__builtin_neon_vmin_v:
6296 case NEON::BI__builtin_neon_vminq_v:
6298 Int = usgn ? Intrinsic::umin : Intrinsic::smin;
6299 if (Ty->isFPOrFPVectorTy())
Int = Intrinsic::aarch64_neon_fmin;
6301 case NEON::BI__builtin_neon_vminh_f16: {
6302 Int = Intrinsic::aarch64_neon_fmin;
6305 case NEON::BI__builtin_neon_vabd_v:
6306 case NEON::BI__builtin_neon_vabdq_v:
6308 Int = usgn ? Intrinsic::aarch64_neon_uabd : Intrinsic::aarch64_neon_sabd;
6309 if (Ty->isFPOrFPVectorTy())
Int = Intrinsic::aarch64_neon_fabd;
6311 case NEON::BI__builtin_neon_vpadal_v:
6312 case NEON::BI__builtin_neon_vpadalq_v: {
6313 unsigned ArgElts = VTy->getNumElements();
6315 unsigned BitWidth = EltTy->getBitWidth();
6316 auto *ArgTy = llvm::FixedVectorType::get(
6317 llvm::IntegerType::get(
getLLVMContext(), BitWidth / 2), 2 * ArgElts);
6318 llvm::Type* Tys[2] = { VTy, ArgTy };
6319 Int = usgn ? Intrinsic::aarch64_neon_uaddlp : Intrinsic::aarch64_neon_saddlp;
6321 TmpOps.push_back(Ops[1]);
6324 llvm::Value *addend =
Builder.CreateBitCast(Ops[0], tmp->getType());
6325 return Builder.CreateAdd(tmp, addend);
6327 case NEON::BI__builtin_neon_vpmin_v:
6328 case NEON::BI__builtin_neon_vpminq_v:
6330 Int = usgn ? Intrinsic::aarch64_neon_uminp : Intrinsic::aarch64_neon_sminp;
6331 if (Ty->isFPOrFPVectorTy())
Int = Intrinsic::aarch64_neon_fminp;
6333 case NEON::BI__builtin_neon_vpmax_v:
6334 case NEON::BI__builtin_neon_vpmaxq_v:
6336 Int = usgn ? Intrinsic::aarch64_neon_umaxp : Intrinsic::aarch64_neon_smaxp;
6337 if (Ty->isFPOrFPVectorTy())
Int = Intrinsic::aarch64_neon_fmaxp;
6339 case NEON::BI__builtin_neon_vminnm_v:
6340 case NEON::BI__builtin_neon_vminnmq_v:
6341 Int = Intrinsic::aarch64_neon_fminnm;
6343 case NEON::BI__builtin_neon_vminnmh_f16:
6344 Int = Intrinsic::aarch64_neon_fminnm;
6346 case NEON::BI__builtin_neon_vmaxnm_v:
6347 case NEON::BI__builtin_neon_vmaxnmq_v:
6348 Int = Intrinsic::aarch64_neon_fmaxnm;
6350 case NEON::BI__builtin_neon_vmaxnmh_f16:
6351 Int = Intrinsic::aarch64_neon_fmaxnm;
6353 case NEON::BI__builtin_neon_vrecpss_f32: {
6357 case NEON::BI__builtin_neon_vrecpsd_f64:
6360 case NEON::BI__builtin_neon_vrecpsh_f16:
6363 case NEON::BI__builtin_neon_vqshrun_n_v:
6364 Int = Intrinsic::aarch64_neon_sqshrun;
6366 case NEON::BI__builtin_neon_vqrshrun_n_v:
6367 Int = Intrinsic::aarch64_neon_sqrshrun;
6369 case NEON::BI__builtin_neon_vqshrn_n_v:
6370 Int = usgn ? Intrinsic::aarch64_neon_uqshrn : Intrinsic::aarch64_neon_sqshrn;
6372 case NEON::BI__builtin_neon_vrshrn_n_v:
6373 Int = Intrinsic::aarch64_neon_rshrn;
6375 case NEON::BI__builtin_neon_vqrshrn_n_v:
6376 Int = usgn ? Intrinsic::aarch64_neon_uqrshrn : Intrinsic::aarch64_neon_sqrshrn;
6378 case NEON::BI__builtin_neon_vrndah_f16: {
6380 ? Intrinsic::experimental_constrained_round
6384 case NEON::BI__builtin_neon_vrnda_v:
6385 case NEON::BI__builtin_neon_vrndaq_v: {
6387 ? Intrinsic::experimental_constrained_round
6391 case NEON::BI__builtin_neon_vrndih_f16: {
6393 ? Intrinsic::experimental_constrained_nearbyint
6394 : Intrinsic::nearbyint;
6397 case NEON::BI__builtin_neon_vrndmh_f16: {
6399 ? Intrinsic::experimental_constrained_floor
6403 case NEON::BI__builtin_neon_vrndm_v:
6404 case NEON::BI__builtin_neon_vrndmq_v: {
6406 ? Intrinsic::experimental_constrained_floor
6410 case NEON::BI__builtin_neon_vrndnh_f16: {
6412 ? Intrinsic::experimental_constrained_roundeven
6413 : Intrinsic::roundeven;
6416 case NEON::BI__builtin_neon_vrndn_v:
6417 case NEON::BI__builtin_neon_vrndnq_v: {
6419 ? Intrinsic::experimental_constrained_roundeven
6420 : Intrinsic::roundeven;
6423 case NEON::BI__builtin_neon_vrndns_f32: {
6425 ? Intrinsic::experimental_constrained_roundeven
6426 : Intrinsic::roundeven;
6429 case NEON::BI__builtin_neon_vrndph_f16: {
6431 ? Intrinsic::experimental_constrained_ceil
6435 case NEON::BI__builtin_neon_vrndp_v:
6436 case NEON::BI__builtin_neon_vrndpq_v: {
6438 ? Intrinsic::experimental_constrained_ceil
6442 case NEON::BI__builtin_neon_vrndxh_f16: {
6444 ? Intrinsic::experimental_constrained_rint
6448 case NEON::BI__builtin_neon_vrndx_v:
6449 case NEON::BI__builtin_neon_vrndxq_v: {
6451 ? Intrinsic::experimental_constrained_rint
6455 case NEON::BI__builtin_neon_vrndh_f16: {
6457 ? Intrinsic::experimental_constrained_trunc
6461 case NEON::BI__builtin_neon_vrnd_v:
6462 case NEON::BI__builtin_neon_vrndq_v: {
6464 ? Intrinsic::experimental_constrained_trunc
6468 case NEON::BI__builtin_neon_vcvt_f64_v:
6469 case NEON::BI__builtin_neon_vcvtq_f64_v:
6470 Ops[0] =
Builder.CreateBitCast(Ops[0], Ty);
6472 return usgn ?
Builder.CreateUIToFP(Ops[0], Ty,
"vcvt")
6473 :
Builder.CreateSIToFP(Ops[0], Ty,
"vcvt");
6474 case NEON::BI__builtin_neon_vcvt_f64_f32: {
6476 "unexpected vcvt_f64_f32 builtin");
6480 return Builder.CreateFPExt(Ops[0], Ty,
"vcvt");
6482 case NEON::BI__builtin_neon_vcvt_f32_f64: {
6484 "unexpected vcvt_f32_f64 builtin");
6488 return Builder.CreateFPTrunc(Ops[0], Ty,
"vcvt");
6490 case NEON::BI__builtin_neon_vcvta_s16_f16:
6491 case NEON::BI__builtin_neon_vcvta_u16_f16:
6492 case NEON::BI__builtin_neon_vcvta_s32_v:
6493 case NEON::BI__builtin_neon_vcvtaq_s16_f16:
6494 case NEON::BI__builtin_neon_vcvtaq_s32_v:
6495 case NEON::BI__builtin_neon_vcvta_u32_v:
6496 case NEON::BI__builtin_neon_vcvtaq_u16_f16:
6497 case NEON::BI__builtin_neon_vcvtaq_u32_v:
6498 case NEON::BI__builtin_neon_vcvta_s64_v:
6499 case NEON::BI__builtin_neon_vcvtaq_s64_v:
6500 case NEON::BI__builtin_neon_vcvta_u64_v:
6501 case NEON::BI__builtin_neon_vcvtaq_u64_v: {
6502 Int = usgn ? Intrinsic::aarch64_neon_fcvtau : Intrinsic::aarch64_neon_fcvtas;
6506 case NEON::BI__builtin_neon_vcvtm_s16_f16:
6507 case NEON::BI__builtin_neon_vcvtmq_s16_f16:
6508 case NEON::BI__builtin_neon_vcvtm_u16_f16:
6509 case NEON::BI__builtin_neon_vcvtmq_u16_f16:
6510 case NEON::BI__builtin_neon_vcvtm_s32_v:
6511 case NEON::BI__builtin_neon_vcvtmq_s32_v:
6512 case NEON::BI__builtin_neon_vcvtm_u32_v:
6513 case NEON::BI__builtin_neon_vcvtmq_u32_v:
6514 case NEON::BI__builtin_neon_vcvtm_s64_v:
6515 case NEON::BI__builtin_neon_vcvtmq_s64_v:
6516 case NEON::BI__builtin_neon_vcvtm_u64_v:
6517 case NEON::BI__builtin_neon_vcvtmq_u64_v: {
6518 Int = usgn ? Intrinsic::aarch64_neon_fcvtmu : Intrinsic::aarch64_neon_fcvtms;
6522 case NEON::BI__builtin_neon_vcvtn_s16_f16:
6523 case NEON::BI__builtin_neon_vcvtnq_s16_f16:
6524 case NEON::BI__builtin_neon_vcvtn_u16_f16:
6525 case NEON::BI__builtin_neon_vcvtnq_u16_f16:
6526 case NEON::BI__builtin_neon_vcvtn_s32_v:
6527 case NEON::BI__builtin_neon_vcvtnq_s32_v:
6528 case NEON::BI__builtin_neon_vcvtn_u32_v:
6529 case NEON::BI__builtin_neon_vcvtnq_u32_v:
6530 case NEON::BI__builtin_neon_vcvtn_s64_v:
6531 case NEON::BI__builtin_neon_vcvtnq_s64_v:
6532 case NEON::BI__builtin_neon_vcvtn_u64_v:
6533 case NEON::BI__builtin_neon_vcvtnq_u64_v: {
6534 Int = usgn ? Intrinsic::aarch64_neon_fcvtnu : Intrinsic::aarch64_neon_fcvtns;
6538 case NEON::BI__builtin_neon_vcvtp_s16_f16:
6539 case NEON::BI__builtin_neon_vcvtpq_s16_f16:
6540 case NEON::BI__builtin_neon_vcvtp_u16_f16:
6541 case NEON::BI__builtin_neon_vcvtpq_u16_f16:
6542 case NEON::BI__builtin_neon_vcvtp_s32_v:
6543 case NEON::BI__builtin_neon_vcvtpq_s32_v:
6544 case NEON::BI__builtin_neon_vcvtp_u32_v:
6545 case NEON::BI__builtin_neon_vcvtpq_u32_v:
6546 case NEON::BI__builtin_neon_vcvtp_s64_v:
6547 case NEON::BI__builtin_neon_vcvtpq_s64_v:
6548 case NEON::BI__builtin_neon_vcvtp_u64_v:
6549 case NEON::BI__builtin_neon_vcvtpq_u64_v: {
6550 Int = usgn ? Intrinsic::aarch64_neon_fcvtpu : Intrinsic::aarch64_neon_fcvtps;
6554 case NEON::BI__builtin_neon_vmulx_v:
6555 case NEON::BI__builtin_neon_vmulxq_v: {
6556 Int = Intrinsic::aarch64_neon_fmulx;
6559 case NEON::BI__builtin_neon_vmulxh_lane_f16:
6560 case NEON::BI__builtin_neon_vmulxh_laneq_f16: {
6563 Ops[1] =
Builder.CreateExtractElement(Ops[1], Ops[2],
"extract");
6565 Int = Intrinsic::aarch64_neon_fmulx;
6568 case NEON::BI__builtin_neon_vmul_lane_v:
6569 case NEON::BI__builtin_neon_vmul_laneq_v: {
6572 if (BuiltinID == NEON::BI__builtin_neon_vmul_laneq_v)
6575 llvm::FixedVectorType *VTy =
6577 Ops[1] =
Builder.CreateBitCast(Ops[1], VTy);
6578 Ops[1] =
Builder.CreateExtractElement(Ops[1], Ops[2],
"extract");
6582 case NEON::BI__builtin_neon_vpmaxnm_v:
6583 case NEON::BI__builtin_neon_vpmaxnmq_v: {
6584 Int = Intrinsic::aarch64_neon_fmaxnmp;
6587 case NEON::BI__builtin_neon_vpminnm_v:
6588 case NEON::BI__builtin_neon_vpminnmq_v: {
6589 Int = Intrinsic::aarch64_neon_fminnmp;
6592 case NEON::BI__builtin_neon_vsqrth_f16: {
6594 ? Intrinsic::experimental_constrained_sqrt
6598 case NEON::BI__builtin_neon_vsqrt_v:
6599 case NEON::BI__builtin_neon_vsqrtq_v: {
6601 ? Intrinsic::experimental_constrained_sqrt
6603 Ops[0] =
Builder.CreateBitCast(Ops[0], Ty);
6606 case NEON::BI__builtin_neon_vrbit_v:
6607 case NEON::BI__builtin_neon_vrbitq_v: {
6608 Int = Intrinsic::bitreverse;
6611 case NEON::BI__builtin_neon_vmaxv_f16: {
6612 Int = Intrinsic::aarch64_neon_fmaxv;
6614 VTy = llvm::FixedVectorType::get(
HalfTy, 4);
6615 llvm::Type *Tys[2] = {Ty, VTy};
6618 case NEON::BI__builtin_neon_vmaxvq_f16: {
6619 Int = Intrinsic::aarch64_neon_fmaxv;
6621 VTy = llvm::FixedVectorType::get(
HalfTy, 8);
6622 llvm::Type *Tys[2] = {Ty, VTy};
6625 case NEON::BI__builtin_neon_vminv_f16: {
6626 Int = Intrinsic::aarch64_neon_fminv;
6628 VTy = llvm::FixedVectorType::get(
HalfTy, 4);
6629 llvm::Type *Tys[2] = {Ty, VTy};
6632 case NEON::BI__builtin_neon_vminvq_f16: {
6633 Int = Intrinsic::aarch64_neon_fminv;
6635 VTy = llvm::FixedVectorType::get(
HalfTy, 8);
6636 llvm::Type *Tys[2] = {Ty, VTy};
6639 case NEON::BI__builtin_neon_vmaxnmv_f16: {
6640 Int = Intrinsic::aarch64_neon_fmaxnmv;
6642 VTy = llvm::FixedVectorType::get(
HalfTy, 4);
6643 llvm::Type *Tys[2] = {Ty, VTy};
6646 case NEON::BI__builtin_neon_vmaxnmvq_f16: {
6647 Int = Intrinsic::aarch64_neon_fmaxnmv;
6649 VTy = llvm::FixedVectorType::get(
HalfTy, 8);
6650 llvm::Type *Tys[2] = {Ty, VTy};
6653 case NEON::BI__builtin_neon_vminnmv_f16: {
6654 Int = Intrinsic::aarch64_neon_fminnmv;
6656 VTy = llvm::FixedVectorType::get(
HalfTy, 4);
6657 llvm::Type *Tys[2] = {Ty, VTy};
6660 case NEON::BI__builtin_neon_vminnmvq_f16: {
6661 Int = Intrinsic::aarch64_neon_fminnmv;
6663 VTy = llvm::FixedVectorType::get(
HalfTy, 8);
6664 llvm::Type *Tys[2] = {Ty, VTy};
6667 case NEON::BI__builtin_neon_vmul_n_f64: {
6670 return Builder.CreateFMul(Ops[0], RHS);
6672 case NEON::BI__builtin_neon_vaddlv_u8:
6673 case NEON::BI__builtin_neon_vaddlvq_u8:
6674 case NEON::BI__builtin_neon_vaddlv_u16:
6675 case NEON::BI__builtin_neon_vaddlvq_u16: {
6676 Int = Intrinsic::aarch64_neon_uaddlv;
6679 llvm::Type *Tys[2] = {Ty, VTy};
6681 if (VTy->getElementType()->getPrimitiveSizeInBits() == 8)
6685 case NEON::BI__builtin_neon_vaddlv_s8:
6686 case NEON::BI__builtin_neon_vaddlvq_s8:
6687 case NEON::BI__builtin_neon_vaddlv_s16:
6688 case NEON::BI__builtin_neon_vaddlvq_s16: {
6689 Int = Intrinsic::aarch64_neon_saddlv;
6692 llvm::Type *Tys[2] = {Ty, VTy};
6694 if (VTy->getElementType()->getPrimitiveSizeInBits() == 8)
6698 case NEON::BI__builtin_neon_vsri_n_v:
6699 case NEON::BI__builtin_neon_vsriq_n_v: {
6700 Int = Intrinsic::aarch64_neon_vsri;
6701 llvm::Function *Intrin =
CGM.getIntrinsic(
Int, Ty);
6704 case NEON::BI__builtin_neon_vsli_n_v:
6705 case NEON::BI__builtin_neon_vsliq_n_v: {
6706 Int = Intrinsic::aarch64_neon_vsli;
6707 llvm::Function *Intrin =
CGM.getIntrinsic(
Int, Ty);
6710 case NEON::BI__builtin_neon_vsra_n_v:
6711 case NEON::BI__builtin_neon_vsraq_n_v:
6712 Ops[0] =
Builder.CreateBitCast(Ops[0], Ty);
6714 return Builder.CreateAdd(Ops[0], Ops[1]);
6715 case NEON::BI__builtin_neon_vrsra_n_v:
6716 case NEON::BI__builtin_neon_vrsraq_n_v: {
6717 Int = usgn ? Intrinsic::aarch64_neon_urshl : Intrinsic::aarch64_neon_srshl;
6719 TmpOps.push_back(Ops[1]);
6720 TmpOps.push_back(Ops[2]);
6722 llvm::Value *tmp =
EmitNeonCall(F, TmpOps,
"vrshr_n", 1,
true);
6723 Ops[0] =
Builder.CreateBitCast(Ops[0], VTy);
6724 return Builder.CreateAdd(Ops[0], tmp);
6726 case NEON::BI__builtin_neon_vld1_v:
6727 case NEON::BI__builtin_neon_vld1q_v: {
6730 case NEON::BI__builtin_neon_vst1_v:
6731 case NEON::BI__builtin_neon_vst1q_v:
6732 Ops[1] =
Builder.CreateBitCast(Ops[1], VTy);
6734 case NEON::BI__builtin_neon_vld1_lane_v:
6735 case NEON::BI__builtin_neon_vld1q_lane_v: {
6736 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
6737 Ops[0] =
Builder.CreateAlignedLoad(VTy->getElementType(), Ops[0],
6739 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2],
"vld1_lane");
6741 case NEON::BI__builtin_neon_vldap1_lane_s64:
6742 case NEON::BI__builtin_neon_vldap1q_lane_s64: {
6743 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
6744 llvm::LoadInst *LI =
Builder.CreateAlignedLoad(
6746 LI->setAtomic(llvm::AtomicOrdering::Acquire);
6748 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2],
"vldap1_lane");
6750 case NEON::BI__builtin_neon_vld1_dup_v:
6751 case NEON::BI__builtin_neon_vld1q_dup_v: {
6752 Value *
V = PoisonValue::get(Ty);
6753 Ops[0] =
Builder.CreateAlignedLoad(VTy->getElementType(), Ops[0],
6755 llvm::Constant *CI = ConstantInt::get(
Int32Ty, 0);
6756 Ops[0] =
Builder.CreateInsertElement(
V, Ops[0], CI);
6759 case NEON::BI__builtin_neon_vst1_lane_v:
6760 case NEON::BI__builtin_neon_vst1q_lane_v:
6761 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
6762 Ops[1] =
Builder.CreateExtractElement(Ops[1], Ops[2]);
6764 case NEON::BI__builtin_neon_vstl1_lane_s64:
6765 case NEON::BI__builtin_neon_vstl1q_lane_s64: {
6766 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
6767 Ops[1] =
Builder.CreateExtractElement(Ops[1], Ops[2]);
6768 llvm::StoreInst *SI =
6770 SI->setAtomic(llvm::AtomicOrdering::Release);
6773 case NEON::BI__builtin_neon_vld2_v:
6774 case NEON::BI__builtin_neon_vld2q_v: {
6776 Function *F =
CGM.getIntrinsic(Intrinsic::aarch64_neon_ld2, Tys);
6777 Ops[1] =
Builder.CreateCall(F, Ops[1],
"vld2");
6778 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
6780 case NEON::BI__builtin_neon_vld3_v:
6781 case NEON::BI__builtin_neon_vld3q_v: {
6783 Function *F =
CGM.getIntrinsic(Intrinsic::aarch64_neon_ld3, Tys);
6784 Ops[1] =
Builder.CreateCall(F, Ops[1],
"vld3");
6785 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
6787 case NEON::BI__builtin_neon_vld4_v:
6788 case NEON::BI__builtin_neon_vld4q_v: {
6790 Function *F =
CGM.getIntrinsic(Intrinsic::aarch64_neon_ld4, Tys);
6791 Ops[1] =
Builder.CreateCall(F, Ops[1],
"vld4");
6792 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
6794 case NEON::BI__builtin_neon_vld2_dup_v:
6795 case NEON::BI__builtin_neon_vld2q_dup_v: {
6797 Function *F =
CGM.getIntrinsic(Intrinsic::aarch64_neon_ld2r, Tys);
6798 Ops[1] =
Builder.CreateCall(F, Ops[1],
"vld2");
6799 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
6801 case NEON::BI__builtin_neon_vld3_dup_v:
6802 case NEON::BI__builtin_neon_vld3q_dup_v: {
6804 Function *F =
CGM.getIntrinsic(Intrinsic::aarch64_neon_ld3r, Tys);
6805 Ops[1] =
Builder.CreateCall(F, Ops[1],
"vld3");
6806 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
6808 case NEON::BI__builtin_neon_vld4_dup_v:
6809 case NEON::BI__builtin_neon_vld4q_dup_v: {
6811 Function *F =
CGM.getIntrinsic(Intrinsic::aarch64_neon_ld4r, Tys);
6812 Ops[1] =
Builder.CreateCall(F, Ops[1],
"vld4");
6813 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
6815 case NEON::BI__builtin_neon_vld2_lane_v:
6816 case NEON::BI__builtin_neon_vld2q_lane_v: {
6817 llvm::Type *Tys[2] = { VTy, Ops[1]->getType() };
6818 Function *F =
CGM.getIntrinsic(Intrinsic::aarch64_neon_ld2lane, Tys);
6819 std::rotate(Ops.begin() + 1, Ops.begin() + 2, Ops.end());
6820 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
6821 Ops[2] =
Builder.CreateBitCast(Ops[2], Ty);
6824 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
6826 case NEON::BI__builtin_neon_vld3_lane_v:
6827 case NEON::BI__builtin_neon_vld3q_lane_v: {
6828 llvm::Type *Tys[2] = { VTy, Ops[1]->getType() };
6829 Function *F =
CGM.getIntrinsic(Intrinsic::aarch64_neon_ld3lane, Tys);
6830 std::rotate(Ops.begin() + 1, Ops.begin() + 2, Ops.end());
6831 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
6832 Ops[2] =
Builder.CreateBitCast(Ops[2], Ty);
6833 Ops[3] =
Builder.CreateBitCast(Ops[3], Ty);
6836 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
6838 case NEON::BI__builtin_neon_vld4_lane_v:
6839 case NEON::BI__builtin_neon_vld4q_lane_v: {
6840 llvm::Type *Tys[2] = { VTy, Ops[1]->getType() };
6841 Function *F =
CGM.getIntrinsic(Intrinsic::aarch64_neon_ld4lane, Tys);
6842 std::rotate(Ops.begin() + 1, Ops.begin() + 2, Ops.end());
6843 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
6844 Ops[2] =
Builder.CreateBitCast(Ops[2], Ty);
6845 Ops[3] =
Builder.CreateBitCast(Ops[3], Ty);
6846 Ops[4] =
Builder.CreateBitCast(Ops[4], Ty);
6849 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
6851 case NEON::BI__builtin_neon_vst2_v:
6852 case NEON::BI__builtin_neon_vst2q_v: {
6853 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end());
6854 llvm::Type *Tys[2] = { VTy, Ops[2]->getType() };
6855 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_st2, Tys),
6858 case NEON::BI__builtin_neon_vst2_lane_v:
6859 case NEON::BI__builtin_neon_vst2q_lane_v: {
6860 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end());
6862 llvm::Type *Tys[2] = { VTy, Ops[3]->getType() };
6863 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_st2lane, Tys),
6866 case NEON::BI__builtin_neon_vst3_v:
6867 case NEON::BI__builtin_neon_vst3q_v: {
6868 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end());
6869 llvm::Type *Tys[2] = { VTy, Ops[3]->getType() };
6870 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_st3, Tys),
6873 case NEON::BI__builtin_neon_vst3_lane_v:
6874 case NEON::BI__builtin_neon_vst3q_lane_v: {
6875 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end());
6877 llvm::Type *Tys[2] = { VTy, Ops[4]->getType() };
6878 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_st3lane, Tys),
6881 case NEON::BI__builtin_neon_vst4_v:
6882 case NEON::BI__builtin_neon_vst4q_v: {
6883 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end());
6884 llvm::Type *Tys[2] = { VTy, Ops[4]->getType() };
6885 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_st4, Tys),
6888 case NEON::BI__builtin_neon_vst4_lane_v:
6889 case NEON::BI__builtin_neon_vst4q_lane_v: {
6890 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end());
6892 llvm::Type *Tys[2] = { VTy, Ops[5]->getType() };
6893 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_st4lane, Tys),
6896 case NEON::BI__builtin_neon_vtrn_v:
6897 case NEON::BI__builtin_neon_vtrnq_v: {
6898 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
6899 Ops[2] =
Builder.CreateBitCast(Ops[2], Ty);
6900 Value *SV =
nullptr;
6902 for (
unsigned vi = 0; vi != 2; ++vi) {
6904 for (
unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) {
6905 Indices.push_back(i+vi);
6906 Indices.push_back(i+e+vi);
6909 SV =
Builder.CreateShuffleVector(Ops[1], Ops[2], Indices,
"vtrn");
6914 case NEON::BI__builtin_neon_vuzp_v:
6915 case NEON::BI__builtin_neon_vuzpq_v: {
6916 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
6917 Ops[2] =
Builder.CreateBitCast(Ops[2], Ty);
6918 Value *SV =
nullptr;
6920 for (
unsigned vi = 0; vi != 2; ++vi) {
6922 for (
unsigned i = 0, e = VTy->getNumElements(); i != e; ++i)
6923 Indices.push_back(2*i+vi);
6926 SV =
Builder.CreateShuffleVector(Ops[1], Ops[2], Indices,
"vuzp");
6931 case NEON::BI__builtin_neon_vzip_v:
6932 case NEON::BI__builtin_neon_vzipq_v: {
6933 Ops[1] =
Builder.CreateBitCast(Ops[1], Ty);
6934 Ops[2] =
Builder.CreateBitCast(Ops[2], Ty);
6935 Value *SV =
nullptr;
6937 for (
unsigned vi = 0; vi != 2; ++vi) {
6939 for (
unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) {
6940 Indices.push_back((i + vi*e) >> 1);
6941 Indices.push_back(((i + vi*e) >> 1)+e);
6944 SV =
Builder.CreateShuffleVector(Ops[1], Ops[2], Indices,
"vzip");
6949 case NEON::BI__builtin_neon_vqtbl1q_v: {
6950 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl1, Ty),
6953 case NEON::BI__builtin_neon_vqtbl2q_v: {
6954 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl2, Ty),
6957 case NEON::BI__builtin_neon_vqtbl3q_v: {
6958 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl3, Ty),
6961 case NEON::BI__builtin_neon_vqtbl4q_v: {
6962 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl4, Ty),
6965 case NEON::BI__builtin_neon_vqtbx1q_v: {
6966 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx1, Ty),
6969 case NEON::BI__builtin_neon_vqtbx2q_v: {
6970 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx2, Ty),
6973 case NEON::BI__builtin_neon_vqtbx3q_v: {
6974 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx3, Ty),
6977 case NEON::BI__builtin_neon_vqtbx4q_v: {
6978 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx4, Ty),
6981 case NEON::BI__builtin_neon_vsqadd_v:
6982 case NEON::BI__builtin_neon_vsqaddq_v: {
6983 Int = Intrinsic::aarch64_neon_usqadd;
6986 case NEON::BI__builtin_neon_vuqadd_v:
6987 case NEON::BI__builtin_neon_vuqaddq_v: {
6988 Int = Intrinsic::aarch64_neon_suqadd;
6992 case NEON::BI__builtin_neon_vluti2_laneq_mf8:
6993 case NEON::BI__builtin_neon_vluti2_laneq_bf16:
6994 case NEON::BI__builtin_neon_vluti2_laneq_f16:
6995 case NEON::BI__builtin_neon_vluti2_laneq_p16:
6996 case NEON::BI__builtin_neon_vluti2_laneq_p8:
6997 case NEON::BI__builtin_neon_vluti2_laneq_s16:
6998 case NEON::BI__builtin_neon_vluti2_laneq_s8:
6999 case NEON::BI__builtin_neon_vluti2_laneq_u16:
7000 case NEON::BI__builtin_neon_vluti2_laneq_u8: {
7001 Int = Intrinsic::aarch64_neon_vluti2_laneq;
7008 case NEON::BI__builtin_neon_vluti2q_laneq_mf8:
7009 case NEON::BI__builtin_neon_vluti2q_laneq_bf16:
7010 case NEON::BI__builtin_neon_vluti2q_laneq_f16:
7011 case NEON::BI__builtin_neon_vluti2q_laneq_p16:
7012 case NEON::BI__builtin_neon_vluti2q_laneq_p8:
7013 case NEON::BI__builtin_neon_vluti2q_laneq_s16:
7014 case NEON::BI__builtin_neon_vluti2q_laneq_s8:
7015 case NEON::BI__builtin_neon_vluti2q_laneq_u16:
7016 case NEON::BI__builtin_neon_vluti2q_laneq_u8: {
7017 Int = Intrinsic::aarch64_neon_vluti2_laneq;
7024 case NEON::BI__builtin_neon_vluti2_lane_mf8:
7025 case NEON::BI__builtin_neon_vluti2_lane_bf16:
7026 case NEON::BI__builtin_neon_vluti2_lane_f16:
7027 case NEON::BI__builtin_neon_vluti2_lane_p16:
7028 case NEON::BI__builtin_neon_vluti2_lane_p8:
7029 case NEON::BI__builtin_neon_vluti2_lane_s16:
7030 case NEON::BI__builtin_neon_vluti2_lane_s8:
7031 case NEON::BI__builtin_neon_vluti2_lane_u16:
7032 case NEON::BI__builtin_neon_vluti2_lane_u8: {
7033 Int = Intrinsic::aarch64_neon_vluti2_lane;
7040 case NEON::BI__builtin_neon_vluti2q_lane_mf8:
7041 case NEON::BI__builtin_neon_vluti2q_lane_bf16:
7042 case NEON::BI__builtin_neon_vluti2q_lane_f16:
7043 case NEON::BI__builtin_neon_vluti2q_lane_p16:
7044 case NEON::BI__builtin_neon_vluti2q_lane_p8:
7045 case NEON::BI__builtin_neon_vluti2q_lane_s16:
7046 case NEON::BI__builtin_neon_vluti2q_lane_s8:
7047 case NEON::BI__builtin_neon_vluti2q_lane_u16:
7048 case NEON::BI__builtin_neon_vluti2q_lane_u8: {
7049 Int = Intrinsic::aarch64_neon_vluti2_lane;
7056 case NEON::BI__builtin_neon_vluti4q_lane_mf8:
7057 case NEON::BI__builtin_neon_vluti4q_lane_p8:
7058 case NEON::BI__builtin_neon_vluti4q_lane_s8:
7059 case NEON::BI__builtin_neon_vluti4q_lane_u8: {
7060 Int = Intrinsic::aarch64_neon_vluti4q_lane;
7063 case NEON::BI__builtin_neon_vluti4q_laneq_mf8:
7064 case NEON::BI__builtin_neon_vluti4q_laneq_p8:
7065 case NEON::BI__builtin_neon_vluti4q_laneq_s8:
7066 case NEON::BI__builtin_neon_vluti4q_laneq_u8: {
7067 Int = Intrinsic::aarch64_neon_vluti4q_laneq;
7070 case NEON::BI__builtin_neon_vluti4q_lane_bf16_x2:
7071 case NEON::BI__builtin_neon_vluti4q_lane_f16_x2:
7072 case NEON::BI__builtin_neon_vluti4q_lane_p16_x2:
7073 case NEON::BI__builtin_neon_vluti4q_lane_s16_x2:
7074 case NEON::BI__builtin_neon_vluti4q_lane_u16_x2: {
7075 Int = Intrinsic::aarch64_neon_vluti4q_lane_x2;
7078 case NEON::BI__builtin_neon_vluti4q_laneq_bf16_x2:
7079 case NEON::BI__builtin_neon_vluti4q_laneq_f16_x2:
7080 case NEON::BI__builtin_neon_vluti4q_laneq_p16_x2:
7081 case NEON::BI__builtin_neon_vluti4q_laneq_s16_x2:
7082 case NEON::BI__builtin_neon_vluti4q_laneq_u16_x2: {
7083 Int = Intrinsic::aarch64_neon_vluti4q_laneq_x2;
7086 case NEON::BI__builtin_neon_vmmlaq_f16_mf8_fpm:
7088 {llvm::FixedVectorType::get(
HalfTy, 8),
7089 llvm::FixedVectorType::get(
Int8Ty, 16)},
7091 case NEON::BI__builtin_neon_vmmlaq_f32_mf8_fpm:
7093 {llvm::FixedVectorType::get(
FloatTy, 4),
7094 llvm::FixedVectorType::get(
Int8Ty, 16)},
7096 case NEON::BI__builtin_neon_vcvt1_low_bf16_mf8_fpm:
7099 case NEON::BI__builtin_neon_vcvt1_bf16_mf8_fpm:
7100 case NEON::BI__builtin_neon_vcvt1_high_bf16_mf8_fpm:
7102 llvm::FixedVectorType::get(
BFloatTy, 8),
7103 Ops[0]->
getType(), ExtractLow, Ops, E,
"vbfcvt1");
7104 case NEON::BI__builtin_neon_vcvt2_low_bf16_mf8_fpm:
7107 case NEON::BI__builtin_neon_vcvt2_bf16_mf8_fpm:
7108 case NEON::BI__builtin_neon_vcvt2_high_bf16_mf8_fpm:
7110 llvm::FixedVectorType::get(
BFloatTy, 8),
7111 Ops[0]->
getType(), ExtractLow, Ops, E,
"vbfcvt2");
7112 case NEON::BI__builtin_neon_vcvt1_low_f16_mf8_fpm:
7115 case NEON::BI__builtin_neon_vcvt1_f16_mf8_fpm:
7116 case NEON::BI__builtin_neon_vcvt1_high_f16_mf8_fpm:
7118 llvm::FixedVectorType::get(
HalfTy, 8),
7119 Ops[0]->
getType(), ExtractLow, Ops, E,
"vbfcvt1");
7120 case NEON::BI__builtin_neon_vcvt2_low_f16_mf8_fpm:
7123 case NEON::BI__builtin_neon_vcvt2_f16_mf8_fpm:
7124 case NEON::BI__builtin_neon_vcvt2_high_f16_mf8_fpm:
7126 llvm::FixedVectorType::get(
HalfTy, 8),
7127 Ops[0]->
getType(), ExtractLow, Ops, E,
"vbfcvt2");
7128 case NEON::BI__builtin_neon_vcvt_mf8_f32_fpm:
7130 llvm::FixedVectorType::get(
Int8Ty, 8),
7131 Ops[0]->
getType(),
false, Ops, E,
"vfcvtn");
7132 case NEON::BI__builtin_neon_vcvt_mf8_f16_fpm:
7134 llvm::FixedVectorType::get(
Int8Ty, 8),
7135 llvm::FixedVectorType::get(
HalfTy, 4),
false, Ops,
7137 case NEON::BI__builtin_neon_vcvtq_mf8_f16_fpm:
7139 llvm::FixedVectorType::get(
Int8Ty, 16),
7140 llvm::FixedVectorType::get(
HalfTy, 8),
false, Ops,
7142 case NEON::BI__builtin_neon_vcvt_high_mf8_f32_fpm: {
7143 llvm::Type *Ty = llvm::FixedVectorType::get(
Int8Ty, 16);
7144 Ops[0] =
Builder.CreateInsertVector(Ty, PoisonValue::get(Ty), Ops[0],
7147 Ops[1]->
getType(),
false, Ops, E,
"vfcvtn2");
7150 case NEON::BI__builtin_neon_vdot_f16_mf8_fpm:
7151 case NEON::BI__builtin_neon_vdotq_f16_mf8_fpm:
7154 case NEON::BI__builtin_neon_vdot_lane_f16_mf8_fpm:
7155 case NEON::BI__builtin_neon_vdotq_lane_f16_mf8_fpm:
7156 ExtendLaneArg =
true;
7158 case NEON::BI__builtin_neon_vdot_laneq_f16_mf8_fpm:
7159 case NEON::BI__builtin_neon_vdotq_laneq_f16_mf8_fpm:
7161 ExtendLaneArg,
HalfTy, Ops, E,
"fdot2_lane");
7162 case NEON::BI__builtin_neon_vdot_f32_mf8_fpm:
7163 case NEON::BI__builtin_neon_vdotq_f32_mf8_fpm:
7166 case NEON::BI__builtin_neon_vdot_lane_f32_mf8_fpm:
7167 case NEON::BI__builtin_neon_vdotq_lane_f32_mf8_fpm:
7168 ExtendLaneArg =
true;
7170 case NEON::BI__builtin_neon_vdot_laneq_f32_mf8_fpm:
7171 case NEON::BI__builtin_neon_vdotq_laneq_f32_mf8_fpm:
7173 ExtendLaneArg,
FloatTy, Ops, E,
"fdot4_lane");
7175 case NEON::BI__builtin_neon_vdot_f32_f16:
7176 case NEON::BI__builtin_neon_vdotq_f32_f16: {
7177 llvm::Type *InputTy =
7178 llvm::FixedVectorType::get(
HalfTy, Ty->getPrimitiveSizeInBits() / 16);
7179 llvm::Type *Tys[2] = {Ty, InputTy};
7180 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_fdot, Tys),
7184 case NEON::BI__builtin_neon_vdot_lane_f32_f16:
7185 case NEON::BI__builtin_neon_vdot_laneq_f32_f16:
7186 case NEON::BI__builtin_neon_vdotq_lane_f32_f16:
7187 case NEON::BI__builtin_neon_vdotq_laneq_f32_f16: {
7188 llvm::FixedVectorType *InputTy =
7189 llvm::FixedVectorType::get(
HalfTy, Ty->getPrimitiveSizeInBits() / 16);
7190 llvm::FixedVectorType *LaneTy = llvm::FixedVectorType::get(
7194 Ops[2] =
Builder.CreateBitCast(Ops[2], LaneTy);
7196 InputTy->getElementCount());
7197 llvm::Type *Tys[2] = {Ty, InputTy};
7199 return EmitNeonCall(
CGM.getIntrinsic(Intrinsic::aarch64_neon_fdot, Tys),
7203 case NEON::BI__builtin_neon_vmlalbq_f16_mf8_fpm:
7205 {llvm::FixedVectorType::get(
HalfTy, 8)}, Ops, E,
7207 case NEON::BI__builtin_neon_vmlaltq_f16_mf8_fpm:
7209 {llvm::FixedVectorType::get(
HalfTy, 8)}, Ops, E,
7211 case NEON::BI__builtin_neon_vmlallbbq_f32_mf8_fpm:
7213 {llvm::FixedVectorType::get(
FloatTy, 4)}, Ops, E,
7215 case NEON::BI__builtin_neon_vmlallbtq_f32_mf8_fpm:
7217 {llvm::FixedVectorType::get(
FloatTy, 4)}, Ops, E,
7219 case NEON::BI__builtin_neon_vmlalltbq_f32_mf8_fpm:
7221 {llvm::FixedVectorType::get(
FloatTy, 4)}, Ops, E,
7223 case NEON::BI__builtin_neon_vmlallttq_f32_mf8_fpm:
7225 {llvm::FixedVectorType::get(
FloatTy, 4)}, Ops, E,
7227 case NEON::BI__builtin_neon_vmlalbq_lane_f16_mf8_fpm:
7228 ExtendLaneArg =
true;
7230 case NEON::BI__builtin_neon_vmlalbq_laneq_f16_mf8_fpm:
7232 ExtendLaneArg,
HalfTy, Ops, E,
"vmlal_lane");
7233 case NEON::BI__builtin_neon_vmlaltq_lane_f16_mf8_fpm:
7234 ExtendLaneArg =
true;
7236 case NEON::BI__builtin_neon_vmlaltq_laneq_f16_mf8_fpm:
7238 ExtendLaneArg,
HalfTy, Ops, E,
"vmlal_lane");
7239 case NEON::BI__builtin_neon_vmlallbbq_lane_f32_mf8_fpm:
7240 ExtendLaneArg =
true;
7242 case NEON::BI__builtin_neon_vmlallbbq_laneq_f32_mf8_fpm:
7244 ExtendLaneArg,
FloatTy, Ops, E,
"vmlall_lane");
7245 case NEON::BI__builtin_neon_vmlallbtq_lane_f32_mf8_fpm:
7246 ExtendLaneArg =
true;
7248 case NEON::BI__builtin_neon_vmlallbtq_laneq_f32_mf8_fpm:
7250 ExtendLaneArg,
FloatTy, Ops, E,
"vmlall_lane");
7251 case NEON::BI__builtin_neon_vmlalltbq_lane_f32_mf8_fpm:
7252 ExtendLaneArg =
true;
7254 case NEON::BI__builtin_neon_vmlalltbq_laneq_f32_mf8_fpm:
7256 ExtendLaneArg,
FloatTy, Ops, E,
"vmlall_lane");
7257 case NEON::BI__builtin_neon_vmlallttq_lane_f32_mf8_fpm:
7258 ExtendLaneArg =
true;
7260 case NEON::BI__builtin_neon_vmlallttq_laneq_f32_mf8_fpm:
7262 ExtendLaneArg,
FloatTy, Ops, E,
"vmlall_lane");
7263 case NEON::BI__builtin_neon_vamin_f16:
7264 case NEON::BI__builtin_neon_vaminq_f16:
7265 case NEON::BI__builtin_neon_vamin_f32:
7266 case NEON::BI__builtin_neon_vaminq_f32:
7267 case NEON::BI__builtin_neon_vaminq_f64: {
7268 Int = Intrinsic::aarch64_neon_famin;
7271 case NEON::BI__builtin_neon_vamax_f16:
7272 case NEON::BI__builtin_neon_vamaxq_f16:
7273 case NEON::BI__builtin_neon_vamax_f32:
7274 case NEON::BI__builtin_neon_vamaxq_f32:
7275 case NEON::BI__builtin_neon_vamaxq_f64: {
7276 Int = Intrinsic::aarch64_neon_famax;
7279 case NEON::BI__builtin_neon_vscale_f16:
7280 case NEON::BI__builtin_neon_vscaleq_f16:
7281 case NEON::BI__builtin_neon_vscale_f32:
7282 case NEON::BI__builtin_neon_vscaleq_f32:
7283 case NEON::BI__builtin_neon_vscaleq_f64: {
7284 Int = Intrinsic::aarch64_neon_fp8_fscale;