https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/123599

>From 9a8e5f8f0afd7d5f139862f28e53414a3d9fd7f2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbae...@redhat.com>
Date: Mon, 20 Jan 2025 13:05:37 +0100
Subject: [PATCH] [clang][bytecode] Don't memcpy() FixedPoint values

llvm::FixedPoint is not trivially copyable.
---
 clang/lib/AST/ByteCode/ByteCodeEmitter.cpp |  6 +++++
 clang/lib/AST/ByteCode/Disasm.cpp          |  6 +++++
 clang/lib/AST/ByteCode/FixedPoint.h        | 26 ++++++++++++++++++++++
 clang/lib/AST/ByteCode/Interp.h            |  7 ++++++
 4 files changed, 45 insertions(+)

diff --git a/clang/lib/AST/ByteCode/ByteCodeEmitter.cpp 
b/clang/lib/AST/ByteCode/ByteCodeEmitter.cpp
index 3f2bc46664a4ae..19e2416c4c9422 100644
--- a/clang/lib/AST/ByteCode/ByteCodeEmitter.cpp
+++ b/clang/lib/AST/ByteCode/ByteCodeEmitter.cpp
@@ -332,6 +332,12 @@ void emit(Program &P, std::vector<std::byte> &Code, const 
IntegralAP<true> &Val,
   emitSerialized(Code, Val, Success);
 }
 
+template <>
+void emit(Program &P, std::vector<std::byte> &Code, const FixedPoint &Val,
+          bool &Success) {
+  emitSerialized(Code, Val, Success);
+}
+
 template <typename... Tys>
 bool ByteCodeEmitter::emitOp(Opcode Op, const Tys &...Args,
                              const SourceInfo &SI) {
diff --git a/clang/lib/AST/ByteCode/Disasm.cpp 
b/clang/lib/AST/ByteCode/Disasm.cpp
index 1aba778eaf7b90..3c55c884a3507c 100644
--- a/clang/lib/AST/ByteCode/Disasm.cpp
+++ b/clang/lib/AST/ByteCode/Disasm.cpp
@@ -62,6 +62,12 @@ inline IntegralAP<true> ReadArg<IntegralAP<true>>(Program 
&P, CodePtr &OpPC) {
   return I;
 }
 
+template <> inline FixedPoint ReadArg<FixedPoint>(Program &P, CodePtr &OpPC) {
+  FixedPoint I = FixedPoint::deserialize(*OpPC);
+  OpPC += align(I.bytesToSerialize());
+  return I;
+}
+
 LLVM_DUMP_METHOD void Function::dump() const { dump(llvm::errs()); }
 
 LLVM_DUMP_METHOD void Function::dump(llvm::raw_ostream &OS) const {
diff --git a/clang/lib/AST/ByteCode/FixedPoint.h 
b/clang/lib/AST/ByteCode/FixedPoint.h
index ab8d6d7f02b52f..fcb3c79cc10978 100644
--- a/clang/lib/AST/ByteCode/FixedPoint.h
+++ b/clang/lib/AST/ByteCode/FixedPoint.h
@@ -91,6 +91,32 @@ class FixedPoint final {
     return ComparisonCategoryResult::Greater;
   }
 
+  size_t bytesToSerialize() const {
+    return sizeof(uint32_t) + (V.getValue().getBitWidth() / CHAR_BIT);
+  }
+
+  void serialize(std::byte *Buff) const {
+    // Semantics followed by APInt.
+    uint32_t SemI = V.getSemantics().toOpaqueInt();
+    std::memcpy(Buff, &SemI, sizeof(SemI));
+
+    llvm::APInt API = V.getValue();
+    llvm::StoreIntToMemory(API, (uint8_t *)(Buff + sizeof(SemI)),
+                           bitWidth() / 8);
+  }
+
+  static FixedPoint deserialize(const std::byte *Buff) {
+    auto Sem = llvm::FixedPointSemantics::getFromOpaqueInt(
+        *reinterpret_cast<const uint32_t *>(Buff));
+    unsigned BitWidth = Sem.getWidth();
+    APInt I(BitWidth, 0ull, !Sem.isSigned());
+    llvm::LoadIntFromMemory(
+        I, reinterpret_cast<const uint8_t *>(Buff + sizeof(uint32_t)),
+        BitWidth / CHAR_BIT);
+
+    return FixedPoint(I, Sem);
+  }
+
   static bool neg(const FixedPoint &A, FixedPoint *R) {
     bool Overflow = false;
     *R = FixedPoint(A.V.negate(&Overflow));
diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h
index 58c0256c7d7df8..510ff88e07f938 100644
--- a/clang/lib/AST/ByteCode/Interp.h
+++ b/clang/lib/AST/ByteCode/Interp.h
@@ -3070,6 +3070,13 @@ inline IntegralAP<true> 
ReadArg<IntegralAP<true>>(InterpState &S,
   return I;
 }
 
+template <>
+inline FixedPoint ReadArg<FixedPoint>(InterpState &S, CodePtr &OpPC) {
+  FixedPoint FP = FixedPoint::deserialize(*OpPC);
+  OpPC += align(FP.bytesToSerialize());
+  return FP;
+}
+
 } // namespace interp
 } // namespace clang
 

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to