Skip to content

Commit 99cd218

Browse files
committed
[WIP][SPARC] Properly handle CC for long double on sparc32
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 #41838.
1 parent e61b6f6 commit 99cd218

File tree

6 files changed

+48
-18
lines changed

6 files changed

+48
-18
lines changed

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: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,19 +26,41 @@ 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

3334

3435
ABIArgInfo
3536
SparcV8ABIInfo::classifyReturnType(QualType Ty) const {
37+
if (Ty->isRealFloatingType() && getContext().getTypeSize(Ty) == 128)
38+
return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace());
39+
3640
if (Ty->isAnyComplexType()) {
37-
return ABIArgInfo::getDirect();
38-
}
39-
else {
40-
return DefaultABIInfo::classifyReturnType(Ty);
41+
auto AI = ABIArgInfo::getDirect();
42+
AI.setInReg(true);
43+
return AI;
4144
}
45+
46+
return DefaultABIInfo::classifyReturnType(Ty);
47+
}
48+
49+
ABIArgInfo SparcV8ABIInfo::classifyArgumentType(QualType Ty) const {
50+
const BuiltinType *BT = Ty->getAs<BuiltinType>();
51+
bool IsF128 = false;
52+
53+
if (Ty->isRealFloatingType() && getContext().getTypeSize(Ty) == 128)
54+
IsF128 = true;
55+
56+
// FIXME not sure if redundant
57+
if (BT && BT->getKind() == BuiltinType::LongDouble)
58+
IsF128 = true;
59+
60+
if (IsF128)
61+
return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace());
62+
63+
return DefaultABIInfo::classifyArgumentType(Ty);
4264
}
4365

4466
void SparcV8ABIInfo::computeInfo(CGFunctionInfo &FI) const {

compiler-rt/lib/builtins/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -960,9 +960,9 @@ else ()
960960
list(APPEND BUILTIN_CFLAGS_${arch} -fomit-frame-pointer -DCOMPILER_RT_ARMHF_TARGET)
961961
endif()
962962

963-
# For RISCV32, we must force enable int128 for compiling long
963+
# For RISCV32 and 32-bit SPARC, we must force enable int128 for compiling long
964964
# double routines.
965-
if(COMPILER_RT_ENABLE_SOFTWARE_INT128 OR "${arch}" STREQUAL "riscv32")
965+
if(COMPILER_RT_ENABLE_SOFTWARE_INT128 OR "${arch}" MATCHES "riscv32|sparc$" AND NOT CMAKE_COMPILER_IS_GNUCC)
966966
list(APPEND BUILTIN_CFLAGS_${arch} -fforce-enable-int128)
967967
endif()
968968

compiler-rt/test/builtins/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ foreach(arch ${BUILTIN_TEST_ARCH})
4444
string(REPLACE ";" " " BUILTINS_TEST_TARGET_CFLAGS "${BUILTINS_TEST_TARGET_CFLAGS}")
4545
endif()
4646

47-
if (COMPILER_RT_ENABLE_SOFTWARE_INT128 OR ${arch} STREQUAL "riscv32")
47+
if (COMPILER_RT_ENABLE_SOFTWARE_INT128 OR "${arch}" MATCHES "riscv32|sparc$" AND NOT CMAKE_COMPILER_IS_GNUCC)
4848
list(APPEND BUILTINS_TEST_TARGET_CFLAGS -fforce-enable-int128)
4949
string(REPLACE ";" " " BUILTINS_TEST_TARGET_CFLAGS "${BUILTINS_TEST_TARGET_CFLAGS}")
5050
endif()

llvm/lib/Target/Sparc/SparcCallingConv.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ def CC_Sparc32 : CallingConv<[
2424
// As are v2i32 arguments (this would be the default behavior for
2525
// v2i32 if it wasn't allocated to the IntPair register-class)
2626
CCIfType<[v2i32], CCCustom<"CC_Sparc_Assign_Split_64">>,
27-
28-
27+
// f128 arguments are passed indirectly.
28+
CCIfType<[f128], CCPassIndirect<i32>>,
2929
// Alternatively, they are assigned to the stack in 4-byte aligned units.
3030
CCAssignToStack<4, 4>
3131
]>;

llvm/lib/Target/Sparc/SparcISelLowering.cpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -554,20 +554,19 @@ SDValue SparcTargetLowering::LowerFormalArguments_32(
554554
continue;
555555
}
556556

557-
int FI = MF.getFrameInfo().CreateFixedObject(4,
558-
Offset,
559-
true);
560-
SDValue FIPtr = DAG.getFrameIndex(FI, PtrVT);
561-
SDValue Load ;
557+
int FI;
562558
if (VA.getValVT() == MVT::i32 || VA.getValVT() == MVT::f32) {
563-
Load = DAG.getLoad(VA.getValVT(), dl, Chain, FIPtr, MachinePointerInfo());
559+
FI = MF.getFrameInfo().CreateFixedObject(4, Offset, true);
564560
} else if (VA.getValVT() == MVT::f128) {
565-
report_fatal_error("SPARCv8 does not handle f128 in calls; "
566-
"pass indirectly");
561+
FI = MF.getFrameInfo().CreateFixedObject(16, Offset, false);
567562
} else {
568563
// We shouldn't see any other value types here.
569564
llvm_unreachable("Unexpected ValVT encountered in frame lowering.");
570565
}
566+
567+
SDValue FIPtr = DAG.getFrameIndex(FI, PtrVT);
568+
SDValue Load =
569+
DAG.getLoad(VA.getValVT(), dl, Chain, FIPtr, MachinePointerInfo());
571570
InVals.push_back(Load);
572571
}
573572

@@ -913,7 +912,9 @@ SparcTargetLowering::LowerCall_32(TargetLowering::CallLoweringInfo &CLI,
913912
// Promote the value if needed.
914913
switch (VA.getLocInfo()) {
915914
default: llvm_unreachable("Unknown loc info!");
916-
case CCValAssign::Full: break;
915+
case CCValAssign::Full:
916+
case CCValAssign::Indirect:
917+
break;
917918
case CCValAssign::SExt:
918919
Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg);
919920
break;

0 commit comments

Comments
 (0)