1 //===--- InterpBuiltin.cpp - Interpreter for the constexpr VM ---*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 #include "../ExprConstShared.h"
9 #include "Boolean.h"
10 #include "Interp.h"
11 #include "PrimType.h"
12 #include "clang/AST/RecordLayout.h"
13 #include "clang/Basic/Builtins.h"
14 #include "clang/Basic/TargetInfo.h"
15 
16 namespace clang {
17 namespace interp {
18 
19 template <typename T>
20 static T getParam(const InterpFrame *Frame, unsigned Index) {
21   assert(Frame->getFunction()->getNumParams() > Index);
22   unsigned Offset = Frame->getFunction()->getParamOffset(Index);
23   return Frame->getParam<T>(Offset);
24 }
25 
26 PrimType getIntPrimType(const InterpState &S) {
27   const TargetInfo &TI = S.getCtx().getTargetInfo();
28   unsigned IntWidth = TI.getIntWidth();
29 
30   if (IntWidth == 32)
31     return PT_Sint32;
32   else if (IntWidth == 16)
33     return PT_Sint16;
34   llvm_unreachable("Int isn't 16 or 32 bit?");
35 }
36 
37 PrimType getLongPrimType(const InterpState &S) {
38   const TargetInfo &TI = S.getCtx().getTargetInfo();
39   unsigned LongWidth = TI.getLongWidth();
40 
41   if (LongWidth == 64)
42     return PT_Sint64;
43   else if (LongWidth == 32)
44     return PT_Sint32;
45   else if (LongWidth == 16)
46     return PT_Sint16;
47   llvm_unreachable("long isn't 16, 32 or 64 bit?");
48 }
49 
50 /// Peek an integer value from the stack into an APSInt.
51 static APSInt peekToAPSInt(InterpStack &Stk, PrimType T, size_t Offset = 0) {
52   if (Offset == 0)
53     Offset = align(primSize(T));
54 
55   APSInt R;
56   INT_TYPE_SWITCH(T, {
57     T Val = Stk.peek<T>(Offset);
58     R = APSInt(
59         APInt(Val.bitWidth(), static_cast<uint64_t>(Val), T::isSigned()));
60   });
61 
62   return R;
63 }
64 
65 /// Pushes \p Val to the stack, as a target-dependent 'int'.
66 static void pushInt(InterpState &S, int32_t Val) {
67   PrimType IntType = getIntPrimType(S);
68   if (IntType == PT_Sint32)
69     S.Stk.push<Integral<32, true>>(Integral<32, true>::from(Val));
70   else if (IntType == PT_Sint16)
71     S.Stk.push<Integral<16, true>>(Integral<16, true>::from(Val));
72   else
73     llvm_unreachable("Int isn't 16 or 32 bit?");
74 }
75 
76 static void pushAPSInt(InterpState &S, const APSInt &Val) {
77   bool Signed = Val.isSigned();
78 
79   if (Signed) {
80     switch (Val.getBitWidth()) {
81     case 64:
82       S.Stk.push<Integral<64, true>>(
83           Integral<64, true>::from(Val.getSExtValue()));
84       break;
85     case 32:
86       S.Stk.push<Integral<32, true>>(
87           Integral<32, true>::from(Val.getSExtValue()));
88       break;
89     case 16:
90       S.Stk.push<Integral<16, true>>(
91           Integral<16, true>::from(Val.getSExtValue()));
92       break;
93     case 8:
94       S.Stk.push<Integral<8, true>>(
95           Integral<8, true>::from(Val.getSExtValue()));
96       break;
97     default:
98       llvm_unreachable("Invalid integer bitwidth");
99     }
100     return;
101   }
102 
103   // Unsigned.
104   switch (Val.getBitWidth()) {
105   case 64:
106     S.Stk.push<Integral<64, false>>(
107         Integral<64, false>::from(Val.getZExtValue()));
108     break;
109   case 32:
110     S.Stk.push<Integral<32, false>>(
111         Integral<32, false>::from(Val.getZExtValue()));
112     break;
113   case 16:
114     S.Stk.push<Integral<16, false>>(
115         Integral<16, false>::from(Val.getZExtValue()));
116     break;
117   case 8:
118     S.Stk.push<Integral<8, false>>(
119         Integral<8, false>::from(Val.getZExtValue()));
120     break;
121   default:
122     llvm_unreachable("Invalid integer bitwidth");
123   }
124 }
125 
126 /// Pushes \p Val to the stack, as a target-dependent 'long'.
127 static void pushLong(InterpState &S, int64_t Val) {
128   PrimType LongType = getLongPrimType(S);
129   if (LongType == PT_Sint64)
130     S.Stk.push<Integral<64, true>>(Integral<64, true>::from(Val));
131   else if (LongType == PT_Sint32)
132     S.Stk.push<Integral<32, true>>(Integral<32, true>::from(Val));
133   else if (LongType == PT_Sint16)
134     S.Stk.push<Integral<16, true>>(Integral<16, true>::from(Val));
135   else
136     llvm_unreachable("Long isn't 16, 32 or 64 bit?");
137 }
138 
139 static void pushSizeT(InterpState &S, uint64_t Val) {
140   const TargetInfo &TI = S.getCtx().getTargetInfo();
141   unsigned SizeTWidth = TI.getTypeWidth(TI.getSizeType());
142 
143   switch (SizeTWidth) {
144   case 64:
145     S.Stk.push<Integral<64, false>>(Integral<64, false>::from(Val));
146     break;
147   case 32:
148     S.Stk.push<Integral<32, false>>(Integral<32, false>::from(Val));
149     break;
150   case 16:
151     S.Stk.push<Integral<16, false>>(Integral<16, false>::from(Val));
152     break;
153   default:
154     llvm_unreachable("We don't handle this size_t size.");
155   }
156 }
157 
158 static bool retPrimValue(InterpState &S, CodePtr OpPC, APValue &Result,
159                          std::optional<PrimType> &T) {
160   if (!T)
161     return RetVoid(S, OpPC, Result);
162 
163 #define RET_CASE(X)                                                            \
164   case X:                                                                      \
165     return Ret<X>(S, OpPC, Result);
166   switch (*T) {
167     RET_CASE(PT_Float);
168     RET_CASE(PT_Bool);
169     RET_CASE(PT_Sint8);
170     RET_CASE(PT_Uint8);
171     RET_CASE(PT_Sint16);
172     RET_CASE(PT_Uint16);
173     RET_CASE(PT_Sint32);
174     RET_CASE(PT_Uint32);
175     RET_CASE(PT_Sint64);
176     RET_CASE(PT_Uint64);
177   default:
178     llvm_unreachable("Unsupported return type for builtin function");
179   }
180 #undef RET_CASE
181 }
182 
183 static bool interp__builtin_strcmp(InterpState &S, CodePtr OpPC,
184                                    const InterpFrame *Frame) {
185   const Pointer &A = getParam<Pointer>(Frame, 0);
186   const Pointer &B = getParam<Pointer>(Frame, 1);
187 
188   if (!CheckLive(S, OpPC, A, AK_Read) || !CheckLive(S, OpPC, B, AK_Read))
189     return false;
190 
191   assert(A.getFieldDesc()->isPrimitiveArray());
192   assert(B.getFieldDesc()->isPrimitiveArray());
193 
194   unsigned IndexA = A.getIndex();
195   unsigned IndexB = B.getIndex();
196   int32_t Result = 0;
197   for (;; ++IndexA, ++IndexB) {
198     const Pointer &PA = A.atIndex(IndexA);
199     const Pointer &PB = B.atIndex(IndexB);
200     if (!CheckRange(S, OpPC, PA, AK_Read) ||
201         !CheckRange(S, OpPC, PB, AK_Read)) {
202       return false;
203     }
204     uint8_t CA = PA.deref<uint8_t>();
205     uint8_t CB = PB.deref<uint8_t>();
206 
207     if (CA > CB) {
208       Result = 1;
209       break;
210     } else if (CA < CB) {
211       Result = -1;
212       break;
213     }
214     if (CA == 0 || CB == 0)
215       break;
216   }
217 
218   pushInt(S, Result);
219   return true;
220 }
221 
222 static bool interp__builtin_strlen(InterpState &S, CodePtr OpPC,
223                                    const InterpFrame *Frame) {
224   const Pointer &StrPtr = getParam<Pointer>(Frame, 0);
225 
226   if (!CheckArray(S, OpPC, StrPtr))
227     return false;
228 
229   if (!CheckLive(S, OpPC, StrPtr, AK_Read))
230     return false;
231 
232   if (!CheckDummy(S, OpPC, StrPtr))
233     return false;
234 
235   assert(StrPtr.getFieldDesc()->isPrimitiveArray());
236 
237   size_t Len = 0;
238   for (size_t I = StrPtr.getIndex();; ++I, ++Len) {
239     const Pointer &ElemPtr = StrPtr.atIndex(I);
240 
241     if (!CheckRange(S, OpPC, ElemPtr, AK_Read))
242       return false;
243 
244     uint8_t Val = ElemPtr.deref<uint8_t>();
245     if (Val == 0)
246       break;
247   }
248 
249   pushSizeT(S, Len);
250   return true;
251 }
252 
253 static bool interp__builtin_nan(InterpState &S, CodePtr OpPC,
254                                 const InterpFrame *Frame, const Function *F,
255                                 bool Signaling) {
256   const Pointer &Arg = getParam<Pointer>(Frame, 0);
257 
258   if (!CheckLoad(S, OpPC, Arg))
259     return false;
260 
261   assert(Arg.getFieldDesc()->isPrimitiveArray());
262 
263   // Convert the given string to an integer using StringRef's API.
264   llvm::APInt Fill;
265   std::string Str;
266   assert(Arg.getNumElems() >= 1);
267   for (unsigned I = 0;; ++I) {
268     const Pointer &Elem = Arg.atIndex(I);
269 
270     if (!CheckLoad(S, OpPC, Elem))
271       return false;
272 
273     if (Elem.deref<int8_t>() == 0)
274       break;
275 
276     Str += Elem.deref<char>();
277   }
278 
279   // Treat empty strings as if they were zero.
280   if (Str.empty())
281     Fill = llvm::APInt(32, 0);
282   else if (StringRef(Str).getAsInteger(0, Fill))
283     return false;
284 
285   const llvm::fltSemantics &TargetSemantics =
286       S.getCtx().getFloatTypeSemantics(F->getDecl()->getReturnType());
287 
288   Floating Result;
289   if (S.getCtx().getTargetInfo().isNan2008()) {
290     if (Signaling)
291       Result = Floating(
292           llvm::APFloat::getSNaN(TargetSemantics, /*Negative=*/false, &Fill));
293     else
294       Result = Floating(
295           llvm::APFloat::getQNaN(TargetSemantics, /*Negative=*/false, &Fill));
296   } else {
297     // Prior to IEEE 754-2008, architectures were allowed to choose whether
298     // the first bit of their significand was set for qNaN or sNaN. MIPS chose
299     // a different encoding to what became a standard in 2008, and for pre-
300     // 2008 revisions, MIPS interpreted sNaN-2008 as qNan and qNaN-2008 as
301     // sNaN. This is now known as "legacy NaN" encoding.
302     if (Signaling)
303       Result = Floating(
304           llvm::APFloat::getQNaN(TargetSemantics, /*Negative=*/false, &Fill));
305     else
306       Result = Floating(
307           llvm::APFloat::getSNaN(TargetSemantics, /*Negative=*/false, &Fill));
308   }
309 
310   S.Stk.push<Floating>(Result);
311   return true;
312 }
313 
314 static bool interp__builtin_inf(InterpState &S, CodePtr OpPC,
315                                 const InterpFrame *Frame, const Function *F) {
316   const llvm::fltSemantics &TargetSemantics =
317       S.getCtx().getFloatTypeSemantics(F->getDecl()->getReturnType());
318 
319   S.Stk.push<Floating>(Floating::getInf(TargetSemantics));
320   return true;
321 }
322 
323 static bool interp__builtin_copysign(InterpState &S, CodePtr OpPC,
324                                      const InterpFrame *Frame,
325                                      const Function *F) {
326   const Floating &Arg1 = getParam<Floating>(Frame, 0);
327   const Floating &Arg2 = getParam<Floating>(Frame, 1);
328 
329   APFloat Copy = Arg1.getAPFloat();
330   Copy.copySign(Arg2.getAPFloat());
331   S.Stk.push<Floating>(Floating(Copy));
332 
333   return true;
334 }
335 
336 static bool interp__builtin_fmin(InterpState &S, CodePtr OpPC,
337                                  const InterpFrame *Frame, const Function *F) {
338   const Floating &LHS = getParam<Floating>(Frame, 0);
339   const Floating &RHS = getParam<Floating>(Frame, 1);
340 
341   Floating Result;
342 
343   // When comparing zeroes, return -0.0 if one of the zeroes is negative.
344   if (LHS.isZero() && RHS.isZero() && RHS.isNegative())
345     Result = RHS;
346   else if (LHS.isNan() || RHS < LHS)
347     Result = RHS;
348   else
349     Result = LHS;
350 
351   S.Stk.push<Floating>(Result);
352   return true;
353 }
354 
355 static bool interp__builtin_fmax(InterpState &S, CodePtr OpPC,
356                                  const InterpFrame *Frame,
357                                  const Function *Func) {
358   const Floating &LHS = getParam<Floating>(Frame, 0);
359   const Floating &RHS = getParam<Floating>(Frame, 1);
360 
361   Floating Result;
362 
363   // When comparing zeroes, return +0.0 if one of the zeroes is positive.
364   if (LHS.isZero() && RHS.isZero() && LHS.isNegative())
365     Result = RHS;
366   else if (LHS.isNan() || RHS > LHS)
367     Result = RHS;
368   else
369     Result = LHS;
370 
371   S.Stk.push<Floating>(Result);
372   return true;
373 }
374 
375 /// Defined as __builtin_isnan(...), to accommodate the fact that it can
376 /// take a float, double, long double, etc.
377 /// But for us, that's all a Floating anyway.
378 static bool interp__builtin_isnan(InterpState &S, CodePtr OpPC,
379                                   const InterpFrame *Frame, const Function *F) {
380   const Floating &Arg = S.Stk.peek<Floating>();
381 
382   pushInt(S, Arg.isNan());
383   return true;
384 }
385 
386 static bool interp__builtin_issignaling(InterpState &S, CodePtr OpPC,
387                                         const InterpFrame *Frame,
388                                         const Function *F) {
389   const Floating &Arg = S.Stk.peek<Floating>();
390 
391   pushInt(S, Arg.isSignaling());
392   return true;
393 }
394 
395 static bool interp__builtin_isinf(InterpState &S, CodePtr OpPC,
396                                   const InterpFrame *Frame, const Function *F,
397                                   bool CheckSign) {
398   const Floating &Arg = S.Stk.peek<Floating>();
399   bool IsInf = Arg.isInf();
400 
401   if (CheckSign)
402     pushInt(S, IsInf ? (Arg.isNegative() ? -1 : 1) : 0);
403   else
404     pushInt(S, Arg.isInf());
405   return true;
406 }
407 
408 static bool interp__builtin_isfinite(InterpState &S, CodePtr OpPC,
409                                      const InterpFrame *Frame,
410                                      const Function *F) {
411   const Floating &Arg = S.Stk.peek<Floating>();
412 
413   pushInt(S, Arg.isFinite());
414   return true;
415 }
416 
417 static bool interp__builtin_isnormal(InterpState &S, CodePtr OpPC,
418                                      const InterpFrame *Frame,
419                                      const Function *F) {
420   const Floating &Arg = S.Stk.peek<Floating>();
421 
422   pushInt(S, Arg.isNormal());
423   return true;
424 }
425 
426 static bool interp__builtin_issubnormal(InterpState &S, CodePtr OpPC,
427                                         const InterpFrame *Frame,
428                                         const Function *F) {
429   const Floating &Arg = S.Stk.peek<Floating>();
430 
431   pushInt(S, Arg.isDenormal());
432   return true;
433 }
434 
435 static bool interp__builtin_iszero(InterpState &S, CodePtr OpPC,
436                                    const InterpFrame *Frame,
437                                    const Function *F) {
438   const Floating &Arg = S.Stk.peek<Floating>();
439 
440   pushInt(S, Arg.isZero());
441   return true;
442 }
443 
444 /// First parameter to __builtin_isfpclass is the floating value, the
445 /// second one is an integral value.
446 static bool interp__builtin_isfpclass(InterpState &S, CodePtr OpPC,
447                                       const InterpFrame *Frame,
448                                       const Function *Func,
449                                       const CallExpr *Call) {
450   PrimType FPClassArgT = *S.getContext().classify(Call->getArg(1)->getType());
451   APSInt FPClassArg = peekToAPSInt(S.Stk, FPClassArgT);
452   const Floating &F =
453       S.Stk.peek<Floating>(align(primSize(FPClassArgT) + primSize(PT_Float)));
454 
455   int32_t Result =
456       static_cast<int32_t>((F.classify() & FPClassArg).getZExtValue());
457   pushInt(S, Result);
458 
459   return true;
460 }
461 
462 /// Five int values followed by one floating value.
463 static bool interp__builtin_fpclassify(InterpState &S, CodePtr OpPC,
464                                        const InterpFrame *Frame,
465                                        const Function *Func) {
466   const Floating &Val = S.Stk.peek<Floating>();
467 
468   unsigned Index;
469   switch (Val.getCategory()) {
470   case APFloat::fcNaN:
471     Index = 0;
472     break;
473   case APFloat::fcInfinity:
474     Index = 1;
475     break;
476   case APFloat::fcNormal:
477     Index = Val.isDenormal() ? 3 : 2;
478     break;
479   case APFloat::fcZero:
480     Index = 4;
481     break;
482   }
483 
484   // The last argument is first on the stack.
485   assert(Index <= 4);
486   unsigned IntSize = primSize(getIntPrimType(S));
487   unsigned Offset =
488       align(primSize(PT_Float)) + ((1 + (4 - Index)) * align(IntSize));
489 
490   APSInt I = peekToAPSInt(S.Stk, getIntPrimType(S), Offset);
491   pushInt(S, I.getZExtValue());
492   return true;
493 }
494 
495 // The C standard says "fabs raises no floating-point exceptions,
496 // even if x is a signaling NaN. The returned value is independent of
497 // the current rounding direction mode."  Therefore constant folding can
498 // proceed without regard to the floating point settings.
499 // Reference, WG14 N2478 F.10.4.3
500 static bool interp__builtin_fabs(InterpState &S, CodePtr OpPC,
501                                  const InterpFrame *Frame,
502                                  const Function *Func) {
503   const Floating &Val = getParam<Floating>(Frame, 0);
504 
505   S.Stk.push<Floating>(Floating::abs(Val));
506   return true;
507 }
508 
509 static bool interp__builtin_popcount(InterpState &S, CodePtr OpPC,
510                                      const InterpFrame *Frame,
511                                      const Function *Func,
512                                      const CallExpr *Call) {
513   PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType());
514   APSInt Val = peekToAPSInt(S.Stk, ArgT);
515   pushInt(S, Val.popcount());
516   return true;
517 }
518 
519 static bool interp__builtin_parity(InterpState &S, CodePtr OpPC,
520                                    const InterpFrame *Frame,
521                                    const Function *Func, const CallExpr *Call) {
522   PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType());
523   APSInt Val = peekToAPSInt(S.Stk, ArgT);
524   pushInt(S, Val.popcount() % 2);
525   return true;
526 }
527 
528 static bool interp__builtin_clrsb(InterpState &S, CodePtr OpPC,
529                                   const InterpFrame *Frame,
530                                   const Function *Func, const CallExpr *Call) {
531   PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType());
532   APSInt Val = peekToAPSInt(S.Stk, ArgT);
533   pushInt(S, Val.getBitWidth() - Val.getSignificantBits());
534   return true;
535 }
536 
537 static bool interp__builtin_bitreverse(InterpState &S, CodePtr OpPC,
538                                        const InterpFrame *Frame,
539                                        const Function *Func,
540                                        const CallExpr *Call) {
541   PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType());
542   APSInt Val = peekToAPSInt(S.Stk, ArgT);
543   pushAPSInt(S, APSInt(Val.reverseBits(), /*IsUnsigned=*/true));
544   return true;
545 }
546 
547 static bool interp__builtin_classify_type(InterpState &S, CodePtr OpPC,
548                                           const InterpFrame *Frame,
549                                           const Function *Func,
550                                           const CallExpr *Call) {
551   // This is an unevaluated call, so there are no arguments on the stack.
552   assert(Call->getNumArgs() == 1);
553   const Expr *Arg = Call->getArg(0);
554 
555   GCCTypeClass ResultClass =
556       EvaluateBuiltinClassifyType(Arg->getType(), S.getLangOpts());
557   int32_t ReturnVal = static_cast<int32_t>(ResultClass);
558   pushInt(S, ReturnVal);
559   return true;
560 }
561 
562 // __builtin_expect(long, long)
563 // __builtin_expect_with_probability(long, long, double)
564 static bool interp__builtin_expect(InterpState &S, CodePtr OpPC,
565                                    const InterpFrame *Frame,
566                                    const Function *Func, const CallExpr *Call) {
567   // The return value is simply the value of the first parameter.
568   // We ignore the probability.
569   unsigned NumArgs = Call->getNumArgs();
570   assert(NumArgs == 2 || NumArgs == 3);
571 
572   PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType());
573   unsigned Offset = align(primSize(getLongPrimType(S))) * 2;
574   if (NumArgs == 3)
575     Offset += align(primSize(PT_Float));
576 
577   APSInt Val = peekToAPSInt(S.Stk, ArgT, Offset);
578   pushLong(S, Val.getSExtValue());
579   return true;
580 }
581 
582 /// rotateleft(value, amount)
583 static bool interp__builtin_rotate(InterpState &S, CodePtr OpPC,
584                                    const InterpFrame *Frame,
585                                    const Function *Func, const CallExpr *Call,
586                                    bool Right) {
587   PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType());
588   assert(ArgT == *S.getContext().classify(Call->getArg(1)->getType()));
589 
590   APSInt Amount = peekToAPSInt(S.Stk, ArgT);
591   APSInt Value = peekToAPSInt(S.Stk, ArgT, align(primSize(ArgT)) * 2);
592 
593   APSInt Result;
594   if (Right)
595     Result = APSInt(Value.rotr(Amount.urem(Value.getBitWidth())),
596                     /*IsUnsigned=*/true);
597   else // Left.
598     Result = APSInt(Value.rotl(Amount.urem(Value.getBitWidth())),
599                     /*IsUnsigned=*/true);
600 
601   pushAPSInt(S, Result);
602   return true;
603 }
604 
605 static bool interp__builtin_ffs(InterpState &S, CodePtr OpPC,
606                                 const InterpFrame *Frame, const Function *Func,
607                                 const CallExpr *Call) {
608   PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType());
609   APSInt Value = peekToAPSInt(S.Stk, ArgT);
610 
611   uint64_t N = Value.countr_zero();
612   pushInt(S, N == Value.getBitWidth() ? 0 : N + 1);
613   return true;
614 }
615 
616 bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
617                       const CallExpr *Call) {
618   InterpFrame *Frame = S.Current;
619   APValue Dummy;
620 
621   QualType ReturnType = Call->getCallReturnType(S.getCtx());
622   std::optional<PrimType> ReturnT = S.getContext().classify(ReturnType);
623   // If classify failed, we assume void.
624   assert(ReturnT || ReturnType->isVoidType());
625 
626   switch (F->getBuiltinID()) {
627   case Builtin::BI__builtin_is_constant_evaluated:
628     S.Stk.push<Boolean>(Boolean::from(S.inConstantContext()));
629     break;
630   case Builtin::BI__builtin_assume:
631     break;
632   case Builtin::BI__builtin_strcmp:
633     if (!interp__builtin_strcmp(S, OpPC, Frame))
634       return false;
635     break;
636   case Builtin::BI__builtin_strlen:
637     if (!interp__builtin_strlen(S, OpPC, Frame))
638       return false;
639     break;
640   case Builtin::BI__builtin_nan:
641   case Builtin::BI__builtin_nanf:
642   case Builtin::BI__builtin_nanl:
643   case Builtin::BI__builtin_nanf16:
644   case Builtin::BI__builtin_nanf128:
645     if (!interp__builtin_nan(S, OpPC, Frame, F, /*Signaling=*/false))
646       return false;
647     break;
648   case Builtin::BI__builtin_nans:
649   case Builtin::BI__builtin_nansf:
650   case Builtin::BI__builtin_nansl:
651   case Builtin::BI__builtin_nansf16:
652   case Builtin::BI__builtin_nansf128:
653     if (!interp__builtin_nan(S, OpPC, Frame, F, /*Signaling=*/true))
654       return false;
655     break;
656 
657   case Builtin::BI__builtin_huge_val:
658   case Builtin::BI__builtin_huge_valf:
659   case Builtin::BI__builtin_huge_vall:
660   case Builtin::BI__builtin_huge_valf16:
661   case Builtin::BI__builtin_huge_valf128:
662   case Builtin::BI__builtin_inf:
663   case Builtin::BI__builtin_inff:
664   case Builtin::BI__builtin_infl:
665   case Builtin::BI__builtin_inff16:
666   case Builtin::BI__builtin_inff128:
667     if (!interp__builtin_inf(S, OpPC, Frame, F))
668       return false;
669     break;
670   case Builtin::BI__builtin_copysign:
671   case Builtin::BI__builtin_copysignf:
672   case Builtin::BI__builtin_copysignl:
673   case Builtin::BI__builtin_copysignf128:
674     if (!interp__builtin_copysign(S, OpPC, Frame, F))
675       return false;
676     break;
677 
678   case Builtin::BI__builtin_fmin:
679   case Builtin::BI__builtin_fminf:
680   case Builtin::BI__builtin_fminl:
681   case Builtin::BI__builtin_fminf16:
682   case Builtin::BI__builtin_fminf128:
683     if (!interp__builtin_fmin(S, OpPC, Frame, F))
684       return false;
685     break;
686 
687   case Builtin::BI__builtin_fmax:
688   case Builtin::BI__builtin_fmaxf:
689   case Builtin::BI__builtin_fmaxl:
690   case Builtin::BI__builtin_fmaxf16:
691   case Builtin::BI__builtin_fmaxf128:
692     if (!interp__builtin_fmax(S, OpPC, Frame, F))
693       return false;
694     break;
695 
696   case Builtin::BI__builtin_isnan:
697     if (!interp__builtin_isnan(S, OpPC, Frame, F))
698       return false;
699     break;
700   case Builtin::BI__builtin_issignaling:
701     if (!interp__builtin_issignaling(S, OpPC, Frame, F))
702       return false;
703     break;
704 
705   case Builtin::BI__builtin_isinf:
706     if (!interp__builtin_isinf(S, OpPC, Frame, F, /*Sign=*/false))
707       return false;
708     break;
709 
710   case Builtin::BI__builtin_isinf_sign:
711     if (!interp__builtin_isinf(S, OpPC, Frame, F, /*Sign=*/true))
712       return false;
713     break;
714 
715   case Builtin::BI__builtin_isfinite:
716     if (!interp__builtin_isfinite(S, OpPC, Frame, F))
717       return false;
718     break;
719   case Builtin::BI__builtin_isnormal:
720     if (!interp__builtin_isnormal(S, OpPC, Frame, F))
721       return false;
722     break;
723   case Builtin::BI__builtin_issubnormal:
724     if (!interp__builtin_issubnormal(S, OpPC, Frame, F))
725       return false;
726     break;
727   case Builtin::BI__builtin_iszero:
728     if (!interp__builtin_iszero(S, OpPC, Frame, F))
729       return false;
730     break;
731   case Builtin::BI__builtin_isfpclass:
732     if (!interp__builtin_isfpclass(S, OpPC, Frame, F, Call))
733       return false;
734     break;
735   case Builtin::BI__builtin_fpclassify:
736     if (!interp__builtin_fpclassify(S, OpPC, Frame, F))
737       return false;
738     break;
739 
740   case Builtin::BI__builtin_fabs:
741   case Builtin::BI__builtin_fabsf:
742   case Builtin::BI__builtin_fabsl:
743   case Builtin::BI__builtin_fabsf128:
744     if (!interp__builtin_fabs(S, OpPC, Frame, F))
745       return false;
746     break;
747 
748   case Builtin::BI__builtin_popcount:
749   case Builtin::BI__builtin_popcountl:
750   case Builtin::BI__builtin_popcountll:
751   case Builtin::BI__popcnt16: // Microsoft variants of popcount
752   case Builtin::BI__popcnt:
753   case Builtin::BI__popcnt64:
754     if (!interp__builtin_popcount(S, OpPC, Frame, F, Call))
755       return false;
756     break;
757 
758   case Builtin::BI__builtin_parity:
759   case Builtin::BI__builtin_parityl:
760   case Builtin::BI__builtin_parityll:
761     if (!interp__builtin_parity(S, OpPC, Frame, F, Call))
762       return false;
763     break;
764 
765   case Builtin::BI__builtin_clrsb:
766   case Builtin::BI__builtin_clrsbl:
767   case Builtin::BI__builtin_clrsbll:
768     if (!interp__builtin_clrsb(S, OpPC, Frame, F, Call))
769       return false;
770     break;
771 
772   case Builtin::BI__builtin_bitreverse8:
773   case Builtin::BI__builtin_bitreverse16:
774   case Builtin::BI__builtin_bitreverse32:
775   case Builtin::BI__builtin_bitreverse64:
776     if (!interp__builtin_bitreverse(S, OpPC, Frame, F, Call))
777       return false;
778     break;
779 
780   case Builtin::BI__builtin_classify_type:
781     if (!interp__builtin_classify_type(S, OpPC, Frame, F, Call))
782       return false;
783     break;
784 
785   case Builtin::BI__builtin_expect:
786   case Builtin::BI__builtin_expect_with_probability:
787     if (!interp__builtin_expect(S, OpPC, Frame, F, Call))
788       return false;
789     break;
790 
791   case Builtin::BI__builtin_rotateleft8:
792   case Builtin::BI__builtin_rotateleft16:
793   case Builtin::BI__builtin_rotateleft32:
794   case Builtin::BI__builtin_rotateleft64:
795   case Builtin::BI_rotl8: // Microsoft variants of rotate left
796   case Builtin::BI_rotl16:
797   case Builtin::BI_rotl:
798   case Builtin::BI_lrotl:
799   case Builtin::BI_rotl64:
800     if (!interp__builtin_rotate(S, OpPC, Frame, F, Call, /*Right=*/false))
801       return false;
802     break;
803 
804   case Builtin::BI__builtin_rotateright8:
805   case Builtin::BI__builtin_rotateright16:
806   case Builtin::BI__builtin_rotateright32:
807   case Builtin::BI__builtin_rotateright64:
808   case Builtin::BI_rotr8: // Microsoft variants of rotate right
809   case Builtin::BI_rotr16:
810   case Builtin::BI_rotr:
811   case Builtin::BI_lrotr:
812   case Builtin::BI_rotr64:
813     if (!interp__builtin_rotate(S, OpPC, Frame, F, Call, /*Right=*/true))
814       return false;
815     break;
816 
817   case Builtin::BI__builtin_ffs:
818   case Builtin::BI__builtin_ffsl:
819   case Builtin::BI__builtin_ffsll:
820     if (!interp__builtin_ffs(S, OpPC, Frame, F, Call))
821       return false;
822     break;
823 
824   default:
825     return false;
826   }
827 
828   return retPrimValue(S, OpPC, Dummy, ReturnT);
829 }
830 
831 bool InterpretOffsetOf(InterpState &S, CodePtr OpPC, const OffsetOfExpr *E,
832                        llvm::ArrayRef<int64_t> ArrayIndices,
833                        int64_t &IntResult) {
834   CharUnits Result;
835   unsigned N = E->getNumComponents();
836   assert(N > 0);
837 
838   unsigned ArrayIndex = 0;
839   QualType CurrentType = E->getTypeSourceInfo()->getType();
840   for (unsigned I = 0; I != N; ++I) {
841     const OffsetOfNode &Node = E->getComponent(I);
842     switch (Node.getKind()) {
843     case OffsetOfNode::Field: {
844       const FieldDecl *MemberDecl = Node.getField();
845       const RecordType *RT = CurrentType->getAs<RecordType>();
846       if (!RT)
847         return false;
848       RecordDecl *RD = RT->getDecl();
849       if (RD->isInvalidDecl())
850         return false;
851       const ASTRecordLayout &RL = S.getCtx().getASTRecordLayout(RD);
852       unsigned FieldIndex = MemberDecl->getFieldIndex();
853       assert(FieldIndex < RL.getFieldCount() && "offsetof field in wrong type");
854       Result += S.getCtx().toCharUnitsFromBits(RL.getFieldOffset(FieldIndex));
855       CurrentType = MemberDecl->getType().getNonReferenceType();
856       break;
857     }
858     case OffsetOfNode::Array: {
859       // When generating bytecode, we put all the index expressions as Sint64 on
860       // the stack.
861       int64_t Index = ArrayIndices[ArrayIndex];
862       const ArrayType *AT = S.getCtx().getAsArrayType(CurrentType);
863       if (!AT)
864         return false;
865       CurrentType = AT->getElementType();
866       CharUnits ElementSize = S.getCtx().getTypeSizeInChars(CurrentType);
867       Result += Index * ElementSize;
868       ++ArrayIndex;
869       break;
870     }
871     case OffsetOfNode::Base: {
872       const CXXBaseSpecifier *BaseSpec = Node.getBase();
873       if (BaseSpec->isVirtual())
874         return false;
875 
876       // Find the layout of the class whose base we are looking into.
877       const RecordType *RT = CurrentType->getAs<RecordType>();
878       if (!RT)
879         return false;
880       const RecordDecl *RD = RT->getDecl();
881       if (RD->isInvalidDecl())
882         return false;
883       const ASTRecordLayout &RL = S.getCtx().getASTRecordLayout(RD);
884 
885       // Find the base class itself.
886       CurrentType = BaseSpec->getType();
887       const RecordType *BaseRT = CurrentType->getAs<RecordType>();
888       if (!BaseRT)
889         return false;
890 
891       // Add the offset to the base.
892       Result += RL.getBaseClassOffset(cast<CXXRecordDecl>(BaseRT->getDecl()));
893       break;
894     }
895     case OffsetOfNode::Identifier:
896       llvm_unreachable("Dependent OffsetOfExpr?");
897     }
898   }
899 
900   IntResult = Result.getQuantity();
901 
902   return true;
903 }
904 
905 bool SetThreeWayComparisonField(InterpState &S, CodePtr OpPC,
906                                 const Pointer &Ptr, const APSInt &IntValue) {
907 
908   const Record *R = Ptr.getRecord();
909   assert(R);
910   assert(R->getNumFields() == 1);
911 
912   unsigned FieldOffset = R->getField(0u)->Offset;
913   const Pointer &FieldPtr = Ptr.atField(FieldOffset);
914   PrimType FieldT = *S.getContext().classify(FieldPtr.getType());
915 
916   INT_TYPE_SWITCH(FieldT,
917                   FieldPtr.deref<T>() = T::from(IntValue.getSExtValue()));
918   FieldPtr.initialize();
919   return true;
920 }
921 
922 } // namespace interp
923 } // namespace clang
924