Skip to content

Commit 9b732fe

Browse files
committed
Revert "[RISCV] Hard float ABI support" r366450
The commit was missing a few hunks. Will fix and recommit. llvm-svn: 366454
1 parent abc744d commit 9b732fe

13 files changed

+21
-1462
lines changed

clang/lib/Basic/Targets/RISCV.cpp

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -65,18 +65,9 @@ void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts,
6565
Builder.defineMacro("__riscv");
6666
bool Is64Bit = getTriple().getArch() == llvm::Triple::riscv64;
6767
Builder.defineMacro("__riscv_xlen", Is64Bit ? "64" : "32");
68-
// TODO: modify when more code models are supported.
68+
// TODO: modify when more code models and ABIs are supported.
6969
Builder.defineMacro("__riscv_cmodel_medlow");
70-
71-
StringRef ABIName = getABI();
72-
if (ABIName == "ilp32f" || ABIName == "lp64f")
73-
Builder.defineMacro("__riscv_float_abi_single");
74-
else if (ABIName == "ilp32d" || ABIName == "lp64d")
75-
Builder.defineMacro("__riscv_float_abi_double");
76-
else if (ABIName == "ilp32e")
77-
Builder.defineMacro("__riscv_abi_rve");
78-
else
79-
Builder.defineMacro("__riscv_float_abi_soft");
70+
Builder.defineMacro("__riscv_float_abi_soft");
8071

8172
if (HasM) {
8273
Builder.defineMacro("__riscv_mul");

clang/lib/Basic/Targets/RISCV.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ class LLVM_LIBRARY_VISIBILITY RISCV32TargetInfo : public RISCVTargetInfo {
8787
}
8888

8989
bool setABI(const std::string &Name) override {
90-
if (Name == "ilp32" || Name == "ilp32f" || Name == "ilp32d") {
90+
// TODO: support ilp32f and ilp32d ABIs.
91+
if (Name == "ilp32") {
9192
ABI = Name;
9293
return true;
9394
}
@@ -104,7 +105,8 @@ class LLVM_LIBRARY_VISIBILITY RISCV64TargetInfo : public RISCVTargetInfo {
104105
}
105106

106107
bool setABI(const std::string &Name) override {
107-
if (Name == "lp64" || Name == "lp64f" || Name == "lp64d") {
108+
// TODO: support lp64f and lp64d ABIs.
109+
if (Name == "lp64") {
108110
ABI = Name;
109111
return true;
110112
}

clang/lib/CodeGen/TargetInfo.cpp

Lines changed: 13 additions & 272 deletions
Original file line numberDiff line numberDiff line change
@@ -9188,44 +9188,25 @@ static bool getTypeString(SmallStringEnc &Enc, const Decl *D,
91889188
namespace {
91899189
class RISCVABIInfo : public DefaultABIInfo {
91909190
private:
9191-
// Size of the integer ('x') registers in bits.
9192-
unsigned XLen;
9193-
// Size of the floating point ('f') registers in bits. Note that the target
9194-
// ISA might have a wider FLen than the selected ABI (e.g. an RV32IF target
9195-
// with soft float ABI has FLen==0).
9196-
unsigned FLen;
9191+
unsigned XLen; // Size of the integer ('x') registers in bits.
91979192
static const int NumArgGPRs = 8;
9198-
static const int NumArgFPRs = 8;
9199-
bool detectFPCCEligibleStructHelper(QualType Ty, CharUnits CurOff,
9200-
llvm::Type *&Field1Ty,
9201-
CharUnits &Field1Off,
9202-
llvm::Type *&Field2Ty,
9203-
CharUnits &Field2Off) const;
92049193

92059194
public:
9206-
RISCVABIInfo(CodeGen::CodeGenTypes &CGT, unsigned XLen, unsigned FLen)
9207-
: DefaultABIInfo(CGT), XLen(XLen), FLen(FLen) {}
9195+
RISCVABIInfo(CodeGen::CodeGenTypes &CGT, unsigned XLen)
9196+
: DefaultABIInfo(CGT), XLen(XLen) {}
92089197

92099198
// DefaultABIInfo's classifyReturnType and classifyArgumentType are
92109199
// non-virtual, but computeInfo is virtual, so we overload it.
92119200
void computeInfo(CGFunctionInfo &FI) const override;
92129201

9213-
ABIArgInfo classifyArgumentType(QualType Ty, bool IsFixed, int &ArgGPRsLeft,
9214-
int &ArgFPRsLeft) const;
9202+
ABIArgInfo classifyArgumentType(QualType Ty, bool IsFixed,
9203+
int &ArgGPRsLeft) const;
92159204
ABIArgInfo classifyReturnType(QualType RetTy) const;
92169205

92179206
Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
92189207
QualType Ty) const override;
92199208

92209209
ABIArgInfo extendType(QualType Ty) const;
9221-
9222-
bool detectFPCCEligibleStruct(QualType Ty, llvm::Type *&Field1Ty, CharUnits &Field1Off,
9223-
llvm::Type *&Field2Ty, CharUnits &Field2Off,
9224-
int &NeededArgGPRs, int &NeededArgFPRs) const;
9225-
ABIArgInfo coerceAndExpandFPCCEligibleStruct(llvm::Type *Field1Ty,
9226-
CharUnits Field1Off,
9227-
llvm::Type *Field2Ty,
9228-
CharUnits Field2Off) const;
92299210
};
92309211
} // end anonymous namespace
92319212

@@ -9247,214 +9228,18 @@ void RISCVABIInfo::computeInfo(CGFunctionInfo &FI) const {
92479228
// different for variadic arguments, we must also track whether we are
92489229
// examining a vararg or not.
92499230
int ArgGPRsLeft = IsRetIndirect ? NumArgGPRs - 1 : NumArgGPRs;
9250-
int ArgFPRsLeft = FLen ? NumArgFPRs : 0;
92519231
int NumFixedArgs = FI.getNumRequiredArgs();
92529232

92539233
int ArgNum = 0;
92549234
for (auto &ArgInfo : FI.arguments()) {
92559235
bool IsFixed = ArgNum < NumFixedArgs;
9256-
ArgInfo.info =
9257-
classifyArgumentType(ArgInfo.type, IsFixed, ArgGPRsLeft, ArgFPRsLeft);
9236+
ArgInfo.info = classifyArgumentType(ArgInfo.type, IsFixed, ArgGPRsLeft);
92589237
ArgNum++;
92599238
}
92609239
}
92619240

9262-
// Returns true if the struct is a potential candidate for the floating point
9263-
// calling convention. If this function returns true, the caller is
9264-
// responsible for checking that if there is only a single field then that
9265-
// field is a float.
9266-
bool RISCVABIInfo::detectFPCCEligibleStructHelper(QualType Ty, CharUnits CurOff,
9267-
llvm::Type *&Field1Ty,
9268-
CharUnits &Field1Off,
9269-
llvm::Type *&Field2Ty,
9270-
CharUnits &Field2Off) const {
9271-
bool IsInt = Ty->isIntegralOrEnumerationType();
9272-
bool IsFloat = Ty->isRealFloatingType();
9273-
9274-
if (IsInt || IsFloat) {
9275-
uint64_t Size = getContext().getTypeSize(Ty);
9276-
if (IsInt && Size > XLen)
9277-
return false;
9278-
// Can't be eligible if larger than the FP registers. Half precision isn't
9279-
// currently supported on RISC-V and the ABI hasn't been confirmed, so
9280-
// default to the integer ABI in that case.
9281-
if (IsFloat && (Size > FLen || Size < 32))
9282-
return false;
9283-
// Can't be eligible if an integer type was already found (int+int pairs
9284-
// are not eligible).
9285-
if (IsInt && Field1Ty && Field1Ty->isIntegerTy())
9286-
return false;
9287-
if (!Field1Ty) {
9288-
Field1Ty = CGT.ConvertType(Ty);
9289-
Field1Off = CurOff;
9290-
return true;
9291-
}
9292-
if (!Field2Ty) {
9293-
Field2Ty = CGT.ConvertType(Ty);
9294-
Field2Off = CurOff;
9295-
return true;
9296-
}
9297-
return false;
9298-
}
9299-
9300-
if (auto CTy = Ty->getAs<ComplexType>()) {
9301-
if (Field1Ty)
9302-
return false;
9303-
QualType EltTy = CTy->getElementType();
9304-
if (getContext().getTypeSize(EltTy) > FLen)
9305-
return false;
9306-
Field1Ty = CGT.ConvertType(EltTy);
9307-
Field1Off = CurOff;
9308-
assert(CurOff.isZero() && "Unexpected offset for first field");
9309-
Field2Ty = Field1Ty;
9310-
Field2Off = Field1Off + getContext().getTypeSizeInChars(EltTy);
9311-
return true;
9312-
}
9313-
9314-
if (const ConstantArrayType *ATy = getContext().getAsConstantArrayType(Ty)) {
9315-
uint64_t ArraySize = ATy->getSize().getZExtValue();
9316-
QualType EltTy = ATy->getElementType();
9317-
CharUnits EltSize = getContext().getTypeSizeInChars(EltTy);
9318-
for (uint64_t i = 0; i < ArraySize; ++i) {
9319-
bool Ret = detectFPCCEligibleStructHelper(EltTy, CurOff, Field1Ty, Field1Off,
9320-
Field2Ty, Field2Off);
9321-
if (!Ret)
9322-
return false;
9323-
CurOff += EltSize;
9324-
}
9325-
return true;
9326-
}
9327-
9328-
if (const auto *RTy = Ty->getAs<RecordType>()) {
9329-
// Structures with either a non-trivial destructor or a non-trivial
9330-
// copy constructor are not eligible for the FP calling convention.
9331-
if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, CGT.getCXXABI()))
9332-
return false;
9333-
if (isEmptyRecord(getContext(), Ty, true))
9334-
return true;
9335-
const RecordDecl *RD = RTy->getDecl();
9336-
// Unions aren't eligible unless they're empty (which is caught above).
9337-
if (RD->isUnion())
9338-
return false;
9339-
int ZeroWidthBitFieldCount = 0;
9340-
for (const FieldDecl *FD : RD->fields()) {
9341-
const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
9342-
uint64_t FieldOffInBits = Layout.getFieldOffset(FD->getFieldIndex());
9343-
QualType QTy = FD->getType();
9344-
if (FD->isBitField()) {
9345-
unsigned BitWidth = FD->getBitWidthValue(getContext());
9346-
// Allow a bitfield with a type greater than XLen as long as the
9347-
// bitwidth is XLen or less.
9348-
if (getContext().getTypeSize(QTy) > XLen && BitWidth <= XLen)
9349-
QTy = getContext().getIntTypeForBitwidth(XLen, false);
9350-
if (BitWidth == 0) {
9351-
ZeroWidthBitFieldCount++;
9352-
continue;
9353-
}
9354-
}
9355-
9356-
bool Ret = detectFPCCEligibleStructHelper(
9357-
QTy, CurOff + getContext().toCharUnitsFromBits(FieldOffInBits),
9358-
Field1Ty, Field1Off, Field2Ty, Field2Off);
9359-
if (!Ret)
9360-
return false;
9361-
9362-
// As a quirk of the ABI, zero-width bitfields aren't ignored for fp+fp
9363-
// or int+fp structs, but are ignored for a struct with an fp field and
9364-
// any number of zero-width bitfields.
9365-
if (Field2Ty && ZeroWidthBitFieldCount > 0)
9366-
return false;
9367-
}
9368-
return Field1Ty != nullptr;
9369-
}
9370-
9371-
return false;
9372-
}
9373-
9374-
// Determine if a struct is eligible for passing according to the floating
9375-
// point calling convention (i.e., when flattened it contains a single fp
9376-
// value, fp+fp, or int+fp of appropriate size). If so, NeededArgFPRs and
9377-
// NeededArgGPRs are incremented appropriately.
9378-
bool RISCVABIInfo::detectFPCCEligibleStruct(QualType Ty, llvm::Type *&Field1Ty,
9379-
CharUnits &Field1Off,
9380-
llvm::Type *&Field2Ty,
9381-
CharUnits &Field2Off,
9382-
int &NeededArgGPRs,
9383-
int &NeededArgFPRs) const {
9384-
Field1Ty = nullptr;
9385-
Field2Ty = nullptr;
9386-
NeededArgGPRs = 0;
9387-
NeededArgFPRs = 0;
9388-
bool IsCandidate = detectFPCCEligibleStructHelper(
9389-
Ty, CharUnits::Zero(), Field1Ty, Field1Off, Field2Ty, Field2Off);
9390-
// Not really a candidate if we have a single int but no float.
9391-
if (Field1Ty && !Field2Ty && !Field1Ty->isFloatingPointTy())
9392-
return IsCandidate = false;
9393-
if (!IsCandidate)
9394-
return false;
9395-
if (Field1Ty && Field1Ty->isFloatingPointTy())
9396-
NeededArgFPRs++;
9397-
else if (Field1Ty)
9398-
NeededArgGPRs++;
9399-
if (Field2Ty && Field2Ty->isFloatingPointTy())
9400-
NeededArgFPRs++;
9401-
else if (Field2Ty)
9402-
NeededArgGPRs++;
9403-
return IsCandidate;
9404-
}
9405-
9406-
// Call getCoerceAndExpand for the two-element flattened struct described by
9407-
// Field1Ty, Field1Off, Field2Ty, Field2Off. This method will create an appropriate
9408-
// coerceToType and unpaddedCoerceToType.
9409-
ABIArgInfo RISCVABIInfo::coerceAndExpandFPCCEligibleStruct(
9410-
llvm::Type *Field1Ty, CharUnits Field1Off, llvm::Type *Field2Ty, CharUnits Field2Off) const {
9411-
SmallVector<llvm::Type *, 3> CoerceElts;
9412-
SmallVector<llvm::Type *, 2> UnpaddedCoerceElts;
9413-
if (!Field1Off.isZero())
9414-
CoerceElts.push_back(llvm::ArrayType::get(
9415-
llvm::Type::getInt8Ty(getVMContext()), Field1Off.getQuantity()));
9416-
9417-
CoerceElts.push_back(Field1Ty);
9418-
UnpaddedCoerceElts.push_back(Field1Ty);
9419-
9420-
if (!Field2Ty) {
9421-
return ABIArgInfo::getCoerceAndExpand(
9422-
llvm::StructType::get(getVMContext(), CoerceElts, !Field1Off.isZero()),
9423-
UnpaddedCoerceElts[0]);
9424-
}
9425-
9426-
CharUnits Field2Align =
9427-
CharUnits::fromQuantity(getDataLayout().getABITypeAlignment(Field2Ty));
9428-
CharUnits Field1Size =
9429-
CharUnits::fromQuantity(getDataLayout().getTypeStoreSize(Field1Ty));
9430-
CharUnits Field2OffNoPadNoPack = Field1Size.alignTo(Field2Align);
9431-
9432-
CharUnits Padding = CharUnits::Zero();
9433-
if (Field2Off > Field2OffNoPadNoPack)
9434-
Padding = Field2Off - Field2OffNoPadNoPack;
9435-
else if (Field2Off != Field2Align && Field2Off > Field1Size)
9436-
Padding = Field2Off - Field1Size;
9437-
9438-
bool IsPacked = !Field2Off.isMultipleOf(Field2Align);
9439-
9440-
if (!Padding.isZero())
9441-
CoerceElts.push_back(llvm::ArrayType::get(
9442-
llvm::Type::getInt8Ty(getVMContext()), Padding.getQuantity()));
9443-
9444-
CoerceElts.push_back(Field2Ty);
9445-
UnpaddedCoerceElts.push_back(Field2Ty);
9446-
9447-
auto CoerceToType =
9448-
llvm::StructType::get(getVMContext(), CoerceElts, IsPacked);
9449-
auto UnpaddedCoerceToType =
9450-
llvm::StructType::get(getVMContext(), UnpaddedCoerceElts, IsPacked);
9451-
9452-
return ABIArgInfo::getCoerceAndExpand(CoerceToType, UnpaddedCoerceToType);
9453-
}
9454-
94559241
ABIArgInfo RISCVABIInfo::classifyArgumentType(QualType Ty, bool IsFixed,
9456-
int &ArgGPRsLeft,
9457-
int &ArgFPRsLeft) const {
9242+
int &ArgGPRsLeft) const {
94589243
assert(ArgGPRsLeft <= NumArgGPRs && "Arg GPR tracking underflow");
94599244
Ty = useFirstFieldIfTransparentUnion(Ty);
94609245

@@ -9472,40 +9257,6 @@ ABIArgInfo RISCVABIInfo::classifyArgumentType(QualType Ty, bool IsFixed,
94729257
return ABIArgInfo::getIgnore();
94739258

94749259
uint64_t Size = getContext().getTypeSize(Ty);
9475-
9476-
// Pass floating point values via FPRs if possible.
9477-
if (IsFixed && Ty->isFloatingType() && FLen >= Size && ArgFPRsLeft) {
9478-
ArgFPRsLeft--;
9479-
return ABIArgInfo::getDirect();
9480-
}
9481-
9482-
// Complex types for the hard float ABI must be passed direct rather than
9483-
// using CoerceAndExpand.
9484-
if (IsFixed && Ty->isComplexType() && FLen && ArgFPRsLeft >= 2) {
9485-
QualType EltTy = Ty->getAs<ComplexType>()->getElementType();
9486-
if (getContext().getTypeSize(EltTy) <= FLen) {
9487-
ArgFPRsLeft -= 2;
9488-
return ABIArgInfo::getDirect();
9489-
}
9490-
}
9491-
9492-
if (IsFixed && FLen && Ty->isStructureOrClassType()) {
9493-
llvm::Type *Field1Ty = nullptr;
9494-
llvm::Type *Field2Ty = nullptr;
9495-
CharUnits Field1Off = CharUnits::Zero();
9496-
CharUnits Field2Off = CharUnits::Zero();
9497-
int NeededArgGPRs;
9498-
int NeededArgFPRs;
9499-
bool IsCandidate = detectFPCCEligibleStruct(
9500-
Ty, Field1Ty, Field1Off, Field2Ty, Field2Off, NeededArgGPRs, NeededArgFPRs);
9501-
if (IsCandidate && NeededArgGPRs <= ArgGPRsLeft &&
9502-
NeededArgFPRs <= ArgFPRsLeft) {
9503-
ArgGPRsLeft -= NeededArgGPRs;
9504-
ArgFPRsLeft -= NeededArgFPRs;
9505-
return coerceAndExpandFPCCEligibleStruct(Field1Ty, Field1Off, Field2Ty, Field2Off);
9506-
}
9507-
}
9508-
95099260
uint64_t NeededAlign = getContext().getTypeAlign(Ty);
95109261
bool MustUseStack = false;
95119262
// Determine the number of GPRs needed to pass the current argument
@@ -9564,12 +9315,10 @@ ABIArgInfo RISCVABIInfo::classifyReturnType(QualType RetTy) const {
95649315
return ABIArgInfo::getIgnore();
95659316

95669317
int ArgGPRsLeft = 2;
9567-
int ArgFPRsLeft = FLen ? 2 : 0;
95689318

95699319
// The rules for return and argument types are the same, so defer to
95709320
// classifyArgumentType.
9571-
return classifyArgumentType(RetTy, /*IsFixed=*/true, ArgGPRsLeft,
9572-
ArgFPRsLeft);
9321+
return classifyArgumentType(RetTy, /*IsFixed=*/true, ArgGPRsLeft);
95739322
}
95749323

95759324
Address RISCVABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
@@ -9604,9 +9353,8 @@ ABIArgInfo RISCVABIInfo::extendType(QualType Ty) const {
96049353
namespace {
96059354
class RISCVTargetCodeGenInfo : public TargetCodeGenInfo {
96069355
public:
9607-
RISCVTargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, unsigned XLen,
9608-
unsigned FLen)
9609-
: TargetCodeGenInfo(new RISCVABIInfo(CGT, XLen, FLen)) {}
9356+
RISCVTargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, unsigned XLen)
9357+
: TargetCodeGenInfo(new RISCVABIInfo(CGT, XLen)) {}
96109358

96119359
void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
96129360
CodeGen::CodeGenModule &CGM) const override {
@@ -9745,16 +9493,9 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() {
97459493
return SetCGInfo(new MSP430TargetCodeGenInfo(Types));
97469494

97479495
case llvm::Triple::riscv32:
9748-
case llvm::Triple::riscv64: {
9749-
StringRef ABIStr = getTarget().getABI();
9750-
unsigned XLen = getTarget().getPointerWidth(0);
9751-
unsigned ABIFLen = 0;
9752-
if (ABIStr.endswith("f"))
9753-
ABIFLen = 32;
9754-
else if (ABIStr.endswith("d"))
9755-
ABIFLen = 64;
9756-
return SetCGInfo(new RISCVTargetCodeGenInfo(Types, XLen, ABIFLen));
9757-
}
9496+
return SetCGInfo(new RISCVTargetCodeGenInfo(Types, 32));
9497+
case llvm::Triple::riscv64:
9498+
return SetCGInfo(new RISCVTargetCodeGenInfo(Types, 64));
97589499

97599500
case llvm::Triple::systemz: {
97609501
bool HasVector = getTarget().getABI() == "vector";

0 commit comments

Comments
 (0)