19#include "llvm/ADT/StringExtras.h"
20#include "llvm/Support/ErrorHandling.h"
21#include "llvm/Support/SipHash.h"
28 case Builtin::BIas_const:
29 case Builtin::BIforward:
30 case Builtin::BIforward_like:
32 case Builtin::BImove_if_noexcept:
33 case Builtin::BIaddressof:
34 case Builtin::BI__addressof:
35 case Builtin::BI__builtin_addressof:
36 case Builtin::BI__builtin_launder:
83 int64_t
V = Val.getSExtValue();
87 uint64_t
V = Val.getZExtValue();
94 if constexpr (std::is_same_v<T, APInt>)
96 else if constexpr (std::is_same_v<T, APSInt>)
101 std::is_signed_v<T>),
102 !std::is_signed_v<T>),
119 ValueT, { Dest.
deref<
T>() = T::from(
static_cast<T>(
Value)); });
128 if (
T->isPointerType())
132 if (
const auto *AT =
T->getAsArrayTypeUnsafe())
133 return AT->getElementType();
144 S.
CCEDiag(Loc, diag::note_constexpr_invalid_function)
148 S.
CCEDiag(Loc, diag::note_invalid_subexpr_in_const_expr);
154 "Not a boolean vector");
158 llvm::APSInt
Result(NumElems, 0);
159 for (
unsigned I = 0; I != NumElems; ++I) {
160 if (Val.
elem<
bool>(I))
172 return F && F->isInStdNamespace() && F->getIdentifier() &&
173 F->getIdentifier()->isStr(
"is_constant_evaluated");
184 diag::warn_is_constant_evaluated_always_true_constexpr)
188 diag::warn_is_constant_evaluated_always_true_constexpr)
189 <<
"__builtin_is_constant_evaluated" <<
Call->getSourceRange();
201 assert(
Call->getNumArgs() == 1);
209 uint64_t Limit = ~static_cast<uint64_t>(0);
210 if (ID == Builtin::BIstrncmp || ID == Builtin::BI__builtin_strncmp ||
211 ID == Builtin::BIwcsncmp || ID == Builtin::BI__builtin_wcsncmp)
217 if (ID == Builtin::BIstrcmp || ID == Builtin::BIstrncmp ||
218 ID == Builtin::BIwcscmp || ID == Builtin::BIwcsncmp)
229 if (A.isDummy() || B.
isDummy())
234 bool IsWide = ID == Builtin::BIwcscmp || ID == Builtin::BIwcsncmp ||
235 ID == Builtin::BI__builtin_wcscmp ||
236 ID == Builtin::BI__builtin_wcsncmp;
237 assert(A.getFieldDesc()->isPrimitiveArray());
246 auto returnResult = [&](
int V) ->
bool {
251 unsigned IndexA = A.getIndex();
254 for (;; ++IndexA, ++IndexB, ++Steps) {
270 return returnResult(1);
272 return returnResult(-1);
273 if (CA.isZero() || CB.isZero())
274 return returnResult(0);
279 uint8_t CA = PA.
deref<uint8_t>();
280 uint8_t CB = PB.
deref<uint8_t>();
283 return returnResult(1);
285 return returnResult(-1);
286 if (CA == 0 || CB == 0)
287 return returnResult(0);
290 return returnResult(0);
298 if (ID == Builtin::BIstrlen || ID == Builtin::BIwcslen)
316 if (ID == Builtin::BI__builtin_wcslen || ID == Builtin::BIwcslen) {
322 for (
size_t I = StrPtr.
getIndex();; ++I, ++Len) {
331 Val = ElemPtr.
deref<uint8_t>();
334 Val = ElemPtr.
deref<uint16_t>();
337 Val = ElemPtr.
deref<uint32_t>();
340 llvm_unreachable(
"Unsupported char size");
365 for (
unsigned I = 0;; ++I) {
371 if (Elem.
deref<int8_t>() == 0)
374 Str += Elem.
deref<
char>();
379 Fill = llvm::APInt(32, 0);
380 else if (StringRef(Str).getAsInteger(0, Fill))
383 const llvm::fltSemantics &TargetSemantics =
385 Call->getDirectCallee()->getReturnType());
391 llvm::APFloat::getSNaN(TargetSemantics,
false, &Fill));
394 llvm::APFloat::getQNaN(TargetSemantics,
false, &Fill));
403 llvm::APFloat::getQNaN(TargetSemantics,
false, &Fill));
406 llvm::APFloat::getSNaN(TargetSemantics,
false, &Fill));
416 const llvm::fltSemantics &TargetSemantics =
418 Call->getDirectCallee()->getReturnType());
421 Result.copy(APFloat::getInf(TargetSemantics));
494 bool IsInf = F.isInfinity();
497 pushInteger(S, IsInf ? (F.isNegative() ? -1 : 1) : 0,
Call->getType());
557 case Builtin::BI__builtin_isgreater:
559 case Builtin::BI__builtin_isgreaterequal:
561 case Builtin::BI__builtin_isless:
563 case Builtin::BI__builtin_islessequal:
565 case Builtin::BI__builtin_islessgreater: {
570 case Builtin::BI__builtin_isunordered:
573 llvm_unreachable(
"Unexpected builtin ID: Should be a floating point "
574 "comparison function");
589 int32_t
Result =
static_cast<int32_t
>(
590 (F.
classify() & std::move(FPClassArg)).getZExtValue());
605 for (
unsigned I = 0; I != 5; ++I)
613 case APFloat::fcInfinity:
616 case APFloat::fcNormal:
619 case APFloat::fcZero:
632 if (!In.isNegative())
659 APSInt(APInt::getSignedMinValue(Val.getBitWidth()),
false))
661 if (Val.isNegative())
671 if (
Call->getArg(0)->getType()->isExtVectorBoolType()) {
693 pushInteger(S, Val.getBitWidth() - Val.getSignificantBits(),
Call->getType());
709 assert(
Call->getNumArgs() == 1);
714 int32_t ReturnVal =
static_cast<int32_t
>(ResultClass);
726 unsigned NumArgs =
Call->getNumArgs();
727 assert(NumArgs == 2 || NumArgs == 3);
744 uint64_t N =
Value.countr_zero();
753 assert(
Call->getArg(0)->isLValue());
756 "Unsupported pointer type passed to __builtin_addressof()");
764 return Call->getDirectCallee()->isConstexpr();
781 unsigned BuiltinOp) {
790 QualType ResultType =
Call->getArg(2)->getType()->getPointeeType();
795 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
796 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
797 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
798 bool IsSigned = LHS.isSigned() || RHS.isSigned() ||
800 bool AllSigned = LHS.isSigned() && RHS.isSigned() &&
802 uint64_t LHSSize = LHS.getBitWidth();
803 uint64_t RHSSize = RHS.getBitWidth();
805 uint64_t MaxBits = std::max(std::max(LHSSize, RHSSize), ResultSize);
811 if (IsSigned && !AllSigned)
814 LHS =
APSInt(LHS.extOrTrunc(MaxBits), !IsSigned);
815 RHS =
APSInt(RHS.extOrTrunc(MaxBits), !IsSigned);
822 llvm_unreachable(
"Invalid value for BuiltinOp");
823 case Builtin::BI__builtin_add_overflow:
824 case Builtin::BI__builtin_sadd_overflow:
825 case Builtin::BI__builtin_saddl_overflow:
826 case Builtin::BI__builtin_saddll_overflow:
827 case Builtin::BI__builtin_uadd_overflow:
828 case Builtin::BI__builtin_uaddl_overflow:
829 case Builtin::BI__builtin_uaddll_overflow:
830 Result = LHS.isSigned() ? LHS.sadd_ov(RHS, Overflow)
831 : LHS.uadd_ov(RHS, Overflow);
833 case Builtin::BI__builtin_sub_overflow:
834 case Builtin::BI__builtin_ssub_overflow:
835 case Builtin::BI__builtin_ssubl_overflow:
836 case Builtin::BI__builtin_ssubll_overflow:
837 case Builtin::BI__builtin_usub_overflow:
838 case Builtin::BI__builtin_usubl_overflow:
839 case Builtin::BI__builtin_usubll_overflow:
840 Result = LHS.isSigned() ? LHS.ssub_ov(RHS, Overflow)
841 : LHS.usub_ov(RHS, Overflow);
843 case Builtin::BI__builtin_mul_overflow:
844 case Builtin::BI__builtin_smul_overflow:
845 case Builtin::BI__builtin_smull_overflow:
846 case Builtin::BI__builtin_smulll_overflow:
847 case Builtin::BI__builtin_umul_overflow:
848 case Builtin::BI__builtin_umull_overflow:
849 case Builtin::BI__builtin_umulll_overflow:
850 Result = LHS.isSigned() ? LHS.smul_ov(RHS, Overflow)
851 : LHS.umul_ov(RHS, Overflow);
857 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
858 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
859 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
867 if (!APSInt::isSameValue(Temp,
Result))
877 assert(
Call->getDirectCallee()->getReturnType()->isBooleanType());
903 bool FirstOverflowed =
false;
904 bool SecondOverflowed =
false;
907 llvm_unreachable(
"Invalid value for BuiltinOp");
908 case Builtin::BI__builtin_addcb:
909 case Builtin::BI__builtin_addcs:
910 case Builtin::BI__builtin_addc:
911 case Builtin::BI__builtin_addcl:
912 case Builtin::BI__builtin_addcll:
914 LHS.uadd_ov(RHS, FirstOverflowed).uadd_ov(CarryIn, SecondOverflowed);
916 case Builtin::BI__builtin_subcb:
917 case Builtin::BI__builtin_subcs:
918 case Builtin::BI__builtin_subc:
919 case Builtin::BI__builtin_subcl:
920 case Builtin::BI__builtin_subcll:
922 LHS.usub_ov(RHS, FirstOverflowed).usub_ov(CarryIn, SecondOverflowed);
927 CarryOut = (uint64_t)(FirstOverflowed | SecondOverflowed);
929 QualType CarryOutType =
Call->getArg(3)->getType()->getPointeeType();
934 assert(
Call->getType() ==
Call->getArg(0)->getType());
941 unsigned BuiltinOp) {
943 std::optional<APSInt> Fallback;
944 if (BuiltinOp == Builtin::BI__builtin_clzg &&
Call->getNumArgs() == 2)
948 if (
Call->getArg(0)->getType()->isExtVectorBoolType()) {
957 bool ZeroIsUndefined = BuiltinOp != Builtin::BI__lzcnt16 &&
958 BuiltinOp != Builtin::BI__lzcnt &&
959 BuiltinOp != Builtin::BI__lzcnt64;
977 unsigned BuiltinID) {
978 std::optional<APSInt> Fallback;
979 if (BuiltinID == Builtin::BI__builtin_ctzg &&
Call->getNumArgs() == 2)
983 if (
Call->getArg(0)->getType()->isExtVectorBoolType()) {
1006 assert(Val.getActiveBits() <= 64);
1017 unsigned BuiltinOp) {
1018 auto returnBool = [&S](
bool Value) ->
bool {
1037 if (Size.isPowerOfTwo()) {
1039 unsigned InlineWidthBits =
1046 return returnBool(
true);
1049 assert(BuiltinOp != Builtin::BI__c11_atomic_is_lock_free);
1051 return returnBool(
true);
1055 if (
APSInt(
APInt(64, IntVal,
false),
true).isAligned(Size.getAsAlign()))
1056 return returnBool(
true);
1059 const Expr *PtrArg =
Call->getArg(1);
1061 if (
const auto *ICE = dyn_cast<ImplicitCastExpr>(PtrArg)) {
1064 if (ICE->getCastKind() == CK_BitCast)
1065 PtrArg = ICE->getSubExpr();
1073 return returnBool(
true);
1079 if (BuiltinOp == Builtin::BI__atomic_always_lock_free)
1080 return returnBool(
false);
1093 if (Size.isPowerOfTwo()) {
1095 unsigned InlineWidthBits =
1116 Result.initializeAllElements();
1129 unsigned BuiltinOp) {
1132 if (Alignment < 0 || !Alignment.isPowerOf2()) {
1133 S.
FFDiag(
Call, diag::note_constexpr_invalid_alignment) << Alignment;
1137 APSInt MaxValue(APInt::getOneBitSet(SrcWidth, SrcWidth - 1));
1138 if (APSInt::compareValues(Alignment, MaxValue) > 0) {
1139 S.
FFDiag(
Call, diag::note_constexpr_alignment_too_big)
1140 << MaxValue <<
Call->getArg(0)->getType() << Alignment;
1149 APInt AlignMinusOne = Alignment.extOrTrunc(Src.getBitWidth()) - 1;
1150 if (BuiltinOp == Builtin::BI__builtin_align_up) {
1152 APSInt((Src + AlignMinusOne) & ~AlignMinusOne, Src.isUnsigned());
1154 }
else if (BuiltinOp == Builtin::BI__builtin_align_down) {
1155 APSInt AlignedVal =
APSInt(Src & ~AlignMinusOne, Src.isUnsigned());
1163 assert(FirstArgT ==
PT_Ptr);
1168 unsigned PtrOffset = Ptr.
getIndex();
1174 if (BuiltinOp == Builtin::BI__builtin_is_aligned) {
1189 S.
FFDiag(
Call->getArg(0), diag::note_constexpr_alignment_compute)
1194 assert(BuiltinOp == Builtin::BI__builtin_align_down ||
1195 BuiltinOp == Builtin::BI__builtin_align_up);
1210 assert(Alignment.getBitWidth() <= 64 &&
1211 "Cannot handle > 64-bit address-space");
1212 uint64_t Alignment64 = Alignment.getZExtValue();
1215 ? llvm::alignDown(PtrOffset, Alignment64)
1216 : llvm::alignTo(PtrOffset, Alignment64));
1223 S.
FFDiag(
Call->getArg(0), diag::note_constexpr_alignment_adjust) << Alignment;
1231 assert(
Call->getNumArgs() == 2 ||
Call->getNumArgs() == 3);
1233 std::optional<APSInt> ExtraOffset;
1234 if (
Call->getNumArgs() == 3)
1250 if (BaseAlignment < Align) {
1252 diag::note_constexpr_baa_insufficient_alignment)
1253 << 0 << BaseAlignment.
getQuantity() << Align.getQuantity();
1262 if (AVOffset.
alignTo(Align) != AVOffset) {
1265 diag::note_constexpr_baa_insufficient_alignment)
1266 << 1 << AVOffset.
getQuantity() << Align.getQuantity();
1269 diag::note_constexpr_baa_value_insufficient_alignment)
1283 unsigned BuiltinOp) {
1284 if (
Call->getNumArgs() != 4 || !
Call->getArg(0)->getType()->isIntegerType() ||
1285 !
Call->getArg(1)->getType()->isIntegerType() ||
1286 !
Call->getArg(2)->getType()->isIntegerType())
1295 bool IsAdd = BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u32 ||
1296 BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u64;
1298 unsigned BitWidth = LHS.getBitWidth();
1299 unsigned CarryInBit = CarryIn.ugt(0) ? 1 : 0;
1301 IsAdd ? (LHS.zext(BitWidth + 1) + (RHS.zext(BitWidth + 1) + CarryInBit))
1302 : (LHS.zext(BitWidth + 1) - (RHS.zext(BitWidth + 1) + CarryInBit));
1306 APSInt(ExResult.extractBits(1, BitWidth),
true);
1308 QualType CarryOutType =
Call->getArg(3)->getType()->getPointeeType();
1332 assert(Ptr.getFieldDesc()->isPrimitiveArray());
1336 assert(Ptr.getFieldDesc()->getNumElems() >= 1);
1337 StringRef R(&Ptr.deref<
char>(), Ptr.getFieldDesc()->getNumElems() - 1);
1338 uint64_t
Result = getPointerAuthStableSipHash(R);
1351 if (ElemType.isNull()) {
1353 ? diag::note_constexpr_new_untyped
1354 : diag::note_constexpr_new);
1359 if (ElemType->isIncompleteType() || ElemType->isFunctionType()) {
1360 S.
FFDiag(
Call, diag::note_constexpr_new_not_complete_object_type)
1361 << (ElemType->isIncompleteType() ? 0 : 1) << ElemType;
1368 unsigned NumArgs =
Call->getNumArgs();
1369 assert(NumArgs >= 1);
1372 if (
Call->getArg(NumArgs - 1)->getType()->isNothrowT())
1376 Args = Args.drop_front();
1379 for (
const Expr *Arg : Args)
1385 assert(!ElemSize.
isZero());
1388 APInt NumElems, Remainder;
1390 APInt::udivrem(
Bytes, ElemSizeAP, NumElems, Remainder);
1391 if (Remainder != 0) {
1393 S.
FFDiag(
Call, diag::note_constexpr_operator_new_bad_size)
1399 if (NumElems.getActiveBits() >
1404 S.
FFDiag(Loc, diag::note_constexpr_new_too_large)
1405 << NumElems.getZExtValue();
1412 bool IsArray = NumElems.ugt(1);
1417 Allocator.
allocate(NewCall, *ElemT, NumElems.getZExtValue(),
1454 const Expr *Source =
nullptr;
1455 const Block *BlockToDelete =
nullptr;
1473 S.
CCEDiag(
Call, diag::note_constexpr_deallocate_null);
1478 BlockToDelete = Ptr.
block();
1481 S.
FFDiag(
Call, diag::note_constexpr_delete_not_heap_alloc)
1484 S.
Note(D->getLocation(), diag::note_declared_at);
1487 assert(BlockToDelete);
1491 std::optional<DynamicAllocator::Form> AllocForm =
1494 if (!Allocator.
deallocate(Source, BlockToDelete, S)) {
1497 S.
FFDiag(Loc, diag::note_constexpr_double_delete);
1520 assert(
Call->getType() == ElemType);
1526 unsigned BitWidth =
Result.bitWidth();
1527 for (
unsigned I = 1; I != NumElems; ++I) {
1531 if (ID == Builtin::BI__builtin_reduce_add) {
1533 unsigned OverflowBits = BitWidth + 1;
1535 (PrevResult.toAPSInt(OverflowBits) +
1536 Elem.toAPSInt(OverflowBits)));
1539 }
else if (ID == Builtin::BI__builtin_reduce_mul) {
1541 unsigned OverflowBits = BitWidth * 2;
1543 (PrevResult.toAPSInt(OverflowBits) *
1544 Elem.toAPSInt(OverflowBits)));
1548 }
else if (ID == Builtin::BI__builtin_reduce_and) {
1550 }
else if (ID == Builtin::BI__builtin_reduce_or) {
1552 }
else if (ID == Builtin::BI__builtin_reduce_xor) {
1554 }
else if (ID == Builtin::BI__builtin_reduce_min) {
1557 }
else if (ID == Builtin::BI__builtin_reduce_max) {
1561 llvm_unreachable(
"Unhandled vector reduce builtin");
1573 unsigned BuiltinID) {
1574 assert(
Call->getNumArgs() == 1);
1590 assert(
Call->getArg(0)->getType()->isVectorType());
1602 for (
unsigned I = 0; I != NumElems; ++I) {
1605 Dst.
elem<
T>(I) = T::from(
static_cast<T>(
1623 unsigned BuiltinID) {
1624 assert(
Call->getNumArgs() == 1);
1625 if (
Call->getArg(0)->getType()->isIntegerType()) {
1628 if (BuiltinID == Builtin::BI__builtin_elementwise_popcount) {
1636 assert(
Call->getArg(0)->getType()->isVectorType());
1649 for (
unsigned I = 0; I != NumElems; ++I) {
1651 if (BuiltinID == Builtin::BI__builtin_elementwise_popcount) {
1652 Dst.
elem<
T>(I) = T::from(Arg.
elem<
T>(I).toAPSInt().popcount());
1655 T::from(Arg.
elem<
T>(I).toAPSInt().reverseBits().getZExtValue());
1669 unsigned BuiltinID) {
1670 const bool HasZeroArg =
Call->getNumArgs() == 2;
1671 const bool IsCTTZ = BuiltinID == Builtin::BI__builtin_elementwise_ctzg;
1672 assert(
Call->getNumArgs() == 1 || HasZeroArg);
1673 if (
Call->getArg(0)->getType()->isIntegerType()) {
1676 std::optional<APSInt> ZeroVal;
1690 diag::note_constexpr_countzeroes_zero)
1695 if (BuiltinID == Builtin::BI__builtin_elementwise_clzg) {
1706 assert(
Call->getArg(1)->getType()->isVectorType() &&
1708 Call->getArg(1)->getType()));
1713 assert(
Call->getArg(0)->getType()->isVectorType());
1726 for (
unsigned I = 0; I != NumElems; ++I) {
1729 if (EltVal.isZero()) {
1736 diag::note_constexpr_countzeroes_zero)
1740 }
else if (IsCTTZ) {
1741 Dst.
atIndex(I).
deref<
T>() = T::from(EltVal.countTrailingZeros());
1743 Dst.
atIndex(I).
deref<
T>() = T::from(EltVal.countLeadingZeros());
1755 assert(
Call->getNumArgs() == 3);
1761 assert(!Size.isSigned() &&
"memcpy and friends take an unsigned size");
1763 if (ID == Builtin::BImemcpy || ID == Builtin::BImemmove)
1767 (ID == Builtin::BI__builtin_memmove || ID == Builtin::BImemmove ||
1768 ID == Builtin::BI__builtin_wmemmove || ID == Builtin::BIwmemmove);
1769 bool WChar = ID == Builtin::BIwmemcpy || ID == Builtin::BIwmemmove ||
1770 ID == Builtin::BI__builtin_wmemcpy ||
1771 ID == Builtin::BI__builtin_wmemmove;
1774 if (Size.isZero()) {
1779 if (SrcPtr.
isZero() || DestPtr.isZero()) {
1782 << Move << WChar << !SrcPtr.
isZero()
1789 std::string DiagVal =
"(void *)";
1792 : std::to_string(DestPtr.getIntegerRepresentation());
1794 << Move << WChar << DestPtr.isIntegralPointer() << DiagVal;
1799 if (DestPtr.isDummy() || SrcPtr.
isDummy())
1802 if (DestPtr.getType()->isIncompleteType()) {
1804 diag::note_constexpr_memcpy_incomplete_type)
1805 << Move << DestPtr.getType();
1810 diag::note_constexpr_memcpy_incomplete_type)
1818 diag::note_constexpr_memcpy_incomplete_type)
1819 << Move << DestElemType;
1823 size_t RemainingDestElems;
1824 if (DestPtr.getFieldDesc()->isArray()) {
1825 RemainingDestElems = DestPtr.isUnknownSizeArray()
1827 : (DestPtr.getNumElems() - DestPtr.getIndex());
1829 RemainingDestElems = 1;
1834 uint64_t WCharSize =
1836 Size *=
APSInt(
APInt(Size.getBitWidth(), WCharSize,
false),
1840 if (Size.urem(DestElemSize) != 0) {
1842 diag::note_constexpr_memcpy_unsupported)
1843 << Move << WChar << 0 << DestElemType << Size << DestElemSize;
1848 size_t RemainingSrcElems;
1854 RemainingSrcElems = 1;
1860 << Move << SrcElemType << DestElemType;
1866 << Move << DestElemType;
1871 size_t RemainingDestBytes = RemainingDestElems * DestElemSize;
1872 size_t RemainingSrcBytes = RemainingSrcElems * SrcElemSize;
1873 if (Size.ugt(RemainingDestBytes) || Size.ugt(RemainingSrcBytes)) {
1874 APInt N = Size.udiv(DestElemSize);
1876 diag::note_constexpr_memcpy_unsupported)
1877 << Move << WChar << (Size.ugt(RemainingSrcBytes) ? 1 : 2)
1878 << DestElemType <<
toString(N, 10,
false);
1895 unsigned N = Size.getZExtValue();
1897 if ((SrcIndex <= DstIndex && (SrcIndex + N) > DstIndex) ||
1898 (DstIndex <= SrcIndex && (DstIndex + N) > SrcIndex)) {
1905 assert(Size.getZExtValue() % DestElemSize == 0);
1916 return T->isCharType() ||
T->isChar8Type();
1922 assert(
Call->getNumArgs() == 3);
1927 if (ID == Builtin::BImemcmp || ID == Builtin::BIbcmp ||
1928 ID == Builtin::BIwmemcmp)
1931 if (Size.isZero()) {
1937 (ID == Builtin::BIwmemcmp || ID == Builtin::BI__builtin_wmemcmp);
1947 diag::note_constexpr_memcmp_unsupported)
1953 if (PtrA.isDummy() || PtrB.
isDummy())
1976 unsigned ElemSize = 1;
1981 size_t ByteSize = Size.getZExtValue() * ElemSize;
1982 size_t CmpSize = std::min(MinBufferSize, ByteSize);
1984 for (
size_t I = 0; I != CmpSize; I += ElemSize) {
1987 T A = *reinterpret_cast<T *>(BufferA.Data.get() + I);
1988 T B = *reinterpret_cast<T *>(BufferB.Data.get() + I);
1990 pushInteger(S, -1, Call->getType());
1999 std::byte A = BufferA.
Data[I];
2000 std::byte B = BufferB.
Data[I];
2015 if (ByteSize <= CmpSize) {
2024 S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_access_past_end)
2025 <<
AK_Read << S.Current->getRange(OpPC);
2033 if (ID == Builtin::BImemchr || ID == Builtin::BIwcschr ||
2034 ID == Builtin::BIstrchr || ID == Builtin::BIwmemchr)
2037 std::optional<APSInt> MaxLength;
2038 if (
Call->getNumArgs() == 3)
2044 if (MaxLength && MaxLength->isZero()) {
2052 diag::note_constexpr_ltor_incomplete_type)
2067 bool IsRawByte = ID == Builtin::BImemchr || ID == Builtin::BI__builtin_memchr;
2072 diag::note_constexpr_memchr_unsupported)
2077 if (ID == Builtin::BIstrchr || ID == Builtin::BI__builtin_strchr) {
2087 uint64_t DesiredVal;
2088 if (ID == Builtin::BIwmemchr || ID == Builtin::BI__builtin_wmemchr ||
2089 ID == Builtin::BIwcschr || ID == Builtin::BI__builtin_wcschr) {
2091 DesiredVal = Desired.getZExtValue();
2097 (ID == Builtin::BIstrchr || ID == Builtin::BI__builtin_strchr ||
2098 ID == Builtin::BIwcschr || ID == Builtin::BI__builtin_wcschr);
2107 (Index + Step) > 0 ? Ptr.
atIndex(Index + Step) : Ptr;
2114 ElemT, {
V =
static_cast<uint64_t
>(ElemPtr.
deref<
T>().toUnsigned()); });
2116 if (
V == DesiredVal) {
2121 if (StopAtZero &&
V == 0)
2125 if (MaxLength && Step == MaxLength->getZExtValue())
2149 return std::nullopt;
2187 uint64_t FieldOffset =
2193 llvm_unreachable(
"Unhandled descriptor type");
2229 auto isFlexibleArrayMember = [&](
const Descriptor *FieldDesc) {
2231 FAMKind StrictFlexArraysLevel =
2234 if (StrictFlexArraysLevel == FAMKind::Default)
2237 unsigned NumElems = FieldDesc->getNumElems();
2238 if (NumElems == 0 && StrictFlexArraysLevel != FAMKind::IncompleteOnly)
2241 if (NumElems == 1 && StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete)
2251 isFlexibleArrayMember(FieldDesc);
2264 assert(Kind <= 3 &&
"unexpected kind");
2265 bool UseFieldDesc = (Kind & 1u);
2266 bool ReportMinimum = (Kind & 2u);
2269 if (
Call->getArg(0)->HasSideEffects(ASTCtx)) {
2287 if (!UseFieldDesc || DetermineForCompleteObject) {
2289 if (ReportMinimum && !DetermineForCompleteObject)
2312 unsigned ByteOffset;
2328 assert(ByteOffset <= *FullSize);
2329 unsigned Result = *FullSize - ByteOffset;
2344 bool CalledFromStd =
false;
2346 if (Callee && Callee->isInStdNamespace()) {
2348 CalledFromStd = Identifier && Identifier->
isStr(
"is_within_lifetime");
2353 diag::err_invalid_is_within_lifetime)
2354 << (CalledFromStd ?
"std::is_within_lifetime"
2355 :
"__builtin_is_within_lifetime")
2390 assert(
Call->getNumArgs() == 1);
2391 assert(
Call->getType()->isIntegerType());
2394 if (!
Call->getArg(0)->getType()->isVectorType()) {
2408 assert(
Call->getNumArgs() == 2);
2411 if (!
Call->getArg(0)->getType()->isVectorType()) {
2412 assert(!
Call->getArg(1)->getType()->isVectorType());
2420 const auto *VT =
Call->getArg(0)->getType()->castAs<
VectorType>();
2421 assert(VT->getElementType()->isIntegralOrEnumerationType());
2423 unsigned NumElems = VT->getNumElements();
2424 bool DestUnsigned =
Call->getType()->isUnsignedIntegerOrEnumerationType();
2427 if (!
Call->getArg(1)->getType()->isVectorType()) {
2428 assert(
Call->getArg(1)->getType()->isIntegralOrEnumerationType());
2434 for (
unsigned I = 0; I != NumElems; ++I) {
2436 Dst.elem<
T>(I) =
static_cast<T>(
2445 assert(
Call->getArg(0)->getType()->isVectorType() &&
2446 Call->getArg(1)->getType()->isVectorType());
2447 assert(VT->getElementType() ==
2449 assert(VT->getNumElements() ==
2451 assert(VT->getElementType()->isIntegralOrEnumerationType());
2456 for (
unsigned I = 0; I != NumElems; ++I) {
2458 APSInt Elem1 = LHS.elem<
T>(I).toAPSInt();
2460 Dst.elem<
T>(I) =
static_cast<T>(
APSInt(
Fn(Elem1, Elem2), DestUnsigned));
2470 llvm::function_ref<
APInt(
const APSInt &)> PackFn) {
2472 [[maybe_unused]]
const auto *VT1 =
2474 assert(VT0 && VT1 &&
"pack builtin VT0 and VT1 must be VectorType");
2477 "pack builtin VT0 and VT1 ElementType must be same");
2484 const unsigned SrcBits = ASTCtx.
getIntWidth(VT0->getElementType());
2485 const unsigned LHSVecLen = VT0->getNumElements();
2486 const unsigned SrcPerLane = 128 / SrcBits;
2487 const unsigned Lanes = LHSVecLen * SrcBits / 128;
2491 const bool IsUnsigend =
getElemType(Dst)->isUnsignedIntegerType();
2493 for (
unsigned Lane = 0; Lane != Lanes; ++Lane) {
2494 const unsigned BaseSrc = Lane * SrcPerLane;
2495 const unsigned BaseDst = Lane * (2 * SrcPerLane);
2497 for (
unsigned I = 0; I != SrcPerLane; ++I) {
2499 APSInt A = LHS.elem<
T>(BaseSrc + I).toAPSInt();
2503 APSInt(PackFn(A), IsUnsigend));
2504 assignInteger(S, Dst.atIndex(BaseDst + SrcPerLane + I), DstT,
2505 APSInt(PackFn(B), IsUnsigend));
2510 Dst.initializeAllElements();
2516 unsigned BuiltinID) {
2517 assert(
Call->getNumArgs() == 2);
2528 assert(!
Call->getArg(1)->getType()->isVectorType());
2532 if (BuiltinID == Builtin::BI__builtin_elementwise_max) {
2533 Result = std::max(LHS, RHS);
2534 }
else if (BuiltinID == Builtin::BI__builtin_elementwise_min) {
2535 Result = std::min(LHS, RHS);
2537 llvm_unreachable(
"Wrong builtin ID");
2545 assert(
Call->getArg(0)->getType()->isVectorType() &&
2546 Call->getArg(1)->getType()->isVectorType());
2547 const auto *VT =
Call->getArg(0)->getType()->castAs<
VectorType>();
2548 assert(VT->getElementType() ==
2550 assert(VT->getNumElements() ==
2552 assert(VT->getElementType()->isIntegralOrEnumerationType());
2558 unsigned NumElems = VT->getNumElements();
2559 for (
unsigned I = 0; I != NumElems; ++I) {
2563 Elem1 = LHS.elem<
T>(I).toAPSInt();
2564 Elem2 = RHS.
elem<
T>(I).toAPSInt();
2568 if (BuiltinID == Builtin::BI__builtin_elementwise_max) {
2570 Call->getType()->isUnsignedIntegerOrEnumerationType());
2571 }
else if (BuiltinID == Builtin::BI__builtin_elementwise_min) {
2573 Call->getType()->isUnsignedIntegerOrEnumerationType());
2575 llvm_unreachable(
"Wrong builtin ID");
2579 { Dst.elem<
T>(I) =
static_cast<T>(
Result); });
2581 Dst.initializeAllElements();
2588 unsigned BuiltinID) {
2589 assert(
Call->getArg(0)->getType()->isVectorType() &&
2590 Call->getArg(1)->getType()->isVectorType());
2595 const auto *VT =
Call->getArg(0)->getType()->castAs<
VectorType>();
2597 unsigned SourceLen = VT->getNumElements();
2601 unsigned DstElem = 0;
2602 for (
unsigned I = 0; I != SourceLen; I += 2) {
2606 Elem1 = LHS.elem<
T>(I).toAPSInt();
2607 Elem2 = RHS.
elem<
T>(I).toAPSInt();
2611 switch (BuiltinID) {
2612 case clang::X86::BI__builtin_ia32_pmuludq128:
2613 case clang::X86::BI__builtin_ia32_pmuludq256:
2614 case clang::X86::BI__builtin_ia32_pmuludq512:
2615 Result =
APSInt(llvm::APIntOps::muluExtended(Elem1, Elem2),
2618 case clang::X86::BI__builtin_ia32_pmuldq128:
2619 case clang::X86::BI__builtin_ia32_pmuldq256:
2620 case clang::X86::BI__builtin_ia32_pmuldq512:
2621 Result =
APSInt(llvm::APIntOps::mulsExtended(Elem1, Elem2),
2626 { Dst.elem<
T>(DstElem) =
static_cast<T>(
Result); });
2630 Dst.initializeAllElements();
2637 const APFloat &, llvm::RoundingMode)>
2639 assert(
Call->getNumArgs() == 3);
2676 assert(ElemT->isRealFloatingType());
2683 for (
unsigned I = 0; I != NumElems; ++I) {
2686 APFloat Y = VY.elem<
T>(I).getAPFloat();
2705 unsigned NumElems = LHS.getNumElems();
2706 PrimType ElemT = LHS.getFieldDesc()->getPrimType();
2709 for (
unsigned I = 0; I != NumElems; ++I) {
2717 Elem = Mask[I] ? LHS.elem<
T>(I).toAPSInt() : RHS.
elem<
T>(I).toAPSInt();
2720 { Dst.
elem<
T>(I) =
static_cast<T>(Elem); });
2735 assert(FalseVec.getNumElems() == TrueVec.
getNumElems());
2736 assert(FalseVec.getNumElems() == Dst.getNumElems());
2737 unsigned NumElems = FalseVec.getNumElems();
2738 PrimType ElemT = FalseVec.getFieldDesc()->getPrimType();
2739 PrimType DstElemT = Dst.getFieldDesc()->getPrimType();
2741 for (
unsigned I = 0; I != NumElems; ++I) {
2742 bool MaskBit = Mask[I % 8];
2748 assert(DstElemT == ElemT);
2751 static_cast<T>(MaskBit ? TrueVec.
elem<
T>(I).toAPSInt()
2752 : FalseVec.elem<
T>(I).toAPSInt());
2756 Dst.initializeAllElements();
2763 assert(
Call->getNumArgs() == 2 &&
"masked forms handled via select*");
2769 PrimType ElemT = Dst.getFieldDesc()->getPrimType();
2771 unsigned ElemBits =
static_cast<unsigned>(
primSize(ElemT) * 8);
2772 if (ElemBits != 16 && ElemBits != 32)
2775 unsigned LaneElts = 128u / ElemBits;
2776 assert(LaneElts && (NumElems % LaneElts == 0));
2778 uint8_t Ctl =
static_cast<uint8_t
>(ControlImm.getZExtValue());
2780 for (
unsigned Idx = 0; Idx != NumElems; Idx++) {
2781 unsigned LaneBase = (Idx / LaneElts) * LaneElts;
2782 unsigned LaneIdx = Idx % LaneElts;
2783 unsigned SrcIdx = Idx;
2784 unsigned Sel = (Ctl >> (2 * (LaneIdx & 0x3))) & 0x3;
2785 if (ElemBits == 32) {
2786 SrcIdx = LaneBase + Sel;
2788 constexpr unsigned HalfSize = 4;
2789 bool InHigh = LaneIdx >= HalfSize;
2790 if (!IsShufHW && !InHigh) {
2791 SrcIdx = LaneBase + Sel;
2792 }
else if (IsShufHW && InHigh) {
2793 SrcIdx = LaneBase + HalfSize + Sel;
2799 Dst.initializeAllElements();
2807 assert(
Call->getNumArgs() == 3);
2823 unsigned NumElems = VecT->getNumElements();
2824 bool DestUnsigned =
Call->getType()->isUnsignedIntegerOrEnumerationType();
2833 for (
unsigned I = 0; I != NumElems; ++I) {
2835 Dst.elem<
T>(I) =
static_cast<T>(
APSInt(
2836 Fn(Op0.elem<
T>(I).toAPSInt(), Op1.
elem<
T>(I).toAPSInt(), Op2),
2850 for (
unsigned I = 0; I != NumElems; ++I) {
2853 Val0 = Op0.elem<
T>(I).toAPSInt();
2854 Val1 = Op1.elem<
T>(I).toAPSInt();
2855 Val2 = Op2.
elem<
T>(I).toAPSInt();
2859 { Dst.elem<
T>(I) =
static_cast<T>(
Result); });
2869 assert(
Call->getNumArgs() == 3);
2872 uint64_t Index = ImmAPS.getZExtValue();
2887 assert(SubElements != 0 && BaseElements != 0 &&
2888 (BaseElements % SubElements) == 0);
2890 unsigned NumLanes = BaseElements / SubElements;
2891 unsigned Lane =
static_cast<unsigned>(Index % NumLanes);
2892 unsigned InsertPos = Lane * SubElements;
2897 for (
unsigned I = 0; I != BaseElements; ++I)
2899 for (
unsigned I = 0; I != SubElements; ++I)
2900 Dst.
elem<
T>(InsertPos + I) = SubVec.
elem<
T>(I);
2909 assert(
Call->getNumArgs() == 5);
2925 for (
unsigned I = 0; I != DstLen; ++I) {
2926 APInt ALane = A.elem<
T>(I).toAPSInt();
2927 APInt BLane = B.elem<
T>(I).toAPSInt();
2928 APInt CLane =
C.elem<
T>(I).toAPSInt();
2929 APInt RLane(LaneWidth, 0);
2931 for (
unsigned Bit = 0; Bit != LaneWidth; ++Bit) {
2932 unsigned ABit = ALane[Bit];
2933 unsigned BBit = BLane[Bit];
2934 unsigned CBit = CLane[Bit];
2935 unsigned Idx = (ABit << 2) | (BBit << 1) | (CBit);
2936 RLane.setBitVal(Bit, Imm[Idx]);
2938 Dst.elem<
T>(I) =
static_cast<T>(
APSInt(RLane, DstUnsigned));
2940 Dst.elem<
T>(I) =
static_cast<T>(
APSInt(RLane, DstUnsigned));
2942 Dst.elem<
T>(I) =
static_cast<T>(
APSInt(ALane, DstUnsigned));
2946 Dst.initializeAllElements();
2952 assert(
Call->getNumArgs() == 2);
2961 static_cast<unsigned>(ImmAPS.getZExtValue() & (NumElems - 1));
2979 assert(
Call->getNumArgs() == 3);
2985 if (!
Base.getFieldDesc()->isPrimitiveArray())
2990 unsigned NumElems =
Base.getNumElems();
2992 static_cast<unsigned>(ImmAPS.getZExtValue() & (NumElems - 1));
2996 for (
unsigned I = 0; I != NumElems; ++I)
2998 Dst.
elem<
T>(Index) =
static_cast<T>(ValAPS);
3006 uint32_t BuiltinID) {
3011 switch (BuiltinID) {
3012 case Builtin::BI__builtin_is_constant_evaluated:
3015 case Builtin::BI__builtin_assume:
3016 case Builtin::BI__assume:
3019 case Builtin::BI__builtin_strcmp:
3020 case Builtin::BIstrcmp:
3021 case Builtin::BI__builtin_strncmp:
3022 case Builtin::BIstrncmp:
3023 case Builtin::BI__builtin_wcsncmp:
3024 case Builtin::BIwcsncmp:
3025 case Builtin::BI__builtin_wcscmp:
3026 case Builtin::BIwcscmp:
3029 case Builtin::BI__builtin_strlen:
3030 case Builtin::BIstrlen:
3031 case Builtin::BI__builtin_wcslen:
3032 case Builtin::BIwcslen:
3035 case Builtin::BI__builtin_nan:
3036 case Builtin::BI__builtin_nanf:
3037 case Builtin::BI__builtin_nanl:
3038 case Builtin::BI__builtin_nanf16:
3039 case Builtin::BI__builtin_nanf128:
3042 case Builtin::BI__builtin_nans:
3043 case Builtin::BI__builtin_nansf:
3044 case Builtin::BI__builtin_nansl:
3045 case Builtin::BI__builtin_nansf16:
3046 case Builtin::BI__builtin_nansf128:
3049 case Builtin::BI__builtin_huge_val:
3050 case Builtin::BI__builtin_huge_valf:
3051 case Builtin::BI__builtin_huge_vall:
3052 case Builtin::BI__builtin_huge_valf16:
3053 case Builtin::BI__builtin_huge_valf128:
3054 case Builtin::BI__builtin_inf:
3055 case Builtin::BI__builtin_inff:
3056 case Builtin::BI__builtin_infl:
3057 case Builtin::BI__builtin_inff16:
3058 case Builtin::BI__builtin_inff128:
3061 case Builtin::BI__builtin_copysign:
3062 case Builtin::BI__builtin_copysignf:
3063 case Builtin::BI__builtin_copysignl:
3064 case Builtin::BI__builtin_copysignf128:
3067 case Builtin::BI__builtin_fmin:
3068 case Builtin::BI__builtin_fminf:
3069 case Builtin::BI__builtin_fminl:
3070 case Builtin::BI__builtin_fminf16:
3071 case Builtin::BI__builtin_fminf128:
3074 case Builtin::BI__builtin_fminimum_num:
3075 case Builtin::BI__builtin_fminimum_numf:
3076 case Builtin::BI__builtin_fminimum_numl:
3077 case Builtin::BI__builtin_fminimum_numf16:
3078 case Builtin::BI__builtin_fminimum_numf128:
3081 case Builtin::BI__builtin_fmax:
3082 case Builtin::BI__builtin_fmaxf:
3083 case Builtin::BI__builtin_fmaxl:
3084 case Builtin::BI__builtin_fmaxf16:
3085 case Builtin::BI__builtin_fmaxf128:
3088 case Builtin::BI__builtin_fmaximum_num:
3089 case Builtin::BI__builtin_fmaximum_numf:
3090 case Builtin::BI__builtin_fmaximum_numl:
3091 case Builtin::BI__builtin_fmaximum_numf16:
3092 case Builtin::BI__builtin_fmaximum_numf128:
3095 case Builtin::BI__builtin_isnan:
3098 case Builtin::BI__builtin_issignaling:
3101 case Builtin::BI__builtin_isinf:
3104 case Builtin::BI__builtin_isinf_sign:
3107 case Builtin::BI__builtin_isfinite:
3110 case Builtin::BI__builtin_isnormal:
3113 case Builtin::BI__builtin_issubnormal:
3116 case Builtin::BI__builtin_iszero:
3119 case Builtin::BI__builtin_signbit:
3120 case Builtin::BI__builtin_signbitf:
3121 case Builtin::BI__builtin_signbitl:
3124 case Builtin::BI__builtin_isgreater:
3125 case Builtin::BI__builtin_isgreaterequal:
3126 case Builtin::BI__builtin_isless:
3127 case Builtin::BI__builtin_islessequal:
3128 case Builtin::BI__builtin_islessgreater:
3129 case Builtin::BI__builtin_isunordered:
3132 case Builtin::BI__builtin_isfpclass:
3135 case Builtin::BI__builtin_fpclassify:
3138 case Builtin::BI__builtin_fabs:
3139 case Builtin::BI__builtin_fabsf:
3140 case Builtin::BI__builtin_fabsl:
3141 case Builtin::BI__builtin_fabsf128:
3144 case Builtin::BI__builtin_abs:
3145 case Builtin::BI__builtin_labs:
3146 case Builtin::BI__builtin_llabs:
3149 case Builtin::BI__builtin_popcount:
3150 case Builtin::BI__builtin_popcountl:
3151 case Builtin::BI__builtin_popcountll:
3152 case Builtin::BI__builtin_popcountg:
3153 case Builtin::BI__popcnt16:
3154 case Builtin::BI__popcnt:
3155 case Builtin::BI__popcnt64:
3158 case Builtin::BI__builtin_parity:
3159 case Builtin::BI__builtin_parityl:
3160 case Builtin::BI__builtin_parityll:
3163 case Builtin::BI__builtin_clrsb:
3164 case Builtin::BI__builtin_clrsbl:
3165 case Builtin::BI__builtin_clrsbll:
3168 case Builtin::BI__builtin_bitreverse8:
3169 case Builtin::BI__builtin_bitreverse16:
3170 case Builtin::BI__builtin_bitreverse32:
3171 case Builtin::BI__builtin_bitreverse64:
3174 case Builtin::BI__builtin_classify_type:
3177 case Builtin::BI__builtin_expect:
3178 case Builtin::BI__builtin_expect_with_probability:
3181 case Builtin::BI__builtin_rotateleft8:
3182 case Builtin::BI__builtin_rotateleft16:
3183 case Builtin::BI__builtin_rotateleft32:
3184 case Builtin::BI__builtin_rotateleft64:
3185 case Builtin::BI_rotl8:
3186 case Builtin::BI_rotl16:
3187 case Builtin::BI_rotl:
3188 case Builtin::BI_lrotl:
3189 case Builtin::BI_rotl64:
3192 return Value.rotl(Amount);
3195 case Builtin::BI__builtin_rotateright8:
3196 case Builtin::BI__builtin_rotateright16:
3197 case Builtin::BI__builtin_rotateright32:
3198 case Builtin::BI__builtin_rotateright64:
3199 case Builtin::BI_rotr8:
3200 case Builtin::BI_rotr16:
3201 case Builtin::BI_rotr:
3202 case Builtin::BI_lrotr:
3203 case Builtin::BI_rotr64:
3206 return Value.rotr(Amount);
3209 case Builtin::BI__builtin_ffs:
3210 case Builtin::BI__builtin_ffsl:
3211 case Builtin::BI__builtin_ffsll:
3214 case Builtin::BIaddressof:
3215 case Builtin::BI__addressof:
3216 case Builtin::BI__builtin_addressof:
3220 case Builtin::BIas_const:
3221 case Builtin::BIforward:
3222 case Builtin::BIforward_like:
3223 case Builtin::BImove:
3224 case Builtin::BImove_if_noexcept:
3228 case Builtin::BI__builtin_eh_return_data_regno:
3231 case Builtin::BI__builtin_launder:
3235 case Builtin::BI__builtin_add_overflow:
3236 case Builtin::BI__builtin_sub_overflow:
3237 case Builtin::BI__builtin_mul_overflow:
3238 case Builtin::BI__builtin_sadd_overflow:
3239 case Builtin::BI__builtin_uadd_overflow:
3240 case Builtin::BI__builtin_uaddl_overflow:
3241 case Builtin::BI__builtin_uaddll_overflow:
3242 case Builtin::BI__builtin_usub_overflow:
3243 case Builtin::BI__builtin_usubl_overflow:
3244 case Builtin::BI__builtin_usubll_overflow:
3245 case Builtin::BI__builtin_umul_overflow:
3246 case Builtin::BI__builtin_umull_overflow:
3247 case Builtin::BI__builtin_umulll_overflow:
3248 case Builtin::BI__builtin_saddl_overflow:
3249 case Builtin::BI__builtin_saddll_overflow:
3250 case Builtin::BI__builtin_ssub_overflow:
3251 case Builtin::BI__builtin_ssubl_overflow:
3252 case Builtin::BI__builtin_ssubll_overflow:
3253 case Builtin::BI__builtin_smul_overflow:
3254 case Builtin::BI__builtin_smull_overflow:
3255 case Builtin::BI__builtin_smulll_overflow:
3258 case Builtin::BI__builtin_addcb:
3259 case Builtin::BI__builtin_addcs:
3260 case Builtin::BI__builtin_addc:
3261 case Builtin::BI__builtin_addcl:
3262 case Builtin::BI__builtin_addcll:
3263 case Builtin::BI__builtin_subcb:
3264 case Builtin::BI__builtin_subcs:
3265 case Builtin::BI__builtin_subc:
3266 case Builtin::BI__builtin_subcl:
3267 case Builtin::BI__builtin_subcll:
3270 case Builtin::BI__builtin_clz:
3271 case Builtin::BI__builtin_clzl:
3272 case Builtin::BI__builtin_clzll:
3273 case Builtin::BI__builtin_clzs:
3274 case Builtin::BI__builtin_clzg:
3275 case Builtin::BI__lzcnt16:
3276 case Builtin::BI__lzcnt:
3277 case Builtin::BI__lzcnt64:
3280 case Builtin::BI__builtin_ctz:
3281 case Builtin::BI__builtin_ctzl:
3282 case Builtin::BI__builtin_ctzll:
3283 case Builtin::BI__builtin_ctzs:
3284 case Builtin::BI__builtin_ctzg:
3287 case Builtin::BI__builtin_elementwise_clzg:
3288 case Builtin::BI__builtin_elementwise_ctzg:
3292 case Builtin::BI__builtin_bswap16:
3293 case Builtin::BI__builtin_bswap32:
3294 case Builtin::BI__builtin_bswap64:
3297 case Builtin::BI__atomic_always_lock_free:
3298 case Builtin::BI__atomic_is_lock_free:
3301 case Builtin::BI__c11_atomic_is_lock_free:
3304 case Builtin::BI__builtin_complex:
3307 case Builtin::BI__builtin_is_aligned:
3308 case Builtin::BI__builtin_align_up:
3309 case Builtin::BI__builtin_align_down:
3312 case Builtin::BI__builtin_assume_aligned:
3315 case clang::X86::BI__builtin_ia32_bextr_u32:
3316 case clang::X86::BI__builtin_ia32_bextr_u64:
3317 case clang::X86::BI__builtin_ia32_bextri_u32:
3318 case clang::X86::BI__builtin_ia32_bextri_u64:
3321 unsigned BitWidth = Val.getBitWidth();
3322 uint64_t Shift = Idx.extractBitsAsZExtValue(8, 0);
3323 uint64_t Length = Idx.extractBitsAsZExtValue(8, 8);
3324 if (Length > BitWidth) {
3329 if (Length == 0 || Shift >= BitWidth)
3330 return APInt(BitWidth, 0);
3332 uint64_t
Result = Val.getZExtValue() >> Shift;
3333 Result &= llvm::maskTrailingOnes<uint64_t>(Length);
3337 case clang::X86::BI__builtin_ia32_bzhi_si:
3338 case clang::X86::BI__builtin_ia32_bzhi_di:
3341 unsigned BitWidth = Val.getBitWidth();
3342 uint64_t Index = Idx.extractBitsAsZExtValue(8, 0);
3345 if (Index < BitWidth)
3346 Result.clearHighBits(BitWidth - Index);
3351 case clang::X86::BI__builtin_ia32_lzcnt_u16:
3352 case clang::X86::BI__builtin_ia32_lzcnt_u32:
3353 case clang::X86::BI__builtin_ia32_lzcnt_u64:
3356 return APInt(Src.getBitWidth(), Src.countLeadingZeros());
3359 case clang::X86::BI__builtin_ia32_tzcnt_u16:
3360 case clang::X86::BI__builtin_ia32_tzcnt_u32:
3361 case clang::X86::BI__builtin_ia32_tzcnt_u64:
3364 return APInt(Src.getBitWidth(), Src.countTrailingZeros());
3367 case clang::X86::BI__builtin_ia32_pdep_si:
3368 case clang::X86::BI__builtin_ia32_pdep_di:
3371 unsigned BitWidth = Val.getBitWidth();
3374 for (
unsigned I = 0, P = 0; I != BitWidth; ++I) {
3376 Result.setBitVal(I, Val[P++]);
3382 case clang::X86::BI__builtin_ia32_pext_si:
3383 case clang::X86::BI__builtin_ia32_pext_di:
3386 unsigned BitWidth = Val.getBitWidth();
3389 for (
unsigned I = 0, P = 0; I != BitWidth; ++I) {
3391 Result.setBitVal(P++, Val[I]);
3397 case clang::X86::BI__builtin_ia32_addcarryx_u32:
3398 case clang::X86::BI__builtin_ia32_addcarryx_u64:
3399 case clang::X86::BI__builtin_ia32_subborrow_u32:
3400 case clang::X86::BI__builtin_ia32_subborrow_u64:
3404 case Builtin::BI__builtin_os_log_format_buffer_size:
3407 case Builtin::BI__builtin_ptrauth_string_discriminator:
3410 case Builtin::BI__noop:
3414 case Builtin::BI__builtin_operator_new:
3417 case Builtin::BI__builtin_operator_delete:
3420 case Builtin::BI__arithmetic_fence:
3423 case Builtin::BI__builtin_reduce_add:
3424 case Builtin::BI__builtin_reduce_mul:
3425 case Builtin::BI__builtin_reduce_and:
3426 case Builtin::BI__builtin_reduce_or:
3427 case Builtin::BI__builtin_reduce_xor:
3428 case Builtin::BI__builtin_reduce_min:
3429 case Builtin::BI__builtin_reduce_max:
3432 case Builtin::BI__builtin_elementwise_popcount:
3433 case Builtin::BI__builtin_elementwise_bitreverse:
3437 case Builtin::BI__builtin_elementwise_abs:
3440 case Builtin::BI__builtin_memcpy:
3441 case Builtin::BImemcpy:
3442 case Builtin::BI__builtin_wmemcpy:
3443 case Builtin::BIwmemcpy:
3444 case Builtin::BI__builtin_memmove:
3445 case Builtin::BImemmove:
3446 case Builtin::BI__builtin_wmemmove:
3447 case Builtin::BIwmemmove:
3450 case Builtin::BI__builtin_memcmp:
3451 case Builtin::BImemcmp:
3452 case Builtin::BI__builtin_bcmp:
3453 case Builtin::BIbcmp:
3454 case Builtin::BI__builtin_wmemcmp:
3455 case Builtin::BIwmemcmp:
3458 case Builtin::BImemchr:
3459 case Builtin::BI__builtin_memchr:
3460 case Builtin::BIstrchr:
3461 case Builtin::BI__builtin_strchr:
3462 case Builtin::BIwmemchr:
3463 case Builtin::BI__builtin_wmemchr:
3464 case Builtin::BIwcschr:
3465 case Builtin::BI__builtin_wcschr:
3466 case Builtin::BI__builtin_char_memchr:
3469 case Builtin::BI__builtin_object_size:
3470 case Builtin::BI__builtin_dynamic_object_size:
3473 case Builtin::BI__builtin_is_within_lifetime:
3476 case Builtin::BI__builtin_elementwise_add_sat:
3479 return LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
3482 case Builtin::BI__builtin_elementwise_sub_sat:
3485 return LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
3488 case clang::X86::BI__builtin_ia32_pavgb128:
3489 case clang::X86::BI__builtin_ia32_pavgw128:
3490 case clang::X86::BI__builtin_ia32_pavgb256:
3491 case clang::X86::BI__builtin_ia32_pavgw256:
3492 case clang::X86::BI__builtin_ia32_pavgb512:
3493 case clang::X86::BI__builtin_ia32_pavgw512:
3495 llvm::APIntOps::avgCeilU);
3497 case clang::X86::BI__builtin_ia32_pmulhuw128:
3498 case clang::X86::BI__builtin_ia32_pmulhuw256:
3499 case clang::X86::BI__builtin_ia32_pmulhuw512:
3501 llvm::APIntOps::mulhu);
3503 case clang::X86::BI__builtin_ia32_pmulhw128:
3504 case clang::X86::BI__builtin_ia32_pmulhw256:
3505 case clang::X86::BI__builtin_ia32_pmulhw512:
3507 llvm::APIntOps::mulhs);
3509 case clang::X86::BI__builtin_ia32_psllv2di:
3510 case clang::X86::BI__builtin_ia32_psllv4di:
3511 case clang::X86::BI__builtin_ia32_psllv4si:
3512 case clang::X86::BI__builtin_ia32_psllv8di:
3513 case clang::X86::BI__builtin_ia32_psllv8hi:
3514 case clang::X86::BI__builtin_ia32_psllv8si:
3515 case clang::X86::BI__builtin_ia32_psllv16hi:
3516 case clang::X86::BI__builtin_ia32_psllv16si:
3517 case clang::X86::BI__builtin_ia32_psllv32hi:
3518 case clang::X86::BI__builtin_ia32_psllwi128:
3519 case clang::X86::BI__builtin_ia32_psllwi256:
3520 case clang::X86::BI__builtin_ia32_psllwi512:
3521 case clang::X86::BI__builtin_ia32_pslldi128:
3522 case clang::X86::BI__builtin_ia32_pslldi256:
3523 case clang::X86::BI__builtin_ia32_pslldi512:
3524 case clang::X86::BI__builtin_ia32_psllqi128:
3525 case clang::X86::BI__builtin_ia32_psllqi256:
3526 case clang::X86::BI__builtin_ia32_psllqi512:
3529 if (RHS.uge(LHS.getBitWidth())) {
3530 return APInt::getZero(LHS.getBitWidth());
3532 return LHS.shl(RHS.getZExtValue());
3535 case clang::X86::BI__builtin_ia32_psrav4si:
3536 case clang::X86::BI__builtin_ia32_psrav8di:
3537 case clang::X86::BI__builtin_ia32_psrav8hi:
3538 case clang::X86::BI__builtin_ia32_psrav8si:
3539 case clang::X86::BI__builtin_ia32_psrav16hi:
3540 case clang::X86::BI__builtin_ia32_psrav16si:
3541 case clang::X86::BI__builtin_ia32_psrav32hi:
3542 case clang::X86::BI__builtin_ia32_psravq128:
3543 case clang::X86::BI__builtin_ia32_psravq256:
3544 case clang::X86::BI__builtin_ia32_psrawi128:
3545 case clang::X86::BI__builtin_ia32_psrawi256:
3546 case clang::X86::BI__builtin_ia32_psrawi512:
3547 case clang::X86::BI__builtin_ia32_psradi128:
3548 case clang::X86::BI__builtin_ia32_psradi256:
3549 case clang::X86::BI__builtin_ia32_psradi512:
3550 case clang::X86::BI__builtin_ia32_psraqi128:
3551 case clang::X86::BI__builtin_ia32_psraqi256:
3552 case clang::X86::BI__builtin_ia32_psraqi512:
3555 if (RHS.uge(LHS.getBitWidth())) {
3556 return LHS.ashr(LHS.getBitWidth() - 1);
3558 return LHS.ashr(RHS.getZExtValue());
3561 case clang::X86::BI__builtin_ia32_psrlv2di:
3562 case clang::X86::BI__builtin_ia32_psrlv4di:
3563 case clang::X86::BI__builtin_ia32_psrlv4si:
3564 case clang::X86::BI__builtin_ia32_psrlv8di:
3565 case clang::X86::BI__builtin_ia32_psrlv8hi:
3566 case clang::X86::BI__builtin_ia32_psrlv8si:
3567 case clang::X86::BI__builtin_ia32_psrlv16hi:
3568 case clang::X86::BI__builtin_ia32_psrlv16si:
3569 case clang::X86::BI__builtin_ia32_psrlv32hi:
3570 case clang::X86::BI__builtin_ia32_psrlwi128:
3571 case clang::X86::BI__builtin_ia32_psrlwi256:
3572 case clang::X86::BI__builtin_ia32_psrlwi512:
3573 case clang::X86::BI__builtin_ia32_psrldi128:
3574 case clang::X86::BI__builtin_ia32_psrldi256:
3575 case clang::X86::BI__builtin_ia32_psrldi512:
3576 case clang::X86::BI__builtin_ia32_psrlqi128:
3577 case clang::X86::BI__builtin_ia32_psrlqi256:
3578 case clang::X86::BI__builtin_ia32_psrlqi512:
3581 if (RHS.uge(LHS.getBitWidth())) {
3582 return APInt::getZero(LHS.getBitWidth());
3584 return LHS.lshr(RHS.getZExtValue());
3586 case clang::X86::BI__builtin_ia32_packsswb128:
3587 case clang::X86::BI__builtin_ia32_packsswb256:
3588 case clang::X86::BI__builtin_ia32_packsswb512:
3589 case clang::X86::BI__builtin_ia32_packssdw128:
3590 case clang::X86::BI__builtin_ia32_packssdw256:
3591 case clang::X86::BI__builtin_ia32_packssdw512:
3593 return APInt(Src).truncSSat(Src.getBitWidth() / 2);
3595 case clang::X86::BI__builtin_ia32_packusdw128:
3596 case clang::X86::BI__builtin_ia32_packusdw256:
3597 case clang::X86::BI__builtin_ia32_packusdw512:
3598 case clang::X86::BI__builtin_ia32_packuswb128:
3599 case clang::X86::BI__builtin_ia32_packuswb256:
3600 case clang::X86::BI__builtin_ia32_packuswb512:
3602 unsigned DstBits = Src.getBitWidth() / 2;
3603 if (Src.isNegative())
3604 return APInt::getZero(DstBits);
3605 if (Src.isIntN(DstBits))
3606 return APInt(Src).trunc(DstBits);
3607 return APInt::getAllOnes(DstBits);
3610 case clang::X86::BI__builtin_ia32_vprotbi:
3611 case clang::X86::BI__builtin_ia32_vprotdi:
3612 case clang::X86::BI__builtin_ia32_vprotqi:
3613 case clang::X86::BI__builtin_ia32_vprotwi:
3614 case clang::X86::BI__builtin_ia32_prold128:
3615 case clang::X86::BI__builtin_ia32_prold256:
3616 case clang::X86::BI__builtin_ia32_prold512:
3617 case clang::X86::BI__builtin_ia32_prolq128:
3618 case clang::X86::BI__builtin_ia32_prolq256:
3619 case clang::X86::BI__builtin_ia32_prolq512:
3622 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS.rotl(RHS); });
3624 case clang::X86::BI__builtin_ia32_prord128:
3625 case clang::X86::BI__builtin_ia32_prord256:
3626 case clang::X86::BI__builtin_ia32_prord512:
3627 case clang::X86::BI__builtin_ia32_prorq128:
3628 case clang::X86::BI__builtin_ia32_prorq256:
3629 case clang::X86::BI__builtin_ia32_prorq512:
3632 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS.rotr(RHS); });
3634 case Builtin::BI__builtin_elementwise_max:
3635 case Builtin::BI__builtin_elementwise_min:
3638 case clang::X86::BI__builtin_ia32_pmuldq128:
3639 case clang::X86::BI__builtin_ia32_pmuldq256:
3640 case clang::X86::BI__builtin_ia32_pmuldq512:
3641 case clang::X86::BI__builtin_ia32_pmuludq128:
3642 case clang::X86::BI__builtin_ia32_pmuludq256:
3643 case clang::X86::BI__builtin_ia32_pmuludq512:
3646 case Builtin::BI__builtin_elementwise_fma:
3650 llvm::RoundingMode RM) {
3652 F.fusedMultiplyAdd(Y, Z, RM);
3656 case X86::BI__builtin_ia32_vpshldd128:
3657 case X86::BI__builtin_ia32_vpshldd256:
3658 case X86::BI__builtin_ia32_vpshldd512:
3659 case X86::BI__builtin_ia32_vpshldq128:
3660 case X86::BI__builtin_ia32_vpshldq256:
3661 case X86::BI__builtin_ia32_vpshldq512:
3662 case X86::BI__builtin_ia32_vpshldw128:
3663 case X86::BI__builtin_ia32_vpshldw256:
3664 case X86::BI__builtin_ia32_vpshldw512:
3668 return llvm::APIntOps::fshl(Hi, Lo, Amt);
3671 case X86::BI__builtin_ia32_vpshrdd128:
3672 case X86::BI__builtin_ia32_vpshrdd256:
3673 case X86::BI__builtin_ia32_vpshrdd512:
3674 case X86::BI__builtin_ia32_vpshrdq128:
3675 case X86::BI__builtin_ia32_vpshrdq256:
3676 case X86::BI__builtin_ia32_vpshrdq512:
3677 case X86::BI__builtin_ia32_vpshrdw128:
3678 case X86::BI__builtin_ia32_vpshrdw256:
3679 case X86::BI__builtin_ia32_vpshrdw512:
3684 return llvm::APIntOps::fshr(Hi, Lo, Amt);
3687 case clang::X86::BI__builtin_ia32_blendpd:
3688 case clang::X86::BI__builtin_ia32_blendpd256:
3689 case clang::X86::BI__builtin_ia32_blendps:
3690 case clang::X86::BI__builtin_ia32_blendps256:
3691 case clang::X86::BI__builtin_ia32_pblendw128:
3692 case clang::X86::BI__builtin_ia32_pblendw256:
3693 case clang::X86::BI__builtin_ia32_pblendd128:
3694 case clang::X86::BI__builtin_ia32_pblendd256:
3697 case clang::X86::BI__builtin_ia32_blendvpd:
3698 case clang::X86::BI__builtin_ia32_blendvpd256:
3699 case clang::X86::BI__builtin_ia32_blendvps:
3700 case clang::X86::BI__builtin_ia32_blendvps256:
3704 llvm::RoundingMode) {
return C.isNegative() ?
T : F; });
3706 case clang::X86::BI__builtin_ia32_pblendvb128:
3707 case clang::X86::BI__builtin_ia32_pblendvb256:
3710 return ((
APInt)
C).isNegative() ?
T : F;
3713 case X86::BI__builtin_ia32_selectb_128:
3714 case X86::BI__builtin_ia32_selectb_256:
3715 case X86::BI__builtin_ia32_selectb_512:
3716 case X86::BI__builtin_ia32_selectw_128:
3717 case X86::BI__builtin_ia32_selectw_256:
3718 case X86::BI__builtin_ia32_selectw_512:
3719 case X86::BI__builtin_ia32_selectd_128:
3720 case X86::BI__builtin_ia32_selectd_256:
3721 case X86::BI__builtin_ia32_selectd_512:
3722 case X86::BI__builtin_ia32_selectq_128:
3723 case X86::BI__builtin_ia32_selectq_256:
3724 case X86::BI__builtin_ia32_selectq_512:
3725 case X86::BI__builtin_ia32_selectph_128:
3726 case X86::BI__builtin_ia32_selectph_256:
3727 case X86::BI__builtin_ia32_selectph_512:
3728 case X86::BI__builtin_ia32_selectpbf_128:
3729 case X86::BI__builtin_ia32_selectpbf_256:
3730 case X86::BI__builtin_ia32_selectpbf_512:
3731 case X86::BI__builtin_ia32_selectps_128:
3732 case X86::BI__builtin_ia32_selectps_256:
3733 case X86::BI__builtin_ia32_selectps_512:
3734 case X86::BI__builtin_ia32_selectpd_128:
3735 case X86::BI__builtin_ia32_selectpd_256:
3736 case X86::BI__builtin_ia32_selectpd_512:
3739 case X86::BI__builtin_ia32_pshuflw:
3740 case X86::BI__builtin_ia32_pshuflw256:
3741 case X86::BI__builtin_ia32_pshuflw512:
3744 case X86::BI__builtin_ia32_pshufhw:
3745 case X86::BI__builtin_ia32_pshufhw256:
3746 case X86::BI__builtin_ia32_pshufhw512:
3749 case X86::BI__builtin_ia32_pshufd:
3750 case X86::BI__builtin_ia32_pshufd256:
3751 case X86::BI__builtin_ia32_pshufd512:
3754 case X86::BI__builtin_ia32_kandqi:
3755 case X86::BI__builtin_ia32_kandhi:
3756 case X86::BI__builtin_ia32_kandsi:
3757 case X86::BI__builtin_ia32_kanddi:
3760 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS & RHS; });
3762 case X86::BI__builtin_ia32_kandnqi:
3763 case X86::BI__builtin_ia32_kandnhi:
3764 case X86::BI__builtin_ia32_kandnsi:
3765 case X86::BI__builtin_ia32_kandndi:
3768 [](
const APSInt &LHS,
const APSInt &RHS) {
return ~LHS & RHS; });
3770 case X86::BI__builtin_ia32_korqi:
3771 case X86::BI__builtin_ia32_korhi:
3772 case X86::BI__builtin_ia32_korsi:
3773 case X86::BI__builtin_ia32_kordi:
3776 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS | RHS; });
3778 case X86::BI__builtin_ia32_kxnorqi:
3779 case X86::BI__builtin_ia32_kxnorhi:
3780 case X86::BI__builtin_ia32_kxnorsi:
3781 case X86::BI__builtin_ia32_kxnordi:
3784 [](
const APSInt &LHS,
const APSInt &RHS) {
return ~(LHS ^ RHS); });
3786 case X86::BI__builtin_ia32_kxorqi:
3787 case X86::BI__builtin_ia32_kxorhi:
3788 case X86::BI__builtin_ia32_kxorsi:
3789 case X86::BI__builtin_ia32_kxordi:
3792 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS ^ RHS; });
3794 case X86::BI__builtin_ia32_knotqi:
3795 case X86::BI__builtin_ia32_knothi:
3796 case X86::BI__builtin_ia32_knotsi:
3797 case X86::BI__builtin_ia32_knotdi:
3799 S, OpPC,
Call, [](
const APSInt &Src) {
return ~Src; });
3801 case X86::BI__builtin_ia32_kaddqi:
3802 case X86::BI__builtin_ia32_kaddhi:
3803 case X86::BI__builtin_ia32_kaddsi:
3804 case X86::BI__builtin_ia32_kadddi:
3807 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS + RHS; });
3809 case X86::BI__builtin_ia32_pternlogd128_mask:
3810 case X86::BI__builtin_ia32_pternlogd256_mask:
3811 case X86::BI__builtin_ia32_pternlogd512_mask:
3812 case X86::BI__builtin_ia32_pternlogq128_mask:
3813 case X86::BI__builtin_ia32_pternlogq256_mask:
3814 case X86::BI__builtin_ia32_pternlogq512_mask:
3816 case X86::BI__builtin_ia32_pternlogd128_maskz:
3817 case X86::BI__builtin_ia32_pternlogd256_maskz:
3818 case X86::BI__builtin_ia32_pternlogd512_maskz:
3819 case X86::BI__builtin_ia32_pternlogq128_maskz:
3820 case X86::BI__builtin_ia32_pternlogq256_maskz:
3821 case X86::BI__builtin_ia32_pternlogq512_maskz:
3823 case Builtin::BI__builtin_elementwise_fshl:
3825 llvm::APIntOps::fshl);
3826 case Builtin::BI__builtin_elementwise_fshr:
3828 llvm::APIntOps::fshr);
3830 case X86::BI__builtin_ia32_insertf32x4_256:
3831 case X86::BI__builtin_ia32_inserti32x4_256:
3832 case X86::BI__builtin_ia32_insertf64x2_256:
3833 case X86::BI__builtin_ia32_inserti64x2_256:
3834 case X86::BI__builtin_ia32_insertf32x4:
3835 case X86::BI__builtin_ia32_inserti32x4:
3836 case X86::BI__builtin_ia32_insertf64x2_512:
3837 case X86::BI__builtin_ia32_inserti64x2_512:
3838 case X86::BI__builtin_ia32_insertf32x8:
3839 case X86::BI__builtin_ia32_inserti32x8:
3840 case X86::BI__builtin_ia32_insertf64x4:
3841 case X86::BI__builtin_ia32_inserti64x4:
3842 case X86::BI__builtin_ia32_vinsertf128_ps256:
3843 case X86::BI__builtin_ia32_vinsertf128_pd256:
3844 case X86::BI__builtin_ia32_vinsertf128_si256:
3845 case X86::BI__builtin_ia32_insert128i256:
3848 case X86::BI__builtin_ia32_vec_ext_v4hi:
3849 case X86::BI__builtin_ia32_vec_ext_v16qi:
3850 case X86::BI__builtin_ia32_vec_ext_v8hi:
3851 case X86::BI__builtin_ia32_vec_ext_v4si:
3852 case X86::BI__builtin_ia32_vec_ext_v2di:
3853 case X86::BI__builtin_ia32_vec_ext_v32qi:
3854 case X86::BI__builtin_ia32_vec_ext_v16hi:
3855 case X86::BI__builtin_ia32_vec_ext_v8si:
3856 case X86::BI__builtin_ia32_vec_ext_v4di:
3857 case X86::BI__builtin_ia32_vec_ext_v4sf:
3860 case X86::BI__builtin_ia32_vec_set_v4hi:
3861 case X86::BI__builtin_ia32_vec_set_v16qi:
3862 case X86::BI__builtin_ia32_vec_set_v8hi:
3863 case X86::BI__builtin_ia32_vec_set_v4si:
3864 case X86::BI__builtin_ia32_vec_set_v2di:
3865 case X86::BI__builtin_ia32_vec_set_v32qi:
3866 case X86::BI__builtin_ia32_vec_set_v16hi:
3867 case X86::BI__builtin_ia32_vec_set_v8si:
3868 case X86::BI__builtin_ia32_vec_set_v4di:
3873 diag::note_invalid_subexpr_in_const_expr)
3879 llvm_unreachable(
"Unhandled builtin ID");
3888 unsigned ArrayIndex = 0;
3890 for (
unsigned I = 0; I != N; ++I) {
3896 if (!RD || RD->isInvalidDecl())
3900 assert(FieldIndex < RL.
getFieldCount() &&
"offsetof field in wrong type");
3909 int64_t Index = ArrayIndices[ArrayIndex];
3915 Result += Index * ElementSize;
3926 if (!RD || RD->isInvalidDecl())
3931 CurrentType = BaseSpec->
getType();
3941 llvm_unreachable(
"Dependent OffsetOfExpr?");
3945 IntResult =
Result.getQuantity();
3962 FieldPtr.
deref<
T>() = T::from(IntValue.getSExtValue()));
3972 Dest.deref<T>().~T();
3973 new (&Dest.deref<T>()) T();
3980 for (
const Record::Field &F : R->
fields()) {
3988 for (
unsigned I = 0, N = Desc->
getNumElems(); I != N; ++I) {
3990 Dest.deref<T>().~T();
3991 new (&Dest.deref<T>()) T();
3998 for (
unsigned I = 0, N = Desc->
getNumElems(); I != N; ++I) {
4006static bool copyComposite(InterpState &S, CodePtr OpPC,
const Pointer &Src,
4007 Pointer &Dest,
bool Activate);
4013 auto copyField = [&](
const Record::Field &F,
bool Activate) ->
bool {
4032 for (
const Record::Field &F : R->
fields()) {
4037 if (!copyField(F,
true))
4051 for (
const Record::Base &B : R->
bases()) {
4074 for (
unsigned I = 0, N = DestDesc->
getNumElems(); I != N; ++I) {
4087 for (
unsigned I = 0, N = DestDesc->
getNumElems(); I != N; ++I) {
Defines enum values for all the target-independent builtin functions.
GCCTypeClass
Values returned by __builtin_classify_type, chosen to match the values produced by GCC's builtin.
CharUnits GetAlignOfExpr(const ASTContext &Ctx, const Expr *E, UnaryExprOrTypeTrait ExprKind)
GCCTypeClass EvaluateBuiltinClassifyType(QualType T, const LangOptions &LangOpts)
EvaluateBuiltinClassifyType - Evaluate __builtin_classify_type the same way as GCC.
static bool isOneByteCharacterType(QualType T)
static bool isUserWritingOffTheEnd(const ASTContext &Ctx, const LValue &LVal)
Attempts to detect a user writing into a piece of memory that's impossible to figure out the size of ...
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
#define INT_TYPE_SWITCH_NO_BOOL(Expr, B)
#define INT_TYPE_SWITCH(Expr, B)
#define TYPE_SWITCH(Expr, B)
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
static QualType getPointeeType(const MemRegion *R)
Enumerates target-specific builtins in their own namespaces within namespace clang.
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
CharUnits & getLValueOffset()
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
unsigned getIntWidth(QualType T) const
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
Builtin::Context & BuiltinInfo
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, const Expr *SizeExpr, ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return the unique reference to the type for a constant array of the specified element type.
const LangOptions & getLangOpts() const
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
QualType getWCharType() const
Return the unique wchar_t type available in C++ (and available as __wchar_t as a Microsoft extension)...
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
const TargetInfo & getTargetInfo() const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
CanQualType getCanonicalTagType(const TagDecl *TD) const
uint64_t getCharWidth() const
Return the size of the character type, in bits.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
unsigned getFieldCount() const
getFieldCount - Get the number of fields in the layout.
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
std::string getQuotedName(unsigned ID) const
Return the identifier name for the specified builtin inside single quotes for a diagnostic,...
bool isConstantEvaluated(unsigned ID) const
Return true if this function can be constant evaluated by Clang frontend.
Represents a base class of a C++ class.
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
QualType getType() const
Retrieves the type of the base class.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
CharUnits - This is an opaque type for sizes expressed in character units.
CharUnits alignmentAtOffset(CharUnits offset) const
Given that this is a non-zero alignment value, what is the alignment at the given offset?
bool isZero() const
isZero - Test whether the quantity equals zero.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
CharUnits alignTo(const CharUnits &Align) const
alignTo - Returns the next integer (mod 2**64) that is greater than or equal to this quantity and is ...
static unsigned getMaxSizeBits(const ASTContext &Context)
Determine the maximum number of active bits that an array's size can require, which limits the maximu...
This represents one expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Represents a member of a struct/union/class.
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
Represents a function declaration or definition.
One of these records is kept for each identifier that is lexed.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
StrictFlexArraysLevelKind
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...
const OffsetOfNode & getComponent(unsigned Idx) const
TypeSourceInfo * getTypeSourceInfo() const
unsigned getNumComponents() const
Helper class for OffsetOfExpr.
FieldDecl * getField() const
For a field offsetof node, returns the field.
@ Array
An index into an array.
@ Identifier
A field in a dependent type, known only by its name.
@ Base
An implicit indirection through a C++ base class, when the field found is in a base class.
Kind getKind() const
Determine what kind of offsetof node this is.
CXXBaseSpecifier * getBase() const
For a base class node, returns the base specifier.
PointerType - C99 6.7.5.1 - Pointer Declarators.
A (possibly-)qualified type.
bool isTriviallyCopyableType(const ASTContext &Context) const
Return true if this is a trivially copyable type (C++0x [basic.types]p9)
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
unsigned getMaxAtomicInlineWidth() const
Return the maximum width lock-free atomic operation which can be inlined given the supported features...
virtual int getEHDataRegisterNumber(unsigned RegNo) const
Return the register number that __builtin_eh_return_regno would return with the specified argument.
virtual bool isNan2008() const
Returns true if NaN encoding is IEEE 754-2008.
QualType getType() const
Return the type wrapped by this type source info.
bool isBooleanType() const
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isPointerType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool isVectorType() const
bool isFloatingType() const
const T * getAs() const
Member-template getAs<specific type>'.
Represents a GCC generic vector type.
unsigned getNumElements() const
QualType getElementType() const
A memory block, either on the stack or in the heap.
const Descriptor * getDescriptor() const
Returns the block's descriptor.
Wrapper around boolean types.
static Boolean from(T Value)
Pointer into the code segment.
const LangOptions & getLangOpts() const
Returns the language options.
OptPrimType classify(QualType T) const
Classifies a type.
unsigned getEvalID() const
Manages dynamic memory allocations done during bytecode interpretation.
bool deallocate(const Expr *Source, const Block *BlockToDelete, InterpState &S)
Deallocate the given source+block combination.
std::optional< Form > getAllocationForm(const Expr *Source) const
Checks whether the allocation done at the given source is an array allocation.
Block * allocate(const Descriptor *D, unsigned EvalID, Form AllocForm)
Allocate ONE element of the given descriptor.
If a Floating is constructed from Memory, it DOES NOT OWN THAT MEMORY.
void copy(const APFloat &F)
llvm::FPClassTest classify() const
ComparisonCategoryResult compare(const Floating &RHS) const
APFloat::fltCategory getCategory() const
APFloat getAPFloat() const
Base class for stack frames, shared between VM and walker.
virtual const FunctionDecl * getCallee() const =0
Returns the called function's declaration.
If an IntegralAP is constructed from Memory, it DOES NOT OWN THAT MEMORY.
Frame storing local variables.
const Expr * getExpr(CodePtr PC) const
InterpFrame * Caller
The frame of the previous function.
SourceInfo getSource(CodePtr PC) const
Map a location to a source.
CodePtr getRetPC() const
Returns the return address of the frame.
SourceLocation getLocation(CodePtr PC) const
SourceRange getRange(CodePtr PC) const
unsigned getDepth() const
const FunctionDecl * getCallee() const override
Returns the caller.
Stack frame storing temporaries and parameters.
T pop()
Returns the value from the top of the stack and removes it.
void push(Tys &&...Args)
Constructs a value in place on the top of the stack.
void discard()
Discards the top value from the stack.
T & peek() const
Returns a reference to the value on the top of the stack.
Expr::EvalStatus & getEvalStatus() const override
Context & getContext() const
DynamicAllocator & getAllocator()
Context & Ctx
Interpreter Context.
Floating allocFloat(const llvm::fltSemantics &Sem)
llvm::SmallVector< const Block * > InitializingBlocks
List of blocks we're currently running either constructors or destructors for.
ASTContext & getASTContext() const override
InterpStack & Stk
Temporary stack.
const VarDecl * EvaluatingDecl
Declaration we're initializing/evaluting, if any.
InterpFrame * Current
The current frame.
T allocAP(unsigned BitWidth)
const LangOptions & getLangOpts() const
StdAllocatorCaller getStdAllocatorCaller(StringRef Name) const
bool inConstantContext() const
Program & P
Reference to the module containing all bytecode.
PrimType value_or(PrimType PT) const
A pointer to a memory block, live or dead.
Pointer narrow() const
Restricts the scope of an array element pointer.
bool isInitialized() const
Checks if an object was initialized.
Pointer atIndex(uint64_t Idx) const
Offsets a pointer inside an array.
bool isDummy() const
Checks if the pointer points to a dummy value.
int64_t getIndex() const
Returns the index into an array.
bool isActive() const
Checks if the object is active.
Pointer atField(unsigned Off) const
Creates a pointer to a field.
T & deref() const
Dereferences the pointer, if it's live.
unsigned getNumElems() const
Returns the number of elements.
Pointer getArray() const
Returns the parent array.
bool isUnknownSizeArray() const
Checks if the structure is an array of unknown size.
void activate() const
Activats a field.
bool isIntegralPointer() const
QualType getType() const
Returns the type of the innermost field.
bool isArrayElement() const
Checks if the pointer points to an array.
void initializeAllElements() const
Initialize all elements of a primitive array at once.
bool isLive() const
Checks if the pointer is live.
bool inArray() const
Checks if the innermost field is an array.
T & elem(unsigned I) const
Dereferences the element at index I.
Pointer getBase() const
Returns a pointer to the object of which this pointer is a field.
std::string toDiagnosticString(const ASTContext &Ctx) const
Converts the pointer to a string usable in diagnostics.
bool isZero() const
Checks if the pointer is null.
bool isRoot() const
Pointer points directly to a block.
const Descriptor * getDeclDesc() const
Accessor for information about the declaration site.
static bool pointToSameBlock(const Pointer &A, const Pointer &B)
Checks if both given pointers point to the same block.
APValue toAPValue(const ASTContext &ASTCtx) const
Converts the pointer to an APValue.
bool isOnePastEnd() const
Checks if the index is one past end.
uint64_t getIntegerRepresentation() const
const FieldDecl * getField() const
Returns the field information.
Pointer expand() const
Expands a pointer to the containing array, undoing narrowing.
bool isBlockPointer() const
const Block * block() const
const Descriptor * getFieldDesc() const
Accessors for information about the innermost field.
bool isVirtualBaseClass() const
bool isBaseClass() const
Checks if a structure is a base class.
size_t elemSize() const
Returns the element size of the innermost field.
bool canBeInitialized() const
If this pointer has an InlineDescriptor we can use to initialize.
Lifetime getLifetime() const
void initialize() const
Initializes a field.
bool isField() const
Checks if the item is a field in an object.
const Record * getRecord() const
Returns the record descriptor of a class.
Descriptor * createDescriptor(const DeclTy &D, PrimType T, const Type *SourceTy=nullptr, Descriptor::MetadataSize MDSize=std::nullopt, bool IsConst=false, bool IsTemporary=false, bool IsMutable=false, bool IsVolatile=false)
Creates a descriptor for a primitive type.
Structure/Class descriptor.
const RecordDecl * getDecl() const
Returns the underlying declaration.
bool isUnion() const
Checks if the record is a union.
const Field * getField(const FieldDecl *FD) const
Returns a field.
llvm::iterator_range< const_base_iter > bases() const
unsigned getNumFields() const
llvm::iterator_range< const_field_iter > fields() const
Describes the statement/declaration an opcode was generated from.
OptionalDiagnostic Note(SourceLocation Loc, diag::kind DiagId)
Add a note to a prior diagnostic.
DiagnosticBuilder report(SourceLocation Loc, diag::kind DiagId)
Directly reports a diagnostic message.
OptionalDiagnostic FFDiag(SourceLocation Loc, diag::kind DiagId=diag::note_invalid_subexpr_in_const_expr, unsigned ExtraNotes=0)
Diagnose that the evaluation could not be folded (FF => FoldFailure)
OptionalDiagnostic CCEDiag(SourceLocation Loc, diag::kind DiagId=diag::note_invalid_subexpr_in_const_expr, unsigned ExtraNotes=0)
Diagnose that the evaluation does not produce a C++11 core constant expression.
bool checkingPotentialConstantExpression() const
Are we checking whether the expression is a potential constant expression?
Defines the clang::TargetInfo interface.
bool computeOSLogBufferLayout(clang::ASTContext &Ctx, const clang::CallExpr *E, OSLogBufferLayout &layout)
static bool interp__builtin_is_within_lifetime(InterpState &S, CodePtr OpPC, const CallExpr *Call)
static void assignInteger(InterpState &S, const Pointer &Dest, PrimType ValueT, const APSInt &Value)
bool readPointerToBuffer(const Context &Ctx, const Pointer &FromPtr, BitcastBuffer &Buffer, bool ReturnOnUninit)
static Floating abs(InterpState &S, const Floating &In)
static bool interp__builtin_fmax(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, bool IsNumBuiltin)
static bool interp__builtin_elementwise_maxmin(InterpState &S, CodePtr OpPC, const CallExpr *Call, unsigned BuiltinID)
static bool interp__builtin_bswap(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static bool interp__builtin_elementwise_triop(InterpState &S, CodePtr OpPC, const CallExpr *Call, llvm::function_ref< APInt(const APSInt &, const APSInt &, const APSInt &)> Fn)
static bool interp__builtin_assume(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
bool CheckNewDeleteForms(InterpState &S, CodePtr OpPC, DynamicAllocator::Form AllocForm, DynamicAllocator::Form DeleteForm, const Descriptor *D, const Expr *NewExpr)
Diagnose mismatched new[]/delete or new/delete[] pairs.
static bool interp__builtin_isnan(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
Defined as __builtin_isnan(...), to accommodate the fact that it can take a float,...
static llvm::RoundingMode getRoundingMode(FPOptions FPO)
static bool interp__builtin_elementwise_countzeroes(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call, unsigned BuiltinID)
Can be called with an integer or vector as the first and only parameter.
bool Call(InterpState &S, CodePtr OpPC, const Function *Func, uint32_t VarArgSize)
static bool interp__builtin_classify_type(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static bool interp__builtin_fmin(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, bool IsNumBuiltin)
static bool interp__builtin_blend(InterpState &S, CodePtr OpPC, const CallExpr *Call)
bool SetThreeWayComparisonField(InterpState &S, CodePtr OpPC, const Pointer &Ptr, const APSInt &IntValue)
Sets the given integral value to the pointer, which is of a std::{weak,partial,strong}...
static bool interp__builtin_operator_delete(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static bool interp__builtin_fabs(InterpState &S, CodePtr OpPC, const InterpFrame *Frame)
static bool interp__builtin_memcmp(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call, unsigned ID)
static bool interp__builtin_atomic_lock_free(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call, unsigned BuiltinOp)
bool __atomic_always_lock_free(size_t, void const volatile*) bool __atomic_is_lock_free(size_t,...
static llvm::APSInt convertBoolVectorToInt(const Pointer &Val)
static bool interp__builtin_move(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static bool interp__builtin_clz(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call, unsigned BuiltinOp)
bool CheckMutable(InterpState &S, CodePtr OpPC, const Pointer &Ptr)
Checks if a pointer points to a mutable field.
static bool interp__builtin_parity(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static bool interp__builtin_is_aligned_up_down(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call, unsigned BuiltinOp)
__builtin_is_aligned() __builtin_align_up() __builtin_align_down() The first parameter is either an i...
static bool interp__builtin_bitreverse(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static bool Activate(InterpState &S, CodePtr OpPC)
static bool interp__builtin_ia32_addcarry_subborrow(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call, unsigned BuiltinOp)
(CarryIn, LHS, RHS, Result)
static bool isOneByteCharacterType(QualType T)
Determine if T is a character type for which we guarantee that sizeof(T) == 1.
static unsigned computePointerOffset(const ASTContext &ASTCtx, const Pointer &Ptr)
Compute the byte offset of Ptr in the full declaration.
static bool interp__builtin_strcmp(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call, unsigned ID)
bool CheckLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr, AccessKinds AK)
Checks if a value can be loaded from a block.
static bool interp__builtin_overflowop(InterpState &S, CodePtr OpPC, const CallExpr *Call, unsigned BuiltinOp)
static bool interp__builtin_inf(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static bool interp__builtin_vec_ext(InterpState &S, CodePtr OpPC, const CallExpr *Call, unsigned ID)
static bool interp__builtin_isinf(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, bool CheckSign, const CallExpr *Call)
static bool interp__builtin_os_log_format_buffer_size(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
bool InterpretOffsetOf(InterpState &S, CodePtr OpPC, const OffsetOfExpr *E, ArrayRef< int64_t > ArrayIndices, int64_t &Result)
Interpret an offsetof operation.
static bool interp__builtin_x86_insert_subvector(InterpState &S, CodePtr OpPC, const CallExpr *Call, unsigned ID)
bool CheckRange(InterpState &S, CodePtr OpPC, const Pointer &Ptr, AccessKinds AK)
Checks if a pointer is in range.
static bool pointsToLastObject(const Pointer &Ptr)
Does Ptr point to the last subobject?
static bool interp__builtin_select(InterpState &S, CodePtr OpPC, const CallExpr *Call)
AVX512 predicated move: "Result = Mask[] ? LHS[] : RHS[]".
static bool interp__builtin_ia32_pmul(InterpState &S, CodePtr OpPC, const CallExpr *Call, unsigned BuiltinID)
static void discard(InterpStack &Stk, PrimType T)
bool CheckLive(InterpState &S, CodePtr OpPC, const Pointer &Ptr, AccessKinds AK)
Checks if a pointer is live and accessible.
static bool interp__builtin_fpclassify(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
Five int values followed by one floating value.
static bool interp__builtin_abs(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static bool interp_floating_comparison(InterpState &S, CodePtr OpPC, const CallExpr *Call, unsigned ID)
static bool handleOverflow(InterpState &S, CodePtr OpPC, const T &SrcValue)
static bool copyComposite(InterpState &S, CodePtr OpPC, const Pointer &Src, Pointer &Dest, bool Activate)
static bool copyRecord(InterpState &S, CodePtr OpPC, const Pointer &Src, Pointer &Dest, bool Activate=false)
static bool interp__builtin_c11_atomic_is_lock_free(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
bool __c11_atomic_is_lock_free(size_t)
static void zeroAll(Pointer &Dest)
static bool interp__builtin_elementwise_int_binop(InterpState &S, CodePtr OpPC, const CallExpr *Call, llvm::function_ref< APInt(const APSInt &, const APSInt &)> Fn)
static bool interp__builtin_issubnormal(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static bool interp__builtin_arithmetic_fence(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
PrimType
Enumeration of the primitive types of the VM.
static bool interp__builtin_isfinite(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call, uint32_t BuiltinID)
Interpret a builtin function.
static bool interp__builtin_expect(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static bool interp__builtin_vec_set(InterpState &S, CodePtr OpPC, const CallExpr *Call, unsigned ID)
static bool interp__builtin_complex(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
__builtin_complex(Float A, float B);
static bool interp__builtin_ia32_pshuf(InterpState &S, CodePtr OpPC, const CallExpr *Call, bool IsShufHW)
bool CheckDummy(InterpState &S, CodePtr OpPC, const Block *B, AccessKinds AK)
Checks if a pointer is a dummy pointer.
static bool interp__builtin_assume_aligned(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
__builtin_assume_aligned(Ptr, Alignment[, ExtraOffset])
static bool interp__builtin_ptrauth_string_discriminator(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static bool interp__builtin_ffs(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static bool interp__builtin_memchr(InterpState &S, CodePtr OpPC, const CallExpr *Call, unsigned ID)
static bool interp__builtin_x86_pack(InterpState &S, CodePtr, const CallExpr *E, llvm::function_ref< APInt(const APSInt &)> PackFn)
static void pushInteger(InterpState &S, const APSInt &Val, QualType QT)
Pushes Val on the stack as the type given by QT.
static bool interp__builtin_operator_new(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static bool interp__builtin_strlen(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call, unsigned ID)
bool CheckArray(InterpState &S, CodePtr OpPC, const Pointer &Ptr)
Checks if the array is offsetable.
static bool interp__builtin_elementwise_abs(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call, unsigned BuiltinID)
static bool interp__builtin_copysign(InterpState &S, CodePtr OpPC, const InterpFrame *Frame)
static bool interp__builtin_iszero(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static bool interp__builtin_elementwise_popcount(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call, unsigned BuiltinID)
Can be called with an integer or vector as the first and only parameter.
static bool interp__builtin_addressof(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static bool interp__builtin_signbit(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
bool Error(InterpState &S, CodePtr OpPC)
Do nothing and just abort execution.
static bool interp__builtin_vector_reduce(InterpState &S, CodePtr OpPC, const CallExpr *Call, unsigned ID)
static bool interp__builtin_memcpy(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call, unsigned ID)
static bool interp__builtin_elementwise_triop_fp(InterpState &S, CodePtr OpPC, const CallExpr *Call, llvm::function_ref< APFloat(const APFloat &, const APFloat &, const APFloat &, llvm::RoundingMode)> Fn)
size_t primSize(PrimType Type)
Returns the size of a primitive type in bytes.
static bool interp__builtin_popcount(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static bool interp__builtin_object_size(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static bool interp__builtin_carryop(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call, unsigned BuiltinOp)
Three integral values followed by a pointer (lhs, rhs, carry, carryOut).
bool CheckArraySize(InterpState &S, CodePtr OpPC, uint64_t NumElems)
static bool interp__builtin_ctz(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call, unsigned BuiltinID)
static bool interp__builtin_is_constant_evaluated(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static APSInt popToAPSInt(InterpStack &Stk, PrimType T)
static std::optional< unsigned > computeFullDescSize(const ASTContext &ASTCtx, const Descriptor *Desc)
static bool interp__builtin_isfpclass(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
First parameter to __builtin_isfpclass is the floating value, the second one is an integral value.
static bool interp__builtin_issignaling(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static bool interp__builtin_nan(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call, bool Signaling)
static bool interp__builtin_clrsb(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
bool DoMemcpy(InterpState &S, CodePtr OpPC, const Pointer &Src, Pointer &Dest)
Copy the contents of Src into Dest.
static bool interp__builtin_elementwise_int_unaryop(InterpState &S, CodePtr OpPC, const CallExpr *Call, llvm::function_ref< APInt(const APSInt &)> Fn)
constexpr bool isIntegralType(PrimType T)
static bool interp__builtin_eh_return_data_regno(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static LLVM_ATTRIBUTE_UNUSED bool isNoopBuiltin(unsigned ID)
static void diagnoseNonConstexprBuiltin(InterpState &S, CodePtr OpPC, unsigned ID)
static QualType getElemType(const Pointer &P)
static bool interp__builtin_ia32_pternlog(InterpState &S, CodePtr OpPC, const CallExpr *Call, bool MaskZ)
static bool interp__builtin_isnormal(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static void swapBytes(std::byte *M, size_t N)
The JSON file list parser is used to communicate input to InstallAPI.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
ComparisonCategoryResult
An enumeration representing the possible results of a three-way comparison.
@ Result
The result type of a method or function.
const FunctionProtoType * T
U cast(CodeGen::Address addr)
SmallVectorImpl< PartialDiagnosticAt > * Diag
Diag - If this is non-null, it will be filled in with a stack of notes indicating why evaluation fail...
Track what bits have been initialized to known values and which ones have indeterminate value.
std::unique_ptr< std::byte[]> Data
size_t getQuantity() const
Describes a memory block created by an allocation site.
unsigned getNumElems() const
Returns the number of elements stored in the block.
bool isPrimitive() const
Checks if the descriptor is of a primitive.
QualType getElemQualType() const
bool isCompositeArray() const
Checks if the descriptor is of an array of composites.
const ValueDecl * asValueDecl() const
static constexpr unsigned MaxArrayElemBytes
Maximum number of bytes to be used for array elements.
const Decl * asDecl() const
static constexpr MetadataSize InlineDescMD
unsigned getElemSize() const
returns the size of an element when the structure is viewed as an array.
bool isPrimitiveArray() const
Checks if the descriptor is of an array of primitives.
const VarDecl * asVarDecl() const
PrimType getPrimType() const
bool isRecord() const
Checks if the descriptor is of a record.
const Record *const ElemRecord
Pointer to the record, if block contains records.
const Expr * asExpr() const
bool isArray() const
Checks if the descriptor is of an array.
Mapping from primitive types to their representation.