From 3a5b9da11598e714890f4e9f37f894fc2c7287c2 Mon Sep 17 00:00:00 2001 From: Timm Baeder Date: Sat, 28 Sep 2024 19:11:49 +0200 Subject: [PATCH] [clang][bytecode] Implement fixed-point-to-float casts (#110369) --- clang/lib/AST/ByteCode/Compiler.cpp | 6 ++++++ clang/lib/AST/ByteCode/FixedPoint.h | 4 ++++ clang/lib/AST/ByteCode/Interp.h | 8 ++++++++ clang/lib/AST/ByteCode/Opcodes.td | 3 +++ clang/test/AST/ByteCode/fixed-point.cpp | 3 +++ 5 files changed, 24 insertions(+) diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index 40cb1b2dd80f..77bfb3d8cd7f 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -691,6 +691,12 @@ bool Compiler::VisitCastExpr(const CastExpr *CE) { std::memcpy(&I, &Sem, sizeof(Sem)); return this->emitCastFloatingFixedPoint(I, CE); } + case CK_FixedPointToFloating: { + if (!this->visit(SubExpr)) + return false; + const auto *TargetSemantics = &Ctx.getFloatSemantics(CE->getType()); + return this->emitCastFixedPointFloating(TargetSemantics, CE); + } case CK_ToVoid: return discard(SubExpr); diff --git a/clang/lib/AST/ByteCode/FixedPoint.h b/clang/lib/AST/ByteCode/FixedPoint.h index daa62945346a..fb8457a08e93 100644 --- a/clang/lib/AST/ByteCode/FixedPoint.h +++ b/clang/lib/AST/ByteCode/FixedPoint.h @@ -52,6 +52,10 @@ public: unsigned bitWidth() const { return V.getWidth(); } bool isSigned() const { return V.isSigned(); } + llvm::APFloat toFloat(const llvm::fltSemantics *Sem) const { + return V.convertToFloat(*Sem); + } + ComparisonCategoryResult compare(const FixedPoint &Other) const { if (Other.V == V) return ComparisonCategoryResult::Equal; diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h index 23405765d8de..0a99d9440ff8 100644 --- a/clang/lib/AST/ByteCode/Interp.h +++ b/clang/lib/AST/ByteCode/Interp.h @@ -2367,6 +2367,14 @@ static inline bool CastFloatingFixedPoint(InterpState &S, CodePtr OpPC, return true; } +static inline bool CastFixedPointFloating(InterpState &S, CodePtr OpPC, + const llvm::fltSemantics *Sem) { + const auto &Fixed = S.Stk.pop(); + + S.Stk.push(Fixed.toFloat(Sem)); + return true; +} + static inline bool PtrPtrCast(InterpState &S, CodePtr OpPC, bool SrcIsVoidPtr) { const auto &Ptr = S.Stk.peek(); diff --git a/clang/lib/AST/ByteCode/Opcodes.td b/clang/lib/AST/ByteCode/Opcodes.td index 240e00e59d97..4f11b9279890 100644 --- a/clang/lib/AST/ByteCode/Opcodes.td +++ b/clang/lib/AST/ByteCode/Opcodes.td @@ -682,6 +682,9 @@ def CastIntegralFixedPoint : Opcode { def CastFloatingFixedPoint : Opcode { let Args = [ArgUint32]; } +def CastFixedPointFloating : Opcode { + let Args = [ArgFltSemantics]; +} 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 76da06a02e15..68137618b5db 100644 --- a/clang/test/AST/ByteCode/fixed-point.cpp +++ b/clang/test/AST/ByteCode/fixed-point.cpp @@ -31,4 +31,7 @@ namespace FloatToFixedPointCast { // both-note {{outside the range of representable values of type 'const _Fract'}} constexpr _Fract sf2 = 0.5; + static_assert(sf2 == 0.5); + constexpr float sf2f = sf2; + static_assert(sf2f == 0.5); }