@@ -1695,32 +1695,42 @@ static bool interp__builtin_vector_reduce(InterpState &S, CodePtr OpPC,
16951695 assert (Arg.getFieldDesc ()->isPrimitiveArray ());
16961696
16971697 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)) {
1698+ QualType ElemType = Arg.getFieldDesc ()->getElemQualType ();
1699+ assert (Call->getType () == ElemType);
1700+ PrimType ElemT = *S.getContext ().classify (ElemType);
1701+ unsigned NumElems = Arg.getNumElems ();
1702+
1703+ INT_TYPE_SWITCH (ElemT, {
1704+ T Result = Arg.atIndex (0 ).deref <T>();
1705+ unsigned BitWidth = Result.bitWidth ();
1706+ for (unsigned I = 1 ; I != NumElems; ++I) {
1707+ T Elem = Arg.atIndex (I).deref <T>();
1708+ T PrevResult = Result;
1709+
1710+ if (ID == Builtin::BI__builtin_reduce_add) {
1711+ if (T::add (Result, Elem, BitWidth, &Result)) {
17101712 unsigned OverflowBits = BitWidth + 1 ;
1711- (void )handleOverflow (
1712- S, OpPC,
1713- (Sum. toAPSInt (OverflowBits) + Elem.toAPSInt (OverflowBits)));
1713+ (void )handleOverflow (S, OpPC,
1714+ (PrevResult. toAPSInt (OverflowBits) +
1715+ Elem.toAPSInt (OverflowBits)));
17141716 return false ;
17151717 }
1718+ } else if (ID == Builtin::BI__builtin_reduce_mul) {
1719+ if (T::mul (Result, Elem, BitWidth, &Result)) {
1720+ unsigned OverflowBits = BitWidth * 2 ;
1721+ (void )handleOverflow (S, OpPC,
1722+ (PrevResult.toAPSInt (OverflowBits) *
1723+ Elem.toAPSInt (OverflowBits)));
1724+ return false ;
1725+ }
1726+ } else {
1727+ llvm_unreachable (" Unhandled vector reduce builtin" );
17161728 }
1717- pushInteger (S, Sum, Call->getType ());
1718- });
1719-
1720- return true ;
1721- }
1729+ }
1730+ pushInteger (S, Result, Call->getType ());
1731+ });
17221732
1723- llvm_unreachable ( " Unsupported vector reduce builtin " ) ;
1733+ return true ;
17241734}
17251735
17261736static bool interp__builtin_memcpy (InterpState &S, CodePtr OpPC,
@@ -2195,6 +2205,7 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
21952205 break ;
21962206
21972207 case Builtin::BI__builtin_reduce_add:
2208+ case Builtin::BI__builtin_reduce_mul:
21982209 if (!interp__builtin_vector_reduce (S, OpPC, Frame, F, Call))
21992210 return false ;
22002211 break ;
0 commit comments