@@ -34,6 +34,19 @@ PrimType getIntPrimType(const InterpState &S) {
3434 llvm_unreachable (" Int isn't 16 or 32 bit?" );
3535}
3636
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+
3750// / Peek an integer value from the stack into an APSInt.
3851static APSInt peekToAPSInt (InterpStack &Stk, PrimType T, size_t Offset = 0 ) {
3952 if (Offset == 0 )
@@ -110,6 +123,19 @@ static void pushAPSInt(InterpState &S, const APSInt &Val) {
110123 }
111124}
112125
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+
113139static void pushSizeT (InterpState &S, uint64_t Val) {
114140 const TargetInfo &TI = S.getCtx ().getTargetInfo ();
115141 unsigned SizeTWidth = TI.getTypeWidth (TI.getSizeType ());
@@ -533,6 +559,26 @@ static bool interp__builtin_classify_type(InterpState &S, CodePtr OpPC,
533559 return true ;
534560}
535561
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+
536582bool InterpretBuiltin (InterpState &S, CodePtr OpPC, const Function *F,
537583 const CallExpr *Call) {
538584 InterpFrame *Frame = S.Current ;
@@ -702,6 +748,12 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
702748 return false ;
703749 break ;
704750
751+ case Builtin::BI__builtin_expect:
752+ case Builtin::BI__builtin_expect_with_probability:
753+ if (!interp__builtin_expect (S, OpPC, Frame, F, Call))
754+ return false ;
755+ break ;
756+
705757 default :
706758 return false ;
707759 }
0 commit comments