clang: lib/AST/ByteCode/InterpBuiltin.cpp Source File (original) (raw)
1
2
3
4
5
6
7
21#include "llvm/ADT/StringExtras.h"
22#include "llvm/Support/AllocToken.h"
23#include "llvm/Support/ErrorHandling.h"
24#include "llvm/Support/SipHash.h"
25
28
30 switch (ID) {
31 case Builtin::BIas_const:
32 case Builtin::BIforward:
33 case Builtin::BIforward_like:
34 case Builtin::BImove:
35 case Builtin::BImove_if_noexcept:
36 case Builtin::BIaddressof:
37 case Builtin::BI__addressof:
38 case Builtin::BI__builtin_addressof:
39 case Builtin::BI__builtin_launder:
40 return true;
41 default:
42 return false;
43 }
44 return false;
45}
46
50
53 return static_cast<uint64_t>(S.Stk.pop<T>()));
54}
55
59
66
67
72 assert(T);
73
75
80 return;
81 }
82
87 return;
88 }
89
91 int64_t V = Val.getSExtValue();
93 } else {
95 uint64_t V = Val.getZExtValue();
97 }
98}
99
100template
102 if constexpr (std::is_same_v<T, APInt>)
104 else if constexpr (std::is_same_v<T, APSInt>)
106 else
108 APSInt(APInt(sizeof(T) * 8, static_cast<uint64_t>(Val),
109 std::is_signed_v),
110 !std::is_signed_v),
111 QT);
112}
113
116
121 } else if (ValueT == PT_IntAP) {
125 } else {
127 ValueT, { Dest.deref<T>() = T::from(static_cast<T>(Value)); });
128 }
129}
130
135 return T;
136 if (T->isPointerType())
140 if (const auto *AT = T->getAsArrayTypeUnsafe())
141 return AT->getElementType();
142 return T;
143}
144
146 unsigned ID) {
148 return;
149
152 S.CCEDiag(Loc, diag::note_constexpr_invalid_function)
153 << 0 << 0
155 else
156 S.CCEDiag(Loc, diag::note_invalid_subexpr_in_const_expr);
157}
158
162 "Not a boolean vector");
164
165
166 llvm::APSInt Result(NumElems, 0);
167 for (unsigned I = 0; I != NumElems; ++I) {
168 if (Val.elem<bool>(I))
170 }
171
173}
174
175
176
179 if (Src.isInfinity()) {
181 S.CCEDiag(DiagExpr, diag::note_constexpr_float_arithmetic) << 0;
182 return false;
183 }
184 if (Src.isNaN()) {
186 S.CCEDiag(DiagExpr, diag::note_constexpr_float_arithmetic) << 1;
187 return false;
188 }
190 bool LosesInfo = false;
191 APFloat::opStatus Status = Val.convert(
192 APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven, &LosesInfo);
193 if (LosesInfo || Val.isDenormal()) {
195 S.CCEDiag(DiagExpr, diag::note_constexpr_float_arithmetic_strict);
196 return false;
197 }
198 if (Status != APFloat::opOK) {
200 S.CCEDiag(DiagExpr, diag::note_invalid_subexpr_in_const_expr);
201 return false;
202 }
203 Dst.copy(Val);
204 return true;
205}
206
211 auto isStdCall = [](const FunctionDecl *F) -> bool {
212 return F && F->isInStdNamespace() && F->getIdentifier() &&
213 F->getIdentifier()->isStr("is_constant_evaluated");
214 };
216
217
220 (Depth == 0 || (Depth == 1 && isStdCall(Frame->getCallee())))) {
224 diag::warn_is_constant_evaluated_always_true_constexpr)
225 << "std::is_constant_evaluated" << E->getSourceRange();
226 } else {
228 diag::warn_is_constant_evaluated_always_true_constexpr)
229 << "__builtin_is_constant_evaluated" << Call->getSourceRange();
230 }
231 }
232
234 return true;
235}
236
237
241 assert(Call->getNumArgs() == 1);
243 return true;
244}
245
249 uint64_t Limit = ~static_cast<uint64_t>(0);
250 if (ID == Builtin::BIstrncmp || ID == Builtin::BI__builtin_strncmp ||
251 ID == Builtin::BIwcsncmp || ID == Builtin::BI__builtin_wcsncmp)
253
256 if (ID == Builtin::BIstrcmp || ID == Builtin::BIstrncmp ||
257 ID == Builtin::BIwcscmp || ID == Builtin::BIwcsncmp)
259
260 if (Limit == 0) {
262 return true;
263 }
264
266 return false;
267
268 if (A.isDummy() || B.isDummy())
269 return false;
271 return false;
272
273 bool IsWide = ID == Builtin::BIwcscmp || ID == Builtin::BIwcsncmp ||
274 ID == Builtin::BI__builtin_wcscmp ||
275 ID == Builtin::BI__builtin_wcsncmp;
276 assert(A.getFieldDesc()->isPrimitiveArray());
278
279
281 return false;
282
284
285 auto returnResult = [&](int V) -> bool {
287 return true;
288 };
289
290 unsigned IndexA = A.getIndex();
291 unsigned IndexB = B.getIndex();
292 uint64_t Steps = 0;
293 for (;; ++IndexA, ++IndexB, ++Steps) {
294
295 if (Steps >= Limit)
296 break;
301 return false;
302 }
303
304 if (IsWide) {
308 if (CA > CB)
309 return returnResult(1);
310 if (CA < CB)
311 return returnResult(-1);
312 if (CA.isZero() || CB.isZero())
313 return returnResult(0);
314 });
315 continue;
316 }
317
318 uint8_t CA = PA.deref<uint8_t>();
319 uint8_t CB = PB.deref<uint8_t>();
320
321 if (CA > CB)
322 return returnResult(1);
323 if (CA < CB)
324 return returnResult(-1);
325 if (CA == 0 || CB == 0)
326 return returnResult(0);
327 }
328
329 return returnResult(0);
330}
331
336
337 if (ID == Builtin::BIstrlen || ID == Builtin::BIwcslen)
339
341 return false;
342
344 return false;
345
347 return false;
348
350 return false;
351
354
355 if (ID == Builtin::BI__builtin_wcslen || ID == Builtin::BIwcslen) {
358 }
359
360 size_t Len = 0;
361 for (size_t I = StrPtr.getIndex();; ++I, ++Len) {
363
365 return false;
366
367 uint32_t Val;
368 switch (ElemSize) {
369 case 1:
370 Val = ElemPtr.deref<uint8_t>();
371 break;
372 case 2:
373 Val = ElemPtr.deref<uint16_t>();
374 break;
375 case 4:
376 Val = ElemPtr.deref<uint32_t>();
377 break;
378 default:
379 llvm_unreachable("Unsupported char size");
380 }
381 if (Val == 0)
382 break;
383 }
384
386
387 return true;
388}
389
392 bool Signaling) {
394
396 return false;
397
399
400
401 llvm::APInt Fill;
402 std::string Str;
404 for (unsigned I = 0;; ++I) {
406
408 return false;
409
410 if (Elem.deref<int8_t>() == 0)
411 break;
412
413 Str += Elem.deref<char>();
414 }
415
416
417 if (Str.empty())
418 Fill = llvm::APInt(32, 0);
419 else if (StringRef(Str).getAsInteger(0, Fill))
420 return false;
421
422 const llvm::fltSemantics &TargetSemantics =
424 Call->getDirectCallee()->getReturnType());
425
428 if (Signaling)
430 llvm::APFloat::getSNaN(TargetSemantics, false, &Fill));
431 else
433 llvm::APFloat::getQNaN(TargetSemantics, false, &Fill));
434 } else {
435
436
437
438
439
440 if (Signaling)
442 llvm::APFloat::getQNaN(TargetSemantics, false, &Fill));
443 else
445 llvm::APFloat::getSNaN(TargetSemantics, false, &Fill));
446 }
447
449 return true;
450}
451
455 const llvm::fltSemantics &TargetSemantics =
457 Call->getDirectCallee()->getReturnType());
458
460 Result.copy(APFloat::getInf(TargetSemantics));
462 return true;
463}
464
470
475
476 return true;
477}
478
484
485 if (IsNumBuiltin)
486 Result.copy(llvm::minimumnum(LHS.getAPFloat(), RHS.getAPFloat()));
487 else
490 return true;
491}
492
498
499 if (IsNumBuiltin)
500 Result.copy(llvm::maximumnum(LHS.getAPFloat(), RHS.getAPFloat()));
501 else
504 return true;
505}
506
507
508
509
514
516 return true;
517}
518
523
525 return true;
526}
527
533 bool IsInf = F.isInfinity();
534
535 if (CheckSign)
536 pushInteger(S, IsInf ? (F.isNegative() ? -1 : 1) : 0, Call->getType());
537 else
539 return true;
540}
541
546
548 return true;
549}
550
555
557 return true;
558}
559
564
566 return true;
567}
568
573
575 return true;
576}
577
582
584 return true;
585}
586
591
593 S,
594 [&] {
595 switch (ID) {
596 case Builtin::BI__builtin_isgreater:
597 return LHS > RHS;
598 case Builtin::BI__builtin_isgreaterequal:
599 return LHS >= RHS;
600 case Builtin::BI__builtin_isless:
601 return LHS < RHS;
602 case Builtin::BI__builtin_islessequal:
603 return LHS <= RHS;
604 case Builtin::BI__builtin_islessgreater: {
608 }
609 case Builtin::BI__builtin_isunordered:
611 default:
612 llvm_unreachable("Unexpected builtin ID: Should be a floating point "
613 "comparison function");
614 }
615 }(),
616 Call->getType());
617 return true;
618}
619
620
621
627
628 int32_t Result = static_cast<int32_t>(
629 (F.classify() & std::move(FPClassArg)).getZExtValue());
631
632 return true;
633}
634
635
636
641
644 for (unsigned I = 0; I != 5; ++I)
646
647 unsigned Index;
649 case APFloat::fcNaN:
650 Index = 0;
651 break;
652 case APFloat::fcInfinity:
653 Index = 1;
654 break;
655 case APFloat::fcNormal:
657 break;
658 case APFloat::fcZero:
659 Index = 4;
660 break;
661 }
662
663
664 assert(Index <= 4);
665
667 return true;
668}
669
671 if (!In.isNegative())
672 return In;
673
676 New.changeSign();
678 return Output;
679}
680
681
682
683
684
685
692
697 if (Val ==
698 APSInt(APInt::getSignedMinValue(Val.getBitWidth()), false))
699 return false;
700 if (Val.isNegative())
701 Val.negate();
703 return true;
704}
705
710 if (Call->getArg(0)->getType()->isExtVectorBoolType()) {
713 } else {
715 }
717 return true;
718}
719
723
724 assert(Call->getNumArgs() == 1);
725 const Expr *Arg = Call->getArg(0);
726
729 int32_t ReturnVal = static_cast<int32_t>(ResultClass);
731 return true;
732}
733
734
735
739
740
741 unsigned NumArgs = Call->getNumArgs();
742 assert(NumArgs == 2 || NumArgs == 3);
743
745 if (NumArgs == 3)
748
751 return true;
752}
753
757#ifndef NDEBUG
758 assert(Call->getArg(0)->isLValue());
760 assert(PtrT == PT_Ptr &&
761 "Unsupported pointer type passed to __builtin_addressof()");
762#endif
763 return true;
764}
765
769 return Call->getDirectCallee()->isConstexpr();
770}
771
776
778 Arg.getZExtValue());
780 return true;
781}
782
783
786 unsigned BuiltinOp) {
789 return false;
790
795 QualType ResultType = Call->getArg(2)->getType()->getPointeeType();
797 bool Overflow;
798
800 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
801 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
802 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
803 bool IsSigned = LHS.isSigned() || RHS.isSigned() ||
805 bool AllSigned = LHS.isSigned() && RHS.isSigned() &&
807 uint64_t LHSSize = LHS.getBitWidth();
808 uint64_t RHSSize = RHS.getBitWidth();
810 uint64_t MaxBits = std::max(std::max(LHSSize, RHSSize), ResultSize);
811
812
813
814
815
816 if (IsSigned && !AllSigned)
817 ++MaxBits;
818
819 LHS = APSInt(LHS.extOrTrunc(MaxBits), !IsSigned);
820 RHS = APSInt(RHS.extOrTrunc(MaxBits), !IsSigned);
822 }
823
824
825 switch (BuiltinOp) {
826 default:
827 llvm_unreachable("Invalid value for BuiltinOp");
828 case Builtin::BI__builtin_add_overflow:
829 case Builtin::BI__builtin_sadd_overflow:
830 case Builtin::BI__builtin_saddl_overflow:
831 case Builtin::BI__builtin_saddll_overflow:
832 case Builtin::BI__builtin_uadd_overflow:
833 case Builtin::BI__builtin_uaddl_overflow:
834 case Builtin::BI__builtin_uaddll_overflow:
835 Result = LHS.isSigned() ? LHS.sadd_ov(RHS, Overflow)
836 : LHS.uadd_ov(RHS, Overflow);
837 break;
838 case Builtin::BI__builtin_sub_overflow:
839 case Builtin::BI__builtin_ssub_overflow:
840 case Builtin::BI__builtin_ssubl_overflow:
841 case Builtin::BI__builtin_ssubll_overflow:
842 case Builtin::BI__builtin_usub_overflow:
843 case Builtin::BI__builtin_usubl_overflow:
844 case Builtin::BI__builtin_usubll_overflow:
845 Result = LHS.isSigned() ? LHS.ssub_ov(RHS, Overflow)
846 : LHS.usub_ov(RHS, Overflow);
847 break;
848 case Builtin::BI__builtin_mul_overflow:
849 case Builtin::BI__builtin_smul_overflow:
850 case Builtin::BI__builtin_smull_overflow:
851 case Builtin::BI__builtin_smulll_overflow:
852 case Builtin::BI__builtin_umul_overflow:
853 case Builtin::BI__builtin_umull_overflow:
854 case Builtin::BI__builtin_umulll_overflow:
855 Result = LHS.isSigned() ? LHS.smul_ov(RHS, Overflow)
856 : LHS.umul_ov(RHS, Overflow);
857 break;
858 }
859
860
861
862 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
863 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
864 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
865
866
867
868
871
872 if (!APSInt::isSameValue(Temp, Result))
873 Overflow = true;
874 Result = std::move(Temp);
875 }
876
877
881
882 assert(Call->getDirectCallee()->getReturnType()->isBooleanType());
884 return true;
885}
886
887
897
899 return false;
900
902
904
906 CarryOut = LHS;
907
908 bool FirstOverflowed = false;
909 bool SecondOverflowed = false;
910 switch (BuiltinOp) {
911 default:
912 llvm_unreachable("Invalid value for BuiltinOp");
913 case Builtin::BI__builtin_addcb:
914 case Builtin::BI__builtin_addcs:
915 case Builtin::BI__builtin_addc:
916 case Builtin::BI__builtin_addcl:
917 case Builtin::BI__builtin_addcll:
919 LHS.uadd_ov(RHS, FirstOverflowed).uadd_ov(CarryIn, SecondOverflowed);
920 break;
921 case Builtin::BI__builtin_subcb:
922 case Builtin::BI__builtin_subcs:
923 case Builtin::BI__builtin_subc:
924 case Builtin::BI__builtin_subcl:
925 case Builtin::BI__builtin_subcll:
927 LHS.usub_ov(RHS, FirstOverflowed).usub_ov(CarryIn, SecondOverflowed);
928 break;
929 }
930
931
932 CarryOut = (uint64_t)(FirstOverflowed | SecondOverflowed);
933
934 QualType CarryOutType = Call->getArg(3)->getType()->getPointeeType();
936 assignInteger(S, CarryOutPtr, CarryOutT, CarryOut);
938
939 assert(Call->getType() == Call->getArg(0)->getType());
941 return true;
942}
943
946 unsigned BuiltinOp) {
947
948 std::optional Fallback;
949 if (BuiltinOp == Builtin::BI__builtin_clzg && Call->getNumArgs() == 2)
951
953 if (Call->getArg(0)->getType()->isExtVectorBoolType()) {
956 } else {
958 }
959
960
961
962 bool ZeroIsUndefined = BuiltinOp != Builtin::BI__lzcnt16 &&
963 BuiltinOp != Builtin::BI__lzcnt &&
964 BuiltinOp != Builtin::BI__lzcnt64;
965
966 if (Val == 0) {
967 if (Fallback) {
969 return true;
970 }
971
972 if (ZeroIsUndefined)
973 return false;
974 }
975
977 return true;
978}
979
982 unsigned BuiltinID) {
983 std::optional Fallback;
984 if (BuiltinID == Builtin::BI__builtin_ctzg && Call->getNumArgs() == 2)
986
988 if (Call->getArg(0)->getType()->isExtVectorBoolType()) {
991 } else {
993 }
994
995 if (Val == 0) {
996 if (Fallback) {
998 return true;
999 }
1000 return false;
1001 }
1002
1004 return true;
1005}
1006
1011 if (Val.getBitWidth() == 8)
1013 else
1015 return true;
1016}
1017
1018
1019
1023 unsigned BuiltinOp) {
1024 auto returnBool = [&S](bool Value) -> bool {
1026 return true;
1027 };
1028
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1043 if (Size.isPowerOfTwo()) {
1044
1045 unsigned InlineWidthBits =
1048
1049
1050
1052 return returnBool(true);
1053
1054
1055 assert(BuiltinOp != Builtin::BI__c11_atomic_is_lock_free);
1057 return returnBool(true);
1058
1061 if (APSInt(APInt(64, IntVal, false), true).isAligned(Size.getAsAlign()))
1062 return returnBool(true);
1063 }
1064
1065 const Expr *PtrArg = Call->getArg(1);
1066
1067 if (const auto *ICE = dyn_cast(PtrArg)) {
1068
1069
1070 if (ICE->getCastKind() == CK_BitCast)
1071 PtrArg = ICE->getSubExpr();
1072 }
1073
1078
1079 return returnBool(true);
1080 }
1081 }
1082 }
1083 }
1084
1085 if (BuiltinOp == Builtin::BI__atomic_always_lock_free)
1086 return returnBool(false);
1087
1088 return false;
1089}
1090
1091
1097
1099 if (Size.isPowerOfTwo()) {
1100
1101 unsigned InlineWidthBits =
1105 return true;
1106 }
1107 }
1108
1109 return false;
1110}
1111
1112
1119
1122 Result.initializeAllElements();
1123
1124 return true;
1125}
1126
1127
1128
1129
1130
1131
1135 unsigned BuiltinOp) {
1137
1138 if (Alignment < 0 || !Alignment.isPowerOf2()) {
1139 S.FFDiag(Call, diag::note_constexpr_invalid_alignment) << Alignment;
1140 return false;
1141 }
1143 APSInt MaxValue(APInt::getOneBitSet(SrcWidth, SrcWidth - 1));
1144 if (APSInt::compareValues(Alignment, MaxValue) > 0) {
1145 S.FFDiag(Call, diag::note_constexpr_alignment_too_big)
1146 << MaxValue << Call->getArg(0)->getType() << Alignment;
1147 return false;
1148 }
1149
1150
1152
1155 APInt AlignMinusOne = Alignment.extOrTrunc(Src.getBitWidth()) - 1;
1156 if (BuiltinOp == Builtin::BI__builtin_align_up) {
1158 APSInt((Src + AlignMinusOne) & ~AlignMinusOne, Src.isUnsigned());
1160 } else if (BuiltinOp == Builtin::BI__builtin_align_down) {
1161 APSInt AlignedVal = APSInt(Src & ~AlignMinusOne, Src.isUnsigned());
1163 } else {
1166 }
1167 return true;
1168 }
1169 assert(FirstArgT == PT_Ptr);
1172 return false;
1173
1174 unsigned PtrOffset = Ptr.getIndex();
1179
1180 if (BuiltinOp == Builtin::BI__builtin_is_aligned) {
1181 if (PtrAlign.getQuantity() >= Alignment) {
1183 return true;
1184 }
1185
1186
1187
1188
1189 if (BaseAlignment.getQuantity() >= Alignment &&
1192 return true;
1193 }
1194
1195 S.FFDiag(Call->getArg(0), diag::note_constexpr_alignment_compute)
1196 << Alignment;
1197 return false;
1198 }
1199
1200 assert(BuiltinOp == Builtin::BI__builtin_align_down ||
1201 BuiltinOp == Builtin::BI__builtin_align_up);
1202
1203
1204
1205 if (PtrAlign.getQuantity() >= Alignment) {
1207 return true;
1208 }
1209
1210
1211
1212
1213
1214
1215 if (BaseAlignment.getQuantity() >= Alignment) {
1216 assert(Alignment.getBitWidth() <= 64 &&
1217 "Cannot handle > 64-bit address-space");
1218 uint64_t Alignment64 = Alignment.getZExtValue();
1221 ? llvm::alignDown(PtrOffset, Alignment64)
1222 : llvm::alignTo(PtrOffset, Alignment64));
1223
1225 return true;
1226 }
1227
1228
1229 S.FFDiag(Call->getArg(0), diag::note_constexpr_alignment_adjust) << Alignment;
1230 return false;
1231}
1232
1233
1237 assert(Call->getNumArgs() == 2 || Call->getNumArgs() == 3);
1238
1239 std::optional ExtraOffset;
1240 if (Call->getNumArgs() == 3)
1242
1245
1247
1248
1255
1256 if (BaseAlignment < Align) {
1258 diag::note_constexpr_baa_insufficient_alignment)
1259 << 0 << BaseAlignment.getQuantity() << Align.getQuantity();
1260 return false;
1261 }
1262 }
1263
1266 if (ExtraOffset)
1268 if (AVOffset.alignTo(Align) != AVOffset) {
1271 diag::note_constexpr_baa_insufficient_alignment)
1272 << 1 << AVOffset.getQuantity() << Align.getQuantity();
1273 else
1275 diag::note_constexpr_baa_value_insufficient_alignment)
1276 << AVOffset.getQuantity() << Align.getQuantity();
1277 return false;
1278 }
1279
1281 return true;
1282}
1283
1284
1289 unsigned BuiltinOp) {
1290 if (Call->getNumArgs() != 4 || ->getArg(0)->getType()->isIntegerType() ||
1291 ->getArg(1)->getType()->isIntegerType() ||
1292 ->getArg(2)->getType()->isIntegerType())
1293 return false;
1294
1296
1300
1301 bool IsAdd = BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u32 ||
1302 BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u64;
1303
1304 unsigned BitWidth = LHS.getBitWidth();
1305 unsigned CarryInBit = CarryIn.ugt(0) ? 1 : 0;
1306 APInt ExResult =
1307 IsAdd ? (LHS.zext(BitWidth + 1) + (RHS.zext(BitWidth + 1) + CarryInBit))
1308 : (LHS.zext(BitWidth + 1) - (RHS.zext(BitWidth + 1) + CarryInBit));
1309
1310 APInt Result = ExResult.extractBits(BitWidth, 0);
1312 APSInt(ExResult.extractBits(1, BitWidth), true);
1313
1314 QualType CarryOutType = Call->getArg(3)->getType()->getPointeeType();
1317
1319
1320 return true;
1321}
1322
1332
1333static bool
1338 assert(Ptr.getFieldDesc()->isPrimitiveArray());
1339
1340
1341
1342 assert(Ptr.getFieldDesc()->getNumElems() >= 1);
1343 StringRef R(&Ptr.deref<char>(), Ptr.getFieldDesc()->getNumElems() - 1);
1344 uint64_t Result = getPointerAuthStableSipHash(R);
1346 return true;
1347}
1348
1354 auto Mode =
1357 uint64_t MaxTokens =
1358 MaxTokensOpt.value_or(0) ? *MaxTokensOpt : (~0ULL >> (64 - BitWidth));
1359
1360
1361 for (int I = Call->getNumArgs() - 1; I >= 0; --I)
1363
1364
1365
1367 if (AllocType.isNull()) {
1369 diag::note_constexpr_infer_alloc_token_type_inference_failed);
1370 return false;
1371 }
1372
1374 if (!ATMD) {
1375 S.CCEDiag(Call, diag::note_constexpr_infer_alloc_token_no_metadata);
1376 return false;
1377 }
1378
1379 auto MaybeToken = llvm::getAllocToken(Mode, *ATMD, MaxTokens);
1380 if (!MaybeToken) {
1381 S.CCEDiag(Call, diag::note_constexpr_infer_alloc_token_stateful_mode);
1382 return false;
1383 }
1384
1386 return true;
1387}
1388
1392
1393
1394
1396
1397 if (ElemType.isNull()) {
1399 ? diag::note_constexpr_new_untyped
1400 : diag::note_constexpr_new);
1401 return false;
1402 }
1403 assert(NewCall);
1404
1405 if (ElemType->isIncompleteType() || ElemType->isFunctionType()) {
1406 S.FFDiag(Call, diag::note_constexpr_new_not_complete_object_type)
1407 << (ElemType->isIncompleteType() ? 0 : 1) << ElemType;
1408 return false;
1409 }
1410
1411
1412
1413 {
1414 unsigned NumArgs = Call->getNumArgs();
1415 assert(NumArgs >= 1);
1416
1417
1418 if (Call->getArg(NumArgs - 1)->getType()->isNothrowT())
1419 --NumArgs;
1421
1422 Args = Args.drop_front();
1423
1424
1425 for (const Expr *Arg : Args)
1427 }
1428
1431 assert(!ElemSize.isZero());
1432
1433
1434 APInt NumElems, Remainder;
1436 APInt::udivrem(Bytes, ElemSizeAP, NumElems, Remainder);
1437 if (Remainder != 0) {
1438
1439 S.FFDiag(Call, diag::note_constexpr_operator_new_bad_size)
1440 << Bytes << APSInt(ElemSizeAP, true) << ElemType;
1441 return false;
1442 }
1443
1444
1445 if (NumElems.getActiveBits() >
1448
1450 S.FFDiag(Loc, diag::note_constexpr_new_too_large)
1451 << NumElems.getZExtValue();
1452 return false;
1453 }
1454
1455 if ((S, OpPC, NumElems.getZExtValue()))
1456 return false;
1457
1458 bool IsArray = NumElems.ugt(1);
1461 if (ElemT) {
1463 Allocator.allocate(NewCall, *ElemT, NumElems.getZExtValue(),
1465 assert(B);
1467 return true;
1468 }
1469
1470 assert(!ElemT);
1471
1472
1473 if (IsArray) {
1475 S.P.createDescriptor(NewCall, ElemType.getTypePtr(), std::nullopt);
1479 assert(B);
1481 return true;
1482 }
1483
1484
1487
1492 assert(B);
1494 return true;
1495}
1496
1500 const Expr *Source = nullptr;
1501 const Block *BlockToDelete = nullptr;
1502
1505 return false;
1506 }
1507
1508
1512 return true;
1513 }
1514
1515 {
1517
1519 S.CCEDiag(Call, diag::note_constexpr_deallocate_null);
1520 return true;
1521 }
1522
1524 BlockToDelete = Ptr.block();
1525
1526 if (!BlockToDelete->isDynamic()) {
1527 S.FFDiag(Call, diag::note_constexpr_delete_not_heap_alloc)
1530 S.Note(D->getLocation(), diag::note_declared_at);
1531 }
1532 }
1533 assert(BlockToDelete);
1534
1537 std::optionalDynamicAllocator::Form AllocForm =
1539
1540 if (!Allocator.deallocate(Source, BlockToDelete, S)) {
1541
1543 S.FFDiag(Loc, diag::note_constexpr_double_delete);
1544 return false;
1545 }
1546 assert(AllocForm);
1547
1550}
1551
1559
1564
1566 assert(Call->getType() == ElemType);
1569
1572 unsigned BitWidth = Result.bitWidth();
1573 for (unsigned I = 1; I != NumElems; ++I) {
1576
1577 if (ID == Builtin::BI__builtin_reduce_add) {
1578 if (T::add(Result, Elem, BitWidth, &Result)) {
1579 unsigned OverflowBits = BitWidth + 1;
1581 (PrevResult.toAPSInt(OverflowBits) +
1582 Elem.toAPSInt(OverflowBits)));
1583 return false;
1584 }
1585 } else if (ID == Builtin::BI__builtin_reduce_mul) {
1586 if (T::mul(Result, Elem, BitWidth, &Result)) {
1587 unsigned OverflowBits = BitWidth * 2;
1589 (PrevResult.toAPSInt(OverflowBits) *
1590 Elem.toAPSInt(OverflowBits)));
1591 return false;
1592 }
1593
1594 } else if (ID == Builtin::BI__builtin_reduce_and) {
1595 (void)T::bitAnd(Result, Elem, BitWidth, &Result);
1596 } else if (ID == Builtin::BI__builtin_reduce_or) {
1597 (void)T::bitOr(Result, Elem, BitWidth, &Result);
1598 } else if (ID == Builtin::BI__builtin_reduce_xor) {
1599 (void)T::bitXor(Result, Elem, BitWidth, &Result);
1600 } else if (ID == Builtin::BI__builtin_reduce_min) {
1603 } else if (ID == Builtin::BI__builtin_reduce_max) {
1606 } else {
1607 llvm_unreachable("Unhandled vector reduce builtin");
1608 }
1609 }
1611 });
1612
1613 return true;
1614}
1615
1619 unsigned BuiltinID) {
1620 assert(Call->getNumArgs() == 1);
1625 return true;
1626 }
1627
1632 return true;
1633 }
1634
1635
1636 assert(Call->getArg(0)->getType()->isVectorType());
1643
1647
1648 for (unsigned I = 0; I != NumElems; ++I) {
1651 Dst.elem<T>(I) = T::from(static_cast<T>(
1654 });
1655 } else {
1658 }
1659 }
1661
1662 return true;
1663}
1664
1665
1670 unsigned BuiltinID) {
1671 bool HasZeroArg = Call->getNumArgs() == 2;
1672 bool IsCTTZ = BuiltinID == Builtin::BI__builtin_elementwise_ctzg;
1673 assert(Call->getNumArgs() == 1 || HasZeroArg);
1674 if (Call->getArg(0)->getType()->isIntegerType()) {
1677 std::optional ZeroVal;
1678 if (HasZeroArg) {
1679 ZeroVal = Val;
1681 }
1682
1683 if (Val.isZero()) {
1684 if (ZeroVal) {
1686 return true;
1687 }
1688
1689
1691 diag::note_constexpr_countzeroes_zero)
1692 << IsCTTZ;
1693 return false;
1694 }
1695
1696 if (BuiltinID == Builtin::BI__builtin_elementwise_clzg) {
1697 pushInteger(S, Val.countLeadingZeros(), Call->getType());
1698 } else {
1699 pushInteger(S, Val.countTrailingZeros(), Call->getType());
1700 }
1701 return true;
1702 }
1703
1706 if (HasZeroArg) {
1707 assert(Call->getArg(1)->getType()->isVectorType() &&
1709 Call->getArg(1)->getType()));
1710 (void)ASTCtx;
1713 }
1714 assert(Call->getArg(0)->getType()->isVectorType());
1721
1725
1726
1727 for (unsigned I = 0; I != NumElems; ++I) {
1730 if (EltVal.isZero()) {
1731 if (HasZeroArg) {
1733 } else {
1734
1735
1737 diag::note_constexpr_countzeroes_zero)
1738 << IsCTTZ;
1739 return false;
1740 }
1741 } else if (IsCTTZ) {
1742 Dst.atIndex(I).deref<T>() = T::from(EltVal.countTrailingZeros());
1743 } else {
1744 Dst.atIndex(I).deref<T>() = T::from(EltVal.countLeadingZeros());
1745 }
1747 });
1748 }
1749
1750 return true;
1751}
1752
1756 assert(Call->getNumArgs() == 3);
1761
1762 if (ID == Builtin::BImemcpy || ID == Builtin::BImemmove)
1764
1765 bool Move =
1766 (ID == Builtin::BI__builtin_memmove || ID == Builtin::BImemmove ||
1767 ID == Builtin::BI__builtin_wmemmove || ID == Builtin::BIwmemmove);
1768 bool WChar = ID == Builtin::BIwmemcpy || ID == Builtin::BIwmemmove ||
1769 ID == Builtin::BI__builtin_wmemcpy ||
1770 ID == Builtin::BI__builtin_wmemmove;
1771
1772
1773 if (Size == 0) {
1775 return true;
1776 }
1777
1779 Pointer DiagPtr = (SrcPtr.isZero() ? SrcPtr : DestPtr);
1781 << Move << WChar << !SrcPtr.isZero()
1783 return false;
1784 }
1785
1786
1788 std::string DiagVal = "(void *)";
1794 return false;
1795 }
1796
1797
1799 return false;
1800
1803 diag::note_constexpr_memcpy_incomplete_type)
1804 << Move << DestPtr.getType();
1805 return false;
1806 }
1809 diag::note_constexpr_memcpy_incomplete_type)
1810 << Move << SrcPtr.getType();
1811 return false;
1812 }
1813
1817 diag::note_constexpr_memcpy_incomplete_type)
1818 << Move << DestElemType;
1819 return false;
1820 }
1821
1822 size_t RemainingDestElems;
1825 ? 0
1827 } else {
1828 RemainingDestElems = 1;
1829 }
1831
1832 if (WChar) {
1833 uint64_t WCharSize =
1835 Size *= WCharSize;
1836 }
1837
1838 if (Size % DestElemSize != 0) {
1840 diag::note_constexpr_memcpy_unsupported)
1841 << Move << WChar << 0 << DestElemType << Size << DestElemSize;
1842 return false;
1843 }
1844
1846 size_t RemainingSrcElems;
1849 ? 0
1851 } else {
1852 RemainingSrcElems = 1;
1853 }
1855
1858 << Move << SrcElemType << DestElemType;
1859 return false;
1860 }
1861
1864 << Move << DestElemType;
1865 return false;
1866 }
1867
1868
1869 size_t RemainingDestBytes = RemainingDestElems * DestElemSize;
1870 size_t RemainingSrcBytes = RemainingSrcElems * SrcElemSize;
1871 if (Size > RemainingDestBytes || Size > RemainingSrcBytes) {
1872 APInt N = APInt(64, Size / DestElemSize);
1874 diag::note_constexpr_memcpy_unsupported)
1875 << Move << WChar << (Size > RemainingSrcBytes ? 1 : 2) << DestElemType
1876 << toString(N, 10, false);
1877 return false;
1878 }
1879
1880
1882
1886
1887 Pointer DestP = DestPtr;
1889 DestP = DestP.getBase();
1890
1893
1894 if ((SrcIndex <= DstIndex && (SrcIndex + Size) > DstIndex) ||
1895 (DstIndex <= SrcIndex && (DstIndex + Size) > SrcIndex)) {
1897 << false;
1898 return false;
1899 }
1900 }
1901
1902 assert(Size % DestElemSize == 0);
1903 if ((S, OpPC, SrcPtr, DestPtr, Bytes(Size).toBits()))
1904 return false;
1905
1907 return true;
1908}
1909
1910
1911
1913 return T->isCharType() || T->isChar8Type();
1914}
1915
1919 assert(Call->getNumArgs() == 3);
1923
1924 if (ID == Builtin::BImemcmp || ID == Builtin::BIbcmp ||
1925 ID == Builtin::BIwmemcmp)
1927
1928 if (Size == 0) {
1930 return true;
1931 }
1932
1933 if (!PtrA.isBlockPointer() || !PtrB.isBlockPointer())
1934 return false;
1935
1936 bool IsWide =
1937 (ID == Builtin::BIwmemcmp || ID == Builtin::BI__builtin_wmemcmp);
1938
1942
1943
1947 diag::note_constexpr_memcmp_unsupported)
1950 return false;
1951 }
1952
1953 if (PtrA.isDummy() || PtrB.isDummy())
1954 return false;
1955
1958 return false;
1959
1960
1962 Bits(ASTCtx.getTypeSize(ElemTypeA) * PtrA.getNumElems()));
1964
1965
1968
1972
1973
1976
1979
1980 unsigned ElemSize = 1;
1981 if (IsWide)
1983
1984
1985 size_t ByteSize = Size * ElemSize;
1986 size_t CmpSize = std::min(MinBufferSize, ByteSize);
1987
1988 for (size_t I = 0; I != CmpSize; I += ElemSize) {
1989 if (IsWide) {
1991 T A = *reinterpret_cast<T *>(BufferA.atByte(I));
1992 T B = *reinterpret_cast<T *>(BufferB.atByte(I));
1993 if (A < B) {
1994 pushInteger(S, -1, Call->getType());
1995 return true;
1996 }
1997 if (A > B) {
1999 return true;
2000 }
2001 });
2002 } else {
2003 std::byte A = BufferA.derefstd::byte(Bytes(I));
2004 std::byte B = BufferB.derefstd::byte(Bytes(I));
2005
2006 if (A < B) {
2008 return true;
2009 }
2010 if (A > B) {
2012 return true;
2013 }
2014 }
2015 }
2016
2017
2018
2019 if (ByteSize <= CmpSize) {
2021 return true;
2022 }
2023
2024
2025
2026
2027
2028 S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_access_past_end)
2029 << AK_Read << S.Current->getRange(OpPC);
2030 return false;
2031}
2032
2033
2034
2037 if (ID == Builtin::BImemchr || ID == Builtin::BIwcschr ||
2038 ID == Builtin::BIstrchr || ID == Builtin::BIwmemchr)
2040
2041 std::optional MaxLength;
2042 if (Call->getNumArgs() == 3)
2044
2047
2048 if (MaxLength && MaxLength->isZero()) {
2050 return true;
2051 }
2052
2056 diag::note_constexpr_ltor_incomplete_type)
2058 return false;
2059 }
2060
2061
2065 return false;
2066 }
2067
2071 bool IsRawByte = ID == Builtin::BImemchr || ID == Builtin::BI__builtin_memchr;
2072
2073
2076 diag::note_constexpr_memchr_unsupported)
2078 return false;
2079 }
2080
2081 if (ID == Builtin::BIstrchr || ID == Builtin::BI__builtin_strchr) {
2082 int64_t DesiredTrunc;
2084 DesiredTrunc =
2086 else
2087 DesiredTrunc =
2089
2090
2091 if (Desired != DesiredTrunc) {
2093 return true;
2094 }
2095 }
2096
2097 uint64_t DesiredVal;
2098 if (ID == Builtin::BIwmemchr || ID == Builtin::BI__builtin_wmemchr ||
2099 ID == Builtin::BIwcschr || ID == Builtin::BI__builtin_wcschr) {
2100
2101 DesiredVal = Desired.getZExtValue();
2102 } else {
2104 }
2105
2106 bool StopAtZero =
2107 (ID == Builtin::BIstrchr || ID == Builtin::BI__builtin_strchr ||
2108 ID == Builtin::BIwcschr || ID == Builtin::BI__builtin_wcschr);
2109
2112
2113 size_t Index = Ptr.getIndex();
2114 size_t Step = 0;
2115 for (;;) {
2116 const Pointer &ElemPtr =
2117 (Index + Step) > 0 ? Ptr.atIndex(Index + Step) : Ptr;
2118
2119 if ((S, OpPC, ElemPtr))
2120 return false;
2121
2122 uint64_t V;
2124 ElemT, { V = static_cast<uint64_t>(ElemPtr.deref<T>().toUnsigned()); });
2125
2126 if (V == DesiredVal) {
2128 return true;
2129 }
2130
2131 if (StopAtZero && V == 0)
2132 break;
2133
2134 ++Step;
2135 if (MaxLength && Step == MaxLength->getZExtValue())
2136 break;
2137 }
2138
2140 return true;
2141}
2142
2151
2152
2153 return ASTCtx
2157 }
2158
2159 return std::nullopt;
2160}
2161
2162
2165 unsigned Result = 0;
2166
2171
2173 unsigned ElemSize =
2177 else
2185
2188 if (IsVirtual)
2190 else
2192 } else if (P.isField()) {
2197 uint64_t FieldOffset =
2200 Result += FieldOffset;
2202 } else
2203 llvm_unreachable("Unhandled descriptor type");
2204 }
2205
2207}
2208
2209
2212 while (!P.isRoot()) {
2213
2216 continue;
2217 }
2220 return false;
2222 continue;
2223 }
2224
2226 if (const Record *R = Base.getRecord()) {
2229 return false;
2230 }
2232 }
2233
2234 return true;
2235}
2236
2237
2239 auto isFlexibleArrayMember = [&](const Descriptor *FieldDesc) {
2241 FAMKind StrictFlexArraysLevel =
2242 Ctx.getLangOpts().getStrictFlexArraysLevel();
2243
2244 if (StrictFlexArraysLevel == FAMKind::Default)
2245 return true;
2246
2247 unsigned NumElems = FieldDesc->getNumElems();
2248 if (NumElems == 0 && StrictFlexArraysLevel != FAMKind::IncompleteOnly)
2249 return true;
2250
2251 if (NumElems == 1 && StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete)
2252 return true;
2253 return false;
2254 };
2255
2257 if (!FieldDesc->isArray())
2258 return false;
2259
2261 isFlexibleArrayMember(FieldDesc);
2262}
2263
2268
2269
2270
2271
2272
2274 assert(Kind <= 3 && "unexpected kind");
2275 bool UseFieldDesc = (Kind & 1u);
2276 bool ReportMinimum = (Kind & 2u);
2278
2279 if (Call->getArg(0)->HasSideEffects(ASTCtx)) {
2280
2281
2283 return true;
2284 }
2285
2287 return false;
2288
2289
2291 return false;
2292
2295 assert(DeclDesc);
2296
2297 if (!UseFieldDesc || DetermineForCompleteObject) {
2298
2299 if (ReportMinimum && !DetermineForCompleteObject)
2300 return false;
2301
2302
2303 if (!UseFieldDesc && !ReportMinimum && DeclDesc->getType()->isPointerType())
2304 return false;
2305 } else {
2307
2308
2309
2310 if (Kind == 1)
2311 return false;
2312 }
2313 }
2314
2316 assert(Desc);
2317
2319 if (!FullSize)
2320 return false;
2321
2322 unsigned ByteOffset;
2323 if (UseFieldDesc) {
2327 else {
2329 ByteOffset =
2332 else
2333 ByteOffset = 0;
2334 }
2335 } else
2337
2338 assert(ByteOffset <= *FullSize);
2339 unsigned Result = *FullSize - ByteOffset;
2340
2342 return true;
2343}
2344
2347
2349 return false;
2350
2352
2354 bool CalledFromStd = false;
2356 if (Callee && Callee->isInStdNamespace()) {
2357 const IdentifierInfo *Identifier = Callee->getIdentifier();
2358 CalledFromStd = Identifier && Identifier->isStr("is_within_lifetime");
2359 }
2363 diag::err_invalid_is_within_lifetime)
2364 << (CalledFromStd ? "std::is_within_lifetime"
2365 : "__builtin_is_within_lifetime")
2367 return false;
2368 };
2369
2371 return Error(0);
2373 return Error(1);
2374
2378 } else {
2380 return false;
2382 return false;
2384 return false;
2385 }
2386
2387
2389 return Error(2);
2391 return Error(2);
2392
2394 return true;
2395}
2396
2400 assert(Call->getNumArgs() == 1);
2401
2402
2403 if (->getArg(0)->getType()->isVectorType()) {
2404 assert(Call->getType()->isIntegerType());
2408 return true;
2409 }
2410
2411
2418
2422 bool DestUnsigned = Call->getType()->isUnsignedIntegerOrEnumerationType();
2423
2424 for (unsigned I = 0; I != NumElems; ++I) {
2428 Dst.elem<T>(I) = static_cast<T>(APSInt(std::move(Result), DestUnsigned));
2429 });
2430 }
2432
2433 return true;
2434}
2435
2439 assert(Call->getNumArgs() == 2);
2440
2441
2442 if (->getArg(0)->getType()->isVectorType()) {
2443 assert(->getArg(1)->getType()->isVectorType());
2448 return true;
2449 }
2450
2451 const auto *VT = Call->getArg(0)->getType()->castAs<VectorType>();
2452 assert(VT->getElementType()->isIntegralOrEnumerationType());
2454 unsigned NumElems = VT->getNumElements();
2455 bool DestUnsigned = Call->getType()->isUnsignedIntegerOrEnumerationType();
2456
2457
2458 if (->getArg(1)->getType()->isVectorType()) {
2459 assert(Call->getArg(1)->getType()->isIntegralOrEnumerationType());
2460
2464
2465 for (unsigned I = 0; I != NumElems; ++I) {
2467 Dst.elem<T>(I) = static_cast<T>(
2468 APSInt(Fn(LHS.elem<T>(I).toAPSInt(), RHS), DestUnsigned));
2469 });
2470 }
2472 return true;
2473 }
2474
2475
2476 assert(Call->getArg(0)->getType()->isVectorType() &&
2477 Call->getArg(1)->getType()->isVectorType());
2478 assert(VT->getElementType() ==
2480 assert(VT->getNumElements() ==
2482 assert(VT->getElementType()->isIntegralOrEnumerationType());
2483
2487 for (unsigned I = 0; I != NumElems; ++I) {
2489 APSInt Elem1 = LHS.elem<T>(I).toAPSInt();
2490 APSInt Elem2 = RHS.elem<T>(I).toAPSInt();
2491 Dst.elem<T>(I) = static_cast<T>(APSInt(Fn(Elem1, Elem2), DestUnsigned));
2492 });
2493 }
2495
2496 return true;
2497}
2498
2499static bool
2501 llvm::function_ref<APInt(const APSInt &)> PackFn) {
2503 [[maybe_unused]] const auto *VT1 =
2505 assert(VT0 && VT1 && "pack builtin VT0 and VT1 must be VectorType");
2506 assert(VT0->getElementType() == VT1->getElementType() &&
2508 "pack builtin VT0 and VT1 ElementType must be same");
2509
2513
2515 unsigned SrcBits = ASTCtx.getIntWidth(VT0->getElementType());
2516 unsigned LHSVecLen = VT0->getNumElements();
2517 unsigned SrcPerLane = 128 / SrcBits;
2518 unsigned Lanes = LHSVecLen * SrcBits / 128;
2519
2522 bool IsUnsigend = getElemType(Dst)->isUnsignedIntegerType();
2523
2524 for (unsigned Lane = 0; Lane != Lanes; ++Lane) {
2525 unsigned BaseSrc = Lane * SrcPerLane;
2526 unsigned BaseDst = Lane * (2 * SrcPerLane);
2527
2528 for (unsigned I = 0; I != SrcPerLane; ++I) {
2530 APSInt A = LHS.elem<T>(BaseSrc + I).toAPSInt();
2531 APSInt B = RHS.elem<T>(BaseSrc + I).toAPSInt();
2532
2533 assignInteger(S, Dst.atIndex(BaseDst + I), DstT,
2534 APSInt(PackFn(A), IsUnsigend));
2535 assignInteger(S, Dst.atIndex(BaseDst + SrcPerLane + I), DstT,
2536 APSInt(PackFn(B), IsUnsigend));
2537 });
2538 }
2539 }
2540
2541 Dst.initializeAllElements();
2542 return true;
2543}
2544
2547 unsigned BuiltinID) {
2548 assert(Call->getNumArgs() == 2);
2549
2550 QualType Arg0Type = Call->getArg(0)->getType();
2551
2552
2556 return false;
2557
2559 assert(->getArg(1)->getType()->isVectorType());
2563 if (BuiltinID == Builtin::BI__builtin_elementwise_max) {
2564 Result = std::max(LHS, RHS);
2565 } else if (BuiltinID == Builtin::BI__builtin_elementwise_min) {
2566 Result = std::min(LHS, RHS);
2567 } else {
2568 llvm_unreachable("Wrong builtin ID");
2569 }
2570
2572 return true;
2573 }
2574
2575
2576 assert(Call->getArg(0)->getType()->isVectorType() &&
2577 Call->getArg(1)->getType()->isVectorType());
2578 const auto *VT = Call->getArg(0)->getType()->castAs<VectorType>();
2579 assert(VT->getElementType() ==
2581 assert(VT->getNumElements() ==
2583 assert(VT->getElementType()->isIntegralOrEnumerationType());
2584
2589 unsigned NumElems = VT->getNumElements();
2590 for (unsigned I = 0; I != NumElems; ++I) {
2594 Elem1 = LHS.elem<T>(I).toAPSInt();
2595 Elem2 = RHS.elem<T>(I).toAPSInt();
2596 });
2597
2599 if (BuiltinID == Builtin::BI__builtin_elementwise_max) {
2601 Call->getType()->isUnsignedIntegerOrEnumerationType());
2602 } else if (BuiltinID == Builtin::BI__builtin_elementwise_min) {
2604 Call->getType()->isUnsignedIntegerOrEnumerationType());
2605 } else {
2606 llvm_unreachable("Wrong builtin ID");
2607 }
2608
2610 { Dst.elem<T>(I) = static_cast<T>(Result); });
2611 }
2612 Dst.initializeAllElements();
2613
2614 return true;
2615}
2616
2621 Fn) {
2622 assert(Call->getArg(0)->getType()->isVectorType() &&
2623 Call->getArg(1)->getType()->isVectorType());
2627
2628 const auto *VT = Call->getArg(0)->getType()->castAs<VectorType>();
2630 unsigned NumElems = VT->getNumElements();
2631 const auto *DestVT = Call->getType()->castAs<VectorType>();
2633 bool DestUnsigned = Call->getType()->isUnsignedIntegerOrEnumerationType();
2634
2635 unsigned DstElem = 0;
2636 for (unsigned I = 0; I != NumElems; I += 2) {
2639 APSInt LoLHS = LHS.elem<T>(I).toAPSInt();
2640 APSInt HiLHS = LHS.elem<T>(I + 1).toAPSInt();
2641 APSInt LoRHS = RHS.elem<T>(I).toAPSInt();
2642 APSInt HiRHS = RHS.elem<T>(I + 1).toAPSInt();
2643 Result = APSInt(Fn(LoLHS, HiLHS, LoRHS, HiRHS), DestUnsigned);
2644 });
2645
2647 { Dst.elem<T>(DstElem) = static_cast<T>(Result); });
2648 ++DstElem;
2649 }
2650
2651 Dst.initializeAllElements();
2652 return true;
2653}
2654
2658 const auto *VT = Call->getArg(0)->getType()->castAs<VectorType>();
2660 bool DestUnsigned = Call->getType()->isUnsignedIntegerOrEnumerationType();
2661
2665 unsigned NumElts = VT->getNumElements();
2667 unsigned EltsPerLane = 128 / EltBits;
2668 unsigned Lanes = NumElts * EltBits / 128;
2669 unsigned DestIndex = 0;
2670
2671 for (unsigned Lane = 0; Lane < Lanes; ++Lane) {
2672 unsigned LaneStart = Lane * EltsPerLane;
2673 for (unsigned I = 0; I < EltsPerLane; I += 2) {
2675 APSInt Elem1 = LHS.elem<T>(LaneStart + I).toAPSInt();
2676 APSInt Elem2 = LHS.elem<T>(LaneStart + I + 1).toAPSInt();
2677 APSInt ResL = APSInt(Fn(Elem1, Elem2), DestUnsigned);
2678 Dst.elem<T>(DestIndex++) = static_cast<T>(ResL);
2679 });
2680 }
2681
2682 for (unsigned I = 0; I < EltsPerLane; I += 2) {
2684 APSInt Elem1 = RHS.elem<T>(LaneStart + I).toAPSInt();
2685 APSInt Elem2 = RHS.elem<T>(LaneStart + I + 1).toAPSInt();
2686 APSInt ResR = APSInt(Fn(Elem1, Elem2), DestUnsigned);
2687 Dst.elem<T>(DestIndex++) = static_cast<T>(ResR);
2688 });
2689 }
2690 }
2691 Dst.initializeAllElements();
2692 return true;
2693}
2694
2698 llvm::RoundingMode)>
2699 Fn) {
2705 const auto *VT = Call->getArg(0)->getType()->castAs<VectorType>();
2706
2709 unsigned NumLanes = NumElts * EltBits / 128;
2710 unsigned NumElemsPerLane = NumElts / NumLanes;
2711 unsigned HalfElemsPerLane = NumElemsPerLane / 2;
2712
2713 for (unsigned L = 0; L != NumElts; L += NumElemsPerLane) {
2715 for (unsigned E = 0; E != HalfElemsPerLane; ++E) {
2716 APFloat Elem1 = LHS.elem<T>(L + (2 * E) + 0).getAPFloat();
2717 APFloat Elem2 = LHS.elem<T>(L + (2 * E) + 1).getAPFloat();
2718 Dst.elem<T>(L + E) = static_cast<T>(Fn(Elem1, Elem2, RM));
2719 }
2720 for (unsigned E = 0; E != HalfElemsPerLane; ++E) {
2721 APFloat Elem1 = RHS.elem<T>(L + (2 * E) + 0).getAPFloat();
2722 APFloat Elem2 = RHS.elem<T>(L + (2 * E) + 1).getAPFloat();
2723 Dst.elem<T>(L + E + HalfElemsPerLane) =
2724 static_cast<T>(Fn(Elem1, Elem2, RM));
2725 }
2726 }
2727 Dst.initializeAllElements();
2728 return true;
2729}
2730
2733
2734
2740 const auto *VT = Call->getArg(0)->getType()->castAs<VectorType>();
2742
2744 for (unsigned I = 0; I != NumElems; ++I) {
2745 APFloat LElem = LHS.elem<T>(I).getAPFloat();
2746 APFloat RElem = RHS.elem<T>(I).getAPFloat();
2747 if (I % 2 == 0) {
2748
2749 LElem.subtract(RElem, RM);
2750 } else {
2751
2752 LElem.add(RElem, RM);
2753 }
2754 Dst.elem<T>(I) = static_cast<T>(LElem);
2755 }
2756 Dst.initializeAllElements();
2757 return true;
2758}
2759
2763 const APFloat &, llvm::RoundingMode)>
2764 Fn) {
2765 assert(Call->getNumArgs() == 3);
2766
2769 QualType Arg1Type = Call->getArg(0)->getType();
2770 QualType Arg2Type = Call->getArg(1)->getType();
2771 QualType Arg3Type = Call->getArg(2)->getType();
2772
2773
2777 (void)Arg2Type;
2778 (void)Arg3Type;
2779
2787 return true;
2788 }
2789
2790
2793
2797
2802 assert(ElemQT->isRealFloatingType());
2803 (void)ElemQT;
2804
2809 for (unsigned I = 0; I != NumElems; ++I) {
2811 APFloat X = VX.elem<T>(I).getAPFloat();
2812 APFloat Y = VY.elem<T>(I).getAPFloat();
2816 }
2818 return true;
2819}
2820
2821
2828
2829 assert(LHS.getNumElems() == RHS.getNumElems());
2830 assert(LHS.getNumElems() == Dst.getNumElems());
2831 unsigned NumElems = LHS.getNumElems();
2832 PrimType ElemT = LHS.getFieldDesc()->getPrimType();
2834
2835 for (unsigned I = 0; I != NumElems; ++I) {
2837 assert(DstElemT == PT_Float);
2840 } else {
2843 Elem = Mask[I] ? LHS.elem<T>(I).toAPSInt() : RHS.elem<T>(I).toAPSInt();
2844 });
2846 { Dst.elem<T>(I) = static_cast<T>(Elem); });
2847 }
2848 }
2850
2851 return true;
2852}
2853
2854
2855
2856
2859 unsigned N =
2860 Call->getArg(1)->getType()->getAs<VectorType>()->getNumElements();
2861
2866
2867 bool TakeA0 = U.getZExtValue() & 1ULL;
2868
2869 for (unsigned I = TakeA0; I != N; ++I)
2871 if (TakeA0)
2873
2875 return true;
2876}
2877
2880 llvm::function_ref<bool(const APInt &A, const APInt &B)> Fn) {
2883
2884 assert(LHS.getNumElems() == RHS.getNumElems());
2885
2886 unsigned SourceLen = LHS.getNumElems();
2890
2891 APInt AWide(LaneWidth * SourceLen, 0);
2892 APInt BWide(LaneWidth * SourceLen, 0);
2893
2894 for (unsigned I = 0; I != SourceLen; ++I) {
2897
2900 ALane = LHS.elem<T>(I).toAPSInt();
2901 BLane = RHS.elem<T>(I).toAPSInt();
2902 });
2903 } else if (ElemQT->isFloatingType()) {
2905 ALane = LHS.elem<T>(I).getAPFloat().bitcastToAPInt().isNegative();
2906 BLane = RHS.elem<T>(I).getAPFloat().bitcastToAPInt().isNegative();
2907 } else {
2908 return false;
2909 }
2910 AWide.insertBits(ALane, I * LaneWidth);
2911 BWide.insertBits(BLane, I * LaneWidth);
2912 }
2914 return true;
2915}
2916
2919 assert(Call->getNumArgs() == 1);
2920
2922
2923 unsigned SourceLen = Source.getNumElems();
2926 unsigned ResultLen =
2929
2930 for (unsigned I = 0; I != SourceLen; ++I) {
2936 Elem = Source.elem<T>(I).getAPFloat().bitcastToAPInt();
2937 } else {
2938 return false;
2939 }
2940 Result.setBitVal(I, Elem.isNegative());
2941 }
2943 return true;
2944}
2945
2949 Fn) {
2950 assert(Call->getNumArgs() == 3);
2951
2952 QualType Arg0Type = Call->getArg(0)->getType();
2953 QualType Arg2Type = Call->getArg(2)->getType();
2954
2961 return true;
2962 }
2963
2966 unsigned NumElems = VecT->getNumElements();
2967 bool DestUnsigned = Call->getType()->isUnsignedIntegerOrEnumerationType();
2968
2969
2972
2976 for (unsigned I = 0; I != NumElems; ++I) {
2978 Dst.elem<T>(I) = static_cast<T>(APSInt(
2979 Fn(Op0.elem<T>(I).toAPSInt(), Op1.elem<T>(I).toAPSInt(), Op2),
2980 DestUnsigned));
2981 });
2982 }
2984
2985 return true;
2986 }
2987
2988
2993 for (unsigned I = 0; I != NumElems; ++I) {
2994 APSInt Val0, Val1, Val2;
2996 Val0 = Op0.elem<T>(I).toAPSInt();
2997 Val1 = Op1.elem<T>(I).toAPSInt();
2998 Val2 = Op2.elem<T>(I).toAPSInt();
2999 });
3002 { Dst.elem<T>(I) = static_cast<T>(Result); });
3003 }
3005
3006 return true;
3007}
3008
3011 unsigned ID) {
3012 assert(Call->getNumArgs() == 2);
3013
3015 uint64_t Index = ImmAPS.getZExtValue();
3016
3019 return false;
3020
3023 return false;
3024
3027
3028 unsigned NumLanes = SrcElems / DstElems;
3029 unsigned Lane = static_cast<unsigned>(Index % NumLanes);
3030 unsigned ExtractPos = Lane * DstElems;
3031
3033
3035 for (unsigned I = 0; I != DstElems; ++I) {
3036 Dst.elem<T>(I) = Src.elem<T>(ExtractPos + I);
3037 }
3038 });
3039
3041 return true;
3042}
3043
3047 unsigned ID) {
3048 assert(Call->getNumArgs() == 4);
3049
3054
3057 return false;
3058
3061 return false;
3062
3065
3066 unsigned NumLanes = SrcElems / DstElems;
3067 unsigned Lane = static_cast<unsigned>(ImmAPS.getZExtValue() % NumLanes);
3068 unsigned Base = Lane * DstElems;
3069
3071
3073 for (unsigned I = 0; I != DstElems; ++I) {
3074 if (MaskAPS[I])
3076 else
3078 }
3079 });
3080
3082 return true;
3083}
3084
3087 unsigned ID) {
3088 assert(Call->getNumArgs() == 3);
3089
3091 uint64_t Index = ImmAPS.getZExtValue();
3092
3095 return false;
3096
3099 return false;
3100
3102
3103 unsigned BaseElements = BaseVec.getNumElems();
3104 unsigned SubElements = SubVec.getNumElems();
3105
3106 assert(SubElements != 0 && BaseElements != 0 &&
3107 (BaseElements % SubElements) == 0);
3108
3109 unsigned NumLanes = BaseElements / SubElements;
3110 unsigned Lane = static_cast<unsigned>(Index % NumLanes);
3111 unsigned InsertPos = Lane * SubElements;
3112
3114
3116 for (unsigned I = 0; I != BaseElements; ++I)
3117 Dst.elem<T>(I) = BaseVec.elem<T>(I);
3118 for (unsigned I = 0; I != SubElements; ++I)
3119 Dst.elem<T>(InsertPos + I) = SubVec.elem<T>(I);
3120 });
3121
3123 return true;
3124}
3125
3128 assert(Call->getNumArgs() == 1);
3129
3132
3133 unsigned SourceLen = Source.getNumElems();
3137
3140 ->getElementType()
3142
3144 APSInt MinIndex(ElemBitWidth, DestUnsigned);
3145 APSInt MinVal = Source.elem<T>(0).toAPSInt();
3146
3147 for (unsigned I = 1; I != SourceLen; ++I) {
3148 APSInt Val = Source.elem<T>(I).toAPSInt();
3149 if (MinVal.ugt(Val)) {
3150 MinVal = Val;
3151 MinIndex = I;
3152 }
3153 }
3154
3155 Dest.elem<T>(0) = static_cast<T>(MinVal);
3156 Dest.elem<T>(1) = static_cast<T>(MinIndex);
3157 for (unsigned I = 2; I != SourceLen; ++I) {
3158 Dest.elem<T>(I) = static_cast<T>(APSInt(ElemBitWidth, DestUnsigned));
3159 }
3160 });
3161 Dest.initializeAllElements();
3162 return true;
3163}
3164
3167 assert(Call->getNumArgs() == 5);
3168
3175
3181
3183 for (unsigned I = 0; I != DstLen; ++I) {
3184 APInt ALane = A.elem<T>(I).toAPSInt();
3185 APInt BLane = B.elem<T>(I).toAPSInt();
3186 APInt CLane = C.elem<T>(I).toAPSInt();
3187 APInt RLane(LaneWidth, 0);
3188 if (U[I]) {
3189 for (unsigned Bit = 0; Bit != LaneWidth; ++Bit) {
3190 unsigned ABit = ALane[Bit];
3191 unsigned BBit = BLane[Bit];
3192 unsigned CBit = CLane[Bit];
3193 unsigned Idx = (ABit << 2) | (BBit << 1) | (CBit);
3194 RLane.setBitVal(Bit, Imm[Idx]);
3195 }
3196 Dst.elem<T>(I) = static_cast<T>(APSInt(RLane, DstUnsigned));
3197 } else if (MaskZ) {
3198 Dst.elem<T>(I) = static_cast<T>(APSInt(RLane, DstUnsigned));
3199 } else {
3200 Dst.elem<T>(I) = static_cast<T>(APSInt(ALane, DstUnsigned));
3201 }
3202 }
3203 });
3204 Dst.initializeAllElements();
3205 return true;
3206}
3207
3210 assert(Call->getNumArgs() == 2);
3211
3215 return false;
3216
3218 unsigned Index =
3219 static_cast<unsigned>(ImmAPS.getZExtValue() & (NumElems - 1));
3220
3222
3225 return true;
3226 }
3230 });
3231
3232 return true;
3233}
3234
3237 assert(Call->getNumArgs() == 3);
3238
3241
3243 if (.getFieldDesc()->isPrimitiveArray())
3244 return false;
3245
3247
3248 unsigned NumElems = Base.getNumElems();
3249 unsigned Index =
3250 static_cast<unsigned>(ImmAPS.getZExtValue() & (NumElems - 1));
3251
3252 PrimType ElemT = Base.getFieldDesc()->getPrimType();
3254 for (unsigned I = 0; I != NumElems; ++I)
3256 Dst.elem<T>(Index) = static_cast<T>(ValAPS);
3257 });
3258
3260 return true;
3261}
3262
3264 bool IsUnsigned) {
3265 switch (Imm & 0x7) {
3266 case 0x00:
3267 return (A == B);
3268 case 0x01:
3269 return IsUnsigned ? A.ult(B) : A.slt(B);
3270 case 0x02:
3271 return IsUnsigned ? A.ule(B) : A.sle(B);
3272 case 0x03:
3273 return false;
3274 case 0x04:
3275 return (A != B);
3276 case 0x05:
3277 return IsUnsigned ? A.ugt(B) : A.sgt(B);
3278 case 0x06:
3279 return IsUnsigned ? A.uge(B) : A.sge(B);
3280 case 0x07:
3281 return true;
3282 default:
3283 llvm_unreachable("Invalid Op");
3284 }
3285}
3286
3289 bool IsUnsigned) {
3290 assert(Call->getNumArgs() == 4);
3291
3294 unsigned CmpOp = static_cast<unsigned>(Opcode.getZExtValue());
3297
3298 assert(LHS.getNumElems() == RHS.getNumElems());
3299
3300 APInt RetMask = APInt::getZero(LHS.getNumElems());
3301 unsigned VectorLen = LHS.getNumElems();
3302 PrimType ElemT = LHS.getFieldDesc()->getPrimType();
3303
3304 for (unsigned ElemNum = 0; ElemNum < VectorLen; ++ElemNum) {
3307 A = LHS.elem<T>(ElemNum).toAPSInt();
3308 B = RHS.elem<T>(ElemNum).toAPSInt();
3309 });
3310 RetMask.setBitVal(ElemNum,
3311 Mask[ElemNum] && evalICmpImm(CmpOp, A, B, IsUnsigned));
3312 }
3314 return true;
3315}
3316
3319 assert(Call->getNumArgs() == 1);
3320
3321 QualType Arg0Type = Call->getArg(0)->getType();
3324 unsigned NumElems = VecT->getNumElements();
3325 bool DestUnsigned = Call->getType()->isUnsignedIntegerOrEnumerationType();
3328
3329 for (unsigned I = 0; I != NumElems; ++I) {
3331 APSInt ElemI = Src.elem<T>(I).toAPSInt();
3332 APInt ConflictMask(ElemI.getBitWidth(), 0);
3333 for (unsigned J = 0; J != I; ++J) {
3334 APSInt ElemJ = Src.elem<T>(J).toAPSInt();
3335 ConflictMask.setBitVal(J, ElemI == ElemJ);
3336 }
3337 Dst.elem<T>(I) = static_cast<T>(APSInt(ConflictMask, DestUnsigned));
3338 });
3339 }
3341 return true;
3342}
3343
3346 unsigned ID) {
3347 assert(Call->getNumArgs() == 1);
3348
3351 APInt RetMask(RetWidth, 0);
3352
3355
3356 for (unsigned ElemNum = 0; ElemNum != VectorLen; ++ElemNum) {
3359 unsigned MSB = A[A.getBitWidth() - 1];
3360 RetMask.setBitVal(ElemNum, MSB);
3361 }
3363 return true;
3364}
3367 bool HasRoundingMask) {
3368 APSInt Rounding, MaskInt;
3370
3371 if (HasRoundingMask) {
3372 assert(Call->getNumArgs() == 5);
3380 return false;
3381 } else {
3382 assert(Call->getNumArgs() == 2);
3386 return false;
3387 }
3388
3389 const auto *DstVTy = Call->getType()->castAs<VectorType>();
3392
3393
3394 for (unsigned I = 1; I != NumElems; ++I)
3396
3397
3398 if (!HasRoundingMask || (MaskInt.getZExtValue() & 0x1)) {
3400 "cvtsd2ss requires float element type in destination vector");
3401
3406 return false;
3408 } else {
3410 }
3411
3413 return true;
3414}
3415
3418 bool HasRounding) {
3419
3424
3425 if (IsMasked) {
3426
3427 if (HasRounding) {
3432 } else {
3436 }
3437
3438 if ((S, OpPC, PassThrough))
3439 return false;
3440 } else {
3441
3443 }
3444
3446 return false;
3447
3448 const auto *RetVTy = Call->getType()->castAs<VectorType>();
3452
3453
3454 for (unsigned I = 0; I != RetElems; ++I)
3455 if (IsMasked)
3457 else
3459
3461 "cvtpd2ps requires float element type in return vector");
3462
3463
3464
3465 for (unsigned I = 0; I != SrcElems; ++I) {
3466 if (IsMasked && !MaskVal[I])
3467 continue;
3468
3470
3474 return false;
3476 }
3477
3479 return true;
3480}
3481
3484 llvm::function_ref<std::pair<unsigned, int>(unsigned, unsigned)>
3485 GetSourceIndex) {
3486
3487 assert(Call->getNumArgs() == 2 || Call->getNumArgs() == 3);
3488
3489 unsigned ShuffleMask = 0;
3490 Pointer A, MaskVector, B;
3491 bool IsVectorMask = false;
3492 bool IsSingleOperand = (Call->getNumArgs() == 2);
3493
3494 if (IsSingleOperand) {
3495 QualType MaskType = Call->getArg(1)->getType();
3497 IsVectorMask = true;
3500 B = A;
3502 ShuffleMask = popToAPSInt(S, Call->getArg(1)).getZExtValue();
3504 B = A;
3505 } else {
3506 return false;
3507 }
3508 } else {
3509 QualType Arg2Type = Call->getArg(2)->getType();
3511 IsVectorMask = true;
3516 ShuffleMask = popToAPSInt(S, Call->getArg(2)).getZExtValue();
3519 } else {
3520 return false;
3521 }
3522 }
3523
3524 QualType Arg0Type = Call->getArg(0)->getType();
3527 unsigned NumElems = VecT->getNumElements();
3528
3530
3532 if (IsVectorMask) {
3533 QualType Arg1Type = Call->getArg(1)->getType();
3535 QualType MaskElemType = MaskVecT->getElementType();
3537 }
3538
3539 for (unsigned DstIdx = 0; DstIdx != NumElems; ++DstIdx) {
3540 if (IsVectorMask) {
3542 ShuffleMask = static_cast<unsigned>(MaskVector.elem<T>(DstIdx));
3543 });
3544 }
3545
3546 auto [SrcVecIdx, SrcIdx] = GetSourceIndex(DstIdx, ShuffleMask);
3547
3548 if (SrcIdx < 0) {
3549
3553 } else {
3555 }
3556 } else {
3557 const Pointer &Src = (SrcVecIdx == 0) ? A : B;
3559 }
3560 }
3562
3563 return true;
3564}
3565
3568 llvm::function_ref<APInt(const APInt &, uint64_t)> ShiftOp,
3569 llvm::function_ref<APInt(const APInt &, unsigned)> OverflowOp) {
3570
3571 assert(Call->getNumArgs() == 2);
3572
3575
3576 QualType SourceType = Call->getArg(0)->getType();
3577 QualType CountType = Call->getArg(1)->getType();
3578 assert(SourceType->isVectorType() && CountType->isVectorType());
3579
3580 const auto *SourceVecT = SourceType->castAs<VectorType>();
3584
3586
3587 unsigned DestEltWidth =
3589 bool IsDestUnsigned = SourceVecT->getElementType()->isUnsignedIntegerType();
3590 unsigned DestLen = SourceVecT->getNumElements();
3591 unsigned CountEltWidth =
3593 unsigned NumBitsInQWord = 64;
3594 unsigned NumCountElts = NumBitsInQWord / CountEltWidth;
3595
3596 uint64_t CountLQWord = 0;
3597 for (unsigned EltIdx = 0; EltIdx != NumCountElts; ++EltIdx) {
3598 uint64_t Elt = 0;
3600 { Elt = static_cast<uint64_t>(Count.elem<T>(EltIdx)); });
3601 CountLQWord |= (Elt << (EltIdx * CountEltWidth));
3602 }
3603
3604 for (unsigned EltIdx = 0; EltIdx != DestLen; ++EltIdx) {
3606 INT_TYPE_SWITCH(SourceElemT, { Elt = Source.elem<T>(EltIdx).toAPSInt(); });
3607
3609 if (CountLQWord < DestEltWidth) {
3610 Result = ShiftOp(Elt, CountLQWord);
3611 } else {
3612 Result = OverflowOp(Elt, DestEltWidth);
3613 }
3614 if (IsDestUnsigned) {
3616 Dst.elem<T>(EltIdx) = T::from(Result.getZExtValue());
3617 });
3618 } else {
3620 Dst.elem<T>(EltIdx) = T::from(Result.getSExtValue());
3621 });
3622 }
3623 }
3624
3626 return true;
3627}
3628
3631
3632 assert(Call->getNumArgs() == 3);
3633
3634 QualType SourceType = Call->getArg(0)->getType();
3635 QualType ShuffleMaskType = Call->getArg(1)->getType();
3636 QualType ZeroMaskType = Call->getArg(2)->getType();
3639 return false;
3640 }
3641
3642 Pointer Source, ShuffleMask;
3646
3648 const auto *ShuffleMaskVecT = ShuffleMaskType->castAs<VectorType>();
3649 assert(SourceVecT->getNumElements() == ShuffleMaskVecT->getNumElements());
3650 assert(ZeroMask.getBitWidth() == SourceVecT->getNumElements());
3651
3655
3656 unsigned NumBytesInQWord = 8;
3657 unsigned NumBitsInByte = 8;
3658 unsigned NumBytes = SourceVecT->getNumElements();
3659 unsigned NumQWords = NumBytes / NumBytesInQWord;
3660 unsigned RetWidth = ZeroMask.getBitWidth();
3661 APSInt RetMask(llvm::APInt(RetWidth, 0), true);
3662
3663 for (unsigned QWordId = 0; QWordId != NumQWords; ++QWordId) {
3664 APInt SourceQWord(64, 0);
3665 for (unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
3666 uint64_t Byte = 0;
3668 Byte = static_cast<uint64_t>(
3669 Source.elem<T>(QWordId * NumBytesInQWord + ByteIdx));
3670 });
3671 SourceQWord.insertBits(APInt(8, Byte & 0xFF), ByteIdx * NumBitsInByte);
3672 }
3673
3674 for (unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
3675 unsigned SelIdx = QWordId * NumBytesInQWord + ByteIdx;
3676 unsigned M = 0;
3678 M = static_cast<unsigned>(ShuffleMask.elem<T>(SelIdx)) & 0x3F;
3679 });
3680
3681 if (ZeroMask[SelIdx]) {
3682 RetMask.setBitVal(SelIdx, SourceQWord[M]);
3683 }
3684 }
3685 }
3686
3688 return true;
3689}
3690
3693
3694 assert(Call->getNumArgs() == 2);
3695
3699
3701 assert(Dst.getFieldDesc()->isPrimitiveArray());
3702
3703 const auto *SrcVTy = Call->getArg(0)->getType()->castAs<VectorType>();
3705 const auto *DstVTy = Call->getType()->castAs<VectorType>();
3707
3708 const llvm::fltSemantics &HalfSem =
3710
3711
3712
3713 int ImmVal = Imm.getZExtValue();
3714 bool UseMXCSR = (ImmVal & 4) != 0;
3715 bool IsFPConstrained =
3717 .isFPConstrained();
3718
3719 llvm::RoundingMode RM;
3720 if (!UseMXCSR) {
3721 switch (ImmVal & 3) {
3722 case 0:
3723 RM = llvm::RoundingMode::NearestTiesToEven;
3724 break;
3725 case 1:
3726 RM = llvm::RoundingMode::TowardNegative;
3727 break;
3728 case 2:
3729 RM = llvm::RoundingMode::TowardPositive;
3730 break;
3731 case 3:
3732 RM = llvm::RoundingMode::TowardZero;
3733 break;
3734 default:
3735 llvm_unreachable("Invalid immediate rounding mode");
3736 }
3737 } else {
3738
3739
3740 RM = llvm::RoundingMode::NearestTiesToEven;
3741 }
3742
3743 QualType DstElemQT = Dst.getFieldDesc()->getElemQualType();
3745
3746 for (unsigned I = 0; I != SrcNumElems; ++I) {
3749
3750 bool LostInfo;
3751 APFloat::opStatus St = DstVal.convert(HalfSem, RM, &LostInfo);
3752
3753 if (UseMXCSR && IsFPConstrained && St != APFloat::opOK) {
3755 diag::note_constexpr_dynamic_rounding);
3756 return false;
3757 }
3758
3760
3761
3762 uint64_t RawBits = DstVal.bitcastToAPInt().getZExtValue();
3763 Dst.elem<T>(I) = T::from(RawBits);
3764 });
3765 }
3766
3767
3768
3769 if (DstNumElems > SrcNumElems) {
3770 for (unsigned I = SrcNumElems; I != DstNumElems; ++I) {
3772 }
3773 }
3774
3775 Dst.initializeAllElements();
3776 return true;
3777}
3778
3781 assert(Call->getNumArgs() == 2);
3782
3786 return false;
3787 }
3788
3792 assert(AVecT->getNumElements() ==
3794
3796
3797 unsigned NumBytesInQWord = 8;
3798 unsigned NumBitsInByte = 8;
3799 unsigned NumBytes = AVecT->getNumElements();
3800 unsigned NumQWords = NumBytes / NumBytesInQWord;
3802
3803 for (unsigned QWordId = 0; QWordId != NumQWords; ++QWordId) {
3804 APInt BQWord(64, 0);
3805 for (unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
3806 unsigned Idx = QWordId * NumBytesInQWord + ByteIdx;
3808 uint64_t Byte = static_cast<uint64_t>(BPtr.elem<T>(Idx));
3809 BQWord.insertBits(APInt(8, Byte & 0xFF), ByteIdx * NumBitsInByte);
3810 });
3811 }
3812
3813 for (unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
3814 unsigned Idx = QWordId * NumBytesInQWord + ByteIdx;
3815 uint64_t Ctrl = 0;
3817 ElemT, { Ctrl = static_cast<uint64_t>(APtr.elem<T>(Idx)) & 0x3F; });
3818
3819 APInt Byte(8, 0);
3820 for (unsigned BitIdx = 0; BitIdx != NumBitsInByte; ++BitIdx) {
3821 Byte.setBitVal(BitIdx, BQWord[(Ctrl + BitIdx) & 0x3F]);
3822 }
3824 { Dst.elem<T>(Idx) = T::from(Byte.getZExtValue()); });
3825 }
3826 }
3827
3829
3830 return true;
3831}
3832
3835 bool Inverse) {
3836 assert(Call->getNumArgs() == 3);
3837 QualType XType = Call->getArg(0)->getType();
3838 QualType AType = Call->getArg(1)->getType();
3839 QualType ImmType = Call->getArg(2)->getType();
3842 return false;
3843 }
3844
3849
3853 AVecT->getNumElements());
3854 unsigned NumBytesInQWord = 8;
3855 unsigned NumBytes = AVecT->getNumElements();
3856 unsigned NumBitsInQWord = 64;
3857 unsigned NumQWords = NumBytes / NumBytesInQWord;
3858 unsigned NumBitsInByte = 8;
3860
3861
3862 for (unsigned QWordIdx = 0; QWordIdx != NumQWords; ++QWordIdx) {
3863
3864 APInt XQWord(NumBitsInQWord, 0);
3865 APInt AQWord(NumBitsInQWord, 0);
3866 for (unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
3867 unsigned Idx = QWordIdx * NumBytesInQWord + ByteIdx;
3868 uint8_t XByte;
3869 uint8_t AByte;
3871 XByte = static_cast<uint8_t>(X.elem<T>(Idx));
3872 AByte = static_cast<uint8_t>(A.elem<T>(Idx));
3873 });
3874
3875 XQWord.insertBits(APInt(NumBitsInByte, XByte), ByteIdx * NumBitsInByte);
3876 AQWord.insertBits(APInt(NumBitsInByte, AByte), ByteIdx * NumBitsInByte);
3877 }
3878
3879 for (unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
3880 unsigned Idx = QWordIdx * NumBytesInQWord + ByteIdx;
3881 uint8_t XByte =
3882 XQWord.lshr(ByteIdx * NumBitsInByte).getLoBits(8).getZExtValue();
3884 Dst.elem<T>(Idx) = T::from(GFNIAffine(XByte, AQWord, Imm, Inverse));
3885 });
3886 }
3887 }
3888 Dst.initializeAllElements();
3889 return true;
3890}
3891
3894 assert(Call->getNumArgs() == 2);
3895
3896 QualType AType = Call->getArg(0)->getType();
3897 QualType BType = Call->getArg(1)->getType();
3899 return false;
3900 }
3901
3905
3908 assert(AVecT->getNumElements() ==
3910
3913
3914 for (unsigned ByteIdx = 0; ByteIdx != NumBytes; ++ByteIdx) {
3915 uint8_t AByte, BByte;
3917 AByte = static_cast<uint8_t>(A.elem<T>(ByteIdx));
3918 BByte = static_cast<uint8_t>(B.elem<T>(ByteIdx));
3919 Dst.elem<T>(ByteIdx) = T::from(GFNIMul(AByte, BByte));
3920 });
3921 }
3922
3923 Dst.initializeAllElements();
3924 return true;
3925}
3926
3928 uint32_t BuiltinID) {
3930 return Invalid(S, OpPC);
3931
3933 switch (BuiltinID) {
3934 case Builtin::BI__builtin_is_constant_evaluated:
3936
3937 case Builtin::BI__builtin_assume:
3938 case Builtin::BI__assume:
3940
3941 case Builtin::BI__builtin_strcmp:
3942 case Builtin::BIstrcmp:
3943 case Builtin::BI__builtin_strncmp:
3944 case Builtin::BIstrncmp:
3945 case Builtin::BI__builtin_wcsncmp:
3946 case Builtin::BIwcsncmp:
3947 case Builtin::BI__builtin_wcscmp:
3948 case Builtin::BIwcscmp:
3950
3951 case Builtin::BI__builtin_strlen:
3952 case Builtin::BIstrlen:
3953 case Builtin::BI__builtin_wcslen:
3954 case Builtin::BIwcslen:
3956
3957 case Builtin::BI__builtin_nan:
3958 case Builtin::BI__builtin_nanf:
3959 case Builtin::BI__builtin_nanl:
3960 case Builtin::BI__builtin_nanf16:
3961 case Builtin::BI__builtin_nanf128:
3963
3964 case Builtin::BI__builtin_nans:
3965 case Builtin::BI__builtin_nansf:
3966 case Builtin::BI__builtin_nansl:
3967 case Builtin::BI__builtin_nansf16:
3968 case Builtin::BI__builtin_nansf128:
3970
3971 case Builtin::BI__builtin_huge_val:
3972 case Builtin::BI__builtin_huge_valf:
3973 case Builtin::BI__builtin_huge_vall:
3974 case Builtin::BI__builtin_huge_valf16:
3975 case Builtin::BI__builtin_huge_valf128:
3976 case Builtin::BI__builtin_inf:
3977 case Builtin::BI__builtin_inff:
3978 case Builtin::BI__builtin_infl:
3979 case Builtin::BI__builtin_inff16:
3980 case Builtin::BI__builtin_inff128:
3982
3983 case Builtin::BI__builtin_copysign:
3984 case Builtin::BI__builtin_copysignf:
3985 case Builtin::BI__builtin_copysignl:
3986 case Builtin::BI__builtin_copysignf128:
3988
3989 case Builtin::BI__builtin_fmin:
3990 case Builtin::BI__builtin_fminf:
3991 case Builtin::BI__builtin_fminl:
3992 case Builtin::BI__builtin_fminf16:
3993 case Builtin::BI__builtin_fminf128:
3995
3996 case Builtin::BI__builtin_fminimum_num:
3997 case Builtin::BI__builtin_fminimum_numf:
3998 case Builtin::BI__builtin_fminimum_numl:
3999 case Builtin::BI__builtin_fminimum_numf16:
4000 case Builtin::BI__builtin_fminimum_numf128:
4002
4003 case Builtin::BI__builtin_fmax:
4004 case Builtin::BI__builtin_fmaxf:
4005 case Builtin::BI__builtin_fmaxl:
4006 case Builtin::BI__builtin_fmaxf16:
4007 case Builtin::BI__builtin_fmaxf128:
4009
4010 case Builtin::BI__builtin_fmaximum_num:
4011 case Builtin::BI__builtin_fmaximum_numf:
4012 case Builtin::BI__builtin_fmaximum_numl:
4013 case Builtin::BI__builtin_fmaximum_numf16:
4014 case Builtin::BI__builtin_fmaximum_numf128:
4016
4017 case Builtin::BI__builtin_isnan:
4019
4020 case Builtin::BI__builtin_issignaling:
4022
4023 case Builtin::BI__builtin_isinf:
4025
4026 case Builtin::BI__builtin_isinf_sign:
4028
4029 case Builtin::BI__builtin_isfinite:
4031
4032 case Builtin::BI__builtin_isnormal:
4034
4035 case Builtin::BI__builtin_issubnormal:
4037
4038 case Builtin::BI__builtin_iszero:
4040
4041 case Builtin::BI__builtin_signbit:
4042 case Builtin::BI__builtin_signbitf:
4043 case Builtin::BI__builtin_signbitl:
4045
4046 case Builtin::BI__builtin_isgreater:
4047 case Builtin::BI__builtin_isgreaterequal:
4048 case Builtin::BI__builtin_isless:
4049 case Builtin::BI__builtin_islessequal:
4050 case Builtin::BI__builtin_islessgreater:
4051 case Builtin::BI__builtin_isunordered:
4053
4054 case Builtin::BI__builtin_isfpclass:
4056
4057 case Builtin::BI__builtin_fpclassify:
4059
4060 case Builtin::BI__builtin_fabs:
4061 case Builtin::BI__builtin_fabsf:
4062 case Builtin::BI__builtin_fabsl:
4063 case Builtin::BI__builtin_fabsf128:
4065
4066 case Builtin::BI__builtin_abs:
4067 case Builtin::BI__builtin_labs:
4068 case Builtin::BI__builtin_llabs:
4070
4071 case Builtin::BI__builtin_popcount:
4072 case Builtin::BI__builtin_popcountl:
4073 case Builtin::BI__builtin_popcountll:
4074 case Builtin::BI__builtin_popcountg:
4075 case Builtin::BI__popcnt16:
4076 case Builtin::BI__popcnt:
4077 case Builtin::BI__popcnt64:
4079
4080 case Builtin::BI__builtin_parity:
4081 case Builtin::BI__builtin_parityl:
4082 case Builtin::BI__builtin_parityll:
4084 S, OpPC, Call, [](const APSInt &Val) {
4085 return APInt(Val.getBitWidth(), Val.popcount() % 2);
4086 });
4087 case Builtin::BI__builtin_clrsb:
4088 case Builtin::BI__builtin_clrsbl:
4089 case Builtin::BI__builtin_clrsbll:
4091 S, OpPC, Call, [](const APSInt &Val) {
4092 return APInt(Val.getBitWidth(),
4093 Val.getBitWidth() - Val.getSignificantBits());
4094 });
4095 case Builtin::BI__builtin_bitreverse8:
4096 case Builtin::BI__builtin_bitreverse16:
4097 case Builtin::BI__builtin_bitreverse32:
4098 case Builtin::BI__builtin_bitreverse64:
4100 S, OpPC, Call, [](const APSInt &Val) { return Val.reverseBits(); });
4101
4102 case Builtin::BI__builtin_classify_type:
4104
4105 case Builtin::BI__builtin_expect:
4106 case Builtin::BI__builtin_expect_with_probability:
4108
4109 case Builtin::BI__builtin_rotateleft8:
4110 case Builtin::BI__builtin_rotateleft16:
4111 case Builtin::BI__builtin_rotateleft32:
4112 case Builtin::BI__builtin_rotateleft64:
4113 case Builtin::BI_rotl8:
4114 case Builtin::BI_rotl16:
4115 case Builtin::BI_rotl:
4116 case Builtin::BI_lrotl:
4117 case Builtin::BI_rotl64:
4120 return Value.rotl(Amount);
4121 });
4122
4123 case Builtin::BI__builtin_rotateright8:
4124 case Builtin::BI__builtin_rotateright16:
4125 case Builtin::BI__builtin_rotateright32:
4126 case Builtin::BI__builtin_rotateright64:
4127 case Builtin::BI_rotr8:
4128 case Builtin::BI_rotr16:
4129 case Builtin::BI_rotr:
4130 case Builtin::BI_lrotr:
4131 case Builtin::BI_rotr64:
4134 return Value.rotr(Amount);
4135 });
4136
4137 case Builtin::BI__builtin_ffs:
4138 case Builtin::BI__builtin_ffsl:
4139 case Builtin::BI__builtin_ffsll:
4141 S, OpPC, Call, [](const APSInt &Val) {
4142 return APInt(Val.getBitWidth(),
4143 Val.isZero() ? 0u : Val.countTrailingZeros() + 1u);
4144 });
4145
4146 case Builtin::BIaddressof:
4147 case Builtin::BI__addressof:
4148 case Builtin::BI__builtin_addressof:
4151
4152 case Builtin::BIas_const:
4153 case Builtin::BIforward:
4154 case Builtin::BIforward_like:
4155 case Builtin::BImove:
4156 case Builtin::BImove_if_noexcept:
4159
4160 case Builtin::BI__builtin_eh_return_data_regno:
4162
4163 case Builtin::BI__builtin_launder:
4165 return true;
4166
4167 case Builtin::BI__builtin_add_overflow:
4168 case Builtin::BI__builtin_sub_overflow:
4169 case Builtin::BI__builtin_mul_overflow:
4170 case Builtin::BI__builtin_sadd_overflow:
4171 case Builtin::BI__builtin_uadd_overflow:
4172 case Builtin::BI__builtin_uaddl_overflow:
4173 case Builtin::BI__builtin_uaddll_overflow:
4174 case Builtin::BI__builtin_usub_overflow:
4175 case Builtin::BI__builtin_usubl_overflow:
4176 case Builtin::BI__builtin_usubll_overflow:
4177 case Builtin::BI__builtin_umul_overflow:
4178 case Builtin::BI__builtin_umull_overflow:
4179 case Builtin::BI__builtin_umulll_overflow:
4180 case Builtin::BI__builtin_saddl_overflow:
4181 case Builtin::BI__builtin_saddll_overflow:
4182 case Builtin::BI__builtin_ssub_overflow:
4183 case Builtin::BI__builtin_ssubl_overflow:
4184 case Builtin::BI__builtin_ssubll_overflow:
4185 case Builtin::BI__builtin_smul_overflow:
4186 case Builtin::BI__builtin_smull_overflow:
4187 case Builtin::BI__builtin_smulll_overflow:
4189
4190 case Builtin::BI__builtin_addcb:
4191 case Builtin::BI__builtin_addcs:
4192 case Builtin::BI__builtin_addc:
4193 case Builtin::BI__builtin_addcl:
4194 case Builtin::BI__builtin_addcll:
4195 case Builtin::BI__builtin_subcb:
4196 case Builtin::BI__builtin_subcs:
4197 case Builtin::BI__builtin_subc:
4198 case Builtin::BI__builtin_subcl:
4199 case Builtin::BI__builtin_subcll:
4201
4202 case Builtin::BI__builtin_clz:
4203 case Builtin::BI__builtin_clzl:
4204 case Builtin::BI__builtin_clzll:
4205 case Builtin::BI__builtin_clzs:
4206 case Builtin::BI__builtin_clzg:
4207 case Builtin::BI__lzcnt16:
4208 case Builtin::BI__lzcnt:
4209 case Builtin::BI__lzcnt64:
4211
4212 case Builtin::BI__builtin_ctz:
4213 case Builtin::BI__builtin_ctzl:
4214 case Builtin::BI__builtin_ctzll:
4215 case Builtin::BI__builtin_ctzs:
4216 case Builtin::BI__builtin_ctzg:
4218
4219 case Builtin::BI__builtin_elementwise_clzg:
4220 case Builtin::BI__builtin_elementwise_ctzg:
4222 BuiltinID);
4223 case Builtin::BI__builtin_bswapg:
4224 case Builtin::BI__builtin_bswap16:
4225 case Builtin::BI__builtin_bswap32:
4226 case Builtin::BI__builtin_bswap64:
4228
4229 case Builtin::BI__atomic_always_lock_free:
4230 case Builtin::BI__atomic_is_lock_free:
4232
4233 case Builtin::BI__c11_atomic_is_lock_free:
4235
4236 case Builtin::BI__builtin_complex:
4238
4239 case Builtin::BI__builtin_is_aligned:
4240 case Builtin::BI__builtin_align_up:
4241 case Builtin::BI__builtin_align_down:
4243
4244 case Builtin::BI__builtin_assume_aligned:
4246
4247 case clang::X86::BI__builtin_ia32_bextr_u32:
4248 case clang::X86::BI__builtin_ia32_bextr_u64:
4249 case clang::X86::BI__builtin_ia32_bextri_u32:
4250 case clang::X86::BI__builtin_ia32_bextri_u64:
4253 unsigned BitWidth = Val.getBitWidth();
4254 uint64_t Shift = Idx.extractBitsAsZExtValue(8, 0);
4255 uint64_t Length = Idx.extractBitsAsZExtValue(8, 8);
4256 if (Length > BitWidth) {
4257 Length = BitWidth;
4258 }
4259
4260
4261 if (Length == 0 || Shift >= BitWidth)
4262 return APInt(BitWidth, 0);
4263
4264 uint64_t Result = Val.getZExtValue() >> Shift;
4265 Result &= llvm::maskTrailingOnes<uint64_t>(Length);
4267 });
4268
4269 case clang::X86::BI__builtin_ia32_bzhi_si:
4270 case clang::X86::BI__builtin_ia32_bzhi_di:
4273 unsigned BitWidth = Val.getBitWidth();
4274 uint64_t Index = Idx.extractBitsAsZExtValue(8, 0);
4276
4277 if (Index < BitWidth)
4278 Result.clearHighBits(BitWidth - Index);
4279
4281 });
4282
4283 case clang::X86::BI__builtin_ia32_ktestcqi:
4284 case clang::X86::BI__builtin_ia32_ktestchi:
4285 case clang::X86::BI__builtin_ia32_ktestcsi:
4286 case clang::X86::BI__builtin_ia32_ktestcdi:
4289 return APInt(sizeof(unsigned char) * 8, (~A & B) == 0);
4290 });
4291
4292 case clang::X86::BI__builtin_ia32_ktestzqi:
4293 case clang::X86::BI__builtin_ia32_ktestzhi:
4294 case clang::X86::BI__builtin_ia32_ktestzsi:
4295 case clang::X86::BI__builtin_ia32_ktestzdi:
4298 return APInt(sizeof(unsigned char) * 8, (A & B) == 0);
4299 });
4300
4301 case clang::X86::BI__builtin_ia32_kortestcqi:
4302 case clang::X86::BI__builtin_ia32_kortestchi:
4303 case clang::X86::BI__builtin_ia32_kortestcsi:
4304 case clang::X86::BI__builtin_ia32_kortestcdi:
4307 return APInt(sizeof(unsigned char) * 8, ~(A | B) == 0);
4308 });
4309
4310 case clang::X86::BI__builtin_ia32_kortestzqi:
4311 case clang::X86::BI__builtin_ia32_kortestzhi:
4312 case clang::X86::BI__builtin_ia32_kortestzsi:
4313 case clang::X86::BI__builtin_ia32_kortestzdi:
4316 return APInt(sizeof(unsigned char) * 8, (A | B) == 0);
4317 });
4318
4319 case clang::X86::BI__builtin_ia32_kshiftliqi:
4320 case clang::X86::BI__builtin_ia32_kshiftlihi:
4321 case clang::X86::BI__builtin_ia32_kshiftlisi:
4322 case clang::X86::BI__builtin_ia32_kshiftlidi:
4325 unsigned Amt = RHS.getZExtValue() & 0xFF;
4326 if (Amt >= LHS.getBitWidth())
4327 return APInt::getZero(LHS.getBitWidth());
4328 return LHS.shl(Amt);
4329 });
4330
4331 case clang::X86::BI__builtin_ia32_kshiftriqi:
4332 case clang::X86::BI__builtin_ia32_kshiftrihi:
4333 case clang::X86::BI__builtin_ia32_kshiftrisi:
4334 case clang::X86::BI__builtin_ia32_kshiftridi:
4337 unsigned Amt = RHS.getZExtValue() & 0xFF;
4338 if (Amt >= LHS.getBitWidth())
4339 return APInt::getZero(LHS.getBitWidth());
4340 return LHS.lshr(Amt);
4341 });
4342
4343 case clang::X86::BI__builtin_ia32_lzcnt_u16:
4344 case clang::X86::BI__builtin_ia32_lzcnt_u32:
4345 case clang::X86::BI__builtin_ia32_lzcnt_u64:
4347 S, OpPC, Call, [](const APSInt &Src) {
4348 return APInt(Src.getBitWidth(), Src.countLeadingZeros());
4349 });
4350
4351 case clang::X86::BI__builtin_ia32_tzcnt_u16:
4352 case clang::X86::BI__builtin_ia32_tzcnt_u32:
4353 case clang::X86::BI__builtin_ia32_tzcnt_u64:
4355 S, OpPC, Call, [](const APSInt &Src) {
4356 return APInt(Src.getBitWidth(), Src.countTrailingZeros());
4357 });
4358
4359 case clang::X86::BI__builtin_ia32_pdep_si:
4360 case clang::X86::BI__builtin_ia32_pdep_di:
4363 unsigned BitWidth = Val.getBitWidth();
4364 APInt Result = APInt::getZero(BitWidth);
4365
4366 for (unsigned I = 0, P = 0; I != BitWidth; ++I) {
4367 if (Mask[I])
4368 Result.setBitVal(I, Val[P++]);
4369 }
4370
4372 });
4373
4374 case clang::X86::BI__builtin_ia32_pext_si:
4375 case clang::X86::BI__builtin_ia32_pext_di:
4378 unsigned BitWidth = Val.getBitWidth();
4379 APInt Result = APInt::getZero(BitWidth);
4380
4381 for (unsigned I = 0, P = 0; I != BitWidth; ++I) {
4382 if (Mask[I])
4383 Result.setBitVal(P++, Val[I]);
4384 }
4385
4387 });
4388
4389 case clang::X86::BI__builtin_ia32_addcarryx_u32:
4390 case clang::X86::BI__builtin_ia32_addcarryx_u64:
4391 case clang::X86::BI__builtin_ia32_subborrow_u32:
4392 case clang::X86::BI__builtin_ia32_subborrow_u64:
4394 BuiltinID);
4395
4396 case Builtin::BI__builtin_os_log_format_buffer_size:
4398
4399 case Builtin::BI__builtin_ptrauth_string_discriminator:
4401
4402 case Builtin::BI__builtin_infer_alloc_token:
4404
4405 case Builtin::BI__noop:
4407 return true;
4408
4409 case Builtin::BI__builtin_operator_new:
4411
4412 case Builtin::BI__builtin_operator_delete:
4414
4415 case Builtin::BI__arithmetic_fence:
4417
4418 case Builtin::BI__builtin_reduce_add:
4419 case Builtin::BI__builtin_reduce_mul:
4420 case Builtin::BI__builtin_reduce_and:
4421 case Builtin::BI__builtin_reduce_or:
4422 case Builtin::BI__builtin_reduce_xor:
4423 case Builtin::BI__builtin_reduce_min:
4424 case Builtin::BI__builtin_reduce_max:
4426
4427 case Builtin::BI__builtin_elementwise_popcount:
4429 S, OpPC, Call, [](const APSInt &Src) {
4430 return APInt(Src.getBitWidth(), Src.popcount());
4431 });
4432 case Builtin::BI__builtin_elementwise_bitreverse:
4434 S, OpPC, Call, [](const APSInt &Src) { return Src.reverseBits(); });
4435
4436 case Builtin::BI__builtin_elementwise_abs:
4438
4439 case Builtin::BI__builtin_memcpy:
4440 case Builtin::BImemcpy:
4441 case Builtin::BI__builtin_wmemcpy:
4442 case Builtin::BIwmemcpy:
4443 case Builtin::BI__builtin_memmove:
4444 case Builtin::BImemmove:
4445 case Builtin::BI__builtin_wmemmove:
4446 case Builtin::BIwmemmove:
4448
4449 case Builtin::BI__builtin_memcmp:
4450 case Builtin::BImemcmp:
4451 case Builtin::BI__builtin_bcmp:
4452 case Builtin::BIbcmp:
4453 case Builtin::BI__builtin_wmemcmp:
4454 case Builtin::BIwmemcmp:
4456
4457 case Builtin::BImemchr:
4458 case Builtin::BI__builtin_memchr:
4459 case Builtin::BIstrchr:
4460 case Builtin::BI__builtin_strchr:
4461 case Builtin::BIwmemchr:
4462 case Builtin::BI__builtin_wmemchr:
4463 case Builtin::BIwcschr:
4464 case Builtin::BI__builtin_wcschr:
4465 case Builtin::BI__builtin_char_memchr:
4467
4468 case Builtin::BI__builtin_object_size:
4469 case Builtin::BI__builtin_dynamic_object_size:
4471
4472 case Builtin::BI__builtin_is_within_lifetime:
4474
4475 case Builtin::BI__builtin_elementwise_add_sat:
4478 return LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
4479 });
4480
4481 case Builtin::BI__builtin_elementwise_sub_sat:
4484 return LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
4485 });
4486 case X86::BI__builtin_ia32_extract128i256:
4487 case X86::BI__builtin_ia32_vextractf128_pd256:
4488 case X86::BI__builtin_ia32_vextractf128_ps256:
4489 case X86::BI__builtin_ia32_vextractf128_si256:
4491
4492 case X86::BI__builtin_ia32_extractf32x4_256_mask:
4493 case X86::BI__builtin_ia32_extractf32x4_mask:
4494 case X86::BI__builtin_ia32_extractf32x8_mask:
4495 case X86::BI__builtin_ia32_extractf64x2_256_mask:
4496 case X86::BI__builtin_ia32_extractf64x2_512_mask:
4497 case X86::BI__builtin_ia32_extractf64x4_mask:
4498 case X86::BI__builtin_ia32_extracti32x4_256_mask:
4499 case X86::BI__builtin_ia32_extracti32x4_mask:
4500 case X86::BI__builtin_ia32_extracti32x8_mask:
4501 case X86::BI__builtin_ia32_extracti64x2_256_mask:
4502 case X86::BI__builtin_ia32_extracti64x2_512_mask:
4503 case X86::BI__builtin_ia32_extracti64x4_mask:
4505
4506 case clang::X86::BI__builtin_ia32_pmulhrsw128:
4507 case clang::X86::BI__builtin_ia32_pmulhrsw256:
4508 case clang::X86::BI__builtin_ia32_pmulhrsw512:
4511 return (llvm::APIntOps::mulsExtended(LHS, RHS).ashr(14) + 1)
4512 .extractBits(16, 1);
4513 });
4514
4515 case clang::X86::BI__builtin_ia32_movmskps:
4516 case clang::X86::BI__builtin_ia32_movmskpd:
4517 case clang::X86::BI__builtin_ia32_pmovmskb128:
4518 case clang::X86::BI__builtin_ia32_pmovmskb256:
4519 case clang::X86::BI__builtin_ia32_movmskps256:
4520 case clang::X86::BI__builtin_ia32_movmskpd256: {
4522 }
4523
4524 case X86::BI__builtin_ia32_psignb128:
4525 case X86::BI__builtin_ia32_psignb256:
4526 case X86::BI__builtin_ia32_psignw128:
4527 case X86::BI__builtin_ia32_psignw256:
4528 case X86::BI__builtin_ia32_psignd128:
4529 case X86::BI__builtin_ia32_psignd256:
4531 S, OpPC, Call, [](const APInt &AElem, const APInt &BElem) {
4532 if (BElem.isZero())
4533 return APInt::getZero(AElem.getBitWidth());
4534 if (BElem.isNegative())
4535 return -AElem;
4536 return AElem;
4537 });
4538
4539 case clang::X86::BI__builtin_ia32_pavgb128:
4540 case clang::X86::BI__builtin_ia32_pavgw128:
4541 case clang::X86::BI__builtin_ia32_pavgb256:
4542 case clang::X86::BI__builtin_ia32_pavgw256:
4543 case clang::X86::BI__builtin_ia32_pavgb512:
4544 case clang::X86::BI__builtin_ia32_pavgw512:
4546 llvm::APIntOps::avgCeilU);
4547
4548 case clang::X86::BI__builtin_ia32_pmaddubsw128:
4549 case clang::X86::BI__builtin_ia32_pmaddubsw256:
4550 case clang::X86::BI__builtin_ia32_pmaddubsw512:
4552 S, OpPC, Call,
4554 const APSInt &HiRHS) {
4555 unsigned BitWidth = 2 * LoLHS.getBitWidth();
4556 return (LoLHS.zext(BitWidth) * LoRHS.sext(BitWidth))
4557 .sadd_sat((HiLHS.zext(BitWidth) * HiRHS.sext(BitWidth)));
4558 });
4559
4560 case clang::X86::BI__builtin_ia32_pmaddwd128:
4561 case clang::X86::BI__builtin_ia32_pmaddwd256:
4562 case clang::X86::BI__builtin_ia32_pmaddwd512:
4564 S, OpPC, Call,
4566 const APSInt &HiRHS) {
4567 unsigned BitWidth = 2 * LoLHS.getBitWidth();
4568 return (LoLHS.sext(BitWidth) * LoRHS.sext(BitWidth)) +
4569 (HiLHS.sext(BitWidth) * HiRHS.sext(BitWidth));
4570 });
4571
4572 case clang::X86::BI__builtin_ia32_pmulhuw128:
4573 case clang::X86::BI__builtin_ia32_pmulhuw256:
4574 case clang::X86::BI__builtin_ia32_pmulhuw512:
4576 llvm::APIntOps::mulhu);
4577
4578 case clang::X86::BI__builtin_ia32_pmulhw128:
4579 case clang::X86::BI__builtin_ia32_pmulhw256:
4580 case clang::X86::BI__builtin_ia32_pmulhw512:
4582 llvm::APIntOps::mulhs);
4583
4584 case clang::X86::BI__builtin_ia32_psllv2di:
4585 case clang::X86::BI__builtin_ia32_psllv4di:
4586 case clang::X86::BI__builtin_ia32_psllv4si:
4587 case clang::X86::BI__builtin_ia32_psllv8di:
4588 case clang::X86::BI__builtin_ia32_psllv8hi:
4589 case clang::X86::BI__builtin_ia32_psllv8si:
4590 case clang::X86::BI__builtin_ia32_psllv16hi:
4591 case clang::X86::BI__builtin_ia32_psllv16si:
4592 case clang::X86::BI__builtin_ia32_psllv32hi:
4593 case clang::X86::BI__builtin_ia32_psllwi128:
4594 case clang::X86::BI__builtin_ia32_psllwi256:
4595 case clang::X86::BI__builtin_ia32_psllwi512:
4596 case clang::X86::BI__builtin_ia32_pslldi128:
4597 case clang::X86::BI__builtin_ia32_pslldi256:
4598 case clang::X86::BI__builtin_ia32_pslldi512:
4599 case clang::X86::BI__builtin_ia32_psllqi128:
4600 case clang::X86::BI__builtin_ia32_psllqi256:
4601 case clang::X86::BI__builtin_ia32_psllqi512:
4604 if (RHS.uge(LHS.getBitWidth())) {
4605 return APInt::getZero(LHS.getBitWidth());
4606 }
4607 return LHS.shl(RHS.getZExtValue());
4608 });
4609
4610 case clang::X86::BI__builtin_ia32_psrav4si:
4611 case clang::X86::BI__builtin_ia32_psrav8di:
4612 case clang::X86::BI__builtin_ia32_psrav8hi:
4613 case clang::X86::BI__builtin_ia32_psrav8si:
4614 case clang::X86::BI__builtin_ia32_psrav16hi:
4615 case clang::X86::BI__builtin_ia32_psrav16si:
4616 case clang::X86::BI__builtin_ia32_psrav32hi:
4617 case clang::X86::BI__builtin_ia32_psravq128:
4618 case clang::X86::BI__builtin_ia32_psravq256:
4619 case clang::X86::BI__builtin_ia32_psrawi128:
4620 case clang::X86::BI__builtin_ia32_psrawi256:
4621 case clang::X86::BI__builtin_ia32_psrawi512:
4622 case clang::X86::BI__builtin_ia32_psradi128:
4623 case clang::X86::BI__builtin_ia32_psradi256:
4624 case clang::X86::BI__builtin_ia32_psradi512:
4625 case clang::X86::BI__builtin_ia32_psraqi128:
4626 case clang::X86::BI__builtin_ia32_psraqi256:
4627 case clang::X86::BI__builtin_ia32_psraqi512:
4630 if (RHS.uge(LHS.getBitWidth())) {
4631 return LHS.ashr(LHS.getBitWidth() - 1);
4632 }
4633 return LHS.ashr(RHS.getZExtValue());
4634 });
4635
4636 case clang::X86::BI__builtin_ia32_psrlv2di:
4637 case clang::X86::BI__builtin_ia32_psrlv4di:
4638 case clang::X86::BI__builtin_ia32_psrlv4si:
4639 case clang::X86::BI__builtin_ia32_psrlv8di:
4640 case clang::X86::BI__builtin_ia32_psrlv8hi:
4641 case clang::X86::BI__builtin_ia32_psrlv8si:
4642 case clang::X86::BI__builtin_ia32_psrlv16hi:
4643 case clang::X86::BI__builtin_ia32_psrlv16si:
4644 case clang::X86::BI__builtin_ia32_psrlv32hi:
4645 case clang::X86::BI__builtin_ia32_psrlwi128:
4646 case clang::X86::BI__builtin_ia32_psrlwi256:
4647 case clang::X86::BI__builtin_ia32_psrlwi512:
4648 case clang::X86::BI__builtin_ia32_psrldi128:
4649 case clang::X86::BI__builtin_ia32_psrldi256:
4650 case clang::X86::BI__builtin_ia32_psrldi512:
4651 case clang::X86::BI__builtin_ia32_psrlqi128:
4652 case clang::X86::BI__builtin_ia32_psrlqi256:
4653 case clang::X86::BI__builtin_ia32_psrlqi512:
4656 if (RHS.uge(LHS.getBitWidth())) {
4657 return APInt::getZero(LHS.getBitWidth());
4658 }
4659 return LHS.lshr(RHS.getZExtValue());
4660 });
4661 case clang::X86::BI__builtin_ia32_packsswb128:
4662 case clang::X86::BI__builtin_ia32_packsswb256:
4663 case clang::X86::BI__builtin_ia32_packsswb512:
4664 case clang::X86::BI__builtin_ia32_packssdw128:
4665 case clang::X86::BI__builtin_ia32_packssdw256:
4666 case clang::X86::BI__builtin_ia32_packssdw512:
4668 return APInt(Src).truncSSat(Src.getBitWidth() / 2);
4669 });
4670 case clang::X86::BI__builtin_ia32_packusdw128:
4671 case clang::X86::BI__builtin_ia32_packusdw256:
4672 case clang::X86::BI__builtin_ia32_packusdw512:
4673 case clang::X86::BI__builtin_ia32_packuswb128:
4674 case clang::X86::BI__builtin_ia32_packuswb256:
4675 case clang::X86::BI__builtin_ia32_packuswb512:
4677 unsigned DstBits = Src.getBitWidth() / 2;
4678 if (Src.isNegative())
4679 return APInt::getZero(DstBits);
4680 if (Src.isIntN(DstBits))
4681 return APInt(Src).trunc(DstBits);
4682 return APInt::getAllOnes(DstBits);
4683 });
4684
4685 case clang::X86::BI__builtin_ia32_selectss_128:
4686 case clang::X86::BI__builtin_ia32_selectsd_128:
4687 case clang::X86::BI__builtin_ia32_selectsh_128:
4688 case clang::X86::BI__builtin_ia32_selectsbf_128:
4690 case clang::X86::BI__builtin_ia32_vprotbi:
4691 case clang::X86::BI__builtin_ia32_vprotdi:
4692 case clang::X86::BI__builtin_ia32_vprotqi:
4693 case clang::X86::BI__builtin_ia32_vprotwi:
4694 case clang::X86::BI__builtin_ia32_prold128:
4695 case clang::X86::BI__builtin_ia32_prold256:
4696 case clang::X86::BI__builtin_ia32_prold512:
4697 case clang::X86::BI__builtin_ia32_prolq128:
4698 case clang::X86::BI__builtin_ia32_prolq256:
4699 case clang::X86::BI__builtin_ia32_prolq512:
4701 S, OpPC, Call,
4702 [](const APSInt &LHS, const APSInt &RHS) { return LHS.rotl(RHS); });
4703
4704 case clang::X86::BI__builtin_ia32_prord128:
4705 case clang::X86::BI__builtin_ia32_prord256:
4706 case clang::X86::BI__builtin_ia32_prord512:
4707 case clang::X86::BI__builtin_ia32_prorq128:
4708 case clang::X86::BI__builtin_ia32_prorq256:
4709 case clang::X86::BI__builtin_ia32_prorq512:
4711 S, OpPC, Call,
4712 [](const APSInt &LHS, const APSInt &RHS) { return LHS.rotr(RHS); });
4713
4714 case Builtin::BI__builtin_elementwise_max:
4715 case Builtin::BI__builtin_elementwise_min:
4717
4718 case clang::X86::BI__builtin_ia32_phaddw128:
4719 case clang::X86::BI__builtin_ia32_phaddw256:
4720 case clang::X86::BI__builtin_ia32_phaddd128:
4721 case clang::X86::BI__builtin_ia32_phaddd256:
4723 S, OpPC, Call,
4724 [](const APSInt &LHS, const APSInt &RHS) { return LHS + RHS; });
4725 case clang::X86::BI__builtin_ia32_phaddsw128:
4726 case clang::X86::BI__builtin_ia32_phaddsw256:
4728 S, OpPC, Call,
4729 [](const APSInt &LHS, const APSInt &RHS) { return LHS.sadd_sat(RHS); });
4730 case clang::X86::BI__builtin_ia32_phsubw128:
4731 case clang::X86::BI__builtin_ia32_phsubw256:
4732 case clang::X86::BI__builtin_ia32_phsubd128:
4733 case clang::X86::BI__builtin_ia32_phsubd256:
4735 S, OpPC, Call,
4736 [](const APSInt &LHS, const APSInt &RHS) { return LHS - RHS; });
4737 case clang::X86::BI__builtin_ia32_phsubsw128:
4738 case clang::X86::BI__builtin_ia32_phsubsw256:
4740 S, OpPC, Call,
4741 [](const APSInt &LHS, const APSInt &RHS) { return LHS.ssub_sat(RHS); });
4742 case clang::X86::BI__builtin_ia32_haddpd:
4743 case clang::X86::BI__builtin_ia32_haddps:
4744 case clang::X86::BI__builtin_ia32_haddpd256:
4745 case clang::X86::BI__builtin_ia32_haddps256:
4747 S, OpPC, Call,
4748 [](const APFloat &LHS, const APFloat &RHS, llvm::RoundingMode RM) {
4750 F.add(RHS, RM);
4751 return F;
4752 });
4753 case clang::X86::BI__builtin_ia32_hsubpd:
4754 case clang::X86::BI__builtin_ia32_hsubps:
4755 case clang::X86::BI__builtin_ia32_hsubpd256:
4756 case clang::X86::BI__builtin_ia32_hsubps256:
4758 S, OpPC, Call,
4759 [](const APFloat &LHS, const APFloat &RHS, llvm::RoundingMode RM) {
4761 F.subtract(RHS, RM);
4762 return F;
4763 });
4764 case clang::X86::BI__builtin_ia32_addsubpd:
4765 case clang::X86::BI__builtin_ia32_addsubps:
4766 case clang::X86::BI__builtin_ia32_addsubpd256:
4767 case clang::X86::BI__builtin_ia32_addsubps256:
4769
4770 case clang::X86::BI__builtin_ia32_pmuldq128:
4771 case clang::X86::BI__builtin_ia32_pmuldq256:
4772 case clang::X86::BI__builtin_ia32_pmuldq512:
4774 S, OpPC, Call,
4776 const APSInt &HiRHS) {
4777 return llvm::APIntOps::mulsExtended(LoLHS, LoRHS);
4778 });
4779
4780 case clang::X86::BI__builtin_ia32_pmuludq128:
4781 case clang::X86::BI__builtin_ia32_pmuludq256:
4782 case clang::X86::BI__builtin_ia32_pmuludq512:
4784 S, OpPC, Call,
4786 const APSInt &HiRHS) {
4787 return llvm::APIntOps::muluExtended(LoLHS, LoRHS);
4788 });
4789
4790 case Builtin::BI__builtin_elementwise_fma:
4792 S, OpPC, Call,
4794 llvm::RoundingMode RM) {
4796 F.fusedMultiplyAdd(Y, Z, RM);
4797 return F;
4798 });
4799
4800 case X86::BI__builtin_ia32_vpmadd52luq128:
4801 case X86::BI__builtin_ia32_vpmadd52luq256:
4802 case X86::BI__builtin_ia32_vpmadd52luq512:
4805 return A + (B.trunc(52) * C.trunc(52)).zext(64);
4806 });
4807 case X86::BI__builtin_ia32_vpmadd52huq128:
4808 case X86::BI__builtin_ia32_vpmadd52huq256:
4809 case X86::BI__builtin_ia32_vpmadd52huq512:
4812 return A + llvm::APIntOps::mulhu(B.trunc(52), C.trunc(52)).zext(64);
4813 });
4814
4815 case X86::BI__builtin_ia32_vpshldd128:
4816 case X86::BI__builtin_ia32_vpshldd256:
4817 case X86::BI__builtin_ia32_vpshldd512:
4818 case X86::BI__builtin_ia32_vpshldq128:
4819 case X86::BI__builtin_ia32_vpshldq256:
4820 case X86::BI__builtin_ia32_vpshldq512:
4821 case X86::BI__builtin_ia32_vpshldw128:
4822 case X86::BI__builtin_ia32_vpshldw256:
4823 case X86::BI__builtin_ia32_vpshldw512:
4825 S, OpPC, Call,
4827 return llvm::APIntOps::fshl(Hi, Lo, Amt);
4828 });
4829
4830 case X86::BI__builtin_ia32_vpshrdd128:
4831 case X86::BI__builtin_ia32_vpshrdd256:
4832 case X86::BI__builtin_ia32_vpshrdd512:
4833 case X86::BI__builtin_ia32_vpshrdq128:
4834 case X86::BI__builtin_ia32_vpshrdq256:
4835 case X86::BI__builtin_ia32_vpshrdq512:
4836 case X86::BI__builtin_ia32_vpshrdw128:
4837 case X86::BI__builtin_ia32_vpshrdw256:
4838 case X86::BI__builtin_ia32_vpshrdw512:
4839
4841 S, OpPC, Call,
4843 return llvm::APIntOps::fshr(Hi, Lo, Amt);
4844 });
4845 case X86::BI__builtin_ia32_vpconflictsi_128:
4846 case X86::BI__builtin_ia32_vpconflictsi_256:
4847 case X86::BI__builtin_ia32_vpconflictsi_512:
4848 case X86::BI__builtin_ia32_vpconflictdi_128:
4849 case X86::BI__builtin_ia32_vpconflictdi_256:
4850 case X86::BI__builtin_ia32_vpconflictdi_512:
4852 case clang::X86::BI__builtin_ia32_blendpd:
4853 case clang::X86::BI__builtin_ia32_blendpd256:
4854 case clang::X86::BI__builtin_ia32_blendps:
4855 case clang::X86::BI__builtin_ia32_blendps256:
4856 case clang::X86::BI__builtin_ia32_pblendw128:
4857 case clang::X86::BI__builtin_ia32_pblendw256:
4858 case clang::X86::BI__builtin_ia32_pblendd128:
4859 case clang::X86::BI__builtin_ia32_pblendd256:
4861 S, OpPC, Call, [](unsigned DstIdx, unsigned ShuffleMask) {
4862
4863 unsigned MaskBit = (ShuffleMask >> (DstIdx % 8)) & 0x1;
4864 unsigned SrcVecIdx = MaskBit ? 1 : 0;
4865 return std::pair<unsigned, int>{SrcVecIdx, static_cast<int>(DstIdx)};
4866 });
4867
4868
4869
4870 case clang::X86::BI__builtin_ia32_blendvpd:
4871 case clang::X86::BI__builtin_ia32_blendvpd256:
4872 case clang::X86::BI__builtin_ia32_blendvps:
4873 case clang::X86::BI__builtin_ia32_blendvps256:
4875 S, OpPC, Call,
4877 llvm::RoundingMode) { return C.isNegative() ? T : F; });
4878
4879 case clang::X86::BI__builtin_ia32_pblendvb128:
4880 case clang::X86::BI__builtin_ia32_pblendvb256:
4883 return ((APInt)C).isNegative() ? T : F;
4884 });
4885 case X86::BI__builtin_ia32_ptestz128:
4886 case X86::BI__builtin_ia32_ptestz256:
4887 case X86::BI__builtin_ia32_vtestzps:
4888 case X86::BI__builtin_ia32_vtestzps256:
4889 case X86::BI__builtin_ia32_vtestzpd:
4890 case X86::BI__builtin_ia32_vtestzpd256:
4892 S, OpPC, Call,
4893 [](const APInt &A, const APInt &B) { return (A & B) == 0; });
4894 case X86::BI__builtin_ia32_ptestc128:
4895 case X86::BI__builtin_ia32_ptestc256:
4896 case X86::BI__builtin_ia32_vtestcps:
4897 case X86::BI__builtin_ia32_vtestcps256:
4898 case X86::BI__builtin_ia32_vtestcpd:
4899 case X86::BI__builtin_ia32_vtestcpd256:
4901 S, OpPC, Call,
4902 [](const APInt &A, const APInt &B) { return (~A & B) == 0; });
4903 case X86::BI__builtin_ia32_ptestnzc128:
4904 case X86::BI__builtin_ia32_ptestnzc256:
4905 case X86::BI__builtin_ia32_vtestnzcps:
4906 case X86::BI__builtin_ia32_vtestnzcps256:
4907 case X86::BI__builtin_ia32_vtestnzcpd:
4908 case X86::BI__builtin_ia32_vtestnzcpd256:
4911 return ((A & B) != 0) && ((~A & B) != 0);
4912 });
4913 case X86::BI__builtin_ia32_selectb_128:
4914 case X86::BI__builtin_ia32_selectb_256:
4915 case X86::BI__builtin_ia32_selectb_512:
4916 case X86::BI__builtin_ia32_selectw_128:
4917 case X86::BI__builtin_ia32_selectw_256:
4918 case X86::BI__builtin_ia32_selectw_512:
4919 case X86::BI__builtin_ia32_selectd_128:
4920 case X86::BI__builtin_ia32_selectd_256:
4921 case X86::BI__builtin_ia32_selectd_512:
4922 case X86::BI__builtin_ia32_selectq_128:
4923 case X86::BI__builtin_ia32_selectq_256:
4924 case X86::BI__builtin_ia32_selectq_512:
4925 case X86::BI__builtin_ia32_selectph_128:
4926 case X86::BI__builtin_ia32_selectph_256:
4927 case X86::BI__builtin_ia32_selectph_512:
4928 case X86::BI__builtin_ia32_selectpbf_128:
4929 case X86::BI__builtin_ia32_selectpbf_256:
4930 case X86::BI__builtin_ia32_selectpbf_512:
4931 case X86::BI__builtin_ia32_selectps_128:
4932 case X86::BI__builtin_ia32_selectps_256:
4933 case X86::BI__builtin_ia32_selectps_512:
4934 case X86::BI__builtin_ia32_selectpd_128:
4935 case X86::BI__builtin_ia32_selectpd_256:
4936 case X86::BI__builtin_ia32_selectpd_512:
4938
4939 case X86::BI__builtin_ia32_shufps:
4940 case X86::BI__builtin_ia32_shufps256:
4941 case X86::BI__builtin_ia32_shufps512:
4943 S, OpPC, Call, [](unsigned DstIdx, unsigned ShuffleMask) {
4944 unsigned NumElemPerLane = 4;
4945 unsigned NumSelectableElems = NumElemPerLane / 2;
4946 unsigned BitsPerElem = 2;
4947 unsigned IndexMask = 0x3;
4948 unsigned MaskBits = 8;
4949 unsigned Lane = DstIdx / NumElemPerLane;
4950 unsigned ElemInLane = DstIdx % NumElemPerLane;
4951 unsigned LaneOffset = Lane * NumElemPerLane;
4952 unsigned SrcIdx = ElemInLane >= NumSelectableElems ? 1 : 0;
4953 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
4954 unsigned Index = (ShuffleMask >> BitIndex) & IndexMask;
4955 return std::pair<unsigned, int>{SrcIdx,
4956 static_cast<int>(LaneOffset + Index)};
4957 });
4958 case X86::BI__builtin_ia32_shufpd:
4959 case X86::BI__builtin_ia32_shufpd256:
4960 case X86::BI__builtin_ia32_shufpd512:
4962 S, OpPC, Call, [](unsigned DstIdx, unsigned ShuffleMask) {
4963 unsigned NumElemPerLane = 2;
4964 unsigned NumSelectableElems = NumElemPerLane / 2;
4965 unsigned BitsPerElem = 1;
4966 unsigned IndexMask = 0x1;
4967 unsigned MaskBits = 8;
4968 unsigned Lane = DstIdx / NumElemPerLane;
4969 unsigned ElemInLane = DstIdx % NumElemPerLane;
4970 unsigned LaneOffset = Lane * NumElemPerLane;
4971 unsigned SrcIdx = ElemInLane >= NumSelectableElems ? 1 : 0;
4972 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
4973 unsigned Index = (ShuffleMask >> BitIndex) & IndexMask;
4974 return std::pair<unsigned, int>{SrcIdx,
4975 static_cast<int>(LaneOffset + Index)};
4976 });
4977
4978 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v16qi:
4979 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v32qi:
4980 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v64qi:
4982 case X86::BI__builtin_ia32_vgf2p8affineqb_v16qi:
4983 case X86::BI__builtin_ia32_vgf2p8affineqb_v32qi:
4984 case X86::BI__builtin_ia32_vgf2p8affineqb_v64qi:
4986
4987 case X86::BI__builtin_ia32_vgf2p8mulb_v16qi:
4988 case X86::BI__builtin_ia32_vgf2p8mulb_v32qi:
4989 case X86::BI__builtin_ia32_vgf2p8mulb_v64qi:
4991
4992 case X86::BI__builtin_ia32_insertps128:
4994 S, OpPC, Call, [](unsigned DstIdx, unsigned Mask) {
4995
4996 if ((Mask & (1 << DstIdx)) != 0) {
4997 return std::pair<unsigned, int>{0, -1};
4998 }
4999
5000
5001 unsigned SrcElem = (Mask >> 6) & 0x3;
5002 unsigned DstElem = (Mask >> 4) & 0x3;
5003 if (DstIdx == DstElem) {
5004
5005 return std::pair<unsigned, int>{1, static_cast<int>(SrcElem)};
5006 } else {
5007
5008 return std::pair<unsigned, int>{0, static_cast<int>(DstIdx)};
5009 }
5010 });
5011 case X86::BI__builtin_ia32_permvarsi256:
5012 case X86::BI__builtin_ia32_permvarsf256:
5013 case X86::BI__builtin_ia32_permvardf512:
5014 case X86::BI__builtin_ia32_permvardi512:
5015 case X86::BI__builtin_ia32_permvarhi128:
5017 S, OpPC, Call, [](unsigned DstIdx, unsigned ShuffleMask) {
5018 int Offset = ShuffleMask & 0x7;
5019 return std::pair<unsigned, int>{0, Offset};
5020 });
5021 case X86::BI__builtin_ia32_permvarqi128:
5022 case X86::BI__builtin_ia32_permvarhi256:
5023 case X86::BI__builtin_ia32_permvarsi512:
5024 case X86::BI__builtin_ia32_permvarsf512:
5026 S, OpPC, Call, [](unsigned DstIdx, unsigned ShuffleMask) {
5027 int Offset = ShuffleMask & 0xF;
5028 return std::pair<unsigned, int>{0, Offset};
5029 });
5030 case X86::BI__builtin_ia32_permvardi256:
5031 case X86::BI__builtin_ia32_permvardf256:
5033 S, OpPC, Call, [](unsigned DstIdx, unsigned ShuffleMask) {
5034 int Offset = ShuffleMask & 0x3;
5035 return std::pair<unsigned, int>{0, Offset};
5036 });
5037 case X86::BI__builtin_ia32_permvarqi256:
5038 case X86::BI__builtin_ia32_permvarhi512:
5040 S, OpPC, Call, [](unsigned DstIdx, unsigned ShuffleMask) {
5041 int Offset = ShuffleMask & 0x1F;
5042 return std::pair<unsigned, int>{0, Offset};
5043 });
5044 case X86::BI__builtin_ia32_permvarqi512:
5046 S, OpPC, Call, [](unsigned DstIdx, unsigned ShuffleMask) {
5047 int Offset = ShuffleMask & 0x3F;
5048 return std::pair<unsigned, int>{0, Offset};
5049 });
5050 case X86::BI__builtin_ia32_vpermi2varq128:
5051 case X86::BI__builtin_ia32_vpermi2varpd128:
5053 S, OpPC, Call, [](unsigned DstIdx, unsigned ShuffleMask) {
5054 int Offset = ShuffleMask & 0x1;
5055 unsigned SrcIdx = (ShuffleMask >> 1) & 0x1;
5056 return std::pair<unsigned, int>{SrcIdx, Offset};
5057 });
5058 case X86::BI__builtin_ia32_vpermi2vard128:
5059 case X86::BI__builtin_ia32_vpermi2varps128:
5060 case X86::BI__builtin_ia32_vpermi2varq256:
5061 case X86::BI__builtin_ia32_vpermi2varpd256:
5063 S, OpPC, Call, [](unsigned DstIdx, unsigned ShuffleMask) {
5064 int Offset = ShuffleMask & 0x3;
5065 unsigned SrcIdx = (ShuffleMask >> 2) & 0x1;
5066 return std::pair<unsigned, int>{SrcIdx, Offset};
5067 });
5068 case X86::BI__builtin_ia32_vpermi2varhi128:
5069 case X86::BI__builtin_ia32_vpermi2vard256:
5070 case X86::BI__builtin_ia32_vpermi2varps256:
5071 case X86::BI__builtin_ia32_vpermi2varq512:
5072 case X86::BI__builtin_ia32_vpermi2varpd512:
5074 S, OpPC, Call, [](unsigned DstIdx, unsigned ShuffleMask) {
5075 int Offset = ShuffleMask & 0x7;
5076 unsigned SrcIdx = (ShuffleMask >> 3) & 0x1;
5077 return std::pair<unsigned, int>{SrcIdx, Offset};
5078 });
5079 case X86::BI__builtin_ia32_vpermi2varqi128:
5080 case X86::BI__builtin_ia32_vpermi2varhi256:
5081 case X86::BI__builtin_ia32_vpermi2vard512:
5082 case X86::BI__builtin_ia32_vpermi2varps512:
5084 S, OpPC, Call, [](unsigned DstIdx, unsigned ShuffleMask) {
5085 int Offset = ShuffleMask & 0xF;
5086 unsigned SrcIdx = (ShuffleMask >> 4) & 0x1;
5087 return std::pair<unsigned, int>{SrcIdx, Offset};
5088 });
5089 case X86::BI__builtin_ia32_vpermi2varqi256:
5090 case X86::BI__builtin_ia32_vpermi2varhi512:
5092 S, OpPC, Call, [](unsigned DstIdx, unsigned ShuffleMask) {
5093 int Offset = ShuffleMask & 0x1F;
5094 unsigned SrcIdx = (ShuffleMask >> 5) & 0x1;
5095 return std::pair<unsigned, int>{SrcIdx, Offset};
5096 });
5097 case X86::BI__builtin_ia32_vpermi2varqi512:
5099 S, OpPC, Call, [](unsigned DstIdx, unsigned ShuffleMask) {
5100 int Offset = ShuffleMask & 0x3F;
5101 unsigned SrcIdx = (ShuffleMask >> 6) & 0x1;
5102 return std::pair<unsigned, int>{SrcIdx, Offset};
5103 });
5104 case X86::BI__builtin_ia32_pshufb128:
5105 case X86::BI__builtin_ia32_pshufb256:
5106 case X86::BI__builtin_ia32_pshufb512:
5108 S, OpPC, Call, [](unsigned DstIdx, unsigned ShuffleMask) {
5109 uint8_t Ctlb = static_cast<uint8_t>(ShuffleMask);
5110 if (Ctlb & 0x80)
5111 return std::make_pair(0, -1);
5112
5113 unsigned LaneBase = (DstIdx / 16) * 16;
5114 unsigned SrcOffset = Ctlb & 0x0F;
5115 unsigned SrcIdx = LaneBase + SrcOffset;
5116 return std::make_pair(0, static_cast<int>(SrcIdx));
5117 });
5118
5119 case X86::BI__builtin_ia32_pshuflw:
5120 case X86::BI__builtin_ia32_pshuflw256:
5121 case X86::BI__builtin_ia32_pshuflw512:
5123 S, OpPC, Call, [](unsigned DstIdx, unsigned ShuffleMask) {
5124 unsigned LaneBase = (DstIdx / 8) * 8;
5125 unsigned LaneIdx = DstIdx % 8;
5126 if (LaneIdx < 4) {
5127 unsigned Sel = (ShuffleMask >> (2 * LaneIdx)) & 0x3;
5128 return std::make_pair(0, static_cast<int>(LaneBase + Sel));
5129 }
5130
5131 return std::make_pair(0, static_cast<int>(DstIdx));
5132 });
5133
5134 case X86::BI__builtin_ia32_pshufhw:
5135 case X86::BI__builtin_ia32_pshufhw256:
5136 case X86::BI__builtin_ia32_pshufhw512:
5138 S, OpPC, Call, [](unsigned DstIdx, unsigned ShuffleMask) {
5139 unsigned LaneBase = (DstIdx / 8) * 8;
5140 unsigned LaneIdx = DstIdx % 8;
5141 if (LaneIdx >= 4) {
5142 unsigned Sel = (ShuffleMask >> (2 * (LaneIdx - 4))) & 0x3;
5143 return std::make_pair(0, static_cast<int>(LaneBase + 4 + Sel));
5144 }
5145
5146 return std::make_pair(0, static_cast<int>(DstIdx));
5147 });
5148
5149 case X86::BI__builtin_ia32_pshufd:
5150 case X86::BI__builtin_ia32_pshufd256:
5151 case X86::BI__builtin_ia32_pshufd512:
5152 case X86::BI__builtin_ia32_vpermilps:
5153 case X86::BI__builtin_ia32_vpermilps256:
5154 case X86::BI__builtin_ia32_vpermilps512:
5156 S, OpPC, Call, [](unsigned DstIdx, unsigned ShuffleMask) {
5157 unsigned LaneBase = (DstIdx / 4) * 4;
5158 unsigned LaneIdx = DstIdx % 4;
5159 unsigned Sel = (ShuffleMask >> (2 * LaneIdx)) & 0x3;
5160 return std::make_pair(0, static_cast<int>(LaneBase + Sel));
5161 });
5162
5163 case X86::BI__builtin_ia32_vpermilvarpd:
5164 case X86::BI__builtin_ia32_vpermilvarpd256:
5165 case X86::BI__builtin_ia32_vpermilvarpd512:
5167 S, OpPC, Call, [](unsigned DstIdx, unsigned ShuffleMask) {
5168 unsigned NumElemPerLane = 2;
5169 unsigned Lane = DstIdx / NumElemPerLane;
5170 unsigned Offset = ShuffleMask & 0b10 ? 1 : 0;
5171 return std::make_pair(
5172 0, static_cast<int>(Lane * NumElemPerLane + Offset));
5173 });
5174
5175 case X86::BI__builtin_ia32_vpermilvarps:
5176 case X86::BI__builtin_ia32_vpermilvarps256:
5177 case X86::BI__builtin_ia32_vpermilvarps512:
5179 S, OpPC, Call, [](unsigned DstIdx, unsigned ShuffleMask) {
5180 unsigned NumElemPerLane = 4;
5181 unsigned Lane = DstIdx / NumElemPerLane;
5182 unsigned Offset = ShuffleMask & 0b11;
5183 return std::make_pair(
5184 0, static_cast<int>(Lane * NumElemPerLane + Offset));
5185 });
5186
5187 case X86::BI__builtin_ia32_vpermilpd:
5188 case X86::BI__builtin_ia32_vpermilpd256:
5189 case X86::BI__builtin_ia32_vpermilpd512:
5191 S, OpPC, Call, [](unsigned DstIdx, unsigned Control) {
5192 unsigned NumElemPerLane = 2;
5193 unsigned BitsPerElem = 1;
5194 unsigned MaskBits = 8;
5195 unsigned IndexMask = 0x1;
5196 unsigned Lane = DstIdx / NumElemPerLane;
5197 unsigned LaneOffset = Lane * NumElemPerLane;
5198 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
5199 unsigned Index = (Control >> BitIndex) & IndexMask;
5200 return std::make_pair(0, static_cast<int>(LaneOffset + Index));
5201 });
5202
5203 case X86::BI__builtin_ia32_permdf256:
5204 case X86::BI__builtin_ia32_permdi256:
5206 S, OpPC, Call, [](unsigned DstIdx, unsigned Control) {
5207
5208
5209 unsigned Index = (Control >> (2 * DstIdx)) & 0x3;
5210 return std::make_pair(0, static_cast<int>(Index));
5211 });
5212
5213 case X86::BI__builtin_ia32_vpmultishiftqb128:
5214 case X86::BI__builtin_ia32_vpmultishiftqb256:
5215 case X86::BI__builtin_ia32_vpmultishiftqb512:
5217 case X86::BI__builtin_ia32_kandqi:
5218 case X86::BI__builtin_ia32_kandhi:
5219 case X86::BI__builtin_ia32_kandsi:
5220 case X86::BI__builtin_ia32_kanddi:
5222 S, OpPC, Call,
5223 [](const APSInt &LHS, const APSInt &RHS) { return LHS & RHS; });
5224
5225 case X86::BI__builtin_ia32_kandnqi:
5226 case X86::BI__builtin_ia32_kandnhi:
5227 case X86::BI__builtin_ia32_kandnsi:
5228 case X86::BI__builtin_ia32_kandndi:
5230 S, OpPC, Call,
5231 [](const APSInt &LHS, const APSInt &RHS) { return ~LHS & RHS; });
5232
5233 case X86::BI__builtin_ia32_korqi:
5234 case X86::BI__builtin_ia32_korhi:
5235 case X86::BI__builtin_ia32_korsi:
5236 case X86::BI__builtin_ia32_kordi:
5238 S, OpPC, Call,
5239 [](const APSInt &LHS, const APSInt &RHS) { return LHS | RHS; });
5240
5241 case X86::BI__builtin_ia32_kxnorqi:
5242 case X86::BI__builtin_ia32_kxnorhi:
5243 case X86::BI__builtin_ia32_kxnorsi:
5244 case X86::BI__builtin_ia32_kxnordi:
5246 S, OpPC, Call,
5247 [](const APSInt &LHS, const APSInt &RHS) { return ~(LHS ^ RHS); });
5248
5249 case X86::BI__builtin_ia32_kxorqi:
5250 case X86::BI__builtin_ia32_kxorhi:
5251 case X86::BI__builtin_ia32_kxorsi:
5252 case X86::BI__builtin_ia32_kxordi:
5254 S, OpPC, Call,
5255 [](const APSInt &LHS, const APSInt &RHS) { return LHS ^ RHS; });
5256
5257 case X86::BI__builtin_ia32_knotqi:
5258 case X86::BI__builtin_ia32_knothi:
5259 case X86::BI__builtin_ia32_knotsi:
5260 case X86::BI__builtin_ia32_knotdi:
5262 S, OpPC, Call, [](const APSInt &Src) { return ~Src; });
5263
5264 case X86::BI__builtin_ia32_kaddqi:
5265 case X86::BI__builtin_ia32_kaddhi:
5266 case X86::BI__builtin_ia32_kaddsi:
5267 case X86::BI__builtin_ia32_kadddi:
5269 S, OpPC, Call,
5270 [](const APSInt &LHS, const APSInt &RHS) { return LHS + RHS; });
5271
5272 case X86::BI__builtin_ia32_kmovb:
5273 case X86::BI__builtin_ia32_kmovw:
5274 case X86::BI__builtin_ia32_kmovd:
5275 case X86::BI__builtin_ia32_kmovq:
5277 S, OpPC, Call, [](const APSInt &Src) { return Src; });
5278
5279 case X86::BI__builtin_ia32_kunpckhi:
5280 case X86::BI__builtin_ia32_kunpckdi:
5281 case X86::BI__builtin_ia32_kunpcksi:
5284
5285
5286 unsigned BW = A.getBitWidth();
5287 return APSInt(A.trunc(BW / 2).concat(B.trunc(BW / 2)),
5288 A.isUnsigned());
5289 });
5290
5291 case X86::BI__builtin_ia32_phminposuw128:
5293
5294 case X86::BI__builtin_ia32_psraq128:
5295 case X86::BI__builtin_ia32_psraq256:
5296 case X86::BI__builtin_ia32_psraq512:
5297 case X86::BI__builtin_ia32_psrad128:
5298 case X86::BI__builtin_ia32_psrad256:
5299 case X86::BI__builtin_ia32_psrad512:
5300 case X86::BI__builtin_ia32_psraw128:
5301 case X86::BI__builtin_ia32_psraw256:
5302 case X86::BI__builtin_ia32_psraw512:
5304 S, OpPC, Call,
5305 [](const APInt &Elt, uint64_t Count) { return Elt.ashr(Count); },
5306 [](const APInt &Elt, unsigned Width) { return Elt.ashr(Width - 1); });
5307
5308 case X86::BI__builtin_ia32_psllq128:
5309 case X86::BI__builtin_ia32_psllq256:
5310 case X86::BI__builtin_ia32_psllq512:
5311 case X86::BI__builtin_ia32_pslld128:
5312 case X86::BI__builtin_ia32_pslld256:
5313 case X86::BI__builtin_ia32_pslld512:
5314 case X86::BI__builtin_ia32_psllw128:
5315 case X86::BI__builtin_ia32_psllw256:
5316 case X86::BI__builtin_ia32_psllw512:
5318 S, OpPC, Call,
5319 [](const APInt &Elt, uint64_t Count) { return Elt.shl(Count); },
5320 [](const APInt &Elt, unsigned Width) { return APInt::getZero(Width); });
5321
5322 case X86::BI__builtin_ia32_psrlq128:
5323 case X86::BI__builtin_ia32_psrlq256:
5324 case X86::BI__builtin_ia32_psrlq512:
5325 case X86::BI__builtin_ia32_psrld128:
5326 case X86::BI__builtin_ia32_psrld256:
5327 case X86::BI__builtin_ia32_psrld512:
5328 case X86::BI__builtin_ia32_psrlw128:
5329 case X86::BI__builtin_ia32_psrlw256:
5330 case X86::BI__builtin_ia32_psrlw512:
5332 S, OpPC, Call,
5333 [](const APInt &Elt, uint64_t Count) { return Elt.lshr(Count); },
5334 [](const APInt &Elt, unsigned Width) { return APInt::getZero(Width); });
5335
5336 case X86::BI__builtin_ia32_pternlogd128_mask:
5337 case X86::BI__builtin_ia32_pternlogd256_mask:
5338 case X86::BI__builtin_ia32_pternlogd512_mask:
5339 case X86::BI__builtin_ia32_pternlogq128_mask:
5340 case X86::BI__builtin_ia32_pternlogq256_mask:
5341 case X86::BI__builtin_ia32_pternlogq512_mask:
5343 case X86::BI__builtin_ia32_pternlogd128_maskz:
5344 case X86::BI__builtin_ia32_pternlogd256_maskz:
5345 case X86::BI__builtin_ia32_pternlogd512_maskz:
5346 case X86::BI__builtin_ia32_pternlogq128_maskz:
5347 case X86::BI__builtin_ia32_pternlogq256_maskz:
5348 case X86::BI__builtin_ia32_pternlogq512_maskz:
5350 case Builtin::BI__builtin_elementwise_fshl:
5352 llvm::APIntOps::fshl);
5353 case Builtin::BI__builtin_elementwise_fshr:
5355 llvm::APIntOps::fshr);
5356
5357 case X86::BI__builtin_ia32_shuf_f32x4_256:
5358 case X86::BI__builtin_ia32_shuf_i32x4_256:
5359 case X86::BI__builtin_ia32_shuf_f64x2_256:
5360 case X86::BI__builtin_ia32_shuf_i64x2_256:
5361 case X86::BI__builtin_ia32_shuf_f32x4:
5362 case X86::BI__builtin_ia32_shuf_i32x4:
5363 case X86::BI__builtin_ia32_shuf_f64x2:
5364 case X86::BI__builtin_ia32_shuf_i64x2: {
5365
5366 QualType VecQT = Call->getArg(0)->getType();
5370 unsigned LaneBits = 128u;
5371 unsigned NumLanes = (NumElems * ElemBits) / LaneBits;
5372 unsigned NumElemsPerLane = LaneBits / ElemBits;
5373
5375 S, OpPC, Call,
5376 [NumLanes, NumElemsPerLane](unsigned DstIdx, unsigned ShuffleMask) {
5377
5378 unsigned BitsPerElem = NumLanes / 2;
5379 unsigned IndexMask = (1u << BitsPerElem) - 1;
5380 unsigned Lane = DstIdx / NumElemsPerLane;
5381 unsigned SrcIdx = (Lane < NumLanes / 2) ? 0 : 1;
5382 unsigned BitIdx = BitsPerElem * Lane;
5383 unsigned SrcLaneIdx = (ShuffleMask >> BitIdx) & IndexMask;
5384 unsigned ElemInLane = DstIdx % NumElemsPerLane;
5385 unsigned IdxToPick = SrcLaneIdx * NumElemsPerLane + ElemInLane;
5386 return std::pair<unsigned, int>{SrcIdx, IdxToPick};
5387 });
5388 }
5389
5390 case X86::BI__builtin_ia32_insertf32x4_256:
5391 case X86::BI__builtin_ia32_inserti32x4_256:
5392 case X86::BI__builtin_ia32_insertf64x2_256:
5393 case X86::BI__builtin_ia32_inserti64x2_256:
5394 case X86::BI__builtin_ia32_insertf32x4:
5395 case X86::BI__builtin_ia32_inserti32x4:
5396 case X86::BI__builtin_ia32_insertf64x2_512:
5397 case X86::BI__builtin_ia32_inserti64x2_512:
5398 case X86::BI__builtin_ia32_insertf32x8:
5399 case X86::BI__builtin_ia32_inserti32x8:
5400 case X86::BI__builtin_ia32_insertf64x4:
5401 case X86::BI__builtin_ia32_inserti64x4:
5402 case X86::BI__builtin_ia32_vinsertf128_ps256:
5403 case X86::BI__builtin_ia32_vinsertf128_pd256:
5404 case X86::BI__builtin_ia32_vinsertf128_si256:
5405 case X86::BI__builtin_ia32_insert128i256:
5407
5408 case clang::X86::BI__builtin_ia32_vcvtps2ph:
5409 case clang::X86::BI__builtin_ia32_vcvtps2ph256:
5411
5412 case X86::BI__builtin_ia32_vec_ext_v4hi:
5413 case X86::BI__builtin_ia32_vec_ext_v16qi:
5414 case X86::BI__builtin_ia32_vec_ext_v8hi:
5415 case X86::BI__builtin_ia32_vec_ext_v4si:
5416 case X86::BI__builtin_ia32_vec_ext_v2di:
5417 case X86::BI__builtin_ia32_vec_ext_v32qi:
5418 case X86::BI__builtin_ia32_vec_ext_v16hi:
5419 case X86::BI__builtin_ia32_vec_ext_v8si:
5420 case X86::BI__builtin_ia32_vec_ext_v4di:
5421 case X86::BI__builtin_ia32_vec_ext_v4sf:
5423
5424 case X86::BI__builtin_ia32_vec_set_v4hi:
5425 case X86::BI__builtin_ia32_vec_set_v16qi:
5426 case X86::BI__builtin_ia32_vec_set_v8hi:
5427 case X86::BI__builtin_ia32_vec_set_v4si:
5428 case X86::BI__builtin_ia32_vec_set_v2di:
5429 case X86::BI__builtin_ia32_vec_set_v32qi:
5430 case X86::BI__builtin_ia32_vec_set_v16hi:
5431 case X86::BI__builtin_ia32_vec_set_v8si:
5432 case X86::BI__builtin_ia32_vec_set_v4di:
5434
5435 case X86::BI__builtin_ia32_cvtb2mask128:
5436 case X86::BI__builtin_ia32_cvtb2mask256:
5437 case X86::BI__builtin_ia32_cvtb2mask512:
5438 case X86::BI__builtin_ia32_cvtw2mask128:
5439 case X86::BI__builtin_ia32_cvtw2mask256:
5440 case X86::BI__builtin_ia32_cvtw2mask512:
5441 case X86::BI__builtin_ia32_cvtd2mask128:
5442 case X86::BI__builtin_ia32_cvtd2mask256:
5443 case X86::BI__builtin_ia32_cvtd2mask512:
5444 case X86::BI__builtin_ia32_cvtq2mask128:
5445 case X86::BI__builtin_ia32_cvtq2mask256:
5446 case X86::BI__builtin_ia32_cvtq2mask512:
5448
5449 case X86::BI__builtin_ia32_cvtsd2ss:
5451
5452 case X86::BI__builtin_ia32_cvtsd2ss_round_mask:
5454
5455 case X86::BI__builtin_ia32_cvtpd2ps:
5456 case X86::BI__builtin_ia32_cvtpd2ps256:
5458 case X86::BI__builtin_ia32_cvtpd2ps_mask:
5460 case X86::BI__builtin_ia32_cvtpd2ps512_mask:
5462
5463 case X86::BI__builtin_ia32_cmpb128_mask:
5464 case X86::BI__builtin_ia32_cmpw128_mask:
5465 case X86::BI__builtin_ia32_cmpd128_mask:
5466 case X86::BI__builtin_ia32_cmpq128_mask:
5467 case X86::BI__builtin_ia32_cmpb256_mask:
5468 case X86::BI__builtin_ia32_cmpw256_mask:
5469 case X86::BI__builtin_ia32_cmpd256_mask:
5470 case X86::BI__builtin_ia32_cmpq256_mask:
5471 case X86::BI__builtin_ia32_cmpb512_mask:
5472 case X86::BI__builtin_ia32_cmpw512_mask:
5473 case X86::BI__builtin_ia32_cmpd512_mask:
5474 case X86::BI__builtin_ia32_cmpq512_mask:
5476 false);
5477
5478 case X86::BI__builtin_ia32_ucmpb128_mask:
5479 case X86::BI__builtin_ia32_ucmpw128_mask:
5480 case X86::BI__builtin_ia32_ucmpd128_mask:
5481 case X86::BI__builtin_ia32_ucmpq128_mask:
5482 case X86::BI__builtin_ia32_ucmpb256_mask:
5483 case X86::BI__builtin_ia32_ucmpw256_mask:
5484 case X86::BI__builtin_ia32_ucmpd256_mask:
5485 case X86::BI__builtin_ia32_ucmpq256_mask:
5486 case X86::BI__builtin_ia32_ucmpb512_mask:
5487 case X86::BI__builtin_ia32_ucmpw512_mask:
5488 case X86::BI__builtin_ia32_ucmpd512_mask:
5489 case X86::BI__builtin_ia32_ucmpq512_mask:
5491 true);
5492
5493 case X86::BI__builtin_ia32_vpshufbitqmb128_mask:
5494 case X86::BI__builtin_ia32_vpshufbitqmb256_mask:
5495 case X86::BI__builtin_ia32_vpshufbitqmb512_mask:
5497
5498 case X86::BI__builtin_ia32_pslldqi128_byteshift:
5499 case X86::BI__builtin_ia32_pslldqi256_byteshift:
5500 case X86::BI__builtin_ia32_pslldqi512_byteshift:
5501
5502
5503
5504
5506 S, OpPC, Call,
5507 [](unsigned DstIdx, unsigned Shift) -> std::pair<unsigned, int> {
5508 unsigned LaneBase = (DstIdx / 16) * 16;
5509 unsigned LaneIdx = DstIdx % 16;
5510 if (LaneIdx < Shift)
5511 return std::make_pair(0, -1);
5512
5513 return std::make_pair(0,
5514 static_cast<int>(LaneBase + LaneIdx - Shift));
5515 });
5516
5517 case X86::BI__builtin_ia32_psrldqi128_byteshift:
5518 case X86::BI__builtin_ia32_psrldqi256_byteshift:
5519 case X86::BI__builtin_ia32_psrldqi512_byteshift:
5520
5521
5522
5523
5525 S, OpPC, Call,
5526 [](unsigned DstIdx, unsigned Shift) -> std::pair<unsigned, int> {
5527 unsigned LaneBase = (DstIdx / 16) * 16;
5528 unsigned LaneIdx = DstIdx % 16;
5529 if (LaneIdx + Shift < 16)
5530 return std::make_pair(0,
5531 static_cast<int>(LaneBase + LaneIdx + Shift));
5532
5533 return std::make_pair(0, -1);
5534 });
5535
5536 case X86::BI__builtin_ia32_palignr128:
5537 case X86::BI__builtin_ia32_palignr256:
5538 case X86::BI__builtin_ia32_palignr512:
5540 S, OpPC, Call, [](unsigned DstIdx, unsigned Shift) {
5541
5542 unsigned VecIdx = 1;
5543 int ElemIdx = -1;
5544
5545 int Lane = DstIdx / 16;
5546 int Offset = DstIdx % 16;
5547
5548
5549 unsigned ShiftedIdx = Offset + (Shift & 0xFF);
5550 if (ShiftedIdx < 16) {
5551 ElemIdx = ShiftedIdx + (Lane * 16);
5552 } else if (ShiftedIdx < 32) {
5553 VecIdx = 0;
5554 ElemIdx = (ShiftedIdx - 16) + (Lane * 16);
5555 }
5556
5557 return std::pair<unsigned, int>{VecIdx, ElemIdx};
5558 });
5559
5560 case X86::BI__builtin_ia32_alignd128:
5561 case X86::BI__builtin_ia32_alignd256:
5562 case X86::BI__builtin_ia32_alignd512:
5563 case X86::BI__builtin_ia32_alignq128:
5564 case X86::BI__builtin_ia32_alignq256:
5565 case X86::BI__builtin_ia32_alignq512: {
5566 unsigned NumElems = Call->getType()->castAs<VectorType>()->getNumElements();
5568 S, OpPC, Call, [NumElems](unsigned DstIdx, unsigned Shift) {
5569 unsigned Imm = Shift & 0xFF;
5570 unsigned EffectiveShift = Imm & (NumElems - 1);
5571 unsigned SourcePos = DstIdx + EffectiveShift;
5572 unsigned VecIdx = SourcePos < NumElems ? 1u : 0u;
5573 unsigned ElemIdx = SourcePos & (NumElems - 1);
5574 return std::pair<unsigned, int>{VecIdx, static_cast<int>(ElemIdx)};
5575 });
5576 }
5577
5578 default:
5580 diag::note_invalid_subexpr_in_const_expr)
5582
5583 return false;
5584 }
5585
5586 llvm_unreachable("Unhandled builtin ID");
5587}
5588
5593 assert(N > 0);
5594
5595 unsigned ArrayIndex = 0;
5597 for (unsigned I = 0; I != N; ++I) {
5599 switch (Node.getKind()) {
5603 if (!RD || RD->isInvalidDecl())
5604 return false;
5606 unsigned FieldIndex = MemberDecl->getFieldIndex();
5607 assert(FieldIndex < RL.getFieldCount() && "offsetof field in wrong type");
5611 break;
5612 }
5614
5615
5616 int64_t Index = ArrayIndices[ArrayIndex];
5618 if (!AT)
5619 return false;
5622 Result += Index * ElementSize;
5623 ++ArrayIndex;
5624 break;
5625 }
5629 return false;
5630
5631
5633 if (!RD || RD->isInvalidDecl())
5634 return false;
5636
5637
5638 CurrentType = BaseSpec->getType();
5640 if (!BaseRD)
5641 return false;
5642
5643
5645 break;
5646 }
5648 llvm_unreachable("Dependent OffsetOfExpr?");
5649 }
5650 }
5651
5652 IntResult = Result.getQuantity();
5653
5654 return true;
5655}
5656
5659
5661 assert(R);
5663
5667
5669 FieldPtr.deref<T>() = T::from(IntValue.getSExtValue()));
5671 return true;
5672}
5673
5676
5679 Dest.deref().~T();
5680 new (&Dest.deref()) T();
5681 });
5682 return;
5683 }
5684
5687 for (const Record::Field &F : R->fields()) {
5690 }
5691 return;
5692 }
5693
5695 for (unsigned I = 0, N = Desc->getNumElems(); I != N; ++I) {
5697 Dest.deref().~T();
5698 new (&Dest.deref()) T();
5699 });
5700 }
5701 return;
5702 }
5703
5705 for (unsigned I = 0, N = Desc->getNumElems(); I != N; ++I) {
5708 }
5709 return;
5710 }
5711}
5712
5713static bool copyComposite(InterpState &S, CodePtr OpPC, const Pointer &Src,
5714 Pointer &Dest, bool Activate);
5719
5720 auto copyField = [&](const Record::Field &F, bool Activate) -> bool {
5729 });
5730 return true;
5731 }
5732
5734 };
5735
5736 assert(SrcDesc->isRecord());
5739 for (const Record::Field &F : R->fields()) {
5741
5744 if (!copyField(F, true))
5745 return false;
5746 } else {
5748 return false;
5751 }
5752 } else {
5753 if (!copyField(F, Activate))
5754 return false;
5755 }
5756 }
5757
5758 for (const Record::Base &B : R->bases()) {
5761 return false;
5762 }
5763
5765 return true;
5766}
5767
5771
5774
5776
5781 for (unsigned I = 0, N = DestDesc->getNumElems(); I != N; ++I) {
5786 });
5787 }
5788 return true;
5789 }
5790
5794 for (unsigned I = 0, N = DestDesc->getNumElems(); I != N; ++I) {
5798 return false;
5799 }
5800 return true;
5801 }
5802
5805 return Invalid(S, OpPC);
5806}
5807
5811
5812}
5813}
Defines enum values for all the target-independent builtin functions.
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 ...
uint8_t GFNIMul(uint8_t AByte, uint8_t BByte)
uint8_t GFNIAffine(uint8_t XByte, const APInt &AQword, const APSInt &Imm, bool Inverse)
TokenType getType() const
Returns the token's type, e.g.
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)...
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.
QualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
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
static bool hasSameUnqualifiedType(QualType T1, QualType T2)
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
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
std::optional< llvm::AllocTokenMode > AllocTokenMode
The allocation token mode.
std::optional< uint64_t > AllocTokenMax
Maximum number of allocation tokens (0 = target SIZE_MAX), nullopt if none set (use target SIZE_MAX).
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)
bool isNull() const
Return true if this QualType doesn't point to a type yet.
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.
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 isRealFloatingType() const
Floating point categories.
bool isFloatingType() const
const T * getAs() const
Member-template getAs'.
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)
std::optional< llvm::AllocTokenMetadata > getAllocTokenMetadata(QualType T, const ASTContext &Ctx)
Get the information required for construction of an allocation token ID.
QualType inferPossibleType(const CallExpr *E, const ASTContext &Ctx, const CastExpr *CastE)
Infer the possible allocated type from an allocation call expression.
static bool isNoopBuiltin(unsigned ID)
Definition InterpBuiltin.cpp:29
static bool interp__builtin_is_within_lifetime(InterpState &S, CodePtr OpPC, const CallExpr *Call)
Definition InterpBuiltin.cpp:2345
static bool interp__builtin_ia32_shuffle_generic(InterpState &S, CodePtr OpPC, const CallExpr *Call, llvm::function_ref< std::pair< unsigned, int >(unsigned, unsigned)> GetSourceIndex)
Definition InterpBuiltin.cpp:3482
static bool interp__builtin_ia32_phminposuw(InterpState &S, CodePtr OpPC, const CallExpr *Call)
Definition InterpBuiltin.cpp:3126
static void assignInteger(InterpState &S, const Pointer &Dest, PrimType ValueT, const APSInt &Value)
Definition InterpBuiltin.cpp:114
static bool interp_builtin_ia32_gfni_affine(InterpState &S, CodePtr OpPC, const CallExpr *Call, bool Inverse)
Definition InterpBuiltin.cpp:3833
bool readPointerToBuffer(const Context &Ctx, const Pointer &FromPtr, BitcastBuffer &Buffer, bool ReturnOnUninit)
static Floating abs(InterpState &S, const Floating &In)
Definition InterpBuiltin.cpp:670
static bool interp__builtin_x86_extract_vector(InterpState &S, CodePtr OpPC, const CallExpr *Call, unsigned ID)
Definition InterpBuiltin.cpp:3009
static bool interp__builtin_fmax(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, bool IsNumBuiltin)
Definition InterpBuiltin.cpp:493
static bool interp__builtin_elementwise_maxmin(InterpState &S, CodePtr OpPC, const CallExpr *Call, unsigned BuiltinID)
Definition InterpBuiltin.cpp:2545
static bool interp__builtin_bswap(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
Definition InterpBuiltin.cpp:1007
static bool interp__builtin_elementwise_triop(InterpState &S, CodePtr OpPC, const CallExpr *Call, llvm::function_ref< APInt(const APSInt &, const APSInt &, const APSInt &)> Fn)
Definition InterpBuiltin.cpp:2946
static bool interp__builtin_assume(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
Definition InterpBuiltin.cpp:238
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_ia32_shift_with_count(InterpState &S, CodePtr OpPC, const CallExpr *Call, llvm::function_ref< APInt(const APInt &, uint64_t)> ShiftOp, llvm::function_ref< APInt(const APInt &, unsigned)> OverflowOp)
Definition InterpBuiltin.cpp:3566
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,...
Definition InterpBuiltin.cpp:510
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.
Definition InterpBuiltin.cpp:1666
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)
Definition InterpBuiltin.cpp:720
static bool interp__builtin_fmin(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, bool IsNumBuiltin)
Definition InterpBuiltin.cpp:479
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}...
Definition InterpBuiltin.cpp:5657
static bool interp__builtin_operator_delete(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
Definition InterpBuiltin.cpp:1497
static bool interp__builtin_fabs(InterpState &S, CodePtr OpPC, const InterpFrame *Frame)
Definition InterpBuiltin.cpp:686
static uint64_t popToUInt64(const InterpState &S, const Expr *E)
Definition InterpBuiltin.cpp:51
static bool interp__builtin_ia32_vpconflict(InterpState &S, CodePtr OpPC, const CallExpr *Call)
Definition InterpBuiltin.cpp:3317
static bool interp__builtin_memcmp(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call, unsigned ID)
Definition InterpBuiltin.cpp:1916
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,...
Definition InterpBuiltin.cpp:1020
static llvm::APSInt convertBoolVectorToInt(const Pointer &Val)
Definition InterpBuiltin.cpp:159
static bool interp__builtin_move(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
Definition InterpBuiltin.cpp:766
static bool interp__builtin_clz(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call, unsigned BuiltinOp)
Definition InterpBuiltin.cpp:944
bool CheckMutable(InterpState &S, CodePtr OpPC, const Pointer &Ptr)
Checks if a pointer points to a mutable field.
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...
Definition InterpBuiltin.cpp:1132
static bool interp__builtin_ia32_addsub(InterpState &S, CodePtr OpPC, const CallExpr *Call)
Definition InterpBuiltin.cpp:2731
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)
Definition InterpBuiltin.cpp:1285
static bool isOneByteCharacterType(QualType T)
Determine if T is a character type for which we guarantee that sizeof(T) == 1.
Definition InterpBuiltin.cpp:1912
static bool convertDoubleToFloatStrict(APFloat Src, Floating &Dst, InterpState &S, const Expr *DiagExpr)
Definition InterpBuiltin.cpp:177
static unsigned computePointerOffset(const ASTContext &ASTCtx, const Pointer &Ptr)
Compute the byte offset of Ptr in the full declaration.
Definition InterpBuiltin.cpp:2163
static bool interp__builtin_strcmp(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call, unsigned ID)
Definition InterpBuiltin.cpp:246
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_ia32_cmp_mask(InterpState &S, CodePtr OpPC, const CallExpr *Call, unsigned ID, bool IsUnsigned)
Definition InterpBuiltin.cpp:3287
static bool interp__builtin_overflowop(InterpState &S, CodePtr OpPC, const CallExpr *Call, unsigned BuiltinOp)
Definition InterpBuiltin.cpp:784
static bool interp__builtin_inf(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
Definition InterpBuiltin.cpp:452
static bool interp__builtin_vec_ext(InterpState &S, CodePtr OpPC, const CallExpr *Call, unsigned ID)
Definition InterpBuiltin.cpp:3208
static bool interp__builtin_ia32_test_op(InterpState &S, CodePtr OpPC, const CallExpr *Call, llvm::function_ref< bool(const APInt &A, const APInt &B)> Fn)
Definition InterpBuiltin.cpp:2878
static bool interp__builtin_isinf(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, bool CheckSign, const CallExpr *Call)
Definition InterpBuiltin.cpp:528
static bool interp__builtin_os_log_format_buffer_size(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
Definition InterpBuiltin.cpp:1323
bool InterpretOffsetOf(InterpState &S, CodePtr OpPC, const OffsetOfExpr *E, ArrayRef< int64_t > ArrayIndices, int64_t &IntResult)
Interpret an offsetof operation.
Definition InterpBuiltin.cpp:5589
static bool interp__builtin_x86_insert_subvector(InterpState &S, CodePtr OpPC, const CallExpr *Call, unsigned ID)
Definition InterpBuiltin.cpp:3085
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?
Definition InterpBuiltin.cpp:2210
static bool interp__builtin_select(InterpState &S, CodePtr OpPC, const CallExpr *Call)
AVX512 predicated move: "Result = Mask[] ? LHS[] : RHS[]".
Definition InterpBuiltin.cpp:2822
static void discard(InterpStack &Stk, PrimType T)
Definition InterpBuiltin.cpp:47
static bool interp__builtin_select_scalar(InterpState &S, const CallExpr *Call)
Scalar variant of AVX512 predicated select: Result[i] = (Mask bit 0) ?
Definition InterpBuiltin.cpp:2857
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.
Definition InterpBuiltin.cpp:637
static bool interp__builtin_abs(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
Definition InterpBuiltin.cpp:693
static bool interp_floating_comparison(InterpState &S, CodePtr OpPC, const CallExpr *Call, unsigned ID)
Definition InterpBuiltin.cpp:587
static bool handleOverflow(InterpState &S, CodePtr OpPC, const T &SrcValue)
static bool copyComposite(InterpState &S, CodePtr OpPC, const Pointer &Src, Pointer &Dest, bool Activate)
Definition InterpBuiltin.cpp:5768
static bool copyRecord(InterpState &S, CodePtr OpPC, const Pointer &Src, Pointer &Dest, bool Activate=false)
Definition InterpBuiltin.cpp:5715
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)
Definition InterpBuiltin.cpp:1092
static void zeroAll(Pointer &Dest)
Definition InterpBuiltin.cpp:5674
static bool interp__builtin_elementwise_int_binop(InterpState &S, CodePtr OpPC, const CallExpr *Call, llvm::function_ref< APInt(const APSInt &, const APSInt &)> Fn)
Definition InterpBuiltin.cpp:2436
static bool interp__builtin_issubnormal(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
Definition InterpBuiltin.cpp:560
static bool interp__builtin_arithmetic_fence(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
Definition InterpBuiltin.cpp:1552
static bool interp__builtin_x86_extract_vector_masked(InterpState &S, CodePtr OpPC, const CallExpr *Call, unsigned ID)
Definition InterpBuiltin.cpp:3044
PrimType
Enumeration of the primitive types of the VM.
static bool interp__builtin_isfinite(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
Definition InterpBuiltin.cpp:542
bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call, uint32_t BuiltinID)
Interpret a builtin function.
Definition InterpBuiltin.cpp:3927
static bool interp__builtin_expect(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
Definition InterpBuiltin.cpp:736
static bool interp__builtin_vec_set(InterpState &S, CodePtr OpPC, const CallExpr *Call, unsigned ID)
Definition InterpBuiltin.cpp:3235
static bool interp__builtin_complex(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
__builtin_complex(Float A, float B);
Definition InterpBuiltin.cpp:1113
static bool evalICmpImm(uint8_t Imm, const APSInt &A, const APSInt &B, bool IsUnsigned)
Definition InterpBuiltin.cpp:3263
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])
Definition InterpBuiltin.cpp:1234
static bool interp__builtin_ia32_cvt_vec2mask(InterpState &S, CodePtr OpPC, const CallExpr *Call, unsigned ID)
Definition InterpBuiltin.cpp:3344
static bool interp__builtin_ptrauth_string_discriminator(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
Definition InterpBuiltin.cpp:1334
static bool interp__builtin_memchr(InterpState &S, CodePtr OpPC, const CallExpr *Call, unsigned ID)
Definition InterpBuiltin.cpp:2035
static bool interp__builtin_ia32_pmul(InterpState &S, CodePtr OpPC, const CallExpr *Call, llvm::function_ref< APInt(const APSInt &, const APSInt &, const APSInt &, const APSInt &)> Fn)
Definition InterpBuiltin.cpp:2617
static bool interp__builtin_x86_pack(InterpState &S, CodePtr, const CallExpr *E, llvm::function_ref< APInt(const APSInt &)> PackFn)
Definition InterpBuiltin.cpp:2500
static void pushInteger(InterpState &S, const APSInt &Val, QualType QT)
Pushes Val on the stack as the type given by QT.
Definition InterpBuiltin.cpp:68
static bool interp__builtin_operator_new(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
Definition InterpBuiltin.cpp:1389
static bool interp__builtin_strlen(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call, unsigned ID)
Definition InterpBuiltin.cpp:332
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)
Definition InterpBuiltin.cpp:1616
static bool interp__builtin_copysign(InterpState &S, CodePtr OpPC, const InterpFrame *Frame)
Definition InterpBuiltin.cpp:465
static bool interp__builtin_iszero(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
Definition InterpBuiltin.cpp:569
static bool interp__builtin_addressof(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
Definition InterpBuiltin.cpp:754
static bool interp__builtin_signbit(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
Definition InterpBuiltin.cpp:578
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)
Definition InterpBuiltin.cpp:1560
static bool interp__builtin_ia32_movmsk_op(InterpState &S, CodePtr OpPC, const CallExpr *Call)
Definition InterpBuiltin.cpp:2917
static bool interp__builtin_memcpy(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call, unsigned ID)
Definition InterpBuiltin.cpp:1753
static bool interp_builtin_horizontal_fp_binop(InterpState &S, CodePtr OpPC, const CallExpr *Call, llvm::function_ref< APFloat(const APFloat &, const APFloat &, llvm::RoundingMode)> Fn)
Definition InterpBuiltin.cpp:2695
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)
Definition InterpBuiltin.cpp:2760
static bool interp__builtin_popcount(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
Definition InterpBuiltin.cpp:706
static bool interp__builtin_object_size(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
Definition InterpBuiltin.cpp:2264
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).
Definition InterpBuiltin.cpp:888
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)
Definition InterpBuiltin.cpp:980
static bool interp__builtin_is_constant_evaluated(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
Definition InterpBuiltin.cpp:207
static APSInt popToAPSInt(InterpStack &Stk, PrimType T)
Definition InterpBuiltin.cpp:56
static std::optional< unsigned > computeFullDescSize(const ASTContext &ASTCtx, const Descriptor *Desc)
Definition InterpBuiltin.cpp:2143
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.
Definition InterpBuiltin.cpp:622
static bool interp__builtin_ia32_vcvtps2ph(InterpState &S, CodePtr OpPC, const CallExpr *Call)
Definition InterpBuiltin.cpp:3691
static bool interp__builtin_issignaling(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
Definition InterpBuiltin.cpp:519
static bool interp__builtin_ia32_multishiftqb(InterpState &S, CodePtr OpPC, const CallExpr *Call)
Definition InterpBuiltin.cpp:3779
static bool interp__builtin_ia32_shufbitqmb_mask(InterpState &S, CodePtr OpPC, const CallExpr *Call)
Definition InterpBuiltin.cpp:3629
static bool interp__builtin_nan(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call, bool Signaling)
Definition InterpBuiltin.cpp:390
bool DoMemcpy(InterpState &S, CodePtr OpPC, const Pointer &Src, Pointer &Dest)
Copy the contents of Src into Dest.
Definition InterpBuiltin.cpp:5808
static bool interp__builtin_elementwise_int_unaryop(InterpState &S, CodePtr OpPC, const CallExpr *Call, llvm::function_ref< APInt(const APSInt &)> Fn)
Definition InterpBuiltin.cpp:2397
constexpr bool isIntegralType(PrimType T)
static bool interp__builtin_eh_return_data_regno(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
Definition InterpBuiltin.cpp:772
static bool interp__builtin_infer_alloc_token(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
Definition InterpBuiltin.cpp:1349
static bool interp_builtin_horizontal_int_binop(InterpState &S, CodePtr OpPC, const CallExpr *Call, llvm::function_ref< APInt(const APSInt &, const APSInt &)> Fn)
Definition InterpBuiltin.cpp:2655
static bool interp__builtin_ia32_cvtsd2ss(InterpState &S, CodePtr OpPC, const CallExpr *Call, bool HasRoundingMask)
Definition InterpBuiltin.cpp:3365
static void diagnoseNonConstexprBuiltin(InterpState &S, CodePtr OpPC, unsigned ID)
Definition InterpBuiltin.cpp:145
static bool interp__builtin_ia32_gfni_mul(InterpState &S, CodePtr OpPC, const CallExpr *Call)
Definition InterpBuiltin.cpp:3892
static QualType getElemType(const Pointer &P)
Definition InterpBuiltin.cpp:131
static bool interp__builtin_ia32_pternlog(InterpState &S, CodePtr OpPC, const CallExpr *Call, bool MaskZ)
Definition InterpBuiltin.cpp:3165
static bool interp__builtin_isnormal(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
Definition InterpBuiltin.cpp:551
static void swapBytes(std::byte *M, size_t N)
static bool interp__builtin_ia32_cvtpd2ps(InterpState &S, CodePtr OpPC, const CallExpr *Call, bool IsMasked, bool HasRounding)
Definition InterpBuiltin.cpp:3416
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.
T deref(Bytes Offset) const
Dereferences the value at the given offset.
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.