CSKY: Consume "float-abi" module flag (#212975)

Start respecting float-abi, and fall back on the TargetOptions
field if not present.

Co-authored-by: Claude (Claude-Opus-4.8) <noreply@anthropic.com>
This commit is contained in:
Matt Arsenault 2026-07-31 21:06:33 +02:00 committed by GitHub
parent 93a1495bcc
commit c3fe6957de
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 121 additions and 27 deletions

View file

@ -14,9 +14,6 @@ include "llvm/Target/Target.td"
def ModeHardFloat :
SubtargetFeature<"hard-float", "UseHardFloat",
"true", "Use hard floating point features">;
def ModeHardFloatABI :
SubtargetFeature<"hard-float-abi", "UseHardFloatABI",
"true", "Use hard floating point ABI to pass args">;
def FeatureFPUV2_SF
: SubtargetFeature<"fpuv2_sf", "HasFPUv2SingleFloat", "true",

View file

@ -23,6 +23,7 @@
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Module.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCInstBuilder.h"
@ -129,7 +130,7 @@ void CSKYAsmPrinter::emitFunctionBodyEnd() {
void CSKYAsmPrinter::emitStartOfAsmFile(Module &M) {
if (TM.getTargetTriple().isOSBinFormatELF())
emitAttributes();
emitAttributes(M);
}
void CSKYAsmPrinter::emitEndOfAsmFile(Module &M) {
@ -245,11 +246,12 @@ void CSKYAsmPrinter::emitMachineConstantPoolValue(
OutStreamer->emitValue(Expr, Size);
}
void CSKYAsmPrinter::emitAttributes() {
void CSKYAsmPrinter::emitAttributes(Module &M) {
CSKYTargetStreamer &CTS =
static_cast<CSKYTargetStreamer &>(*OutStreamer->getTargetStreamer());
CTS.emitTargetAttributes(TM.getMCSubtargetInfo());
CTS.emitTargetAttributes(TM.getMCSubtargetInfo(),
M.getFloatABI() == FloatABI::Hard);
}
bool CSKYAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,

View file

@ -29,7 +29,7 @@ class LLVM_LIBRARY_VISIBILITY CSKYAsmPrinter : public AsmPrinter {
void expandTLSLA(const MachineInstr *MI);
void emitCustomConstantPool(const MachineInstr *MI);
void emitAttributes();
void emitAttributes(Module &M);
public:
explicit CSKYAsmPrinter(TargetMachine &TM,

View file

@ -89,10 +89,12 @@ CSKYSubtarget &CSKYSubtarget::initializeSubtargetDependencies(
}
CSKYSubtarget::CSKYSubtarget(const Triple &TT, StringRef CPU, StringRef TuneCPU,
StringRef FS, const TargetMachine &TM)
StringRef FS, FloatABI::ABIType FloatABI,
const TargetMachine &TM)
: CSKYGenSubtargetInfo(TT, CPU, TuneCPU, FS),
FrameLowering(initializeSubtargetDependencies(TT, CPU, TuneCPU, FS)),
InstrInfo(*this, RegInfo), TLInfo(TM, *this) {
InstrInfo(*this, RegInfo), TLInfo(TM, *this),
UseHardFloatABI(FloatABI == FloatABI::Hard) {
TSInfo = std::make_unique<CSKYSelectionDAGInfo>();
}
@ -101,12 +103,3 @@ CSKYSubtarget::~CSKYSubtarget() = default;
const SelectionDAGTargetInfo *CSKYSubtarget::getSelectionDAGInfo() const {
return TSInfo.get();
}
bool CSKYSubtarget::useHardFloatABI() const {
auto FloatABI = getTargetLowering()->getTargetMachine().Options.FloatABIType;
if (FloatABI == FloatABI::Default)
return UseHardFloatABI;
else
return FloatABI == FloatABI::Hard;
}

View file

@ -109,7 +109,8 @@ class CSKYSubtarget : public CSKYGenSubtargetInfo {
public:
CSKYSubtarget(const Triple &TT, StringRef CPU, StringRef TuneCPU,
StringRef FS, const TargetMachine &TM);
StringRef FS, FloatABI::ABIType FloatABI,
const TargetMachine &TM);
~CSKYSubtarget() override;
@ -134,7 +135,8 @@ public:
// Generated by inc file
void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
bool useHardFloatABI() const;
bool useHardFloatABI() const { return UseHardFloatABI; }
bool useHardFloat() const { return UseHardFloat; }
bool hasFPUv2SingleFloat() const { return HasFPUv2SingleFloat; }
bool hasFPUv2DoubleFloat() const { return HasFPUv2DoubleFloat; }

View file

@ -20,6 +20,7 @@
#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/IR/Module.h"
#include "llvm/MC/TargetRegistry.h"
#include <optional>
@ -59,10 +60,16 @@ CSKYTargetMachine::getSubtargetImpl(const Function &F) const {
std::string FS =
FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS;
FloatABI::ABIType FloatABI = F.getParent()->getFloatABI();
if (FloatABI == FloatABI::Default)
FloatABI = Options.FloatABIType;
std::string Key = CPU + TuneCPU + FS;
Key += FloatABI == FloatABI::Hard ? "+hard-float-abi" : "+soft-float-abi";
auto &I = SubtargetMap[Key];
if (!I) {
I = std::make_unique<CSKYSubtarget>(TargetTriple, CPU, TuneCPU, FS, *this);
I = std::make_unique<CSKYSubtarget>(TargetTriple, CPU, TuneCPU, FS,
FloatABI, *this);
if (I->useHardFloat() && !I->hasAnyFloatExt())
errs() << "Hard-float can't be used with current CPU,"
" set to Soft-float\n";

View file

@ -177,7 +177,8 @@ void CSKYELFStreamer::EmitMappingSymbol(StringRef Name) {
Symbol->setBinding(ELF::STB_LOCAL);
}
void CSKYTargetELFStreamer::emitTargetAttributes(const MCSubtargetInfo &STI) {
void CSKYTargetELFStreamer::emitTargetAttributes(const MCSubtargetInfo &STI,
bool HardFloatABI) {
StringRef CPU = STI.getCPU();
CSKY::ArchKind ArchID = CSKY::parseCPUArch(CPU);
@ -309,8 +310,11 @@ void CSKYTargetELFStreamer::emitTargetAttributes(const MCSubtargetInfo &STI) {
STI.hasFeature(CSKY::FeatureFPUV3_SF) ||
STI.hasFeature(CSKY::FeatureFPUV3_DF);
if (hasAnyFloatExt && STI.hasFeature(CSKY::ModeHardFloat) &&
STI.hasFeature(CSKY::ModeHardFloatABI))
// The hard-float *ABI* (FP values in FP registers at call boundaries) is
// selected by the "float-abi" module flag, resolved by the caller; it does
// not depend on ModeHardFloat, which only distinguishes the soft-float ABI
// that still uses hard-float instructions (SOFTFP) from pure soft float.
if (hasAnyFloatExt && HardFloatABI)
emitAttribute(CSKYAttrs::CSKY_FPU_ABI, CSKYAttrs::FPU_ABI_HARD);
else if (hasAnyFloatExt && STI.hasFeature(CSKY::ModeHardFloat))
emitAttribute(CSKYAttrs::CSKY_FPU_ABI, CSKYAttrs::FPU_ABI_SOFTFP);

View file

@ -91,7 +91,8 @@ private:
void finishAttributeSection() override;
size_t calculateContentSize() const;
void emitTargetAttributes(const MCSubtargetInfo &STI) override;
void emitTargetAttributes(const MCSubtargetInfo &STI,
bool HardFloatABI = false) override;
public:
MCELFStreamer &getStreamer();

View file

@ -124,7 +124,8 @@ void CSKYTargetStreamer::finish() {
finishAttributeSection();
}
void CSKYTargetStreamer::emitTargetAttributes(const MCSubtargetInfo &STI) {}
void CSKYTargetStreamer::emitTargetAttributes(const MCSubtargetInfo &STI,
bool HardFloatABI) {}
void CSKYTargetStreamer::emitAttribute(unsigned Attribute, unsigned Value) {}
void CSKYTargetStreamer::emitTextAttribute(unsigned Attribute,

View file

@ -64,7 +64,8 @@ public:
virtual void emitAttribute(unsigned Attribute, unsigned Value);
virtual void finishAttributeSection();
virtual void emitTargetAttributes(const MCSubtargetInfo &STI);
virtual void emitTargetAttributes(const MCSubtargetInfo &STI,
bool HardFloatABI = false);
/// Add a new entry to the constant pool for the current section and return an
/// MCExpr that can be used to refer to the constant pool location.
const MCExpr *addConstantPoolEntry(const MCExpr *, SMLoc Loc,

View file

@ -0,0 +1,45 @@
; The "float-abi" module flag selects the floating-point calling convention.
; RUN: split-file %s %t
; Soft float ABI (the target default): FP arguments are passed in GPRs and moved
; into VFP registers with fmtvrl.
; RUN: llc -csky-no-aliases -mtriple=csky -mattr=+2e3,+fpuv2_sf,+fpuv2_df,+hard-float < %t/none.ll | FileCheck %s --check-prefix=SOFT
; Hard float ABI module flag: FP arguments arrive directly in VFP registers, so
; no fmtvrl moves are needed.
; RUN: llc -csky-no-aliases -mtriple=csky -mattr=+2e3,+fpuv2_sf,+fpuv2_df,+hard-float < %t/hard.ll | FileCheck %s --check-prefix=HARD
; Soft float ABI module flag matches the default.
; RUN: llc -csky-no-aliases -mtriple=csky -mattr=+2e3,+fpuv2_sf,+fpuv2_df,+hard-float < %t/soft.ll | FileCheck %s --check-prefix=SOFT
; The legacy -float-abi target option still selects the ABI when the module has
; no "float-abi" flag.
; RUN: llc -csky-no-aliases -mtriple=csky -mattr=+2e3,+fpuv2_sf,+fpuv2_df,+hard-float -float-abi=hard < %t/none.ll | FileCheck %s --check-prefix=HARD
; An explicit module flag takes precedence over the legacy -float-abi option.
; RUN: llc -csky-no-aliases -mtriple=csky -mattr=+2e3,+fpuv2_sf,+fpuv2_df,+hard-float -float-abi=hard < %t/soft.ll | FileCheck %s --check-prefix=SOFT
;--- none.ll
define float @f(float %x, float %y) {
%r = fadd float %x, %y
ret float %r
}
;--- hard.ll
define float @f(float %x, float %y) {
%r = fadd float %x, %y
ret float %r
}
!llvm.module.flags = !{!0}
!0 = !{i32 1, !"float-abi", !"hard"}
;--- soft.ll
define float @f(float %x, float %y) {
%r = fadd float %x, %y
ret float %r
}
!llvm.module.flags = !{!0}
!0 = !{i32 1, !"float-abi", !"soft"}
; SOFT: fmtvrl
; HARD-NOT: fmtvrl

View file

@ -0,0 +1,41 @@
; The emitted Tag_CSKY_FPU_ABI build attribute (17) reflects the floating-point
; ABI: hard-float ABI (from the "float-abi" module flag) emits FPU_ABI_HARD (3),
; while the soft-float ABI with hard-float instructions available emits
; FPU_ABI_SOFTFP (2), and no float unit emits FPU_ABI_SOFT (1).
; RUN: split-file %s %t
; Hard float ABI module flag with an FPU: FPU_ABI_HARD (3).
; RUN: llc -mtriple=csky -mattr=+2e3,+fpuv2_sf,+fpuv2_df,+hard-float < %t/hard.ll | FileCheck %s --check-prefix=HARD
; Soft float ABI (target default) with an FPU: FPU_ABI_SOFTFP (2).
; RUN: llc -mtriple=csky -mattr=+2e3,+fpuv2_sf,+fpuv2_df,+hard-float < %t/none.ll | FileCheck %s --check-prefix=SOFTFP
; Explicit soft float ABI module flag with an FPU: FPU_ABI_SOFTFP (2).
; RUN: llc -mtriple=csky -mattr=+2e3,+fpuv2_sf,+fpuv2_df,+hard-float < %t/soft.ll | FileCheck %s --check-prefix=SOFTFP
; No float unit: FPU_ABI_SOFT (1), regardless of the module flag.
; RUN: llc -mtriple=csky -mattr=+2e3 < %t/hard.ll | FileCheck %s --check-prefix=SOFT
; HARD: .csky_attribute 17, 3
; SOFTFP: .csky_attribute 17, 2
; SOFT: .csky_attribute 17, 1
;--- none.ll
define void @f() {
ret void
}
;--- hard.ll
define void @f() {
ret void
}
!llvm.module.flags = !{!0}
!0 = !{i32 1, !"float-abi", !"hard"}
;--- soft.ll
define void @f() {
ret void
}
!llvm.module.flags = !{!0}
!0 = !{i32 1, !"float-abi", !"soft"}