Skip to content

[llvm] Add serialization to uint32_t for FixedPointSemantics #110288

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 9, 2024

Conversation

tbaederr
Copy link
Contributor

FixedPointSemantics is exactly 32bits and this static_assert'ed after its declaration. Add support for converting it to and from a uint32_t.

@llvmbot
Copy link
Member

llvmbot commented Sep 27, 2024

@llvm/pr-subscribers-llvm-adt

@llvm/pr-subscribers-llvm-support

Author: Timm Baeder (tbaederr)

Changes

FixedPointSemantics is exactly 32bits and this static_assert'ed after its declaration. Add support for converting it to and from a uint32_t.


Full diff: https://github.com/llvm/llvm-project/pull/110288.diff

3 Files Affected:

  • (modified) llvm/include/llvm/ADT/APFixedPoint.h (+3)
  • (modified) llvm/lib/Support/APFixedPoint.cpp (+12)
  • (modified) llvm/unittests/ADT/APFixedPointTest.cpp (+31)
diff --git a/llvm/include/llvm/ADT/APFixedPoint.h b/llvm/include/llvm/ADT/APFixedPoint.h
index ae40db96e4818c..45c7b20facab59 100644
--- a/llvm/include/llvm/ADT/APFixedPoint.h
+++ b/llvm/include/llvm/ADT/APFixedPoint.h
@@ -114,6 +114,9 @@ class FixedPointSemantics {
   }
   bool operator!=(FixedPointSemantics Other) const { return !(*this == Other); }
 
+  uint32_t toOpaqueInt() const;
+  static FixedPointSemantics getFromOpaqueInt(uint32_t);
+
 private:
   unsigned Width          : WidthBitWidth;
   signed int LsbWeight    : LsbWeightBitWidth;
diff --git a/llvm/lib/Support/APFixedPoint.cpp b/llvm/lib/Support/APFixedPoint.cpp
index 249c4f1e2153da..3c289c9ad26030 100644
--- a/llvm/lib/Support/APFixedPoint.cpp
+++ b/llvm/lib/Support/APFixedPoint.cpp
@@ -29,6 +29,18 @@ void FixedPointSemantics::print(llvm::raw_ostream &OS) const {
   OS << "IsSaturated=" << IsSaturated;
 }
 
+uint32_t FixedPointSemantics::toOpaqueInt() const {
+  uint32_t Result;
+  std::memcpy(&Result, this, sizeof(uint32_t));
+  return Result;
+}
+
+FixedPointSemantics FixedPointSemantics::getFromOpaqueInt(uint32_t I) {
+  FixedPointSemantics F(0, 0, false, false, false);
+  std::memcpy(&F, &I, sizeof(F));
+  return F;
+}
+
 APFixedPoint APFixedPoint::convert(const FixedPointSemantics &DstSema,
                                    bool *Overflow) const {
   APSInt NewVal = Val;
diff --git a/llvm/unittests/ADT/APFixedPointTest.cpp b/llvm/unittests/ADT/APFixedPointTest.cpp
index ecb89fbf76c8bb..e7aa58a8325773 100644
--- a/llvm/unittests/ADT/APFixedPointTest.cpp
+++ b/llvm/unittests/ADT/APFixedPointTest.cpp
@@ -1274,4 +1274,35 @@ TEST(FixedPoint, div) {
                                               true, false, false)));
 }
 
+TEST(FixedPoint, semanticsSerialization) {
+  auto roundTrip = [](FixedPointSemantics FPS) -> bool {
+    uint32_t I = FPS.toOpaqueInt();
+    FixedPointSemantics FPS2 = FixedPointSemantics::getFromOpaqueInt(I);
+    return FPS == FPS2;
+  };
+
+  ASSERT_TRUE(roundTrip(getS32Pos2()));
+  ASSERT_TRUE(roundTrip(getU8Pos4()));
+  ASSERT_TRUE(roundTrip(getS16Neg18()));
+  ASSERT_TRUE(roundTrip(getU8Neg10()));
+  ASSERT_TRUE(roundTrip(getPadULFractSema()));
+  ASSERT_TRUE(roundTrip(getPadUFractSema()));
+  ASSERT_TRUE(roundTrip(getPadUSFractSema()));
+  ASSERT_TRUE(roundTrip(getPadULAccumSema()));
+  ASSERT_TRUE(roundTrip(getPadUAccumSema()));
+  ASSERT_TRUE(roundTrip(getPadUSAccumSema()));
+  ASSERT_TRUE(roundTrip(getULFractSema()));
+  ASSERT_TRUE(roundTrip(getUFractSema()));
+  ASSERT_TRUE(roundTrip(getUSFractSema()));
+  ASSERT_TRUE(roundTrip(getULAccumSema()));
+  ASSERT_TRUE(roundTrip(getUAccumSema()));
+  ASSERT_TRUE(roundTrip(getUSAccumSema()));
+  ASSERT_TRUE(roundTrip(getLFractSema()));
+  ASSERT_TRUE(roundTrip(getFractSema()));
+  ASSERT_TRUE(roundTrip(getSFractSema()));
+  ASSERT_TRUE(roundTrip(getLAccumSema()));
+  ASSERT_TRUE(roundTrip(getAccumSema()));
+  ASSERT_TRUE(roundTrip(getSAccumSema()));
+}
+
 } // namespace

@tbaederr
Copy link
Contributor Author

tbaederr commented Oct 4, 2024

Ping

@Ralender
Copy link
Collaborator

Ralender commented Oct 4, 2024

What is the serialization for ? would that prevent changing the struct layout in the future ?

Other than that, looks good to me.
But I don't know how much my approval matters.

@@ -29,6 +29,18 @@ void FixedPointSemantics::print(llvm::raw_ostream &OS) const {
OS << "IsSaturated=" << IsSaturated;
}

uint32_t FixedPointSemantics::toOpaqueInt() const {
uint32_t Result;
std::memcpy(&Result, this, sizeof(uint32_t));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: return bit_cast<uint32_t>(*this);

@tbaederr
Copy link
Contributor Author

tbaederr commented Oct 5, 2024

What is the serialization for ?

I use this in the bytecode interpreter in clang.

would that prevent changing the struct layout in the future ?

It forces the struct to be 32bit right now, but there is already a static_assert for this in llvm.

Other than that, looks good to me. But I don't know how much my approval matters.

@Ralender
Copy link
Collaborator

Ralender commented Oct 6, 2024

Ok, for the bytecode interpreter its. good.
I just didn't want this to be used in a something that would need compatibility across llvm versions.

@tbaederr tbaederr requested a review from bevin-hansson October 7, 2024 08:08
Copy link
Contributor

@bevin-hansson bevin-hansson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, though I'm unsure of any future consequences of making it part of a versioned interface, if that's the intention.

@tbaederr
Copy link
Contributor Author

tbaederr commented Oct 8, 2024

I added some clarifying comments to the two new public functions

Copy link

github-actions bot commented Oct 8, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

FixedPointSemantics is exactly 32bits and this static_assert'ed after
its declaration. Add support for converting it to and from a uint32_t.
@tbaederr tbaederr merged commit a579782 into llvm:main Oct 9, 2024
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants