20#include "llvm/Support/AArch64MemoryHints.h"
31 if (BuiltinID == AArch64::BI__builtin_arm_irg) {
32 if (
SemaRef.checkArgCount(TheCall, 2))
42 return Diag(TheCall->
getBeginLoc(), diag::err_memtag_arg_must_be_pointer)
47 Context, Context.getIntTypeForBitwidth(64,
false),
50 SemaRef.PerformCopyInitialization(Entity,
61 if (BuiltinID == AArch64::BI__builtin_arm_addg) {
62 if (
SemaRef.checkArgCount(TheCall, 2))
71 return Diag(TheCall->
getBeginLoc(), diag::err_memtag_arg_must_be_pointer)
79 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 15);
82 if (BuiltinID == AArch64::BI__builtin_arm_gmi) {
83 if (
SemaRef.checkArgCount(TheCall, 2))
93 return Diag(TheCall->
getBeginLoc(), diag::err_memtag_arg_must_be_pointer)
98 Context, Context.getIntTypeForBitwidth(64,
false),
101 SemaRef.PerformCopyInitialization(Entity,
110 if (BuiltinID == AArch64::BI__builtin_arm_ldg ||
111 BuiltinID == AArch64::BI__builtin_arm_stg) {
112 if (
SemaRef.checkArgCount(TheCall, 1))
121 return Diag(TheCall->
getBeginLoc(), diag::err_memtag_arg_must_be_pointer)
126 if (BuiltinID == AArch64::BI__builtin_arm_ldg)
127 TheCall->
setType(FirstArgType);
131 if (BuiltinID == AArch64::BI__builtin_arm_subp) {
144 auto isNull = [&](
Expr *E) ->
bool {
145 return E->isNullPointerConstant(Context,
151 return Diag(TheCall->
getBeginLoc(), diag::err_memtag_arg_null_or_pointer)
155 return Diag(TheCall->
getBeginLoc(), diag::err_memtag_arg_null_or_pointer)
163 if (!Context.typesAreCompatible(
164 Context.getCanonicalType(pointeeA).getUnqualifiedType(),
165 Context.getCanonicalType(pointeeB).getUnqualifiedType())) {
167 diag::err_typecheck_sub_ptr_compatible)
180 SemaRef.ImpCastExprToType(ArgExprA.
get(), ArgTypeB, CK_NullToPointer);
184 SemaRef.ImpCastExprToType(ArgExprB.
get(), ArgTypeA, CK_NullToPointer);
190 assert(
false &&
"Unhandled ARM MTE intrinsic");
197 int ArgNum,
unsigned ExpectedFieldNum,
199 bool IsARMBuiltin = BuiltinID == ARM::BI__builtin_arm_rsr64 ||
200 BuiltinID == ARM::BI__builtin_arm_wsr64 ||
201 BuiltinID == ARM::BI__builtin_arm_rsr ||
202 BuiltinID == ARM::BI__builtin_arm_rsrp ||
203 BuiltinID == ARM::BI__builtin_arm_wsr ||
204 BuiltinID == ARM::BI__builtin_arm_wsrp;
205 bool IsAArch64Builtin = BuiltinID == AArch64::BI__builtin_arm_rsr64 ||
206 BuiltinID == AArch64::BI__builtin_arm_wsr64 ||
207 BuiltinID == AArch64::BI__builtin_arm_rsr128 ||
208 BuiltinID == AArch64::BI__builtin_arm_wsr128 ||
209 BuiltinID == AArch64::BI__builtin_arm_rsr ||
210 BuiltinID == AArch64::BI__builtin_arm_rsrp ||
211 BuiltinID == AArch64::BI__builtin_arm_wsr ||
212 BuiltinID == AArch64::BI__builtin_arm_wsrp;
213 assert((IsARMBuiltin || IsAArch64Builtin) &&
"Unexpected ARM builtin.");
228 Reg.split(Fields,
":");
230 if (Fields.size() != ExpectedFieldNum && !(AllowName && Fields.size() == 1))
238 if (Fields.size() > 1) {
239 bool FiveFields = Fields.size() == 5;
241 bool ValidString =
true;
243 ValidString &= Fields[0].starts_with_insensitive(
"cp") ||
244 Fields[0].starts_with_insensitive(
"p");
246 Fields[0] = Fields[0].drop_front(
247 Fields[0].starts_with_insensitive(
"cp") ? 2 : 1);
249 ValidString &= Fields[2].starts_with_insensitive(
"c");
251 Fields[2] = Fields[2].drop_front(1);
254 ValidString &= Fields[3].starts_with_insensitive(
"c");
256 Fields[3] = Fields[3].drop_front(1);
262 FieldBitWidths.append({IsAArch64Builtin ? 2 : 4, 3, 4, 4, 3});
264 FieldBitWidths.append({4, 3, 4});
266 for (
unsigned i = 0; i < Fields.size(); ++i) {
268 ValidString &= !Fields[i].getAsInteger(10, IntField);
269 ValidString &= (IntField >= 0 && IntField < (1 << FieldBitWidths[i]));
275 }
else if (IsAArch64Builtin && Fields.size() == 1) {
283 if (BuiltinID == AArch64::BI__builtin_arm_rsr128 ||
284 BuiltinID == AArch64::BI__builtin_arm_wsr128)
289 auto MaxLimit = llvm::StringSwitch<std::optional<unsigned>>(Reg)
290 .CaseLower(
"spsel", 15)
291 .CaseLower(
"daifclr", 15)
292 .CaseLower(
"daifset", 15)
293 .CaseLower(
"pan", 15)
294 .CaseLower(
"uao", 15)
295 .CaseLower(
"dit", 15)
296 .CaseLower(
"ssbs", 15)
297 .CaseLower(
"tco", 15)
298 .CaseLower(
"allint", 1)
300 .Default(std::nullopt);
320 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, *MaxLimit);
327 if (
SemaRef.checkArgCount(TheCall, 4))
330 bool IsStore = BuiltinID == AArch64::BI__builtin_arm_atomic_store_with_hint;
337 SemaRef.DefaultFunctionArrayLvalueConversion(TheCall->
getArg(0));
338 if (PtrArgRes.isInvalid())
340 auto *PtrArg = PtrArgRes.get();
341 auto *PtrTy = PtrArg->getType()->getAs<
PointerType>();
344 diag::err_atomic_hint_builtin_must_be_pointer)
345 << PtrArg->getType() << IsStore << PtrArg->getSourceRange();
346 TheCall->
setArg(0, PtrArg);
351 diag::err_atomic_op_needs_non_const_pointer)
352 << PtrQT << PtrArg->getSourceRange();
358 IsStore ? diag::err_atomic_op_needs_atomic_int_or_fp
359 : diag::err_atomic_op_needs_atomic_int)
360 << 0 << PtrQT << PtrArg->getSourceRange();
364 diag::err_atomic_builtin_bit_int_prohibit)
365 << PtrQT << PtrArg->getSourceRange();
367 unsigned TySize = Context.getTypeSize(PtrQT);
368 if (TySize != 8 && TySize != 16 && TySize != 32 && TySize != 64)
369 return Diag(TheCall->
getBeginLoc(), diag::err_atomic_op_hint_data_size)
370 << IsStore << PtrArg->getSourceRange();
378 SemaRef.DefaultFunctionArrayLvalueConversion(TheCall->
getArg(1));
379 if (DataArgRes.isInvalid())
381 auto *DataArg = DataArgRes.get();
384 TheCall->
setArg(1, DataArg);
388 diag::err_typecheck_call_different_arg_types)
393 SemaRef.DefaultFunctionArrayLvalueConversion(TheCall->
getArg(2));
394 if (MemOrdArg.isInvalid())
396 auto *MemOrd = MemOrdArg.get();
397 if (
SemaRef.convertArgumentToType(MemOrd, Context.IntTy))
399 TheCall->
setArg(2, MemOrd);
401 if (!MemOrd->isValueDependent()) {
402 std::optional<llvm::APSInt> MemOrdAP =
403 MemOrd->getIntegerConstantExpr(Context);
406 diag::err_atomic_hint_has_invalid_memory_order)
407 << MemOrd->getType() << MemOrd->getSourceRange();
409 unsigned Ordering = MemOrdAP->getZExtValue();
410 if (!llvm::isValidAtomicOrderingCABI(Ordering))
412 diag::err_atomic_hint_has_invalid_memory_order)
413 << *MemOrdAP << MemOrd->getSourceRange();
415 auto AtomicOrdering =
static_cast<llvm::AtomicOrderingCABI
>(Ordering);
416 if (IsStore && AtomicOrdering != llvm::AtomicOrderingCABI::relaxed &&
417 AtomicOrdering != llvm::AtomicOrderingCABI::release &&
418 AtomicOrdering != llvm::AtomicOrderingCABI::seq_cst)
420 diag::err_atomic_hint_has_invalid_memory_order)
421 << *MemOrdAP << MemOrd->getSourceRange();
427 SemaRef.DefaultFunctionArrayLvalueConversion(TheCall->
getArg(3));
428 if (HintArg.isInvalid())
430 auto Hint = HintArg.get();
431 if (
SemaRef.convertArgumentToType(Hint, Context.IntTy))
435 if (!Hint->isValueDependent()) {
436 std::optional<llvm::APSInt> HintAP = Hint->getIntegerConstantExpr(Context);
439 diag::err_atomic_hint_has_invalid_hint_type)
440 << Hint->getType() << Hint->getSourceRange();
442 auto MemoryHint = llvm::toAArch64MemoryHint(HintAP->getZExtValue());
443 if (MemoryHint == llvm::AArch64MemoryHint::NONE ||
444 (!IsStore && MemoryHint != llvm::AArch64MemoryHint::SHUH &&
445 MemoryHint != llvm::AArch64MemoryHint::SHUH_PH)) {
446 Diag(TheCall->
getBeginLoc(), diag::warn_atomic_hint_has_invalid_hint_type)
447 << *HintAP << Hint->getSourceRange();
458 bool IsPolyUnsigned,
bool IsInt64Long) {
461 return Flags.
isUnsigned() ? Context.UnsignedCharTy : Context.SignedCharTy;
463 return Flags.
isUnsigned() ? Context.UnsignedShortTy : Context.ShortTy;
465 return Flags.
isUnsigned() ? Context.UnsignedIntTy : Context.IntTy;
468 return Flags.
isUnsigned() ? Context.UnsignedLongTy : Context.LongTy;
470 return Flags.
isUnsigned() ? Context.UnsignedLongLongTy
471 : Context.LongLongTy;
473 return IsPolyUnsigned ? Context.UnsignedCharTy : Context.SignedCharTy;
475 return IsPolyUnsigned ? Context.UnsignedShortTy : Context.ShortTy;
478 return Context.UnsignedLongTy;
480 return Context.UnsignedLongLongTy;
484 return Context.HalfTy;
486 return Context.FloatTy;
488 return Context.DoubleTy;
490 return Context.BFloat16Ty;
492 return Context.MFloat8Ty;
494 llvm_unreachable(
"Invalid NeonTypeFlag!");
512 unsigned ArgIdx,
unsigned EltBitWidth,
513 unsigned ContainerBitWidth) {
516 auto CheckImmediateInSet = [&](std::initializer_list<int64_t>
Set,
517 int ErrDiag) ->
bool {
525 if (
SemaRef.BuiltinConstantArg(TheCall, ArgIdx, Imm))
528 if (!llvm::is_contained(
Set, Imm.getSExtValue()))
534 case ImmCheckType::ImmCheck0_31:
535 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, 31))
538 case ImmCheckType::ImmCheck0_13:
539 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, 13))
542 case ImmCheckType::ImmCheck0_63:
543 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, 63))
546 case ImmCheckType::ImmCheck1_16:
547 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 1, 16))
550 case ImmCheckType::ImmCheck0_7:
551 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, 7))
554 case ImmCheckType::ImmCheck1_1:
555 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 1, 1))
558 case ImmCheckType::ImmCheck1_3:
559 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 1, 3))
562 case ImmCheckType::ImmCheck1_7:
563 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 1, 7))
566 case ImmCheckType::ImmCheckExtract:
567 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0,
568 (2048 / EltBitWidth) - 1))
571 case ImmCheckType::ImmCheckCvt:
572 case ImmCheckType::ImmCheckShiftRight:
573 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 1, EltBitWidth))
576 case ImmCheckType::ImmCheckShiftRightNarrow:
577 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 1, EltBitWidth / 2))
580 case ImmCheckType::ImmCheckShiftLeft:
581 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, EltBitWidth - 1))
584 case ImmCheckType::ImmCheckShiftLeftLong:
585 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, (EltBitWidth / 2)))
588 case ImmCheckType::ImmCheckLaneIndex:
589 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0,
590 (ContainerBitWidth / EltBitWidth) - 1))
593 case ImmCheckType::ImmCheckLaneIndexCompRotate:
594 if (
SemaRef.BuiltinConstantArgRange(
595 TheCall, ArgIdx, 0, (ContainerBitWidth / (2 * EltBitWidth)) - 1))
598 case ImmCheckType::ImmCheckLaneIndexDot:
599 if (
SemaRef.BuiltinConstantArgRange(
600 TheCall, ArgIdx, 0, (ContainerBitWidth / (4 * EltBitWidth)) - 1))
603 case ImmCheckType::ImmCheckComplexRot90_270:
604 if (CheckImmediateInSet({90, 270}, diag::err_rotation_argument_to_cadd))
607 case ImmCheckType::ImmCheckComplexRotAll90:
608 if (CheckImmediateInSet({0, 90, 180, 270},
609 diag::err_rotation_argument_to_cmla))
612 case ImmCheckType::ImmCheck0_1:
613 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, 1))
616 case ImmCheckType::ImmCheck0_2:
617 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, 2))
620 case ImmCheckType::ImmCheck0_3:
621 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, 3))
624 case ImmCheckType::ImmCheck0_0:
625 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, 0))
628 case ImmCheckType::ImmCheck0_15:
629 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, 15))
632 case ImmCheckType::ImmCheck0_255:
633 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 0, 255))
636 case ImmCheckType::ImmCheck1_32:
637 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 1, 32))
640 case ImmCheckType::ImmCheck1_64:
641 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 1, 64))
644 case ImmCheckType::ImmCheck2_4_Mul2:
645 if (
SemaRef.BuiltinConstantArgRange(TheCall, ArgIdx, 2, 4) ||
646 SemaRef.BuiltinConstantArgMultiple(TheCall, ArgIdx, 2))
657 bool HasError =
false;
659 for (
const auto &I : ImmChecks) {
660 auto [ArgIdx, CheckTy, ElementBitWidth, VecBitWidth] = I;
662 if (OverloadType >= 0)
674 bool HasError =
false;
676 for (
const auto &I : ImmChecks) {
677 auto [ArgIdx, CheckTy, ElementBitWidth] = I;
686 if (FD->
hasAttr<ArmLocallyStreamingAttr>())
690 if (FPT->getAArch64SMEAttributes() &
693 if (FPT->getAArch64SMEAttributes() &
704 unsigned BuiltinID) {
712 llvm::StringMap<bool> CallerFeatures;
719 const auto FindTopLevelPipe = [](
const char *S) {
721 unsigned I = 0, E = strlen(S);
723 if (S[I] ==
'|' && Depth == 0)
727 else if (S[I] ==
')')
733 const char *RequiredFeatures =
735 unsigned PipeIdx = FindTopLevelPipe(RequiredFeatures);
736 assert(PipeIdx != 0 && PipeIdx != strlen(RequiredFeatures) &&
737 "Expected feature string of the form 'SVE-EXPR|SME-EXPR'");
738 StringRef NonStreamingBuiltinGuard = StringRef(RequiredFeatures, PipeIdx);
739 StringRef StreamingBuiltinGuard = StringRef(RequiredFeatures + PipeIdx + 1);
742 NonStreamingBuiltinGuard, CallerFeatures);
744 StreamingBuiltinGuard, CallerFeatures);
746 if (SatisfiesSVE && SatisfiesSME)
749 else if (SatisfiesSVE)
751 else if (SatisfiesSME)
760 S.
Diag(TheCall->
getBeginLoc(), diag::err_attribute_arm_sm_incompat_builtin)
764 S.
Diag(TheCall->
getBeginLoc(), diag::err_attribute_arm_sm_incompat_builtin)
776#define GET_SME_BUILTIN_GET_STATE
777#include "clang/Basic/arm_sme_builtins_za_state.inc"
778#undef GET_SME_BUILTIN_GET_STATE
785 SemaRef.getCurFunctionDecl(
true)) {
789#define GET_SME_STREAMING_ATTRS
790#include "clang/Basic/arm_sme_streaming_attrs.inc"
791#undef GET_SME_STREAMING_ATTRS
800 diag::err_attribute_arm_za_builtin_no_za_state)
807 diag::err_attribute_arm_zt0_builtin_no_zt0_state)
819#define GET_SME_IMMEDIATE_CHECK
820#include "clang/Basic/arm_sme_sema_rangechecks.inc"
821#undef GET_SME_IMMEDIATE_CHECK
830 SemaRef.getCurFunctionDecl(
true)) {
834#define GET_SVE_STREAMING_ATTRS
835#include "clang/Basic/arm_sve_streaming_attrs.inc"
836#undef GET_SVE_STREAMING_ATTRS
848#define GET_SVE_IMMEDIATE_CHECK
849#include "clang/Basic/arm_sve_sema_rangechecks.inc"
850#undef GET_SVE_IMMEDIATE_CHECK
860 SemaRef.getCurFunctionDecl(
true)) {
866#define GET_NEON_STREAMING_COMPAT_FLAG
867#include "clang/Basic/arm_neon.inc"
868#undef GET_NEON_STREAMING_COMPAT_FLAG
879 bool HasConstPtr =
false;
881#define GET_NEON_OVERLOAD_CHECK
882#include "clang/Basic/arm_fp16.inc"
883#include "clang/Basic/arm_neon.inc"
884#undef GET_NEON_OVERLOAD_CHECK
896 TV =
Result.getLimitedValue(64);
897 if ((TV > 63) || (mask & (1ULL << TV)) == 0)
902 if (PtrArgNum >= 0) {
906 Arg = ICE->getSubExpr();
911 bool IsPolyUnsigned =
Arch == llvm::Triple::aarch64 ||
912 Arch == llvm::Triple::aarch64_32 ||
913 Arch == llvm::Triple::aarch64_be;
916 IsPolyUnsigned, IsInt64Long);
921 ConvTy =
SemaRef.CheckSingleAssignmentConstraints(LHSTy, RHS);
936#define GET_NEON_IMMEDIATE_CHECK
937#include "clang/Basic/arm_fp16.inc"
938#include "clang/Basic/arm_neon.inc"
939#undef GET_NEON_IMMEDIATE_CHECK
950#include "clang/Basic/arm_mve_builtin_sema.inc"
961#include "clang/Basic/arm_cde_builtin_sema.inc"
971 const Expr *CoprocArg,
974 if (
SemaRef.isConstantEvaluatedContext())
982 int64_t CoprocNo = CoprocNoAP.getExtValue();
983 assert(CoprocNo >= 0 &&
"Coprocessor immediate must be non-negative");
986 bool IsCDECoproc = CoprocNo <= 7 && (CDECoprocMask & (1 << CoprocNo));
988 if (IsCDECoproc != WantCDE)
998 assert((BuiltinID == ARM::BI__builtin_arm_ldrex ||
999 BuiltinID == ARM::BI__builtin_arm_ldrexd ||
1000 BuiltinID == ARM::BI__builtin_arm_ldaex ||
1001 BuiltinID == ARM::BI__builtin_arm_strex ||
1002 BuiltinID == ARM::BI__builtin_arm_strexd ||
1003 BuiltinID == ARM::BI__builtin_arm_stlex ||
1004 BuiltinID == AArch64::BI__builtin_arm_ldrex ||
1005 BuiltinID == AArch64::BI__builtin_arm_ldaex ||
1006 BuiltinID == AArch64::BI__builtin_arm_strex ||
1007 BuiltinID == AArch64::BI__builtin_arm_stlex) &&
1008 "unexpected ARM builtin");
1009 bool IsLdrex = BuiltinID == ARM::BI__builtin_arm_ldrex ||
1010 BuiltinID == ARM::BI__builtin_arm_ldrexd ||
1011 BuiltinID == ARM::BI__builtin_arm_ldaex ||
1012 BuiltinID == AArch64::BI__builtin_arm_ldrex ||
1013 BuiltinID == AArch64::BI__builtin_arm_ldaex;
1014 bool IsDoubleWord = BuiltinID == ARM::BI__builtin_arm_ldrexd ||
1015 BuiltinID == ARM::BI__builtin_arm_strexd;
1022 if (
SemaRef.checkArgCount(TheCall, IsLdrex ? 1 : 2))
1029 Expr *PointerArg = TheCall->
getArg(IsLdrex ? 0 : 1);
1031 SemaRef.DefaultFunctionArrayLvalueConversion(PointerArg);
1034 PointerArg = PointerArgRes.
get();
1054 CastNeeded = CK_BitCast;
1055 Diag(DRE->
getBeginLoc(), diag::ext_typecheck_convert_discards_qualifiers)
1056 << PointerArg->
getType() << Context.getPointerType(AddrType)
1061 AddrType = Context.getPointerType(AddrType);
1062 PointerArgRes =
SemaRef.ImpCastExprToType(PointerArg, AddrType, CastNeeded);
1065 PointerArg = PointerArgRes.
get();
1067 TheCall->
setArg(IsLdrex ? 0 : 1, PointerArg);
1072 Diag(DRE->
getBeginLoc(), diag::err_atomic_builtin_must_be_pointer_intfltptr)
1081 unsigned Bits = Context.getTypeSize(ValType);
1088 (llvm::isPowerOf2_64(Bits)) && Bits >= 8 && (Mask & (Bits / 8));
1098 diag::err_atomic_exclusive_builtin_pointer_size)
1100 bool Started =
false;
1101 for (
unsigned Size = 1; Size <= 8; Size <<= 1) {
1108 if (!(Mask & Size)) {
1127 bool EmitDoubleWordDiagnostic =
1130 diag::err_atomic_exclusive_builtin_pointer_size_none)
1131 << (EmitDoubleWordDiagnostic ? 1 : 0)
1159 Context, ValType,
false);
1167 TheCall->
setType(Context.IntTy);
1172 int64_t Low, int64_t High) {
1185 return S.
Diag(
Call->getBeginLoc(), diag::warn_argument_invalid_range)
1194 if (BuiltinID == ARM::BI__builtin_arm_ldrex ||
1195 BuiltinID == ARM::BI__builtin_arm_ldrexd ||
1196 BuiltinID == ARM::BI__builtin_arm_ldaex ||
1197 BuiltinID == ARM::BI__builtin_arm_strex ||
1198 BuiltinID == ARM::BI__builtin_arm_strexd ||
1199 BuiltinID == ARM::BI__builtin_arm_stlex) {
1203 if (BuiltinID == ARM::BI__builtin_arm_prefetch) {
1204 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1) ||
1205 SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 1);
1208 if (BuiltinID == ARM::BI__builtin_arm_rsr64 ||
1209 BuiltinID == ARM::BI__builtin_arm_wsr64)
1212 if (BuiltinID == ARM::BI__builtin_arm_rsr ||
1213 BuiltinID == ARM::BI__builtin_arm_rsrp ||
1214 BuiltinID == ARM::BI__builtin_arm_wsr ||
1215 BuiltinID == ARM::BI__builtin_arm_wsrp)
1227 switch (BuiltinID) {
1230 case ARM::BI__builtin_arm_ssat:
1231 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 1, 32);
1232 case ARM::BI__builtin_arm_usat:
1233 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 31);
1234 case ARM::BI__builtin_arm_ssat16:
1235 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 1, 16);
1236 case ARM::BI__builtin_arm_usat16:
1237 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 15);
1238 case ARM::BI__builtin_arm_vcvtr_f:
1239 case ARM::BI__builtin_arm_vcvtr_d:
1240 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1);
1241 case ARM::BI__builtin_arm_dmb:
1243 case ARM::BI__builtin_arm_dsb:
1245 case ARM::BI__builtin_arm_isb:
1247 case ARM::BI__builtin_arm_dbg:
1248 return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 15);
1249 case ARM::BI__builtin_arm_cdp:
1250 case ARM::BI__builtin_arm_cdp2:
1251 case ARM::BI__builtin_arm_mcr:
1252 case ARM::BI__builtin_arm_mcr2:
1253 case ARM::BI__builtin_arm_mrc:
1254 case ARM::BI__builtin_arm_mrc2:
1255 case ARM::BI__builtin_arm_mcrr:
1256 case ARM::BI__builtin_arm_mcrr2:
1257 case ARM::BI__builtin_arm_mrrc:
1258 case ARM::BI__builtin_arm_mrrc2:
1259 case ARM::BI__builtin_arm_ldc:
1260 case ARM::BI__builtin_arm_ldcl:
1261 case ARM::BI__builtin_arm_ldc2:
1262 case ARM::BI__builtin_arm_ldc2l:
1263 case ARM::BI__builtin_arm_stc:
1264 case ARM::BI__builtin_arm_stcl:
1265 case ARM::BI__builtin_arm_stc2:
1266 case ARM::BI__builtin_arm_stc2l:
1267 return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 15) ||
1276 if (BuiltinID == AArch64::BI__builtin_arm_ldrex ||
1277 BuiltinID == AArch64::BI__builtin_arm_ldaex ||
1278 BuiltinID == AArch64::BI__builtin_arm_strex ||
1279 BuiltinID == AArch64::BI__builtin_arm_stlex) {
1283 if (BuiltinID == AArch64::BI__builtin_arm_prefetch) {
1284 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1) ||
1285 SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 3) ||
1286 SemaRef.BuiltinConstantArgRange(TheCall, 3, 0, 1) ||
1287 SemaRef.BuiltinConstantArgRange(TheCall, 4, 0, 1);
1290 if (BuiltinID == AArch64::BI__builtin_arm_range_prefetch_x) {
1291 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1) ||
1292 SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 1) ||
1293 SemaRef.BuiltinConstantArgRange(TheCall, 3, -2097152, 2097151) ||
1294 SemaRef.BuiltinConstantArgRange(TheCall, 4, 1, 65536) ||
1295 SemaRef.BuiltinConstantArgRange(TheCall, 5, -2097152, 2097151);
1298 if (BuiltinID == AArch64::BI__builtin_arm_range_prefetch) {
1299 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1) ||
1300 SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 1);
1303 if (BuiltinID == AArch64::BI__builtin_arm_rsr64 ||
1304 BuiltinID == AArch64::BI__builtin_arm_wsr64 ||
1305 BuiltinID == AArch64::BI__builtin_arm_rsr128 ||
1306 BuiltinID == AArch64::BI__builtin_arm_wsr128)
1310 if (BuiltinID == AArch64::BI__builtin_arm_irg ||
1311 BuiltinID == AArch64::BI__builtin_arm_addg ||
1312 BuiltinID == AArch64::BI__builtin_arm_gmi ||
1313 BuiltinID == AArch64::BI__builtin_arm_ldg ||
1314 BuiltinID == AArch64::BI__builtin_arm_stg ||
1315 BuiltinID == AArch64::BI__builtin_arm_subp) {
1319 if (BuiltinID == AArch64::BI__builtin_arm_rsr ||
1320 BuiltinID == AArch64::BI__builtin_arm_rsrp ||
1321 BuiltinID == AArch64::BI__builtin_arm_wsr ||
1322 BuiltinID == AArch64::BI__builtin_arm_wsrp)
1325 if (BuiltinID == AArch64::BI__builtin_arm_atomic_store_with_hint ||
1326 BuiltinID == AArch64::BI__builtin_arm_atomic_fetch_add_with_hint ||
1327 BuiltinID == AArch64::BI__builtin_arm_atomic_fetch_sub_with_hint ||
1328 BuiltinID == AArch64::BI__builtin_arm_atomic_fetch_and_with_hint ||
1329 BuiltinID == AArch64::BI__builtin_arm_atomic_fetch_xor_with_hint ||
1330 BuiltinID == AArch64::BI__builtin_arm_atomic_fetch_or_with_hint)
1338 if (BuiltinID == AArch64::BI_ReadStatusReg ||
1339 BuiltinID == AArch64::BI_WriteStatusReg)
1340 return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 0x7fff);
1342 if (BuiltinID == AArch64::BI__sys)
1343 return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 0x3fff);
1345 if (BuiltinID == AArch64::BI__getReg || BuiltinID == AArch64::BI__setReg ||
1346 BuiltinID == AArch64::BI__getRegFp || BuiltinID == AArch64::BI__setRegFp)
1347 return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 31);
1349 if (BuiltinID == AArch64::BI__prefetch2)
1350 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 31);
1352 if (BuiltinID == AArch64::BI__break)
1353 return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 0xffff);
1355 if (BuiltinID == AArch64::BI__hlt)
1356 return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 0xffff);
1358 if (BuiltinID == AArch64::BI__hvc || BuiltinID == AArch64::BI__svc) {
1361 if (
SemaRef.checkArgCountAtMost(TheCall, 5) ||
1362 SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 0xffff))
1365 for (
unsigned I = 1, N = TheCall->
getNumArgs(); I < N; ++I) {
1371 diag::err_aarch64_svc_hvc_invalid_arg_type)
1386 if (BuiltinID == AArch64::BI__arm_set_fpm_lscale)
1389 if (BuiltinID == AArch64::BI__arm_set_fpm_nscale)
1392 if (BuiltinID == AArch64::BI__arm_set_fpm_lscale2)
1397 unsigned i = 0, l = 0, u = 0;
1398 switch (BuiltinID) {
1399 default:
return false;
1400 case AArch64::BI__builtin_arm_dmb:
1401 case AArch64::BI__dmb:
1402 case AArch64::BI__builtin_arm_dsb:
1403 case AArch64::BI__dsb:
1404 case AArch64::BI__builtin_arm_isb:
1405 case AArch64::BI__isb:
1411 return SemaRef.BuiltinConstantArgRange(TheCall, i, l, u + l);
1415struct IntrinToName {
1424 const char *IntrinNames) {
1425 AliasName.consume_front(
"__arm_");
1426 const IntrinToName *It =
1427 llvm::lower_bound(Map, BuiltinID, [](
const IntrinToName &L,
unsigned Id) {
1430 if (It == Map.end() || It->Id != BuiltinID)
1432 StringRef FullName(&IntrinNames[It->FullName]);
1433 if (AliasName == FullName)
1435 if (It->ShortName == -1)
1437 StringRef ShortName(&IntrinNames[It->ShortName]);
1438 return AliasName == ShortName;
1442#include "clang/Basic/arm_mve_builtin_aliases.inc"
1450#include "clang/Basic/arm_cde_builtin_aliases.inc"
1471 Diag(AL.
getLoc(), diag::err_attribute_argument_n_type)
1480 bool IsAArch64 = Context.getTargetInfo().getTriple().isAArch64();
1485 Diag(AL.
getLoc(), diag::err_attribute_arm_builtin_alias);
1489 D->
addAttr(::new (Context) ArmBuiltinAliasAttr(Context, AL, Ident));
1495 auto CheckForIncompatibleAttr =
1497 StringRef IncompatibleStateName) {
1498 if (CurrentState == IncompatibleState) {
1499 S.
Diag(AL.
getLoc(), diag::err_attributes_are_not_compatible)
1500 << (std::string(
"'__arm_new(\"") + StateName.str() +
"\")'")
1501 << (std::string(
"'") + IncompatibleStateName.str() +
"(\"" +
1502 StateName.str() +
"\")'")
1517 Diag(AL.
getLoc(), diag::err_missing_arm_state) << AL;
1522 std::vector<StringRef> NewState;
1523 if (
const auto *ExistingAttr = D->
getAttr<ArmNewAttr>()) {
1524 for (StringRef S : ExistingAttr->newArgs())
1525 NewState.push_back(S);
1529 bool HasZT0 =
false;
1530 for (
unsigned I = 0, E = AL.
getNumArgs(); I != E; ++I) {
1531 StringRef StateName;
1533 if (!
SemaRef.checkStringLiteralArgumentAttr(AL, I, StateName, &LiteralLoc))
1536 if (StateName ==
"za")
1538 else if (StateName ==
"zt0")
1541 Diag(LiteralLoc, diag::err_unknown_arm_state) << StateName;
1546 if (!llvm::is_contained(NewState, StateName))
1547 NewState.push_back(StateName);
1570 Diag(AL.
getLoc(), diag::err_attribute_not_clinkage) << AL;
1575 if (!FD->isExternallyVisible()) {
1576 Diag(AL.
getLoc(), diag::warn_attribute_cmse_entry_static);
1586 Diag(AL.
getLoc(), diag::err_attribute_too_many_arguments) << AL << 1;
1595 else if (!
SemaRef.checkStringLiteralArgumentAttr(AL, 0, Str, &ArgLoc))
1598 ARMInterruptAttr::InterruptType Kind;
1599 if (!ARMInterruptAttr::ConvertStrToInterruptType(Str, Kind)) {
1600 Diag(AL.
getLoc(), diag::warn_attribute_type_not_supported)
1601 << AL << Str << ArgLoc;
1605 if (!D->
hasAttr<ARMSaveFPAttr>()) {
1620 SemaRef.ARM().handleInterruptAttr(D, AL);
1623 if (!D->
hasAttr<ARMInterruptAttr>()) {
1629 bool VFP =
SemaRef.Context.getTargetInfo().hasFeature(
"vfp");
1642 bool UsesSM = FD->
hasAttr<ArmLocallyStreamingAttr>();
1643 bool UsesZA =
Attr &&
Attr->isNewZA();
1644 bool UsesZT0 =
Attr &&
Attr->isNewZT0();
1646 if (UsesZA || UsesZT0) {
1654 if (FD->
hasAttr<ArmLocallyStreamingAttr>()) {
1657 diag::warn_sme_locally_streaming_has_vl_args_returns)
1660 return P->getOriginalType()->isSizelessVectorType();
1663 diag::warn_sme_locally_streaming_has_vl_args_returns)
1676 if (UsesSM || UsesZA) {
1677 llvm::StringMap<bool> FeatureMap;
1678 Context.getFunctionFeatureMap(FeatureMap, FD);
1679 if (!FeatureMap.contains(
"sme")) {
1682 diag::err_sme_definition_using_sm_in_non_sme_target);
1685 diag::err_sme_definition_using_za_in_non_sme_target);
1689 llvm::StringMap<bool> FeatureMap;
1690 Context.getFunctionFeatureMap(FeatureMap, FD);
1691 if (!FeatureMap.contains(
"sme2")) {
1693 diag::err_sme_definition_using_zt0_in_non_sme2_target);
1702 uint64_t VScale = IsStreaming ? Context.getLangOpts().VScaleStreamingMin
1703 : Context.getLangOpts().VScaleMin;
1704 if (Ty->
getKind() == BuiltinType::SveBool ||
1705 Ty->
getKind() == BuiltinType::SveCount)
1706 return (VScale * 128) / Context.getCharWidth();
1707 return VScale * 128;
1711 bool IsStreaming =
false;
1715 SemaRef.getCurFunctionDecl(
true)) {
1718 if (
T->getAArch64SMEAttributes() &
1735 return BT->getKind() == BuiltinType::SveBool;
1737 return VT->getElementType().getCanonicalType() ==
1739 BT->getKind() != BuiltinType::SveBool;
1741 return Context.getTypeSize(SecondType) ==
1743 Context.hasSameType(
1744 VT->getElementType(),
1745 Context.getBuiltinVectorTypeInfo(BT).ElementType);
1751 return IsValidCast(FirstType, SecondType) ||
1752 IsValidCast(SecondType, FirstType);
1757 bool IsStreaming =
false;
1761 SemaRef.getCurFunctionDecl(
true)) {
1764 if (
T->getAArch64SMEAttributes() &
1787 if (BT->getKind() == BuiltinType::SveBool &&
1797 Context.getTypeSize(SecondType) !=
1809 return VecTy->getElementType().getCanonicalType()->isIntegerType() &&
1816 return IsLaxCompatible(FirstType, SecondType) ||
1817 IsLaxCompatible(SecondType, FirstType);
1821 if (!Buffer.empty())
1823 Buffer.append(Feat);
1828 StringRef PriorityString[8] = {
"P0",
"P1",
"P2",
"P3",
1829 "P4",
"P5",
"P6",
"P7"};
1831 assert(Priority > 0 && Priority < 256 &&
"priority out of range");
1833 for (
unsigned BitPos = 0; BitPos < 8; ++BitPos)
1834 if (Priority & (1U << BitPos))
1843 auto [LHS, RHS] = Param.split(
';');
1845 bool IsDefault =
false;
1847 LHS.split(Features,
'+');
1848 for (StringRef Feat : Features) {
1850 if (Feat ==
"default")
1852 else if (!
getASTContext().getTargetInfo().validateCpuSupports(Feat))
1853 return Diag(Loc, diag::warn_unsupported_target_attribute)
1858 if (!RHS.empty() && RHS.consume_front(
"priority=")) {
1860 Diag(Loc, diag::warn_invalid_default_version_priority);
1863 if (RHS.getAsInteger(0, Digit) || Digit < 1 || Digit > 255)
1864 Diag(Loc, diag::warn_version_priority_out_of_range) << RHS;
1880 assert(Params.size() == Locs.size() &&
1881 "Mismatch between number of string parameters and locations");
1883 bool HasDefault =
false;
1884 bool HasNonDefault =
false;
1885 for (
unsigned I = 0, E = Params.size(); I < E; ++I) {
1886 const StringRef Param = Params[I].trim();
1889 auto [LHS, RHS] = Param.split(
';');
1891 bool HasPriority = !RHS.empty() && RHS.consume_front(
"priority=");
1894 return Diag(Loc, diag::warn_unsupported_target_attribute)
1897 if (LHS ==
"default") {
1899 Diag(Loc, diag::warn_target_clone_duplicate_options);
1902 Diag(Loc, diag::warn_invalid_default_version_priority);
1903 NewParams.push_back(LHS);
1909 bool HasCodeGenImpact =
false;
1912 LHS.split(Features,
'+');
1913 for (StringRef Feat : Features) {
1915 if (!
getASTContext().getTargetInfo().validateCpuSupports(Feat)) {
1916 Diag(Loc, diag::warn_unsupported_target_attribute)
1920 if (
getASTContext().getTargetInfo().doesFeatureAffectCodeGen(Feat))
1921 HasCodeGenImpact =
true;
1922 ValidFeatures.push_back(Feat);
1926 if (!HasCodeGenImpact) {
1927 Diag(Loc, diag::warn_target_clone_no_impact_options);
1931 if (ValidFeatures.empty())
1935 llvm::sort(ValidFeatures);
1937 if (llvm::is_contained(NewParams, NewParam)) {
1938 Diag(Loc, diag::warn_target_clone_duplicate_options);
1944 if (RHS.getAsInteger(0, Digit) || Digit < 1 || Digit > 255)
1945 Diag(Loc, diag::warn_version_priority_out_of_range) << RHS;
1951 NewParams.push_back(NewParam);
1952 HasNonDefault =
true;
1955 return !HasNonDefault;
1960 const llvm::StringMap<bool> &FeatureMap) {
1964 if (FeatureMap.lookup(
"sve"))
1968 if (!FeatureMap.lookup(
"sme"))
1969 return Diag(Loc, diag::err_sve_vector_in_non_sve_target) << Ty;
1974 return Diag(Loc, diag::err_sve_vector_in_non_streaming_function) << Ty;
static bool hasFeature(StringRef Feature, const LangOptions &LangOpts, const TargetInfo &Target)
Determine whether a translation unit built using the current language options has the given feature.
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
This file declares semantic analysis functions specific to ARM.
Enumerates target-specific builtins in their own namespaces within namespace clang.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
Builtin::Context & BuiltinInfo
const TargetInfo & getTargetInfo() const
void getFunctionFeatureMap(llvm::StringMap< bool > &FeatureMap, const FunctionDecl *) const
Attr - This represents one attribute.
SourceLocation getLoc() const
This class is used for builtin types like 'int'.
unsigned getAuxBuiltinID(unsigned ID) const
Return real builtin ID (i.e.
const char * getRequiredFeatures(unsigned ID) const
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
SourceLocation getBeginLoc() const
void setArg(unsigned Arg, Expr *ArgExpr)
setArg - Set the specified argument.
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
bool isExternCContext() const
Determines whether this context or some of its ancestors is a linkage specification context that spec...
A reference to a declared variable, function, enum, etc.
SourceLocation getBeginLoc() const
Decl - This represents one declaration (or definition), e.g.
const FunctionType * getFunctionType(bool BlocksToo=true) const
Looks through the Decl's underlying type to extract a FunctionType when possible.
SourceLocation getLocation() const
DeclContext * getDeclContext()
This represents one expression.
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
bool isValueDependent() const
Determines whether the value of this expression depends on.
bool isTypeDependent() const
Determines whether the type of this expression depends on.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
@ NPC_ValueDependentIsNotNull
Specifies that a value-dependent expression should be considered to never be a null pointer constant.
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx, bool AllowRelaxedEval=false) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
Represents a function declaration or definition.
QualType getReturnType() const
ArrayRef< ParmVarDecl * > parameters() const
Represents a prototype with parameter type info, e.g.
@ SME_PStateSMEnabledMask
@ SME_PStateSMCompatibleMask
@ SME_AgnosticZAStateMask
static ArmStateValue getArmZT0State(unsigned AttrBits)
static ArmStateValue getArmZAState(unsigned AttrBits)
One of these records is kept for each identifier that is lexed.
unsigned getBuiltinID() const
Return a value indicating whether this is a builtin function.
IdentifierInfo * getIdentifierInfo() const
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Describes an entity that is being initialized.
static InitializedEntity InitializeParameter(ASTContext &Context, ParmVarDecl *Parm)
Create the initialization entity for a parameter.
@ Integer
Permit vector bitcasts between integer vectors with different numbers of elements but the same total ...
@ All
Permit vector bitcasts between all vectors with the same total bit-width.
Flags to identify the types for overloaded Neon builtins.
unsigned getEltSizeInBits() const
EltType getEltType() const
Represents a parameter to a function.
ParsedAttr - Represents a syntactic attribute.
IdentifierLoc * getArgAsIdent(unsigned Arg) const
void setInvalid(bool b=true) const
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this attribute.
bool isArgIdent(unsigned Arg) const
PointerType - C99 6.7.5.1 - Pointer Declarators.
A (possibly-)qualified type.
QualType withConst() const
void addConst()
Add the const type qualifier to this QualType.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
QualType withVolatile() const
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
bool isConstQualified() const
Determine whether this type is const-qualified.
const Type * getTypePtrOrNull() const
bool isAtLeastAsQualifiedAs(QualType Other, const ASTContext &Ctx) const
Determine whether this type is at least as qualified as the other given type, requiring exact equalit...
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
void CheckSMEFunctionDefAttributes(const FunctionDecl *FD)
bool CheckARMBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
void handleInterruptSaveFPAttr(Decl *D, const ParsedAttr &AL)
bool CheckSMEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
bool CheckARMCoprocessorImmediate(const TargetInfo &TI, const Expr *CoprocArg, bool WantCDE)
bool CheckSVEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
bool CheckNeonBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckCDEBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool PerformNeonImmChecks(CallExpr *TheCall, SmallVectorImpl< std::tuple< int, int, int, int > > &ImmChecks, int OverloadType=-1)
bool CheckMVEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
void handleInterruptAttr(Decl *D, const ParsedAttr &AL)
bool PerformSVEImmChecks(CallExpr *TheCall, SmallVectorImpl< std::tuple< int, int, int > > &ImmChecks)
void handleBuiltinAliasAttr(Decl *D, const ParsedAttr &AL)
@ ArmStreaming
Intrinsic is only available in normal mode.
@ VerifyRuntimeMode
Intrinsic is available both in normal and Streaming-SVE mode.
@ ArmStreamingCompatible
Intrinsic is only available in Streaming-SVE mode.
void handleNewAttr(Decl *D, const ParsedAttr &AL)
bool CheckARMBuiltinExclusiveCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool areCompatibleSveTypes(QualType FirstType, QualType SecondType)
Return true if the given types are an SVE builtin and a VectorType that is a fixed-length representat...
bool BuiltinARMAtomicHintCall(unsigned BuiltinID, CallExpr *TheCall)
bool checkTargetVersionAttr(const StringRef Param, const SourceLocation Loc, SmallString< 64 > &NewParam)
bool checkSVETypeSupport(QualType Ty, SourceLocation Loc, const FunctionDecl *FD, const llvm::StringMap< bool > &FeatureMap)
bool SveAliasValid(unsigned BuiltinID, llvm::StringRef AliasName)
bool areLaxCompatibleSveTypes(QualType FirstType, QualType SecondType)
Return true if the given vector types are lax-compatible SVE vector types, false otherwise.
bool CheckAArch64BuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool MveAliasValid(unsigned BuiltinID, llvm::StringRef AliasName)
bool BuiltinARMMemoryTaggingCall(unsigned BuiltinID, CallExpr *TheCall)
BuiltinARMMemoryTaggingCall - Handle calls of memory tagging extensions.
void handleCmseNSEntryAttr(Decl *D, const ParsedAttr &AL)
bool CheckImmediateArg(CallExpr *TheCall, unsigned CheckTy, unsigned ArgIdx, unsigned EltBitWidth, unsigned VecBitWidth)
bool BuiltinARMSpecialReg(unsigned BuiltinID, CallExpr *TheCall, int ArgNum, unsigned ExpectedFieldNum, bool AllowName)
BuiltinARMSpecialReg - Handle a check if argument ArgNum of CallExpr TheCall is an ARM/AArch64 specia...
bool SmeAliasValid(unsigned BuiltinID, llvm::StringRef AliasName)
bool checkTargetClonesAttr(SmallVectorImpl< StringRef > &Params, SmallVectorImpl< SourceLocation > &Locs, SmallVectorImpl< SmallString< 64 > > &NewParams)
bool CdeAliasValid(unsigned BuiltinID, llvm::StringRef AliasName)
ASTContext & getASTContext() const
const LangOptions & getLangOpts() const
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
Sema - This implements semantic analysis and AST building for C.
Encodes a location in the source.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
SourceLocation getBeginLoc() const LLVM_READONLY
Exposes information about the current target.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
IntType getInt64Type() const
@ ARM_LDREX_D
word (32-bit)
virtual unsigned getARMLDREXMask() const
uint32_t getARMCDECoprocMask() const
For ARM targets returns a mask defining which coprocessors are configured as Custom Datapath.
virtual bool hasFeature(StringRef Feature) const
Determine whether the given target has the given feature.
The base class of the type hierarchy.
bool isBlockPointerType() const
bool isMFloat8Type() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
bool isSVESizelessBuiltinType() const
Returns true for SVE scalable vector types.
bool isSveVLSBuiltinType() const
Determines if this is a sizeless type supported by the 'arm_sve_vector_bits' type attribute,...
bool isIntegralType(const ASTContext &Ctx) const
Determine whether this type is an integral type.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
QualType getSveEltType(const ASTContext &Ctx) const
Returns the representative type for the element of an SVE builtin type.
bool isBitIntType() const
bool isFloatingType() const
bool isAnyPointerType() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isSizelessVectorType() const
Returns true for all scalable vector types.
Represents a GCC generic vector type.
Defines the clang::TargetInfo interface.
bool evaluateRequiredTargetFeatures(llvm::StringRef RequiredFatures, const llvm::StringMap< bool > &TargetFetureMap)
Returns true if the required target features of a builtin function are enabled.
Enums for the diagnostics of target, target_version and target_clones.
const AstTypeMatcher< PointerType > pointerType
Top level wrappers for InstallAPI frontend operations.
bool isa(CodeGen::Address addr)
static void convertPriorityString(unsigned Priority, SmallString< 64 > &NewParam)
static bool BuiltinAliasValid(unsigned BuiltinID, StringRef AliasName, ArrayRef< IntrinToName > Map, const char *IntrinNames)
static ArmSMEState getSMEState(unsigned BuiltinID)
static bool checkArmStreamingBuiltin(Sema &S, CallExpr *TheCall, const FunctionDecl *FD, SemaARM::ArmStreamingType BuiltinType, unsigned BuiltinID)
SemaARM::ArmStreamingType getArmStreamingFnType(const FunctionDecl *FD)
static uint64_t getSVETypeSize(ASTContext &Context, const BuiltinType *Ty, bool IsStreaming)
getSVETypeSize - Return SVE vector or predicate register size.
@ AANT_ArgumentIdentifier
@ Result
The result type of a method or function.
static bool checkFPMScaleIfConstant(Sema &S, CallExpr *Call, unsigned ArgNum, int64_t Low, int64_t High)
const FunctionProtoType * T
AssignConvertType
AssignConvertType - All of the 'assignment' semantic checks return this enum to indicate whether the ...
bool hasArmZT0State(const FunctionDecl *FD)
Returns whether the given FunctionDecl has Arm ZT0 state.
CastKind
CastKind - The kind of operation required for a conversion.
static QualType getNeonEltType(NeonTypeFlags Flags, ASTContext &Context, bool IsPolyUnsigned, bool IsInt64Long)
getNeonEltType - Return the QualType corresponding to the elements of the vector type specified by th...
static bool checkNewAttrMutualExclusion(Sema &S, const ParsedAttr &AL, const FunctionProtoType *FPT, FunctionType::ArmStateValue CurrentState, StringRef StateName)
static void appendFeature(StringRef Feat, SmallString< 64 > &Buffer)
@ SveFixedLengthData
is AArch64 SVE fixed-length data vector
@ Generic
not a target-specific vector type
@ SveFixedLengthPredicate
is AArch64 SVE fixed-length predicate vector
U cast(CodeGen::Address addr)
bool IsArmStreamingFunction(const FunctionDecl *FD, bool IncludeLocallyStreaming)
Returns whether the given FunctionDecl has an __arm[_locally]_streaming attribute.
ActionResult< Expr * > ExprResult
bool hasArmZAState(const FunctionDecl *FD)
Returns whether the given FunctionDecl has Arm ZA state.
__builtin_bitreverse32 uint32_t __builtin_riscv_aaddu_u32 __builtin_riscv_asubu_u32 __builtin_elementwise_add_sat __builtin_elementwise_sub_sat int32_t
Extra information about a function prototype.
unsigned AArch64SMEAttributes