@@ -89,13 +89,14 @@ static void pushInteger(InterpState &S, const APSInt &Val, QualType QT) {
8989 std::optional<PrimType> T = S.getContext ().classify (QT);
9090 assert (T);
9191
92+ unsigned BitWidth = S.getASTContext ().getTypeSize (QT);
9293 if (QT->isSignedIntegerOrEnumerationType ()) {
9394 int64_t V = Val.getSExtValue ();
94- INT_TYPE_SWITCH (*T, { S.Stk .push <T>(T::from (V)); });
95+ INT_TYPE_SWITCH (*T, { S.Stk .push <T>(T::from (V, BitWidth )); });
9596 } else {
9697 assert (QT->isUnsignedIntegerOrEnumerationType ());
9798 uint64_t V = Val.getZExtValue ();
98- INT_TYPE_SWITCH (*T, { S.Stk .push <T>(T::from (V)); });
99+ INT_TYPE_SWITCH (*T, { S.Stk .push <T>(T::from (V, BitWidth )); });
99100 }
100101}
101102
@@ -137,6 +138,8 @@ static bool retPrimValue(InterpState &S, CodePtr OpPC,
137138 RET_CASE (PT_Uint32);
138139 RET_CASE (PT_Sint64);
139140 RET_CASE (PT_Uint64);
141+ RET_CASE (PT_IntAP);
142+ RET_CASE (PT_IntAPS);
140143 default :
141144 llvm_unreachable (" Unsupported return type for builtin function" );
142145 }
@@ -1684,6 +1687,42 @@ static bool interp__builtin_arithmetic_fence(InterpState &S, CodePtr OpPC,
16841687 return true ;
16851688}
16861689
1690+ static bool interp__builtin_vector_reduce (InterpState &S, CodePtr OpPC,
1691+ const InterpFrame *Frame,
1692+ const Function *Func,
1693+ const CallExpr *Call) {
1694+ const Pointer &Arg = S.Stk .peek <Pointer>();
1695+ assert (Arg.getFieldDesc ()->isPrimitiveArray ());
1696+
1697+ unsigned ID = Func->getBuiltinID ();
1698+ if (ID == Builtin::BI__builtin_reduce_add) {
1699+ QualType ElemType = Arg.getFieldDesc ()->getElemQualType ();
1700+ assert (Call->getType () == ElemType);
1701+ PrimType ElemT = *S.getContext ().classify (ElemType);
1702+ unsigned NumElems = Arg.getNumElems ();
1703+
1704+ INT_TYPE_SWITCH (ElemT, {
1705+ T Sum = Arg.atIndex (0 ).deref <T>();
1706+ unsigned BitWidth = Sum.bitWidth ();
1707+ for (unsigned I = 1 ; I != NumElems; ++I) {
1708+ T Elem = Arg.atIndex (I).deref <T>();
1709+ if (T::add (Sum, Elem, BitWidth, &Sum)) {
1710+ unsigned OverflowBits = BitWidth + 1 ;
1711+ (void )handleOverflow (
1712+ S, OpPC,
1713+ (Sum.toAPSInt (OverflowBits) + Elem.toAPSInt (OverflowBits)));
1714+ return false ;
1715+ }
1716+ }
1717+ pushInteger (S, Sum, Call->getType ());
1718+ });
1719+
1720+ return true ;
1721+ }
1722+
1723+ llvm_unreachable (" Unsupported vector reduce builtin" );
1724+ }
1725+
16871726bool InterpretBuiltin (InterpState &S, CodePtr OpPC, const Function *F,
16881727 const CallExpr *Call, uint32_t BuiltinID) {
16891728 const InterpFrame *Frame = S.Current ;
@@ -2129,6 +2168,11 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
21292168 return false ;
21302169 break ;
21312170
2171+ case Builtin::BI__builtin_reduce_add:
2172+ if (!interp__builtin_vector_reduce (S, OpPC, Frame, F, Call))
2173+ return false ;
2174+ break ;
2175+
21322176 default :
21332177 S.FFDiag (S.Current ->getLocation (OpPC),
21342178 diag::note_invalid_subexpr_in_const_expr)
0 commit comments