[clang] [Sparc][clang] Use 64-bit long double on bare-metal targets (PR #222304)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Sep 9 04:44:56 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-codegen
Author: Daniel Cederman (doac)
<details>
<summary>Changes</summary>
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
---
Full diff: https://github.com/llvm/llvm-project/pull/222304.diff
9 Files Affected:
- (modified) clang/lib/Basic/Targets/Sparc.cpp (+2-1)
- (modified) clang/lib/Basic/Targets/Sparc.h (+13-5)
- (modified) clang/lib/CodeGen/Targets/Sparc.cpp (+4-2)
- (added) clang/test/CodeGen/Sparc/sparc-long-double-abi.c (+17)
- (modified) clang/test/CodeGen/Sparc/sparc-vaarg.c (+1-1)
- (modified) clang/test/CodeGen/Sparc/sparcv8-abi.c (+1-1)
- (modified) clang/test/CodeGen/Sparc/variadic-aggregate.c (+1-1)
- (modified) clang/test/Preprocessor/init.c (+22-11)
- (modified) clang/test/Preprocessor/predefined-arch-macros.c (+9)
``````````diff
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
``````````
</details>
https://github.com/llvm/llvm-project/pull/222304
More information about the cfe-commits
mailing list