Author: Timm Baeder Date: 2024-09-29T08:58:21+02:00 New Revision: c2a37e41b9f9f5e28339674dbdc656bc8a0bf708
URL: https://github.com/llvm/llvm-project/commit/c2a37e41b9f9f5e28339674dbdc656bc8a0bf708 DIFF: https://github.com/llvm/llvm-project/commit/c2a37e41b9f9f5e28339674dbdc656bc8a0bf708.diff LOG: [clang][bytecode] Implement fixed point casts (#110409) 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 ef058e8da44b34..3a3ee3b577c29c 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -697,6 +697,14 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) { const auto *TargetSemantics = &Ctx.getFloatSemantics(CE->getType()); return this->emitCastFixedPointFloating(TargetSemantics, CE); } + case CK_FixedPointCast: { + if (!this->visit(SubExpr)) + return false; + auto Sem = Ctx.getASTContext().getFixedPointSemantics(CE->getType()); + uint32_t I; + std::memcpy(&I, &Sem, sizeof(Sem)); + return this->emitCastFixedPoint(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 0a808e13eda4eb..0fb4576c721266 100644 --- a/clang/lib/AST/ByteCode/FixedPoint.h +++ b/clang/lib/AST/ByteCode/FixedPoint.h @@ -61,6 +61,11 @@ class FixedPoint final { FixedPoint truncate(unsigned BitWidth) const { return *this; } + FixedPoint toSemantics(const llvm::FixedPointSemantics &Sem, + bool *Overflow) const { + return FixedPoint(V.convert(Sem, Overflow)); + } + llvm::APFloat toFloat(const llvm::fltSemantics *Sem) const { return V.convertToFloat(*Sem); } diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h index 0a99d9440ff844..fd09deb87d4c51 100644 --- a/clang/lib/AST/ByteCode/Interp.h +++ b/clang/lib/AST/ByteCode/Interp.h @@ -2161,6 +2161,31 @@ inline bool CastFP(InterpState &S, CodePtr OpPC, const llvm::fltSemantics *Sem, return true; } +inline bool CastFixedPoint(InterpState &S, CodePtr OpPC, uint32_t FPS) { + FixedPointSemantics TargetSemantics(0, 0, false, false, false); + std::memcpy(&TargetSemantics, &FPS, sizeof(TargetSemantics)); + + const auto &Source = S.Stk.pop<FixedPoint>(); + + bool Overflow; + FixedPoint Result = Source.toSemantics(TargetSemantics, &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.toDiagnosticString(S.getASTContext()) << E->getType(); + } + S.CCEDiag(E, diag::note_constexpr_overflow) << Result << E->getType(); + if (!S.noteUndefinedBehavior()) + return false; + } + + S.Stk.push<FixedPoint>(Result); + return true; +} + /// Like Cast(), but we cast to an arbitrary-bitwidth integral, so we need /// to know what bitwidth the result should be. template <PrimType Name, class T = typename PrimConv<Name>::T> diff --git a/clang/lib/AST/ByteCode/Opcodes.td b/clang/lib/AST/ByteCode/Opcodes.td index ceea2accc22eff..2955bc5cf8084c 100644 --- a/clang/lib/AST/ByteCode/Opcodes.td +++ b/clang/lib/AST/ByteCode/Opcodes.td @@ -626,6 +626,10 @@ def CastFP : Opcode { let Args = [ArgFltSemantics, ArgRoundingMode]; } +def CastFixedPoint : Opcode { + let Args = [ArgUint32]; +} + def FixedSizeIntegralTypes : TypeClass { let Types = [Uint8, Sint8, Uint16, Sint16, Uint32, Sint32, Uint64, Sint64, Bool]; } diff --git a/clang/test/AST/ByteCode/fixed-point.cpp b/clang/test/AST/ByteCode/fixed-point.cpp index 03324c79fc9cae..dd360382e7ca21 100644 --- a/clang/test/AST/ByteCode/fixed-point.cpp +++ b/clang/test/AST/ByteCode/fixed-point.cpp @@ -47,3 +47,9 @@ namespace BinOps { // ref-error {{is not an integral constant expression}} \ // ref-note {{is outside the range of representable values}} } + +namespace FixedPointCasts { + constexpr _Fract B = 0.3; + constexpr _Accum A = B; + constexpr _Fract C = A; +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits