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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits