This revision was landed with ongoing or failed builds. This revision was automatically updated to reflect the committed changes. Closed by commit rGcf10061da75e: [clang][Interp] Fully serialize Floating values to bytes (authored by tbaeder).
Changed prior to commit: https://reviews.llvm.org/D155165?vs=545353&id=551077#toc Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D155165/new/ https://reviews.llvm.org/D155165 Files: clang/lib/AST/Interp/ByteCodeEmitter.cpp clang/lib/AST/Interp/Disasm.cpp clang/lib/AST/Interp/Floating.h clang/lib/AST/Interp/Interp.h clang/lib/AST/Interp/Source.h clang/test/AST/Interp/floats.cpp
Index: clang/test/AST/Interp/floats.cpp =================================================================== --- clang/test/AST/Interp/floats.cpp +++ clang/test/AST/Interp/floats.cpp @@ -144,6 +144,22 @@ namespace LongDouble { constexpr long double ld = 3.1425926539; + + constexpr long double f() { + const long double L = __LDBL_MAX__; + + return L; + }; + static_assert(f() == __LDBL_MAX__); + +#ifdef __FLOAT128__ + constexpr __float128 f128() { + const __float128 L = __LDBL_MAX__; + + return L; + }; + static_assert(f128() == __LDBL_MAX__); +#endif } namespace Compare { Index: clang/lib/AST/Interp/Source.h =================================================================== --- clang/lib/AST/Interp/Source.h +++ clang/lib/AST/Interp/Source.h @@ -43,6 +43,7 @@ } bool operator!=(const CodePtr &RHS) const { return Ptr != RHS.Ptr; } + const std::byte *operator*() const { return Ptr; } operator bool() const { return Ptr; } Index: clang/lib/AST/Interp/Interp.h =================================================================== --- clang/lib/AST/Interp/Interp.h +++ clang/lib/AST/Interp/Interp.h @@ -1806,6 +1806,12 @@ } } +template <> inline Floating ReadArg<Floating>(InterpState &S, CodePtr &OpPC) { + Floating F = Floating::deserialize(*OpPC); + OpPC += align(F.bytesToSerialize()); + return F; +} + } // namespace interp } // namespace clang Index: clang/lib/AST/Interp/Floating.h =================================================================== --- clang/lib/AST/Interp/Floating.h +++ clang/lib/AST/Interp/Floating.h @@ -119,6 +119,36 @@ return Status; } + static Floating bitcastFromMemory(const std::byte *Buff, + const llvm::fltSemantics &Sem) { + size_t Size = APFloat::semanticsSizeInBits(Sem); + llvm::APInt API(Size, true); + llvm::LoadIntFromMemory(API, (const uint8_t *)Buff, Size / 8); + + return Floating(APFloat(Sem, API)); + } + + // === Serialization support === + size_t bytesToSerialize() const { + return sizeof(llvm::fltSemantics *) + + (APFloat::semanticsSizeInBits(F.getSemantics()) / 8); + } + + void serialize(std::byte *Buff) const { + // Semantics followed by an APInt. + *reinterpret_cast<const llvm::fltSemantics **>(Buff) = &F.getSemantics(); + + llvm::APInt API = F.bitcastToAPInt(); + llvm::StoreIntToMemory(API, (uint8_t *)(Buff + sizeof(void *)), + bitWidth() / 8); + } + + static Floating deserialize(const std::byte *Buff) { + const llvm::fltSemantics *Sem; + std::memcpy((void *)&Sem, Buff, sizeof(void *)); + return bitcastFromMemory(Buff + sizeof(void *), *Sem); + } + static Floating abs(const Floating &F) { APFloat V = F.F; if (V.isNegative()) Index: clang/lib/AST/Interp/Disasm.cpp =================================================================== --- clang/lib/AST/Interp/Disasm.cpp +++ clang/lib/AST/Interp/Disasm.cpp @@ -31,6 +31,12 @@ } } +template <> inline Floating ReadArg<Floating>(Program &P, CodePtr &OpPC) { + Floating F = Floating::deserialize(*OpPC); + OpPC += align(F.bytesToSerialize()); + return F; +} + LLVM_DUMP_METHOD void Function::dump() const { dump(llvm::errs()); } LLVM_DUMP_METHOD void Function::dump(llvm::raw_ostream &OS) const { Index: clang/lib/AST/Interp/ByteCodeEmitter.cpp =================================================================== --- clang/lib/AST/Interp/ByteCodeEmitter.cpp +++ clang/lib/AST/Interp/ByteCodeEmitter.cpp @@ -207,6 +207,25 @@ } } +template <> +void emit(Program &P, std::vector<std::byte> &Code, const Floating &Val, + bool &Success) { + size_t Size = Val.bytesToSerialize(); + + if (Code.size() + Size > std::numeric_limits<unsigned>::max()) { + Success = false; + return; + } + + // Access must be aligned! + size_t ValPos = align(Code.size()); + Size = align(Size); + assert(aligned(ValPos + Size)); + Code.resize(ValPos + Size); + + Val.serialize(Code.data() + ValPos); +} + template <typename... Tys> bool ByteCodeEmitter::emitOp(Opcode Op, const Tys &... Args, const SourceInfo &SI) { bool Success = true;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits