https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/110361
None >From 7583fed959318e8f0e01957d7e278998510d9b0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbae...@redhat.com> Date: Sat, 28 Sep 2024 15:50:04 +0200 Subject: [PATCH] [clang][bytecode] Implement floating-to-fixed-point casts --- clang/lib/AST/ByteCode/Compiler.cpp | 9 +++++++ clang/lib/AST/ByteCode/Interp.h | 35 ++++++++++++++++++++++--- clang/lib/AST/ByteCode/Opcodes.td | 3 +++ clang/test/AST/ByteCode/fixed-point.cpp | 7 +++++ 4 files changed, 50 insertions(+), 4 deletions(-) diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index a80d973056db43..40cb1b2dd80f96 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -682,6 +682,15 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) { return this->emitCastIntegralFixedPoint(classifyPrim(SubExpr->getType()), I, CE); } + case CK_FloatingToFixedPoint: { + if (!this->visit(SubExpr)) + return false; + + auto Sem = Ctx.getASTContext().getFixedPointSemantics(CE->getType()); + uint32_t I; + std::memcpy(&I, &Sem, sizeof(Sem)); + return this->emitCastFloatingFixedPoint(I, CE); + } case CK_ToVoid: return discard(SubExpr); diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h index f88233ed0f8f0a..23405765d8de82 100644 --- a/clang/lib/AST/ByteCode/Interp.h +++ b/clang/lib/AST/ByteCode/Interp.h @@ -2321,7 +2321,7 @@ static inline bool CastIntegralFixedPoint(InterpState &S, CodePtr OpPC, std::memcpy(&Sem, &FPS, sizeof(Sem)); bool Overflow; - llvm::APFixedPoint IntResult = + llvm::APFixedPoint Result = llvm::APFixedPoint::getFromIntValue(Int.toAPSInt(), Sem, &Overflow); if (Overflow) { @@ -2329,14 +2329,41 @@ static inline bool CastIntegralFixedPoint(InterpState &S, CodePtr OpPC, if (S.checkingForUndefinedBehavior()) { S.getASTContext().getDiagnostics().Report( E->getExprLoc(), diag::warn_fixedpoint_constant_overflow) - << IntResult.toString() << E->getType(); + << Result.toString() << E->getType(); } - S.CCEDiag(E, diag::note_constexpr_overflow) << IntResult << E->getType(); + S.CCEDiag(E, diag::note_constexpr_overflow) << Result << E->getType(); if (!S.noteUndefinedBehavior()) return false; } - S.Stk.push<FixedPoint>(IntResult); + S.Stk.push<FixedPoint>(Result); + return true; +} + +static inline bool CastFloatingFixedPoint(InterpState &S, CodePtr OpPC, + uint32_t FPS) { + const auto &Float = S.Stk.pop<Floating>(); + + FixedPointSemantics Sem(0, 0, false, false, false); + std::memcpy(&Sem, &FPS, sizeof(Sem)); + + bool Overflow; + llvm::APFixedPoint Result = + llvm::APFixedPoint::getFromFloatValue(Float.getAPFloat(), 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) + << Result.toString() << E->getType(); + } + S.CCEDiag(E, diag::note_constexpr_overflow) << Result << E->getType(); + if (!S.noteUndefinedBehavior()) + return false; + } + + S.Stk.push<FixedPoint>(Result); return true; } diff --git a/clang/lib/AST/ByteCode/Opcodes.td b/clang/lib/AST/ByteCode/Opcodes.td index 65eb82080a2194..240e00e59d97ec 100644 --- a/clang/lib/AST/ByteCode/Opcodes.td +++ b/clang/lib/AST/ByteCode/Opcodes.td @@ -679,6 +679,9 @@ def CastIntegralFixedPoint : Opcode { let Args = [ArgUint32]; let HasGroup = 1; } +def CastFloatingFixedPoint : Opcode { + let Args = [ArgUint32]; +} 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 51ea166748730c..76da06a02e150c 100644 --- a/clang/test/AST/ByteCode/fixed-point.cpp +++ b/clang/test/AST/ByteCode/fixed-point.cpp @@ -25,3 +25,10 @@ namespace IntToFixedPointCast { static_assert(sf == -1.0k); static_assert(sf == -1); } + +namespace FloatToFixedPointCast { + constexpr _Fract sf = 1.0; // both-error {{must be initialized by a constant expression}} \ + // both-note {{outside the range of representable values of type 'const _Fract'}} + + constexpr _Fract sf2 = 0.5; +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits