@@ -598,6 +598,17 @@ static bool interp__builtin_fpclassify(InterpState &S, CodePtr OpPC,
598598 return true ;
599599}
600600
601+ static inline Floating abs (InterpState &S, const Floating &In) {
602+ if (!In.isNegative ())
603+ return In;
604+
605+ Floating Output = S.allocFloat (In.getSemantics ());
606+ APFloat New = In.getAPFloat ();
607+ New.changeSign ();
608+ Output.copy (New);
609+ return Output;
610+ }
611+
601612// The C standard says "fabs raises no floating-point exceptions,
602613// even if x is a signaling NaN. The returned value is independent of
603614// the current rounding direction mode." Therefore constant folding can
@@ -606,16 +617,7 @@ static bool interp__builtin_fpclassify(InterpState &S, CodePtr OpPC,
606617static bool interp__builtin_fabs (InterpState &S, CodePtr OpPC,
607618 const InterpFrame *Frame) {
608619 const Floating &Val = S.Stk .pop <Floating>();
609- APFloat F = Val.getAPFloat ();
610- if (!F.isNegative ()) {
611- S.Stk .push <Floating>(Val);
612- return true ;
613- }
614-
615- Floating Result = S.allocFloat (Val.getSemantics ());
616- F.changeSign ();
617- Result.copy (F);
618- S.Stk .push <Floating>(Result);
620+ S.Stk .push <Floating>(abs (S, Val));
619621 return true ;
620622}
621623
@@ -1690,19 +1692,23 @@ static bool interp__builtin_elementwise_abs(InterpState &S, CodePtr OpPC,
16901692 const InterpFrame *Frame,
16911693 const CallExpr *Call,
16921694 unsigned BuiltinID) {
1693- // FIXME: add support of floating point
1694- assert (!Call->getArg (0 )->getType ()->isFloatingType () &&
1695- " floating point is currently not supported" );
1696-
16971695 assert (Call->getNumArgs () == 1 );
1698- if (Call->getArg (0 )->getType ()->isIntegerType ()) {
1696+ QualType Ty = Call->getArg (0 )->getType ();
1697+ if (Ty->isIntegerType ()) {
16991698 PrimType ArgT = *S.getContext ().classify (Call->getArg (0 )->getType ());
17001699 APSInt Val = popToAPSInt (S.Stk , ArgT);
17011700
17021701 pushInteger (S, Val.abs (), Call->getType ());
17031702 return true ;
17041703 }
17051704
1705+ if (Ty->isFloatingType ()) {
1706+ Floating Val = S.Stk .pop <Floating>();
1707+ Floating Result = abs (S, Val);
1708+ S.Stk .push <Floating>(Result);
1709+ return true ;
1710+ }
1711+
17061712 // Otherwise, the argument must be a vector.
17071713 assert (Call->getArg (0 )->getType ()->isVectorType ());
17081714 const Pointer &Arg = S.Stk .pop <Pointer>();
@@ -1715,14 +1721,18 @@ static bool interp__builtin_elementwise_abs(InterpState &S, CodePtr OpPC,
17151721 QualType ElemType = Arg.getFieldDesc ()->getElemQualType ();
17161722 PrimType ElemT = *S.getContext ().classify (ElemType);
17171723 unsigned NumElems = Arg.getNumElems ();
1718-
1719- // FIXME: Reading from uninitialized vector elements?
1724+ // we can either have a vector of integer or a vector of floating point
17201725 for (unsigned I = 0 ; I != NumElems; ++I) {
1721- INT_TYPE_SWITCH_NO_BOOL (ElemT, {
1722- Dst.elem <T>(I) = T::from (static_cast <T>(
1723- APSInt (Arg.elem <T>(I).toAPSInt ().abs (),
1724- ElemType->isUnsignedIntegerOrEnumerationType ())));
1725- });
1726+ if (ElemType->isIntegerType ()) {
1727+ INT_TYPE_SWITCH_NO_BOOL (ElemT, {
1728+ Dst.elem <T>(I) = T::from (static_cast <T>(
1729+ APSInt (Arg.elem <T>(I).toAPSInt ().abs (),
1730+ ElemType->isUnsignedIntegerOrEnumerationType ())));
1731+ });
1732+ } else {
1733+ Floating Val = Arg.elem <Floating>(I);
1734+ Dst.elem <Floating>(I) = abs (S, Val);
1735+ }
17261736 }
17271737 Dst.initializeAllElements ();
17281738
0 commit comments