https://github.com/jay87406 updated 
https://github.com/llvm/llvm-project/pull/223286

>From be67d9c113767b385afe0e37225a834fc8fae65b Mon Sep 17 00:00:00 2001
From: Cheng-Chieh Liu <[email protected]>
Date: Mon, 21 Sep 2026 04:33:09 -0500
Subject: [PATCH 1/2] [clang][Lex] Unique ModuleMacros with a UniquingSet (NFC)
 (#223270)

This patch migrates ModuleMacros in Preprocessor from llvm::FoldingSet
to llvm::UniquingSet.

ModuleMacro keys on a pair of Module * and const IdentifierInfo *.
Switching to UniquingSet allows us to look up macros with a typed key,
eliminating FoldingSetNodeID serialization at lookup sites and removing
ModuleMacro::Profile.

Assisted-by: Antigravity
---
 clang/include/clang/Lex/MacroInfo.h    | 12 +++---------
 clang/include/clang/Lex/Preprocessor.h |  2 +-
 clang/lib/Lex/PPMacroExpansion.cpp     | 10 ++--------
 3 files changed, 6 insertions(+), 18 deletions(-)

diff --git a/clang/include/clang/Lex/MacroInfo.h 
b/clang/include/clang/Lex/MacroInfo.h
index 60048688a9a33..e5dbc7f92a9ac 100644
--- a/clang/include/clang/Lex/MacroInfo.h
+++ b/clang/include/clang/Lex/MacroInfo.h
@@ -511,7 +511,7 @@ MacroDirective::DefInfo::getPreviousDefinition() {
 /// the final directive for a macro name within a module. These entities also
 /// represent the macro override graph.
 ///
-/// These are stored in a FoldingSet in the preprocessor.
+/// These are stored in a UniquingSet in the preprocessor.
 class ModuleMacro : public llvm::FoldingSetNode {
   friend class Preprocessor;
 
@@ -543,14 +543,8 @@ class ModuleMacro : public llvm::FoldingSetNode {
                              const IdentifierInfo *II, MacroInfo *Macro,
                              ArrayRef<ModuleMacro *> Overrides);
 
-  void Profile(llvm::FoldingSetNodeID &ID) const {
-    return Profile(ID, OwningModule, II);
-  }
-
-  static void Profile(llvm::FoldingSetNodeID &ID, Module *OwningModule,
-                      const IdentifierInfo *II) {
-    ID.AddPointer(OwningModule);
-    ID.AddPointer(II);
+  std::pair<Module *, const IdentifierInfo *> getKey() const {
+    return {OwningModule, II};
   }
 
   /// Get the name of the macro.
diff --git a/clang/include/clang/Lex/Preprocessor.h 
b/clang/include/clang/Lex/Preprocessor.h
index d94f3d2cbe8ed..31b68a0fd0670 100644
--- a/clang/include/clang/Lex/Preprocessor.h
+++ b/clang/include/clang/Lex/Preprocessor.h
@@ -1091,7 +1091,7 @@ class Preprocessor {
   llvm::SmallSetVector<Module *, 2> AffectingClangModules;
 
   /// The set of known macros exported from modules.
-  llvm::FoldingSet<ModuleMacro> ModuleMacros;
+  llvm::UniquingSet<ModuleMacro> ModuleMacros;
 
   /// The names of potential module macros that we've not yet processed.
   llvm::SmallVector<IdentifierInfo *, 32> PendingModuleMacroNames;
diff --git a/clang/lib/Lex/PPMacroExpansion.cpp 
b/clang/lib/Lex/PPMacroExpansion.cpp
index a8b9bcd4e4572..83f78700a4e72 100644
--- a/clang/lib/Lex/PPMacroExpansion.cpp
+++ b/clang/lib/Lex/PPMacroExpansion.cpp
@@ -131,11 +131,8 @@ ModuleMacro *Preprocessor::addModuleMacro(Module *Mod, 
IdentifierInfo *II,
                                           MacroInfo *Macro,
                                           ArrayRef<ModuleMacro *> Overrides,
                                           bool &New) {
-  llvm::FoldingSetNodeID ID;
-  ModuleMacro::Profile(ID, Mod, II);
-
   llvm::FoldingSetInsertToken InsertToken;
-  if (auto *MM = ModuleMacros.lookup(ID, InsertToken)) {
+  if (auto *MM = ModuleMacros.lookup({Mod, II}, InsertToken)) {
     New = false;
     return MM;
   }
@@ -168,11 +165,8 @@ ModuleMacro *Preprocessor::addModuleMacro(Module *Mod, 
IdentifierInfo *II,
 
 ModuleMacro *Preprocessor::getModuleMacro(Module *Mod,
                                           const IdentifierInfo *II) {
-  llvm::FoldingSetNodeID ID;
-  ModuleMacro::Profile(ID, Mod, II);
-
   llvm::FoldingSetInsertToken InsertToken;
-  return ModuleMacros.lookup(ID, InsertToken);
+  return ModuleMacros.lookup({Mod, II}, InsertToken);
 }
 
 void Preprocessor::updateModuleMacroInfo(const IdentifierInfo *II,

>From fc5c2cad856e7d9293b4d808d3e99151e122a60c Mon Sep 17 00:00:00 2001
From: Cheng-Chieh Liu <[email protected]>
Date: Mon, 21 Sep 2026 04:33:10 -0500
Subject: [PATCH 2/2] [APFloat] Fix sign bit corrupting exponent in unsigned
 FP8 formats

convertIEEEFloatToAPInt unconditionally ORs the sign bit into the top
bit of the encoded value. Float8E8M0FNU and Float8E5M3FNU have no sign
bit (hasSignedRepr = false), so that top bit actually belongs to the
exponent field. Encoding a value with sign set therefore corrupts the
exponent, in one case colliding with the reserved NaN bit pattern.

Guard the OR with hasSignedRepr, matching the existing check in the
decode path (initFromIEEEAPInt).

Extend ConvertLosesUnrepresentableSignAndZero to also check
bitcastToAPInt() after dropping an unrepresentable sign, using -1.0
instead of -2.0 so the corruption is actually visible in the bits.
---
 llvm/lib/Support/APFloat.cpp       |  8 +++++---
 llvm/unittests/ADT/APFloatTest.cpp | 12 ++++++++----
 2 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/llvm/lib/Support/APFloat.cpp b/llvm/lib/Support/APFloat.cpp
index 59a6ba3867d40..e824b00162d33 100644
--- a/llvm/lib/Support/APFloat.cpp
+++ b/llvm/lib/Support/APFloat.cpp
@@ -3569,9 +3569,11 @@ APInt IEEEFloat::convertIEEEFloatToAPInt() const {
   }
   std::fill(words_iter, words.end(), uint64_t{0});
   constexpr size_t last_word = words.size() - 1;
-  uint64_t shifted_sign = static_cast<uint64_t>(sign & 1)
-                          << ((S.sizeInBits - 1) % 64);
-  words[last_word] |= shifted_sign;
+  if constexpr (S.hasSignedRepr) {
+    uint64_t shifted_sign = static_cast<uint64_t>(sign & 1)
+                            << ((S.sizeInBits - 1) % 64);
+    words[last_word] |= shifted_sign;
+  }
   uint64_t shifted_exponent = (myexponent & exponent_mask)
                               << (trailing_significand_bits % 64);
   words[last_word] |= shifted_exponent;
diff --git a/llvm/unittests/ADT/APFloatTest.cpp 
b/llvm/unittests/ADT/APFloatTest.cpp
index e161071e63af4..66147c5f9b46e 100644
--- a/llvm/unittests/ADT/APFloatTest.cpp
+++ b/llvm/unittests/ADT/APFloatTest.cpp
@@ -2494,23 +2494,27 @@ TEST(APFloatTest, 
ConvertLosesUnrepresentableSignAndZero) {
 
   for (const fltSemantics *Sem : NoSignSemantics) {
     // The magnitude converts exactly, so the sign is the whole of the loss.
-    APFloat test(-2.0);
+    APFloat test(-1.0);
     bool losesInfo = false;
     APFloat::opStatus status =
         test.convert(*Sem, APFloat::rmNearestTiesToEven, &losesInfo);
     EXPECT_TRUE(losesInfo);
     EXPECT_EQ(status, APFloat::opInexact);
     EXPECT_TRUE(test.isNegative());
-    EXPECT_EQ(-2.0, test.convertToDouble());
+    EXPECT_EQ(-1.0, test.convertToDouble());
+    APInt negBits = test.bitcastToAPInt();
 
     // The same magnitude without the sign has nothing to report.
-    test = APFloat(2.0);
+    test = APFloat(1.0);
     losesInfo = true;
     status = test.convert(*Sem, APFloat::rmNearestTiesToEven, &losesInfo);
     EXPECT_FALSE(losesInfo);
     EXPECT_EQ(status, APFloat::opOK);
     EXPECT_FALSE(test.isNegative());
-    EXPECT_EQ(2.0, test.convertToDouble());
+    EXPECT_EQ(1.0, test.convertToDouble());
+
+    // No sign bit exists, so the bits must match the positive magnitude.
+    EXPECT_EQ(test.bitcastToAPInt(), negBits);
   }
 
   // Float8E8M0FNU has no zero either, and substitutes 2^-127 for one. That

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to