Skip to content

Commit b5b66d5

Browse files
koachanaahrun
authored andcommitted
[SPARC] Properly handle CC for long double on sparc32 (llvm#162226)
Pass and return `long double`s indirectly, as specified in the psABI. This continues the patch at https://reviews.llvm.org/D89130. This should fix the issue at llvm#41838.
1 parent 92a5a2e commit b5b66d5

File tree

17 files changed

+402
-214
lines changed

17 files changed

+402
-214
lines changed

clang/lib/Basic/Targets/Sparc.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ void SparcV8TargetInfo::getTargetDefines(const LangOptions &Opts,
165165
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
166166
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
167167
}
168+
Builder.defineMacro("__LONG_DOUBLE_128__");
168169
}
169170

170171
void SparcV9TargetInfo::getTargetDefines(const LangOptions &Opts,

clang/lib/Basic/Targets/Sparc.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,13 @@ class LLVM_LIBRARY_VISIBILITY SparcV8TargetInfo : public SparcTargetInfo {
166166
PtrDiffType = SignedLong;
167167
break;
168168
}
169+
170+
// The SPARCv8 System V ABI has long double 128-bits in size, but 64-bit
171+
// aligned.
172+
LongDoubleWidth = 128;
173+
LongDoubleAlign = 64;
174+
LongDoubleFormat = &llvm::APFloat::IEEEquad();
175+
169176
// Up to 32 bits (V8) or 64 bits (V9) are lock-free atomic, but we're
170177
// willing to do atomic ops on up to 64 bits.
171178
MaxAtomicPromoteWidth = 64;

clang/lib/CodeGen/Targets/Sparc.cpp

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,23 +26,39 @@ class SparcV8ABIInfo : public DefaultABIInfo {
2626

2727
private:
2828
ABIArgInfo classifyReturnType(QualType RetTy) const;
29+
ABIArgInfo classifyArgumentType(QualType Ty) const;
2930
void computeInfo(CGFunctionInfo &FI) const override;
3031
};
3132
} // end anonymous namespace
3233

34+
ABIArgInfo SparcV8ABIInfo::classifyReturnType(QualType Ty) const {
35+
const auto *CT = Ty->getAs<ComplexType>();
36+
const auto *BT = Ty->getAs<BuiltinType>();
37+
if (CT)
38+
BT = CT->getElementType()->getAs<BuiltinType>();
39+
bool IsLongDouble = BT && BT->getKind() == BuiltinType::LongDouble;
3340

34-
ABIArgInfo
35-
SparcV8ABIInfo::classifyReturnType(QualType Ty) const {
36-
if (Ty->isAnyComplexType()) {
37-
return ABIArgInfo::getDirect();
38-
}
39-
else {
40-
return DefaultABIInfo::classifyReturnType(Ty);
41-
}
41+
// long double _Complex is special in that it should be marked as inreg.
42+
if (CT)
43+
return IsLongDouble ? ABIArgInfo::getDirectInReg()
44+
: ABIArgInfo::getDirect();
45+
46+
if (IsLongDouble)
47+
return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
48+
/*ByVal=*/false);
49+
50+
return DefaultABIInfo::classifyReturnType(Ty);
4251
}
4352

44-
void SparcV8ABIInfo::computeInfo(CGFunctionInfo &FI) const {
53+
ABIArgInfo SparcV8ABIInfo::classifyArgumentType(QualType Ty) const {
54+
if (const auto *BT = Ty->getAs<BuiltinType>();
55+
BT && BT->getKind() == BuiltinType::LongDouble)
56+
return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace());
4557

58+
return DefaultABIInfo::classifyArgumentType(Ty);
59+
}
60+
61+
void SparcV8ABIInfo::computeInfo(CGFunctionInfo &FI) const {
4662
FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
4763
for (auto &Arg : FI.arguments())
4864
Arg.info = classifyArgumentType(Arg.type);
Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,52 @@
1+
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --filter "^define |^entry:" --version 6
12
// RUN: %clang_cc1 -triple sparc-unknown-unknown -emit-llvm %s -o - | FileCheck %s
23

3-
// CHECK-LABEL: define{{.*}} { float, float } @p(ptr noundef byval({ float, float }) align 4 %a, ptr noundef byval({ float, float }) align 4 %b) #0 {
44
float __complex__
5+
// CHECK-LABEL: define dso_local { float, float } @p(
6+
// CHECK-SAME: ptr noundef byval({ float, float }) align 4 [[A:%.*]], ptr noundef byval({ float, float }) align 4 [[B:%.*]]) #[[ATTR0:[0-9]+]] {
7+
// CHECK: [[ENTRY:.*:]]
8+
//
59
p (float __complex__ a, float __complex__ b)
610
{
711
return 0;
812
}
913

10-
// CHECK-LABEL: define{{.*}} { double, double } @q(ptr noundef byval({ double, double }) align 8 %a, ptr noundef byval({ double, double }) align 8 %b) #0 {
1114
double __complex__
15+
// CHECK-LABEL: define dso_local { double, double } @q(
16+
// CHECK-SAME: ptr noundef byval({ double, double }) align 8 [[A:%.*]], ptr noundef byval({ double, double }) align 8 [[B:%.*]]) #[[ATTR0]] {
17+
// CHECK: [[ENTRY:.*:]]
18+
//
1219
q (double __complex__ a, double __complex__ b)
1320
{
1421
return 0;
1522
}
1623

17-
// CHECK-LABEL: define{{.*}} { i64, i64 } @r(ptr noundef byval({ i64, i64 }) align 8 %a, ptr noundef byval({ i64, i64 }) align 8 %b) #0 {
1824
long long __complex__
25+
// CHECK-LABEL: define dso_local { i64, i64 } @r(
26+
// CHECK-SAME: ptr noundef byval({ i64, i64 }) align 8 [[A:%.*]], ptr noundef byval({ i64, i64 }) align 8 [[B:%.*]]) #[[ATTR0]] {
27+
// CHECK: [[ENTRY:.*:]]
28+
//
1929
r (long long __complex__ a, long long __complex__ b)
2030
{
2131
return 0;
2232
}
33+
34+
long double
35+
// CHECK-LABEL: define dso_local void @s(
36+
// CHECK-SAME: ptr dead_on_unwind noalias writable sret(fp128) align 8 [[AGG_RESULT:%.*]], ptr noundef byval(fp128) align 8 [[TMP0:%.*]]) #[[ATTR0]] {
37+
// CHECK: [[ENTRY:.*:]]
38+
//
39+
s(long double a)
40+
{
41+
return 0;
42+
}
43+
44+
long double _Complex
45+
// CHECK-LABEL: define dso_local inreg { fp128, fp128 } @t(
46+
// CHECK-SAME: ptr noundef byval({ fp128, fp128 }) align 8 [[A:%.*]]) #[[ATTR0]] {
47+
// CHECK: [[ENTRY:.*:]]
48+
//
49+
t(long double _Complex a)
50+
{
51+
return 0;
52+
}

clang/test/Preprocessor/init.c

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1106,19 +1106,19 @@
11061106
// SPARC:#define __INT_LEAST8_MAX__ 127
11071107
// SPARC:#define __INT_LEAST8_TYPE__ signed char
11081108
// SPARC:#define __INT_MAX__ 2147483647
1109-
// SPARC:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324L
1110-
// SPARC:#define __LDBL_DIG__ 15
1111-
// SPARC:#define __LDBL_EPSILON__ 2.2204460492503131e-16L
1109+
// SPARC:#define __LDBL_DENORM_MIN__ 6.47517511943802511092443895822764655e-4966L
1110+
// SPARC:#define __LDBL_DIG__ 33
1111+
// SPARC:#define __LDBL_EPSILON__ 1.92592994438723585305597794258492732e-34L
11121112
// SPARC:#define __LDBL_HAS_DENORM__ 1
11131113
// SPARC:#define __LDBL_HAS_INFINITY__ 1
11141114
// SPARC:#define __LDBL_HAS_QUIET_NAN__ 1
1115-
// SPARC:#define __LDBL_MANT_DIG__ 53
1116-
// SPARC:#define __LDBL_MAX_10_EXP__ 308
1117-
// SPARC:#define __LDBL_MAX_EXP__ 1024
1118-
// SPARC:#define __LDBL_MAX__ 1.7976931348623157e+308L
1119-
// SPARC:#define __LDBL_MIN_10_EXP__ (-307)
1120-
// SPARC:#define __LDBL_MIN_EXP__ (-1021)
1121-
// SPARC:#define __LDBL_MIN__ 2.2250738585072014e-308L
1115+
// SPARC:#define __LDBL_MANT_DIG__ 113
1116+
// SPARC:#define __LDBL_MAX_10_EXP__ 4932
1117+
// SPARC:#define __LDBL_MAX_EXP__ 16384
1118+
// SPARC:#define __LDBL_MAX__ 1.18973149535723176508575932662800702e+4932L
1119+
// SPARC:#define __LDBL_MIN_10_EXP__ (-4931)
1120+
// SPARC:#define __LDBL_MIN_EXP__ (-16381)
1121+
// SPARC:#define __LDBL_MIN__ 3.36210314311209350626267781732175260e-4932L
11221122
// SPARC:#define __LONG_LONG_MAX__ 9223372036854775807LL
11231123
// SPARC:#define __LONG_MAX__ 2147483647L
11241124
// SPARC-NOT:#define __LP64__
@@ -1134,7 +1134,7 @@
11341134
// SPARC:#define __SIZEOF_DOUBLE__ 8
11351135
// SPARC:#define __SIZEOF_FLOAT__ 4
11361136
// SPARC:#define __SIZEOF_INT__ 4
1137-
// SPARC:#define __SIZEOF_LONG_DOUBLE__ 8
1137+
// SPARC:#define __SIZEOF_LONG_DOUBLE__ 16
11381138
// SPARC:#define __SIZEOF_LONG_LONG__ 8
11391139
// SPARC:#define __SIZEOF_LONG__ 4
11401140
// SPARC:#define __SIZEOF_POINTER__ 4

clang/test/Preprocessor/predefined-arch-macros.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4210,6 +4210,11 @@
42104210
// CHECK_SPARC-NOT: #define __sparcv9 1
42114211
// CHECK_SPARC-NOT: #define __sparcv9__ 1
42124212

4213+
// RUN: %clang -E -dM %s -o - 2>&1 \
4214+
// RUN: -target sparc-unknown-linux \
4215+
// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_SPARC_LDBL
4216+
// CHECK_SPARC_LDBL: #define __LONG_DOUBLE_128__ 1
4217+
42134218
// RUN: %clang -mcpu=v9 -E -dM %s -o - 2>&1 \
42144219
// RUN: -target sparc-unknown-linux \
42154220
// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_SPARC-V9

compiler-rt/lib/builtins/CMakeLists.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,9 +1011,10 @@ else ()
10111011
list(APPEND BUILTIN_CFLAGS_${arch} -fomit-frame-pointer -DCOMPILER_RT_ARMHF_TARGET)
10121012
endif()
10131013

1014-
# For RISCV32, we must force enable int128 for compiling long
1014+
# For RISCV32 and 32-bit SPARC, we must force enable int128 for compiling long
10151015
# double routines.
1016-
if(COMPILER_RT_ENABLE_SOFTWARE_INT128 OR "${arch}" STREQUAL "riscv32")
1016+
if (COMPILER_RT_ENABLE_SOFTWARE_INT128 OR ("${arch}" MATCHES "riscv32|sparc$"
1017+
AND NOT CMAKE_COMPILER_IS_GNUCC))
10171018
list(APPEND BUILTIN_CFLAGS_${arch} -fforce-enable-int128)
10181019
endif()
10191020

compiler-rt/test/builtins/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ foreach(arch ${BUILTIN_TEST_ARCH})
4848
string(REPLACE ";" " " BUILTINS_TEST_TARGET_CFLAGS "${BUILTINS_TEST_TARGET_CFLAGS}")
4949
endif()
5050

51-
if (COMPILER_RT_ENABLE_SOFTWARE_INT128 OR ${arch} STREQUAL "riscv32")
51+
if (COMPILER_RT_ENABLE_SOFTWARE_INT128 OR ("${arch}" MATCHES "riscv32|sparc$"
52+
AND NOT CMAKE_COMPILER_IS_GNUCC))
5253
list(APPEND BUILTINS_TEST_TARGET_CFLAGS -fforce-enable-int128)
5354
string(REPLACE ";" " " BUILTINS_TEST_TARGET_CFLAGS "${BUILTINS_TEST_TARGET_CFLAGS}")
5455
endif()

compiler-rt/test/sanitizer_common/TestCases/printf-ldbl.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
// RUN: %clang %s -o %t && %run %t 2>&1
22

3-
// Issue #41838
4-
// XFAIL: sparc-target-arch && target={{.*solaris.*}}
5-
63
#include <assert.h>
74
#include <stdio.h>
85
#include <string.h>

compiler-rt/test/sanitizer_common/TestCases/scanf-ldbl.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
// RUN: %clang %s -o %t && %run %t 2>&1
22

3-
// Issue #41838
4-
// XFAIL: sparc-target-arch && target={{.*solaris.*}}
5-
63
#include <assert.h>
74
#include <stdio.h>
85
#include <string.h>

0 commit comments

Comments
 (0)