https://github.com/doac created https://github.com/llvm/llvm-project/pull/222304

GCC uses 64-bit long double for bare-metal SPARC V8 targets, including RTEMS. 
Keep the default 128-bit for other SPARC targets.

Use the scalar calling convention for 64-bit long double.

Assisted-by: Codex

>From 6d87620fab43b0ab7cf6cc3b46b111316c027010 Mon Sep 17 00:00:00 2001
From: Daniel Cederman <[email protected]>
Date: Wed, 1 Jul 2026 07:42:06 +0200
Subject: [PATCH] [Sparc][clang] Use 64-bit long double on bare-metal targets

GCC uses 64-bit long double for bare-metal SPARC V8 targets,
including RTEMS. Keep the default 128-bit for other SPARC
targets.

Use the scalar calling convention for 64-bit long double.

Assisted-by: Codex
---
 clang/lib/Basic/Targets/Sparc.cpp             |  3 +-
 clang/lib/Basic/Targets/Sparc.h               | 18 +++++++---
 clang/lib/CodeGen/Targets/Sparc.cpp           |  6 ++--
 .../CodeGen/Sparc/sparc-long-double-abi.c     | 17 ++++++++++
 clang/test/CodeGen/Sparc/sparc-vaarg.c        |  2 +-
 clang/test/CodeGen/Sparc/sparcv8-abi.c        |  2 +-
 clang/test/CodeGen/Sparc/variadic-aggregate.c |  2 +-
 clang/test/Preprocessor/init.c                | 33 ++++++++++++-------
 .../Preprocessor/predefined-arch-macros.c     |  9 +++++
 9 files changed, 70 insertions(+), 22 deletions(-)
 create mode 100644 clang/test/CodeGen/Sparc/sparc-long-double-abi.c

diff --git a/clang/lib/Basic/Targets/Sparc.cpp 
b/clang/lib/Basic/Targets/Sparc.cpp
index fe1aad6804aa6..46261d4556998 100644
--- a/clang/lib/Basic/Targets/Sparc.cpp
+++ b/clang/lib/Basic/Targets/Sparc.cpp
@@ -165,7 +165,8 @@ void SparcV8TargetInfo::getTargetDefines(const LangOptions 
&Opts,
     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
   }
-  Builder.defineMacro("__LONG_DOUBLE_128__");
+  if (LongDoubleWidth == 128)
+    Builder.defineMacro("__LONG_DOUBLE_128__");
 }
 
 void SparcV9TargetInfo::getTargetDefines(const LangOptions &Opts,
diff --git a/clang/lib/Basic/Targets/Sparc.h b/clang/lib/Basic/Targets/Sparc.h
index 95b69ff2be4bb..1d0cebaa18496 100644
--- a/clang/lib/Basic/Targets/Sparc.h
+++ b/clang/lib/Basic/Targets/Sparc.h
@@ -167,11 +167,19 @@ class LLVM_LIBRARY_VISIBILITY SparcV8TargetInfo : public 
SparcTargetInfo {
       break;
     }
 
-    // The SPARCv8 System V ABI has long double 128-bits in size, but 64-bit
-    // aligned.
-    LongDoubleWidth = 128;
-    LongDoubleAlign = 64;
-    LongDoubleFormat = &llvm::APFloat::IEEEquad();
+    // Bare-metal and RTEMS targets default to 64-bit long double, matching
+    // GCC. Other targets use 128-bit per the SPARCv8 System V ABI, with
+    // 64-bit alignment.
+    if (getTriple().getOS() == llvm::Triple::UnknownOS ||
+        getTriple().getOS() == llvm::Triple::RTEMS) {
+      LongDoubleWidth = 64;
+      LongDoubleAlign = 64;
+      LongDoubleFormat = &llvm::APFloat::IEEEdouble();
+    } else {
+      LongDoubleWidth = 128;
+      LongDoubleAlign = 64;
+      LongDoubleFormat = &llvm::APFloat::IEEEquad();
+    }
 
     // Up to 32 bits (V8) or 64 bits (V9) are lock-free atomic, but we're
     // willing to do atomic ops on up to 64 bits.
diff --git a/clang/lib/CodeGen/Targets/Sparc.cpp 
b/clang/lib/CodeGen/Targets/Sparc.cpp
index f5a17aa51184a..fd0c18e290655 100644
--- a/clang/lib/CodeGen/Targets/Sparc.cpp
+++ b/clang/lib/CodeGen/Targets/Sparc.cpp
@@ -72,7 +72,8 @@ ABIArgInfo SparcV8ABIInfo::classifyReturnType(QualType Ty) 
const {
     return classifyComplexType(CT, /*IsRet=*/true);
 
   if (const auto *BT = Ty->getAs<BuiltinType>();
-      BT && BT->getKind() == BuiltinType::LongDouble)
+      BT && BT->getKind() == BuiltinType::LongDouble &&
+      getContext().getTypeSize(Ty) > 64)
     return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
                                    /*ByVal=*/false);
 
@@ -84,7 +85,8 @@ ABIArgInfo SparcV8ABIInfo::classifyArgumentType(QualType Ty) 
const {
     return classifyComplexType(CT, /*IsRet=*/false);
 
   const auto *BT = Ty->getAs<BuiltinType>();
-  if (BT && BT->getKind() == BuiltinType::LongDouble)
+  if (BT && BT->getKind() == BuiltinType::LongDouble &&
+      getContext().getTypeSize(Ty) > 64)
     return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace());
 
   return DefaultABIInfo::classifyArgumentType(Ty);
diff --git a/clang/test/CodeGen/Sparc/sparc-long-double-abi.c 
b/clang/test/CodeGen/Sparc/sparc-long-double-abi.c
new file mode 100644
index 0000000000000..e022643e87adc
--- /dev/null
+++ b/clang/test/CodeGen/Sparc/sparc-long-double-abi.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -triple sparc-unknown-none -O1 -emit-llvm -o - %s | 
FileCheck %s
+
+void sink(long double);
+void vararg(int, ...);
+long double source(void);
+
+long double test(long double x) {
+  sink(x);
+  vararg(0, x);
+  return source();
+}
+
+// CHECK-LABEL: define{{.*}} double @test(double noundef %x)
+// CHECK: {{.*}}call void @sink(double noundef %x)
+// CHECK: {{.*}}call void (i32, ...) @vararg(i32 noundef 0, double noundef %x)
+// CHECK: [[RESULT:%.*]] = {{.*}}call double @source()
+// CHECK: ret double [[RESULT]]
diff --git a/clang/test/CodeGen/Sparc/sparc-vaarg.c 
b/clang/test/CodeGen/Sparc/sparc-vaarg.c
index f322229e20c43..bfe1a0209461e 100644
--- a/clang/test/CodeGen/Sparc/sparc-vaarg.c
+++ b/clang/test/CodeGen/Sparc/sparc-vaarg.c
@@ -1,5 +1,5 @@
 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --version 6
-// RUN: %clang_cc1 -triple sparc -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple sparc-unknown-linux -emit-llvm -o - %s | FileCheck 
%s
 #include <stdarg.h>
 
 // CHECK-LABEL: define dso_local i32 @get_int(
diff --git a/clang/test/CodeGen/Sparc/sparcv8-abi.c 
b/clang/test/CodeGen/Sparc/sparcv8-abi.c
index 7beddd20e5e4d..317a5ea1beee5 100644
--- a/clang/test/CodeGen/Sparc/sparcv8-abi.c
+++ b/clang/test/CodeGen/Sparc/sparcv8-abi.c
@@ -1,5 +1,5 @@
 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --filter "^define |^entry:" --version 6
-// RUN: %clang_cc1 -triple sparc-unknown-unknown -emit-llvm %s -o - | 
FileCheck %s
+// RUN: %clang_cc1 -triple sparc-unknown-linux -emit-llvm %s -o - | FileCheck 
%s
 
 float __complex__
 // CHECK-LABEL: define dso_local { float, float } @p(
diff --git a/clang/test/CodeGen/Sparc/variadic-aggregate.c 
b/clang/test/CodeGen/Sparc/variadic-aggregate.c
index be571ecb5fadd..d451056ef434a 100644
--- a/clang/test/CodeGen/Sparc/variadic-aggregate.c
+++ b/clang/test/CodeGen/Sparc/variadic-aggregate.c
@@ -1,5 +1,5 @@
 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --version 6
-// RUN: %clang_cc1 -triple sparc -emit-llvm -o - %s \
+// RUN: %clang_cc1 -triple sparc-unknown-linux -emit-llvm -o - %s \
 // RUN:   | FileCheck %s --check-prefixes=SPARC
 //
 // RUN: %clang_cc1 -triple sparcv9-unknown-unknown -emit-llvm -o - %s \
diff --git a/clang/test/Preprocessor/init.c b/clang/test/Preprocessor/init.c
index 21d61de8c0aaf..56c782aeb1397 100644
--- a/clang/test/Preprocessor/init.c
+++ b/clang/test/Preprocessor/init.c
@@ -1122,19 +1122,29 @@
 // SPARC:#define __INT_LEAST8_MAX__ 127
 // SPARC:#define __INT_LEAST8_TYPE__ signed char
 // SPARC:#define __INT_MAX__ 2147483647
-// SPARC:#define __LDBL_DENORM_MIN__ 
6.47517511943802511092443895822764655e-4966L
-// SPARC:#define __LDBL_DIG__ 33
-// SPARC:#define __LDBL_EPSILON__ 1.92592994438723585305597794258492732e-34L
+// SPARC-DEFAULT:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324L
+// SPARC-NETOPENBSD:#define __LDBL_DENORM_MIN__ 
6.47517511943802511092443895822764655e-4966L
+// SPARC-DEFAULT:#define __LDBL_DIG__ 15
+// SPARC-NETOPENBSD:#define __LDBL_DIG__ 33
+// SPARC-DEFAULT:#define __LDBL_EPSILON__ 2.2204460492503131e-16L
+// SPARC-NETOPENBSD:#define __LDBL_EPSILON__ 
1.92592994438723585305597794258492732e-34L
 // SPARC:#define __LDBL_HAS_DENORM__ 1
 // SPARC:#define __LDBL_HAS_INFINITY__ 1
 // SPARC:#define __LDBL_HAS_QUIET_NAN__ 1
-// SPARC:#define __LDBL_MANT_DIG__ 113
-// SPARC:#define __LDBL_MAX_10_EXP__ 4932
-// SPARC:#define __LDBL_MAX_EXP__ 16384
-// SPARC:#define __LDBL_MAX__ 1.18973149535723176508575932662800702e+4932L
-// SPARC:#define __LDBL_MIN_10_EXP__ (-4931)
-// SPARC:#define __LDBL_MIN_EXP__ (-16381)
-// SPARC:#define __LDBL_MIN__ 3.36210314311209350626267781732175260e-4932L
+// SPARC-DEFAULT:#define __LDBL_MANT_DIG__ 53
+// SPARC-NETOPENBSD:#define __LDBL_MANT_DIG__ 113
+// SPARC-DEFAULT:#define __LDBL_MAX_10_EXP__ 308
+// SPARC-NETOPENBSD:#define __LDBL_MAX_10_EXP__ 4932
+// SPARC-DEFAULT:#define __LDBL_MAX_EXP__ 1024
+// SPARC-NETOPENBSD:#define __LDBL_MAX_EXP__ 16384
+// SPARC-DEFAULT:#define __LDBL_MAX__ 1.7976931348623157e+308L
+// SPARC-NETOPENBSD:#define __LDBL_MAX__ 
1.18973149535723176508575932662800702e+4932L
+// SPARC-DEFAULT:#define __LDBL_MIN_10_EXP__ (-307)
+// SPARC-NETOPENBSD:#define __LDBL_MIN_10_EXP__ (-4931)
+// SPARC-DEFAULT:#define __LDBL_MIN_EXP__ (-1021)
+// SPARC-NETOPENBSD:#define __LDBL_MIN_EXP__ (-16381)
+// SPARC-DEFAULT:#define __LDBL_MIN__ 2.2250738585072014e-308L
+// SPARC-NETOPENBSD:#define __LDBL_MIN__ 
3.36210314311209350626267781732175260e-4932L
 // SPARC:#define __LONG_LONG_MAX__ 9223372036854775807LL
 // SPARC:#define __LONG_MAX__ 2147483647L
 // SPARC-NOT:#define __LP64__
@@ -1150,7 +1160,8 @@
 // SPARC:#define __SIZEOF_DOUBLE__ 8
 // SPARC:#define __SIZEOF_FLOAT__ 4
 // SPARC:#define __SIZEOF_INT__ 4
-// SPARC:#define __SIZEOF_LONG_DOUBLE__ 16
+// SPARC-DEFAULT:#define __SIZEOF_LONG_DOUBLE__ 8
+// SPARC-NETOPENBSD:#define __SIZEOF_LONG_DOUBLE__ 16
 // SPARC:#define __SIZEOF_LONG_LONG__ 8
 // SPARC:#define __SIZEOF_LONG__ 4
 // SPARC:#define __SIZEOF_POINTER__ 4
diff --git a/clang/test/Preprocessor/predefined-arch-macros.c 
b/clang/test/Preprocessor/predefined-arch-macros.c
index 01a132d84daba..1eb28de306421 100644
--- a/clang/test/Preprocessor/predefined-arch-macros.c
+++ b/clang/test/Preprocessor/predefined-arch-macros.c
@@ -4792,6 +4792,15 @@
 // RUN:   | FileCheck -match-full-lines %s -check-prefix=CHECK_SPARC_LDBL
 // CHECK_SPARC_LDBL: #define __LONG_DOUBLE_128__ 1
 
+// RUN: %clang -E -dM %s -o - 2>&1 \
+// RUN:     -target sparc-unknown-none \
+// RUN:   | FileCheck -match-full-lines %s -check-prefix=CHECK_SPARC_LDBL64
+// RUN: %clang -E -dM %s -o - 2>&1 \
+// RUN:     -target sparc-unknown-rtems \
+// RUN:   | FileCheck -match-full-lines %s -check-prefix=CHECK_SPARC_LDBL64
+// CHECK_SPARC_LDBL64-NOT: #define __LONG_DOUBLE_128__ 1
+// CHECK_SPARC_LDBL64: #define __SIZEOF_LONG_DOUBLE__ 8
+
 // RUN: %clang -mcpu=v9 -E -dM %s -o - 2>&1 \
 // RUN:     -target sparc-unknown-linux \
 // RUN:   | FileCheck -match-full-lines %s -check-prefix=CHECK_SPARC-V9

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

Reply via email to