Author: Timm Baeder Date: 2024-09-28T13:10:23+02:00 New Revision: 641b4d5370f1ce2f5d448cf63519f391be1cf263
URL: https://github.com/llvm/llvm-project/commit/641b4d5370f1ce2f5d448cf63519f391be1cf263 DIFF: https://github.com/llvm/llvm-project/commit/641b4d5370f1ce2f5d448cf63519f391be1cf263.diff LOG: [clang][bytecode] Implement integral-to-fixed-point casts (#110350) Added: Modified: clang/lib/AST/ByteCode/Compiler.cpp clang/lib/AST/ByteCode/FixedPoint.h clang/lib/AST/ByteCode/Interp.h clang/lib/AST/ByteCode/Opcodes.td clang/test/AST/ByteCode/fixed-point.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index 2520fe30547b23..8875fc05d24bee 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -672,6 +672,17 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) { ToSize, CE); }; + case CK_IntegralToFixedPoint: { + if (!this->visit(SubExpr)) + return false; + + auto Sem = Ctx.getASTContext().getFixedPointSemantics(CE->getType()); + uint32_t I; + std::memcpy(&I, &Sem, sizeof(Sem)); + return this->emitCastIntegralFixedPoint(classifyPrim(SubExpr->getType()), I, + CE); + } + case CK_ToVoid: return discard(SubExpr); diff --git a/clang/lib/AST/ByteCode/FixedPoint.h b/clang/lib/AST/ByteCode/FixedPoint.h index 9dd300c3dbf6df..daa62945346aeb 100644 --- a/clang/lib/AST/ByteCode/FixedPoint.h +++ b/clang/lib/AST/ByteCode/FixedPoint.h @@ -23,9 +23,10 @@ using APSInt = llvm::APSInt; class FixedPoint final { private: llvm::APFixedPoint V; - FixedPoint(llvm::APFixedPoint &&V) : V(std::move(V)) {} public: + FixedPoint(llvm::APFixedPoint &&V) : V(std::move(V)) {} + FixedPoint(llvm::APFixedPoint &V) : V(V) {} FixedPoint(APInt V, llvm::FixedPointSemantics Sem) : V(V, Sem) {} // This needs to be default-constructible so llvm::endian::read works. FixedPoint() diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h index 79af426f8a913f..f88233ed0f8f0a 100644 --- a/clang/lib/AST/ByteCode/Interp.h +++ b/clang/lib/AST/ByteCode/Interp.h @@ -38,6 +38,7 @@ namespace clang { namespace interp { using APSInt = llvm::APSInt; +using FixedPointSemantics = llvm::FixedPointSemantics; /// Convert a value to an APValue. template <typename T> @@ -2311,6 +2312,34 @@ static inline bool CastPointerIntegralAPS(InterpState &S, CodePtr OpPC, return true; } +template <PrimType Name, class T = typename PrimConv<Name>::T> +static inline bool CastIntegralFixedPoint(InterpState &S, CodePtr OpPC, + uint32_t FPS) { + const T &Int = S.Stk.pop<T>(); + + FixedPointSemantics Sem(0, 0, false, false, false); + std::memcpy(&Sem, &FPS, sizeof(Sem)); + + bool Overflow; + llvm::APFixedPoint IntResult = + llvm::APFixedPoint::getFromIntValue(Int.toAPSInt(), Sem, &Overflow); + + if (Overflow) { + const Expr *E = S.Current->getExpr(OpPC); + if (S.checkingForUndefinedBehavior()) { + S.getASTContext().getDiagnostics().Report( + E->getExprLoc(), diag::warn_fixedpoint_constant_overflow) + << IntResult.toString() << E->getType(); + } + S.CCEDiag(E, diag::note_constexpr_overflow) << IntResult << E->getType(); + if (!S.noteUndefinedBehavior()) + return false; + } + + S.Stk.push<FixedPoint>(IntResult); + return true; +} + static inline bool PtrPtrCast(InterpState &S, CodePtr OpPC, bool SrcIsVoidPtr) { const auto &Ptr = S.Stk.peek<Pointer>(); diff --git a/clang/lib/AST/ByteCode/Opcodes.td b/clang/lib/AST/ByteCode/Opcodes.td index 5fdafd1bf81984..65eb82080a2194 100644 --- a/clang/lib/AST/ByteCode/Opcodes.td +++ b/clang/lib/AST/ByteCode/Opcodes.td @@ -674,6 +674,12 @@ def CastPointerIntegralAP : Opcode { def CastPointerIntegralAPS : Opcode { let Args = [ArgUint32]; } +def CastIntegralFixedPoint : Opcode { + let Types = [FixedSizeIntegralTypes]; + let Args = [ArgUint32]; + let HasGroup = 1; +} + def PtrPtrCast : Opcode { let Args = [ArgBool]; diff --git a/clang/test/AST/ByteCode/fixed-point.cpp b/clang/test/AST/ByteCode/fixed-point.cpp index bf1bd41783448f..77000c08918256 100644 --- a/clang/test/AST/ByteCode/fixed-point.cpp +++ b/clang/test/AST/ByteCode/fixed-point.cpp @@ -12,3 +12,11 @@ static_assert(-12.0k == -(-(-12.0k))); /// Zero-init. constexpr _Accum A{}; static_assert(A == 0.0k); + +namespace IntToFixedPointCast { + constexpr _Accum B = 13; + static_assert(B == 13.0k); + + constexpr _Fract sf = -1; + static_assert(sf == -1.0k); +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits