@@ -89,13 +89,14 @@ static void pushInteger(InterpState &S, const APSInt &Val, QualType QT) {
89
89
std::optional<PrimType> T = S.getContext ().classify (QT);
90
90
assert (T);
91
91
92
+ unsigned BitWidth = S.getASTContext ().getTypeSize (QT);
92
93
if (QT->isSignedIntegerOrEnumerationType ()) {
93
94
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 )); });
95
96
} else {
96
97
assert (QT->isUnsignedIntegerOrEnumerationType ());
97
98
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 )); });
99
100
}
100
101
}
101
102
@@ -137,6 +138,8 @@ static bool retPrimValue(InterpState &S, CodePtr OpPC,
137
138
RET_CASE (PT_Uint32);
138
139
RET_CASE (PT_Sint64);
139
140
RET_CASE (PT_Uint64);
141
+ RET_CASE (PT_IntAP);
142
+ RET_CASE (PT_IntAPS);
140
143
default :
141
144
llvm_unreachable (" Unsupported return type for builtin function" );
142
145
}
@@ -1684,6 +1687,42 @@ static bool interp__builtin_arithmetic_fence(InterpState &S, CodePtr OpPC,
1684
1687
return true ;
1685
1688
}
1686
1689
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
+
1687
1726
bool InterpretBuiltin (InterpState &S, CodePtr OpPC, const Function *F,
1688
1727
const CallExpr *Call, uint32_t BuiltinID) {
1689
1728
const InterpFrame *Frame = S.Current ;
@@ -2129,6 +2168,11 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
2129
2168
return false ;
2130
2169
break ;
2131
2170
2171
+ case Builtin::BI__builtin_reduce_add:
2172
+ if (!interp__builtin_vector_reduce (S, OpPC, Frame, F, Call))
2173
+ return false ;
2174
+ break ;
2175
+
2132
2176
default :
2133
2177
S.FFDiag (S.Current ->getLocation (OpPC),
2134
2178
diag::note_invalid_subexpr_in_const_expr)
0 commit comments