diff options
| author | Mehdi Amini <joker.eph@gmail.com> | 2025-08-14 15:36:46 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-08-14 15:36:46 +0200 |
| commit | df57d6a01e85ca78da2febab21b268d9fd6955a0 (patch) | |
| tree | 19b0aab453e6bc7e2b15d3220024dfdacd4fa57e /clang/lib/AST/ByteCode | |
| parent | df86ea61b7ed484ca797f96d7ad40fd9ada7ba30 (diff) | |
| parent | 7bda76367f19cfc19086f68d9dd5ac019a9ceccd (diff) | |
Merge branch 'main' into users/joker-eph-python-bindings-maintainersusers/joker-eph-python-bindings-maintainers
Diffstat (limited to 'clang/lib/AST/ByteCode')
| -rw-r--r-- | clang/lib/AST/ByteCode/Descriptor.cpp | 4 | ||||
| -rw-r--r-- | clang/lib/AST/ByteCode/InterpBuiltin.cpp | 76 |
2 files changed, 67 insertions, 13 deletions
diff --git a/clang/lib/AST/ByteCode/Descriptor.cpp b/clang/lib/AST/ByteCode/Descriptor.cpp index 234fa2c8cd8f..9ecc7b673cf2 100644 --- a/clang/lib/AST/ByteCode/Descriptor.cpp +++ b/clang/lib/AST/ByteCode/Descriptor.cpp @@ -473,9 +473,7 @@ bool Descriptor::hasTrivialDtor() const { bool Descriptor::isUnion() const { return isRecord() && ElemRecord->isUnion(); } InitMap::InitMap(unsigned N) - : UninitFields(N), Data(std::make_unique<T[]>(numFields(N))) { - std::fill_n(data(), numFields(N), 0); -} + : UninitFields(N), Data(std::make_unique<T[]>(numFields(N))) {} bool InitMap::initializeElement(unsigned I) { unsigned Bucket = I / PER_FIELD; diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp index ee2d53255158..b602b9731a6e 100644 --- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp +++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp @@ -598,6 +598,17 @@ static bool interp__builtin_fpclassify(InterpState &S, CodePtr OpPC, return true; } +static inline Floating abs(InterpState &S, const Floating &In) { + if (!In.isNegative()) + return In; + + Floating Output = S.allocFloat(In.getSemantics()); + APFloat New = In.getAPFloat(); + New.changeSign(); + Output.copy(New); + return Output; +} + // The C standard says "fabs raises no floating-point exceptions, // even if x is a signaling NaN. The returned value is independent of // the current rounding direction mode." Therefore constant folding can @@ -606,16 +617,7 @@ static bool interp__builtin_fpclassify(InterpState &S, CodePtr OpPC, static bool interp__builtin_fabs(InterpState &S, CodePtr OpPC, const InterpFrame *Frame) { const Floating &Val = S.Stk.pop<Floating>(); - APFloat F = Val.getAPFloat(); - if (!F.isNegative()) { - S.Stk.push<Floating>(Val); - return true; - } - - Floating Result = S.allocFloat(Val.getSemantics()); - F.changeSign(); - Result.copy(F); - S.Stk.push<Floating>(Result); + S.Stk.push<Floating>(abs(S, Val)); return true; } @@ -1686,6 +1688,57 @@ static bool interp__builtin_vector_reduce(InterpState &S, CodePtr OpPC, return true; } +static bool interp__builtin_elementwise_abs(InterpState &S, CodePtr OpPC, + const InterpFrame *Frame, + const CallExpr *Call, + unsigned BuiltinID) { + assert(Call->getNumArgs() == 1); + QualType Ty = Call->getArg(0)->getType(); + if (Ty->isIntegerType()) { + PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType()); + APSInt Val = popToAPSInt(S.Stk, ArgT); + + pushInteger(S, Val.abs(), Call->getType()); + return true; + } + + if (Ty->isFloatingType()) { + Floating Val = S.Stk.pop<Floating>(); + Floating Result = abs(S, Val); + S.Stk.push<Floating>(Result); + return true; + } + + // Otherwise, the argument must be a vector. + assert(Call->getArg(0)->getType()->isVectorType()); + const Pointer &Arg = S.Stk.pop<Pointer>(); + assert(Arg.getFieldDesc()->isPrimitiveArray()); + const Pointer &Dst = S.Stk.peek<Pointer>(); + assert(Dst.getFieldDesc()->isPrimitiveArray()); + assert(Arg.getFieldDesc()->getNumElems() == + Dst.getFieldDesc()->getNumElems()); + + QualType ElemType = Arg.getFieldDesc()->getElemQualType(); + PrimType ElemT = *S.getContext().classify(ElemType); + unsigned NumElems = Arg.getNumElems(); + // we can either have a vector of integer or a vector of floating point + for (unsigned I = 0; I != NumElems; ++I) { + if (ElemType->isIntegerType()) { + INT_TYPE_SWITCH_NO_BOOL(ElemT, { + Dst.elem<T>(I) = T::from(static_cast<T>( + APSInt(Arg.elem<T>(I).toAPSInt().abs(), + ElemType->isUnsignedIntegerOrEnumerationType()))); + }); + } else { + Floating Val = Arg.elem<Floating>(I); + Dst.elem<Floating>(I) = abs(S, Val); + } + } + Dst.initializeAllElements(); + + return true; +} + /// Can be called with an integer or vector as the first and only parameter. static bool interp__builtin_elementwise_popcount(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, @@ -2774,6 +2827,9 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call, return interp__builtin_elementwise_popcount(S, OpPC, Frame, Call, BuiltinID); + case Builtin::BI__builtin_elementwise_abs: + return interp__builtin_elementwise_abs(S, OpPC, Frame, Call, BuiltinID); + case Builtin::BI__builtin_memcpy: case Builtin::BImemcpy: case Builtin::BI__builtin_wmemcpy: |
