[clang] [llvm] IR: Use LongDoubleFormat enum for long-double-type module flag (PR #213056)

Matt Arsenault via cfe-commits cfe-commits at lists.llvm.org
Thu Jul 30 08:56:33 PDT 2026


https://github.com/arsenm created https://github.com/llvm/llvm-project/pull/213056

Add parse/print helpers for the LongDoubleFormat enum, and route the
"long-double-type" module flag producers and consumers through them
instead of hardcoded strings in every location. Also clean up some
unnecessary failure checks guaranteed by the verifier.

Co-authored-by: Claude (Claude-Opus-4.8) <noreply at anthropic.com>

>From 960e9b75cb6a48cfcd03f7d21b4400bdc4d8746c Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Wed, 22 Jul 2026 11:58:52 +0200
Subject: [PATCH] IR: Use LongDoubleFormat enum for long-double-type module
 flag

Add parse/print helpers for the LongDoubleFormat enum, and route the
"long-double-type" module flag producers and consumers through them
instead of hardcoded strings in every location. Also clean up some
unnecessary failure checks guaranteed by the verifier.

Co-authored-by: Claude (Claude-Opus-4.8) <noreply at anthropic.com>
---
 clang/lib/CodeGen/Targets/PPC.cpp         | 17 +++++++-----
 llvm/include/llvm/Support/CodeGen.h       | 33 +++++++++++++++++++++++
 llvm/lib/IR/AutoUpgrade.cpp               | 17 +++++++-----
 llvm/lib/IR/Verifier.cpp                  |  6 ++---
 llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp | 19 ++++++++-----
 5 files changed, 68 insertions(+), 24 deletions(-)

diff --git a/clang/lib/CodeGen/Targets/PPC.cpp b/clang/lib/CodeGen/Targets/PPC.cpp
index 92d14261ae81f..5109567212adb 100644
--- a/clang/lib/CodeGen/Targets/PPC.cpp
+++ b/clang/lib/CodeGen/Targets/PPC.cpp
@@ -9,6 +9,7 @@
 #include "ABIInfoImpl.h"
 #include "TargetInfo.h"
 #include "clang/Basic/DiagnosticFrontend.h"
+#include "llvm/Support/CodeGen.h"
 
 using namespace clang;
 using namespace clang::CodeGen;
@@ -1046,17 +1047,19 @@ void PPC64_SVR4_TargetCodeGenInfo::emitTargetMetadata(
   if (CGM.getTypes().isLongDoubleReferenced()) {
     llvm::LLVMContext &Ctx = CGM.getLLVMContext();
     const auto *flt = &CGM.getTarget().getLongDoubleFormat();
-    StringRef Type;
+    std::optional<llvm::LongDoubleFormat> Format;
     if (flt == &llvm::APFloat::PPCDoubleDouble())
-      Type = "ppc_fp128";
+      Format = llvm::LongDoubleFormat::PPCDoubleDouble;
     else if (flt == &llvm::APFloat::IEEEquad())
-      Type = "fp128";
+      Format = llvm::LongDoubleFormat::IEEEquad;
     else if (flt == &llvm::APFloat::IEEEdouble())
-      Type = "double";
+      Format = llvm::LongDoubleFormat::IEEEdouble;
 
-    if (!Type.empty())
-      CGM.getModule().addModuleFlag(llvm::Module::Error, "long-double-type",
-                                    llvm::MDString::get(Ctx, Type));
+    if (Format) {
+      CGM.getModule().addModuleFlag(
+          llvm::Module::Error, "long-double-type",
+          llvm::MDString::get(Ctx, llvm::getLongDoubleFormatName(*Format)));
+    }
   }
 }
 
diff --git a/llvm/include/llvm/Support/CodeGen.h b/llvm/include/llvm/Support/CodeGen.h
index 5bc3993a02dff..dfe426f9cc88a 100644
--- a/llvm/include/llvm/Support/CodeGen.h
+++ b/llvm/include/llvm/Support/CodeGen.h
@@ -72,6 +72,39 @@ namespace llvm {
     PPCDoubleDouble,
   };
 
+  /// Returns the IR floating-point type name for a LongDoubleFormat.
+  inline StringRef getLongDoubleFormatName(LongDoubleFormat Format) {
+    switch (Format) {
+    case LongDoubleFormat::IEEEsingle:
+      return "float";
+    case LongDoubleFormat::IEEEdouble:
+      return "double";
+    case LongDoubleFormat::X87DoubleExtended:
+      return "x86_fp80";
+    case LongDoubleFormat::IEEEquad:
+      return "fp128";
+    case LongDoubleFormat::PPCDoubleDouble:
+      return "ppc_fp128";
+    }
+    return "";
+  }
+
+  /// Parses an IR floating-point type name into a LongDoubleFormat, returning
+  /// std::nullopt if it does not name a supported long double format.
+  inline std::optional<LongDoubleFormat> parseLongDoubleFormat(StringRef Name) {
+    if (Name == "float")
+      return LongDoubleFormat::IEEEsingle;
+    if (Name == "double")
+      return LongDoubleFormat::IEEEdouble;
+    if (Name == "x86_fp80")
+      return LongDoubleFormat::X87DoubleExtended;
+    if (Name == "fp128")
+      return LongDoubleFormat::IEEEquad;
+    if (Name == "ppc_fp128")
+      return LongDoubleFormat::PPCDoubleDouble;
+    return std::nullopt;
+  }
+
   namespace FloatABI {
   enum ABIType {
     Default, // Target-specific (either soft or hard depending on triple, etc).
diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp
index 297bdee30760c..4502759417c5a 100644
--- a/llvm/lib/IR/AutoUpgrade.cpp
+++ b/llvm/lib/IR/AutoUpgrade.cpp
@@ -46,6 +46,7 @@
 #include "llvm/IR/Value.h"
 #include "llvm/IR/Verifier.h"
 #include "llvm/Support/AMDGPUAddrSpace.h"
+#include "llvm/Support/CodeGen.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/NVPTXAddrSpace.h"
@@ -6639,13 +6640,15 @@ bool llvm::UpgradeModuleFlags(Module &M) {
       // soft/hard ABI flag, so leave a valid value alone. Map any other value
       // (including unrecognized ones, which were never valid) to the default.
       if (!FloatABI::parseABIType(Format)) {
-        StringRef NewType = StringSwitch<StringRef>(Format)
-                                .Case("ieeequad", "fp128")
-                                .Case("ieeedouble", "double")
-                                .Default("ppc_fp128");
-        Metadata *Ops[3] = {Op->getOperand(0),
-                            MDString::get(M.getContext(), "long-double-type"),
-                            MDString::get(M.getContext(), NewType)};
+        LongDoubleFormat NewFormat =
+            StringSwitch<LongDoubleFormat>(Format)
+                .Case("ieeequad", LongDoubleFormat::IEEEquad)
+                .Case("ieeedouble", LongDoubleFormat::IEEEdouble)
+                .Default(LongDoubleFormat::PPCDoubleDouble);
+        Metadata *Ops[3] = {
+            Op->getOperand(0),
+            MDString::get(M.getContext(), "long-double-type"),
+            MDString::get(M.getContext(), getLongDoubleFormatName(NewFormat))};
         ModFlags->setOperand(I, MDNode::get(M.getContext(), Ops));
         Changed = true;
       }
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 50e7bc5edefea..c21b8c427ea46 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -117,6 +117,7 @@
 #include "llvm/ProfileData/InstrProf.h"
 #include "llvm/Support/AtomicOrdering.h"
 #include "llvm/Support/Casting.h"
+#include "llvm/Support/CodeGen.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/FormatVariadic.h"
@@ -2006,10 +2007,7 @@ Verifier::visitModuleFlag(const MDNode *Op,
     const MDString *Value = dyn_cast_or_null<MDString>(Op->getOperand(2));
     Check(Value, "long-double-type metadata requires a string argument");
     if (Value)
-      Check(Value->getString() == "ppc_fp128" ||
-                Value->getString() == "fp128" ||
-                Value->getString() == "x86_fp80" ||
-                Value->getString() == "double" || Value->getString() == "float",
+      Check(parseLongDoubleFormat(Value->getString()).has_value(),
             "invalid long-double-type metadata value", Op);
   }
 
diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
index 4ccb578bbe263..a837e21933c56 100644
--- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -1769,24 +1769,31 @@ PPCAsmPrinter::getAdjustedFasterLocalExpr(const MachineOperand &MO,
 
 void PPCLinuxAsmPrinter::emitGNUAttributes(Module &M) {
   // Emit long double format into GNU attribute
-  Metadata *MD = M.getModuleFlag("long-double-type");
-  MDString *LongDoubleType = dyn_cast_or_null<MDString>(MD);
+  MDString *LongDoubleType =
+      cast_or_null<MDString>(M.getModuleFlag("long-double-type"));
   if (!LongDoubleType)
     return;
-  StringRef flt = LongDoubleType->getString();
+
   // TODO: Support emitting soft-fp and hard double/single attributes.
-  if (flt == "ppc_fp128")
+  switch (*parseLongDoubleFormat(LongDoubleType->getString())) {
+  case LongDoubleFormat::PPCDoubleDouble:
     OutStreamer->emitGNUAttribute(Tag_GNU_Power_ABI_FP,
                                   Val_GNU_Power_ABI_HardFloat_DP |
                                       Val_GNU_Power_ABI_LDBL_IBM128);
-  else if (flt == "fp128")
+    break;
+  case LongDoubleFormat::IEEEquad:
     OutStreamer->emitGNUAttribute(Tag_GNU_Power_ABI_FP,
                                   Val_GNU_Power_ABI_HardFloat_DP |
                                       Val_GNU_Power_ABI_LDBL_IEEE128);
-  else if (flt == "double")
+    break;
+  case LongDoubleFormat::IEEEdouble:
     OutStreamer->emitGNUAttribute(Tag_GNU_Power_ABI_FP,
                                   Val_GNU_Power_ABI_HardFloat_DP |
                                       Val_GNU_Power_ABI_LDBL_64);
+    break;
+  default:
+    break;
+  }
 }
 
 void PPCLinuxAsmPrinter::emitInstruction(const MachineInstr *MI) {



More information about the cfe-commits mailing list