From 5b538f8f3c4e9a65f3fc904ff6ae8c8d9b8249a8 Mon Sep 17 00:00:00 2001 From: Shaoce SUN Date: Sat, 13 Sep 2025 02:51:48 +0800 Subject: [PATCH 1/6] [RISCV] Reduce constant pool usage without FP extension The recognition range can be extended later. --- .../RISCV/GISel/RISCVInstructionSelector.cpp | 17 ++- .../Target/RISCV/GISel/RISCVLegalizerInfo.cpp | 17 ++- .../Target/RISCV/GISel/RISCVLegalizerInfo.h | 1 + .../RISCV/GISel/RISCVRegisterBankInfo.cpp | 33 +++--- .../CodeGen/RISCV/GlobalISel/constantpool.ll | 44 +++---- .../CodeGen/RISCV/GlobalISel/double-arith.ll | 54 ++++----- .../CodeGen/RISCV/GlobalISel/float-arith.ll | 112 +++++++----------- llvm/test/CodeGen/RISCV/GlobalISel/vararg.ll | 8 +- 8 files changed, 135 insertions(+), 151 deletions(-) diff --git a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp index 7df1b7e580002..29633481b72be 100644 --- a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp +++ b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp @@ -745,10 +745,19 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) { if (!materializeImm(GPRReg, Imm.getSExtValue(), MIB)) return false; - unsigned Opcode = Size == 64 ? RISCV::FMV_D_X - : Size == 32 ? RISCV::FMV_W_X - : RISCV::FMV_H_X; - auto FMV = MIB.buildInstr(Opcode, {DstReg}, {GPRReg}); + unsigned Opcode = RISCV::INIT_UNDEF; + MachineInstrBuilder FMV; + if (Subtarget->hasStdExtF() || Subtarget->hasStdExtD() || + Subtarget->hasStdExtZfh()) { + Opcode = Size == 64 ? RISCV::FMV_D_X + : Size == 32 ? RISCV::FMV_W_X + : RISCV::FMV_H_X; + FMV = MIB.buildInstr(Opcode, {DstReg}, {GPRReg}); + } else { + Opcode = + (Subtarget->is64Bit() && Size == 32) ? RISCV::ADDW : RISCV::ADD; + FMV = MIB.buildInstr(Opcode, {DstReg}, {GPRReg, Register(RISCV::X0)}); + } if (!FMV.constrainAllUses(TII, TRI, RBI)) return false; } else { diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp index 16f34a89a52ec..61543a28d80c2 100644 --- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp +++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp @@ -572,7 +572,9 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST) .legalFor(ST.hasStdExtF(), {s32}) .legalFor(ST.hasStdExtD(), {s64}) .legalFor(ST.hasStdExtZfh(), {s16}) - .lowerFor({s32, s64, s128}); + .customFor(!ST.is64Bit(), {s32}) + .customFor(ST.is64Bit(), {s32, s64}) + .lowerFor({s64, s128}); getActionDefinitionsBuilder({G_FPTOSI, G_FPTOUI}) .legalFor(ST.hasStdExtF(), {{sXLen, s32}}) @@ -869,6 +871,12 @@ bool RISCVLegalizerInfo::shouldBeInConstantPool(const APInt &APImm, return !(!SeqLo.empty() && (SeqLo.size() + 2) <= STI.getMaxBuildIntsCost()); } +bool RISCVLegalizerInfo::shouldBeInFConstantPool(const APFloat &APImm) const { + if (APImm.isZero() || APImm.isExactlyValue(1.0)) + return false; + return true; +} + bool RISCVLegalizerInfo::legalizeVScale(MachineInstr &MI, MachineIRBuilder &MIB) const { const LLT XLenTy(STI.getXLenVT()); @@ -1358,7 +1366,12 @@ bool RISCVLegalizerInfo::legalizeCustom( return false; case TargetOpcode::G_ABS: return Helper.lowerAbsToMaxNeg(MI); - // TODO: G_FCONSTANT + case TargetOpcode::G_FCONSTANT: { + const ConstantFP *ConstVal = MI.getOperand(1).getFPImm(); + if (!shouldBeInFConstantPool(ConstVal->getValue())) + return true; + return Helper.lowerFConstant(MI); + } case TargetOpcode::G_CONSTANT: { const Function &F = MF.getFunction(); // TODO: if PSI and BFI are present, add " || diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.h b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.h index 4451866745194..bd6d1665849c8 100644 --- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.h +++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.h @@ -39,6 +39,7 @@ class RISCVLegalizerInfo : public LegalizerInfo { private: bool shouldBeInConstantPool(const APInt &APImm, bool ShouldOptForSize) const; + bool shouldBeInFConstantPool(const APFloat &APImm) const; bool legalizeShlAshrLshr(MachineInstr &MI, MachineIRBuilder &MIRBuilder, GISelChangeObserver &Observer) const; diff --git a/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp index a082b18867666..b0d0ce7bdf529 100644 --- a/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp +++ b/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp @@ -112,7 +112,8 @@ using namespace llvm; RISCVRegisterBankInfo::RISCVRegisterBankInfo(unsigned HwMode) : RISCVGenRegisterBankInfo(HwMode) {} -static const RegisterBankInfo::ValueMapping *getFPValueMapping(unsigned Size) { +static const RegisterBankInfo::ValueMapping * +getFPValueMapping(unsigned Size, bool HasFPExt = true) { unsigned Idx; switch (Size) { default: @@ -121,10 +122,10 @@ static const RegisterBankInfo::ValueMapping *getFPValueMapping(unsigned Size) { Idx = RISCV::FPRB16Idx; break; case 32: - Idx = RISCV::FPRB32Idx; + Idx = HasFPExt ? RISCV::FPRB32Idx : RISCV::GPRB32Idx; break; case 64: - Idx = RISCV::FPRB64Idx; + Idx = HasFPExt ? RISCV::FPRB64Idx : RISCV::GPRB64Idx; break; } return &RISCV::ValueMappings[Idx]; @@ -219,6 +220,10 @@ RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { const TargetSubtargetInfo &STI = MF.getSubtarget(); const TargetRegisterInfo &TRI = *STI.getRegisterInfo(); + bool HasFPExt = STI.hasFeature(RISCV::FeatureStdExtF) || + STI.hasFeature(RISCV::FeatureStdExtD) || + STI.hasFeature(RISCV::FeatureStdExtZfh); + unsigned GPRSize = getMaximumSize(RISCV::GPRBRegBankID); assert((GPRSize == 32 || GPRSize == 64) && "Unexpected GPR size"); @@ -266,7 +271,7 @@ RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { if (Ty.isVector()) Mapping = getVRBValueMapping(Size.getKnownMinValue()); else if (isPreISelGenericFloatingPointOpcode(Opc)) - Mapping = getFPValueMapping(Size.getFixedValue()); + Mapping = getFPValueMapping(Size.getFixedValue(), HasFPExt); else Mapping = GPRValueMapping; @@ -301,7 +306,7 @@ RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { if (DstTy.isVector()) Mapping = getVRBValueMapping(DstMinSize); else if (anyUseOnlyUseFP(Dst, MRI, TRI)) - Mapping = getFPValueMapping(DstMinSize); + Mapping = getFPValueMapping(DstMinSize, HasFPExt); return getInstructionMapping(DefaultMappingID, /*Cost=*/1, Mapping, NumOperands); @@ -339,7 +344,7 @@ RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { // assume this was a floating point load in the IR. If it was // not, we would have had a bitcast before reaching that // instruction. - OpdsMapping[0] = getFPValueMapping(Size); + OpdsMapping[0] = getFPValueMapping(Size, HasFPExt); break; } @@ -367,7 +372,7 @@ RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { MachineInstr *DefMI = MRI.getVRegDef(MI.getOperand(0).getReg()); if (onlyDefinesFP(*DefMI, MRI, TRI)) - OpdsMapping[0] = getFPValueMapping(Ty.getSizeInBits()); + OpdsMapping[0] = getFPValueMapping(Ty.getSizeInBits(), HasFPExt); break; } case TargetOpcode::G_SELECT: { @@ -432,7 +437,7 @@ RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { const ValueMapping *Mapping = GPRValueMapping; if (NumFP >= 2) - Mapping = getFPValueMapping(Ty.getSizeInBits()); + Mapping = getFPValueMapping(Ty.getSizeInBits(), HasFPExt); OpdsMapping[0] = OpdsMapping[2] = OpdsMapping[3] = Mapping; break; @@ -444,13 +449,13 @@ RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { case RISCV::G_FCLASS: { LLT Ty = MRI.getType(MI.getOperand(1).getReg()); OpdsMapping[0] = GPRValueMapping; - OpdsMapping[1] = getFPValueMapping(Ty.getSizeInBits()); + OpdsMapping[1] = getFPValueMapping(Ty.getSizeInBits(), HasFPExt); break; } case TargetOpcode::G_SITOFP: case TargetOpcode::G_UITOFP: { LLT Ty = MRI.getType(MI.getOperand(0).getReg()); - OpdsMapping[0] = getFPValueMapping(Ty.getSizeInBits()); + OpdsMapping[0] = getFPValueMapping(Ty.getSizeInBits(), HasFPExt); OpdsMapping[1] = GPRValueMapping; break; } @@ -468,7 +473,7 @@ RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { LLT Ty = MRI.getType(MI.getOperand(0).getReg()); if (GPRSize == 32 && Ty.getSizeInBits() == 64) { assert(MF.getSubtarget().hasStdExtD()); - OpdsMapping[0] = getFPValueMapping(Ty.getSizeInBits()); + OpdsMapping[0] = getFPValueMapping(Ty.getSizeInBits(), HasFPExt); OpdsMapping[1] = GPRValueMapping; OpdsMapping[2] = GPRValueMapping; } @@ -481,7 +486,7 @@ RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { assert(MF.getSubtarget().hasStdExtD()); OpdsMapping[0] = GPRValueMapping; OpdsMapping[1] = GPRValueMapping; - OpdsMapping[2] = getFPValueMapping(Ty.getSizeInBits()); + OpdsMapping[2] = getFPValueMapping(Ty.getSizeInBits(), HasFPExt); } break; } @@ -495,7 +500,7 @@ RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { if ((GPRSize == 32 && ScalarTy.getSizeInBits() == 64) || onlyDefinesFP(*DefMI, MRI, TRI)) { assert(MF.getSubtarget().hasStdExtD()); - OpdsMapping[1] = getFPValueMapping(ScalarTy.getSizeInBits()); + OpdsMapping[1] = getFPValueMapping(ScalarTy.getSizeInBits(), HasFPExt); } else OpdsMapping[1] = GPRValueMapping; break; @@ -514,7 +519,7 @@ RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { OpdsMapping[Idx] = getVRBValueMapping(Ty.getSizeInBits().getKnownMinValue()); else if (isPreISelGenericFloatingPointOpcode(Opc)) - OpdsMapping[Idx] = getFPValueMapping(Ty.getSizeInBits()); + OpdsMapping[Idx] = getFPValueMapping(Ty.getSizeInBits(), HasFPExt); else OpdsMapping[Idx] = GPRValueMapping; } diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/constantpool.ll b/llvm/test/CodeGen/RISCV/GlobalISel/constantpool.ll index 1eeeb60c2eb40..849bb13009e16 100644 --- a/llvm/test/CodeGen/RISCV/GlobalISel/constantpool.ll +++ b/llvm/test/CodeGen/RISCV/GlobalISel/constantpool.ll @@ -15,47 +15,37 @@ define void @constpool_f32(ptr %p) { ; RV32-SMALL-LABEL: constpool_f32: ; RV32-SMALL: # %bb.0: -; RV32-SMALL-NEXT: lui a1, %hi(.LCPI0_0) -; RV32-SMALL-NEXT: lw a1, %lo(.LCPI0_0)(a1) +; RV32-SMALL-NEXT: lui a1, 260096 ; RV32-SMALL-NEXT: sw a1, 0(a0) ; RV32-SMALL-NEXT: ret ; ; RV32-MEDIUM-LABEL: constpool_f32: ; RV32-MEDIUM: # %bb.0: -; RV32-MEDIUM-NEXT: .Lpcrel_hi0: -; RV32-MEDIUM-NEXT: auipc a1, %pcrel_hi(.LCPI0_0) -; RV32-MEDIUM-NEXT: lw a1, %pcrel_lo(.Lpcrel_hi0)(a1) +; RV32-MEDIUM-NEXT: lui a1, 260096 ; RV32-MEDIUM-NEXT: sw a1, 0(a0) ; RV32-MEDIUM-NEXT: ret ; ; RV32-PIC-LABEL: constpool_f32: ; RV32-PIC: # %bb.0: -; RV32-PIC-NEXT: .Lpcrel_hi0: -; RV32-PIC-NEXT: auipc a1, %pcrel_hi(.LCPI0_0) -; RV32-PIC-NEXT: lw a1, %pcrel_lo(.Lpcrel_hi0)(a1) +; RV32-PIC-NEXT: lui a1, 260096 ; RV32-PIC-NEXT: sw a1, 0(a0) ; RV32-PIC-NEXT: ret ; ; RV64-SMALL-LABEL: constpool_f32: ; RV64-SMALL: # %bb.0: -; RV64-SMALL-NEXT: lui a1, %hi(.LCPI0_0) -; RV64-SMALL-NEXT: lw a1, %lo(.LCPI0_0)(a1) +; RV64-SMALL-NEXT: lui a1, 260096 ; RV64-SMALL-NEXT: sw a1, 0(a0) ; RV64-SMALL-NEXT: ret ; ; RV64-MEDIUM-LABEL: constpool_f32: ; RV64-MEDIUM: # %bb.0: -; RV64-MEDIUM-NEXT: .Lpcrel_hi0: -; RV64-MEDIUM-NEXT: auipc a1, %pcrel_hi(.LCPI0_0) -; RV64-MEDIUM-NEXT: lw a1, %pcrel_lo(.Lpcrel_hi0)(a1) +; RV64-MEDIUM-NEXT: lui a1, 260096 ; RV64-MEDIUM-NEXT: sw a1, 0(a0) ; RV64-MEDIUM-NEXT: ret ; ; RV64-PIC-LABEL: constpool_f32: ; RV64-PIC: # %bb.0: -; RV64-PIC-NEXT: .Lpcrel_hi0: -; RV64-PIC-NEXT: auipc a1, %pcrel_hi(.LCPI0_0) -; RV64-PIC-NEXT: lw a1, %pcrel_lo(.Lpcrel_hi0)(a1) +; RV64-PIC-NEXT: lui a1, 260096 ; RV64-PIC-NEXT: sw a1, 0(a0) ; RV64-PIC-NEXT: ret store float 1.0, ptr %p @@ -75,9 +65,9 @@ define void @constpool_f64(ptr %p) { ; ; RV32-MEDIUM-LABEL: constpool_f64: ; RV32-MEDIUM: # %bb.0: -; RV32-MEDIUM-NEXT: .Lpcrel_hi1: +; RV32-MEDIUM-NEXT: .Lpcrel_hi0: ; RV32-MEDIUM-NEXT: auipc a1, %pcrel_hi(.LCPI1_0) -; RV32-MEDIUM-NEXT: addi a1, a1, %pcrel_lo(.Lpcrel_hi1) +; RV32-MEDIUM-NEXT: addi a1, a1, %pcrel_lo(.Lpcrel_hi0) ; RV32-MEDIUM-NEXT: lw a2, 0(a1) ; RV32-MEDIUM-NEXT: lw a1, 4(a1) ; RV32-MEDIUM-NEXT: sw a2, 0(a0) @@ -86,9 +76,9 @@ define void @constpool_f64(ptr %p) { ; ; RV32-PIC-LABEL: constpool_f64: ; RV32-PIC: # %bb.0: -; RV32-PIC-NEXT: .Lpcrel_hi1: +; RV32-PIC-NEXT: .Lpcrel_hi0: ; RV32-PIC-NEXT: auipc a1, %pcrel_hi(.LCPI1_0) -; RV32-PIC-NEXT: addi a1, a1, %pcrel_lo(.Lpcrel_hi1) +; RV32-PIC-NEXT: addi a1, a1, %pcrel_lo(.Lpcrel_hi0) ; RV32-PIC-NEXT: lw a2, 0(a1) ; RV32-PIC-NEXT: lw a1, 4(a1) ; RV32-PIC-NEXT: sw a2, 0(a0) @@ -97,24 +87,22 @@ define void @constpool_f64(ptr %p) { ; ; RV64-SMALL-LABEL: constpool_f64: ; RV64-SMALL: # %bb.0: -; RV64-SMALL-NEXT: lui a1, %hi(.LCPI1_0) -; RV64-SMALL-NEXT: ld a1, %lo(.LCPI1_0)(a1) +; RV64-SMALL-NEXT: li a1, 1023 +; RV64-SMALL-NEXT: slli a1, a1, 52 ; RV64-SMALL-NEXT: sd a1, 0(a0) ; RV64-SMALL-NEXT: ret ; ; RV64-MEDIUM-LABEL: constpool_f64: ; RV64-MEDIUM: # %bb.0: -; RV64-MEDIUM-NEXT: .Lpcrel_hi1: -; RV64-MEDIUM-NEXT: auipc a1, %pcrel_hi(.LCPI1_0) -; RV64-MEDIUM-NEXT: ld a1, %pcrel_lo(.Lpcrel_hi1)(a1) +; RV64-MEDIUM-NEXT: li a1, 1023 +; RV64-MEDIUM-NEXT: slli a1, a1, 52 ; RV64-MEDIUM-NEXT: sd a1, 0(a0) ; RV64-MEDIUM-NEXT: ret ; ; RV64-PIC-LABEL: constpool_f64: ; RV64-PIC: # %bb.0: -; RV64-PIC-NEXT: .Lpcrel_hi1: -; RV64-PIC-NEXT: auipc a1, %pcrel_hi(.LCPI1_0) -; RV64-PIC-NEXT: ld a1, %pcrel_lo(.Lpcrel_hi1)(a1) +; RV64-PIC-NEXT: li a1, 1023 +; RV64-PIC-NEXT: slli a1, a1, 52 ; RV64-PIC-NEXT: sd a1, 0(a0) ; RV64-PIC-NEXT: ret store double 1.0, ptr %p diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/double-arith.ll b/llvm/test/CodeGen/RISCV/GlobalISel/double-arith.ll index 12684f30dbee0..c4dcf72ae6606 100644 --- a/llvm/test/CodeGen/RISCV/GlobalISel/double-arith.ll +++ b/llvm/test/CodeGen/RISCV/GlobalISel/double-arith.ll @@ -508,9 +508,8 @@ define double @fmsub_d(double %a, double %b, double %c) nounwind { ; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill ; RV64I-NEXT: mv s0, a0 ; RV64I-NEXT: mv s1, a1 -; RV64I-NEXT: lui a0, %hi(.LCPI14_0) -; RV64I-NEXT: ld a1, %lo(.LCPI14_0)(a0) ; RV64I-NEXT: mv a0, a2 +; RV64I-NEXT: li a1, 0 ; RV64I-NEXT: call __adddf3 ; RV64I-NEXT: li a1, -1 ; RV64I-NEXT: slli a1, a1, 63 @@ -606,14 +605,12 @@ define double @fnmadd_d(double %a, double %b, double %c) nounwind { ; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill ; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill ; RV64I-NEXT: mv s0, a1 -; RV64I-NEXT: lui a1, %hi(.LCPI15_0) -; RV64I-NEXT: ld s1, %lo(.LCPI15_0)(a1) -; RV64I-NEXT: mv s2, a2 -; RV64I-NEXT: mv a1, s1 +; RV64I-NEXT: mv s1, a2 +; RV64I-NEXT: li a1, 0 ; RV64I-NEXT: call __adddf3 ; RV64I-NEXT: mv s3, a0 -; RV64I-NEXT: mv a0, s2 -; RV64I-NEXT: mv a1, s1 +; RV64I-NEXT: mv a0, s1 +; RV64I-NEXT: li a1, 0 ; RV64I-NEXT: call __adddf3 ; RV64I-NEXT: li a1, -1 ; RV64I-NEXT: slli a2, a1, 63 @@ -716,14 +713,12 @@ define double @fnmadd_d_2(double %a, double %b, double %c) nounwind { ; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill ; RV64I-NEXT: mv s0, a0 ; RV64I-NEXT: mv a0, a1 -; RV64I-NEXT: lui a1, %hi(.LCPI16_0) -; RV64I-NEXT: ld s1, %lo(.LCPI16_0)(a1) -; RV64I-NEXT: mv s2, a2 -; RV64I-NEXT: mv a1, s1 +; RV64I-NEXT: mv s1, a2 +; RV64I-NEXT: li a1, 0 ; RV64I-NEXT: call __adddf3 ; RV64I-NEXT: mv s3, a0 -; RV64I-NEXT: mv a0, s2 -; RV64I-NEXT: mv a1, s1 +; RV64I-NEXT: mv a0, s1 +; RV64I-NEXT: li a1, 0 ; RV64I-NEXT: call __adddf3 ; RV64I-NEXT: li a1, -1 ; RV64I-NEXT: slli a2, a1, 63 @@ -869,9 +864,8 @@ define double @fnmsub_d(double %a, double %b, double %c) nounwind { ; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill ; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill ; RV64I-NEXT: mv s0, a1 -; RV64I-NEXT: lui a1, %hi(.LCPI19_0) -; RV64I-NEXT: ld a1, %lo(.LCPI19_0)(a1) ; RV64I-NEXT: mv s1, a2 +; RV64I-NEXT: li a1, 0 ; RV64I-NEXT: call __adddf3 ; RV64I-NEXT: li a1, -1 ; RV64I-NEXT: slli a1, a1, 63 @@ -948,9 +942,8 @@ define double @fnmsub_d_2(double %a, double %b, double %c) nounwind { ; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill ; RV64I-NEXT: mv s0, a0 ; RV64I-NEXT: mv a0, a1 -; RV64I-NEXT: lui a1, %hi(.LCPI20_0) -; RV64I-NEXT: ld a1, %lo(.LCPI20_0)(a1) ; RV64I-NEXT: mv s1, a2 +; RV64I-NEXT: li a1, 0 ; RV64I-NEXT: call __adddf3 ; RV64I-NEXT: li a1, -1 ; RV64I-NEXT: slli a1, a1, 63 @@ -1078,9 +1071,8 @@ define double @fmsub_d_contract(double %a, double %b, double %c) nounwind { ; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill ; RV64I-NEXT: mv s0, a0 ; RV64I-NEXT: mv s1, a1 -; RV64I-NEXT: lui a0, %hi(.LCPI22_0) -; RV64I-NEXT: ld a1, %lo(.LCPI22_0)(a0) ; RV64I-NEXT: mv a0, a2 +; RV64I-NEXT: li a1, 0 ; RV64I-NEXT: call __adddf3 ; RV64I-NEXT: mv s2, a0 ; RV64I-NEXT: mv a0, s0 @@ -1193,18 +1185,16 @@ define double @fnmadd_d_contract(double %a, double %b, double %c) nounwind { ; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill ; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill ; RV64I-NEXT: mv s0, a1 -; RV64I-NEXT: lui a1, %hi(.LCPI23_0) -; RV64I-NEXT: ld s1, %lo(.LCPI23_0)(a1) -; RV64I-NEXT: mv s2, a2 -; RV64I-NEXT: mv a1, s1 +; RV64I-NEXT: mv s1, a2 +; RV64I-NEXT: li a1, 0 ; RV64I-NEXT: call __adddf3 ; RV64I-NEXT: mv s3, a0 ; RV64I-NEXT: mv a0, s0 -; RV64I-NEXT: mv a1, s1 +; RV64I-NEXT: li a1, 0 ; RV64I-NEXT: call __adddf3 ; RV64I-NEXT: mv s0, a0 -; RV64I-NEXT: mv a0, s2 -; RV64I-NEXT: mv a1, s1 +; RV64I-NEXT: mv a0, s1 +; RV64I-NEXT: li a1, 0 ; RV64I-NEXT: call __adddf3 ; RV64I-NEXT: mv s1, a0 ; RV64I-NEXT: mv a0, s3 @@ -1309,20 +1299,18 @@ define double @fnmsub_d_contract(double %a, double %b, double %c) nounwind { ; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill ; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill ; RV64I-NEXT: mv s0, a1 -; RV64I-NEXT: lui a1, %hi(.LCPI24_0) -; RV64I-NEXT: ld s1, %lo(.LCPI24_0)(a1) -; RV64I-NEXT: mv s2, a2 -; RV64I-NEXT: mv a1, s1 +; RV64I-NEXT: mv s1, a2 +; RV64I-NEXT: li a1, 0 ; RV64I-NEXT: call __adddf3 ; RV64I-NEXT: mv s3, a0 ; RV64I-NEXT: mv a0, s0 -; RV64I-NEXT: mv a1, s1 +; RV64I-NEXT: li a1, 0 ; RV64I-NEXT: call __adddf3 ; RV64I-NEXT: mv a1, a0 ; RV64I-NEXT: mv a0, s3 ; RV64I-NEXT: call __muldf3 ; RV64I-NEXT: mv a1, a0 -; RV64I-NEXT: mv a0, s2 +; RV64I-NEXT: mv a0, s1 ; RV64I-NEXT: call __subdf3 ; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload ; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/float-arith.ll b/llvm/test/CodeGen/RISCV/GlobalISel/float-arith.ll index 739f225ad1525..763b6d6544747 100644 --- a/llvm/test/CodeGen/RISCV/GlobalISel/float-arith.ll +++ b/llvm/test/CodeGen/RISCV/GlobalISel/float-arith.ll @@ -472,9 +472,8 @@ define float @fmsub_s(float %a, float %b, float %c) nounwind { ; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill ; RV32I-NEXT: mv s0, a0 ; RV32I-NEXT: mv s1, a1 -; RV32I-NEXT: lui a0, %hi(.LCPI14_0) -; RV32I-NEXT: lw a1, %lo(.LCPI14_0)(a0) ; RV32I-NEXT: mv a0, a2 +; RV32I-NEXT: li a1, 0 ; RV32I-NEXT: call __addsf3 ; RV32I-NEXT: lui a2, 524288 ; RV32I-NEXT: xor a2, a0, a2 @@ -495,9 +494,8 @@ define float @fmsub_s(float %a, float %b, float %c) nounwind { ; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill ; RV64I-NEXT: mv s0, a0 ; RV64I-NEXT: mv s1, a1 -; RV64I-NEXT: lui a0, %hi(.LCPI14_0) -; RV64I-NEXT: lw a1, %lo(.LCPI14_0)(a0) ; RV64I-NEXT: mv a0, a2 +; RV64I-NEXT: sext.w a1, zero ; RV64I-NEXT: call __addsf3 ; RV64I-NEXT: lui a2, 524288 ; RV64I-NEXT: xor a2, a0, a2 @@ -533,14 +531,12 @@ define float @fnmadd_s(float %a, float %b, float %c) nounwind { ; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill ; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill ; RV32I-NEXT: mv s0, a1 -; RV32I-NEXT: lui a1, %hi(.LCPI15_0) -; RV32I-NEXT: lw s1, %lo(.LCPI15_0)(a1) -; RV32I-NEXT: mv s2, a2 -; RV32I-NEXT: mv a1, s1 +; RV32I-NEXT: mv s1, a2 +; RV32I-NEXT: li a1, 0 ; RV32I-NEXT: call __addsf3 ; RV32I-NEXT: mv s3, a0 -; RV32I-NEXT: mv a0, s2 -; RV32I-NEXT: mv a1, s1 +; RV32I-NEXT: mv a0, s1 +; RV32I-NEXT: li a1, 0 ; RV32I-NEXT: call __addsf3 ; RV32I-NEXT: lui a2, 524288 ; RV32I-NEXT: xor a1, s3, a2 @@ -565,14 +561,13 @@ define float @fnmadd_s(float %a, float %b, float %c) nounwind { ; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill ; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill ; RV64I-NEXT: mv s0, a1 -; RV64I-NEXT: lui a1, %hi(.LCPI15_0) -; RV64I-NEXT: lw s1, %lo(.LCPI15_0)(a1) -; RV64I-NEXT: mv s2, a2 -; RV64I-NEXT: mv a1, s1 +; RV64I-NEXT: mv s1, a2 +; RV64I-NEXT: sext.w s2, zero +; RV64I-NEXT: mv a1, s2 ; RV64I-NEXT: call __addsf3 ; RV64I-NEXT: mv s3, a0 -; RV64I-NEXT: mv a0, s2 -; RV64I-NEXT: mv a1, s1 +; RV64I-NEXT: mv a0, s1 +; RV64I-NEXT: mv a1, s2 ; RV64I-NEXT: call __addsf3 ; RV64I-NEXT: lui a2, 524288 ; RV64I-NEXT: xor a1, s3, a2 @@ -614,14 +609,12 @@ define float @fnmadd_s_2(float %a, float %b, float %c) nounwind { ; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill ; RV32I-NEXT: mv s0, a0 ; RV32I-NEXT: mv a0, a1 -; RV32I-NEXT: lui a1, %hi(.LCPI16_0) -; RV32I-NEXT: lw s1, %lo(.LCPI16_0)(a1) -; RV32I-NEXT: mv s2, a2 -; RV32I-NEXT: mv a1, s1 +; RV32I-NEXT: mv s1, a2 +; RV32I-NEXT: li a1, 0 ; RV32I-NEXT: call __addsf3 ; RV32I-NEXT: mv s3, a0 -; RV32I-NEXT: mv a0, s2 -; RV32I-NEXT: mv a1, s1 +; RV32I-NEXT: mv a0, s1 +; RV32I-NEXT: li a1, 0 ; RV32I-NEXT: call __addsf3 ; RV32I-NEXT: lui a2, 524288 ; RV32I-NEXT: xor a1, s3, a2 @@ -646,14 +639,13 @@ define float @fnmadd_s_2(float %a, float %b, float %c) nounwind { ; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill ; RV64I-NEXT: mv s0, a0 ; RV64I-NEXT: mv a0, a1 -; RV64I-NEXT: lui a1, %hi(.LCPI16_0) -; RV64I-NEXT: lw s1, %lo(.LCPI16_0)(a1) -; RV64I-NEXT: mv s2, a2 -; RV64I-NEXT: mv a1, s1 +; RV64I-NEXT: mv s1, a2 +; RV64I-NEXT: sext.w s2, zero +; RV64I-NEXT: mv a1, s2 ; RV64I-NEXT: call __addsf3 ; RV64I-NEXT: mv s3, a0 -; RV64I-NEXT: mv a0, s2 -; RV64I-NEXT: mv a1, s1 +; RV64I-NEXT: mv a0, s1 +; RV64I-NEXT: mv a1, s2 ; RV64I-NEXT: call __addsf3 ; RV64I-NEXT: lui a2, 524288 ; RV64I-NEXT: xor a1, s3, a2 @@ -778,9 +770,8 @@ define float @fnmsub_s(float %a, float %b, float %c) nounwind { ; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill ; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill ; RV32I-NEXT: mv s0, a1 -; RV32I-NEXT: lui a1, %hi(.LCPI19_0) -; RV32I-NEXT: lw a1, %lo(.LCPI19_0)(a1) ; RV32I-NEXT: mv s1, a2 +; RV32I-NEXT: li a1, 0 ; RV32I-NEXT: call __addsf3 ; RV32I-NEXT: lui a1, 524288 ; RV32I-NEXT: xor a0, a0, a1 @@ -800,9 +791,8 @@ define float @fnmsub_s(float %a, float %b, float %c) nounwind { ; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill ; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill ; RV64I-NEXT: mv s0, a1 -; RV64I-NEXT: lui a1, %hi(.LCPI19_0) -; RV64I-NEXT: lw a1, %lo(.LCPI19_0)(a1) ; RV64I-NEXT: mv s1, a2 +; RV64I-NEXT: sext.w a1, zero ; RV64I-NEXT: call __addsf3 ; RV64I-NEXT: lui a1, 524288 ; RV64I-NEXT: xor a0, a0, a1 @@ -836,9 +826,8 @@ define float @fnmsub_s_2(float %a, float %b, float %c) nounwind { ; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill ; RV32I-NEXT: mv s0, a0 ; RV32I-NEXT: mv a0, a1 -; RV32I-NEXT: lui a1, %hi(.LCPI20_0) -; RV32I-NEXT: lw a1, %lo(.LCPI20_0)(a1) ; RV32I-NEXT: mv s1, a2 +; RV32I-NEXT: li a1, 0 ; RV32I-NEXT: call __addsf3 ; RV32I-NEXT: lui a1, 524288 ; RV32I-NEXT: xor a1, a0, a1 @@ -859,9 +848,8 @@ define float @fnmsub_s_2(float %a, float %b, float %c) nounwind { ; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill ; RV64I-NEXT: mv s0, a0 ; RV64I-NEXT: mv a0, a1 -; RV64I-NEXT: lui a1, %hi(.LCPI20_0) -; RV64I-NEXT: lw a1, %lo(.LCPI20_0)(a1) ; RV64I-NEXT: mv s1, a2 +; RV64I-NEXT: sext.w a1, zero ; RV64I-NEXT: call __addsf3 ; RV64I-NEXT: lui a1, 524288 ; RV64I-NEXT: xor a1, a0, a1 @@ -935,9 +923,8 @@ define float @fmsub_s_contract(float %a, float %b, float %c) nounwind { ; RV32I-NEXT: sw s2, 0(sp) # 4-byte Folded Spill ; RV32I-NEXT: mv s0, a0 ; RV32I-NEXT: mv s1, a1 -; RV32I-NEXT: lui a0, %hi(.LCPI22_0) -; RV32I-NEXT: lw a1, %lo(.LCPI22_0)(a0) ; RV32I-NEXT: mv a0, a2 +; RV32I-NEXT: li a1, 0 ; RV32I-NEXT: call __addsf3 ; RV32I-NEXT: mv s2, a0 ; RV32I-NEXT: mv a0, s0 @@ -961,9 +948,8 @@ define float @fmsub_s_contract(float %a, float %b, float %c) nounwind { ; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill ; RV64I-NEXT: mv s0, a0 ; RV64I-NEXT: mv s1, a1 -; RV64I-NEXT: lui a0, %hi(.LCPI22_0) -; RV64I-NEXT: lw a1, %lo(.LCPI22_0)(a0) ; RV64I-NEXT: mv a0, a2 +; RV64I-NEXT: sext.w a1, zero ; RV64I-NEXT: call __addsf3 ; RV64I-NEXT: mv s2, a0 ; RV64I-NEXT: mv a0, s0 @@ -1004,18 +990,16 @@ define float @fnmadd_s_contract(float %a, float %b, float %c) nounwind { ; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill ; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill ; RV32I-NEXT: mv s0, a1 -; RV32I-NEXT: lui a1, %hi(.LCPI23_0) -; RV32I-NEXT: lw s1, %lo(.LCPI23_0)(a1) -; RV32I-NEXT: mv s2, a2 -; RV32I-NEXT: mv a1, s1 +; RV32I-NEXT: mv s1, a2 +; RV32I-NEXT: li a1, 0 ; RV32I-NEXT: call __addsf3 ; RV32I-NEXT: mv s3, a0 ; RV32I-NEXT: mv a0, s0 -; RV32I-NEXT: mv a1, s1 +; RV32I-NEXT: li a1, 0 ; RV32I-NEXT: call __addsf3 ; RV32I-NEXT: mv s0, a0 -; RV32I-NEXT: mv a0, s2 -; RV32I-NEXT: mv a1, s1 +; RV32I-NEXT: mv a0, s1 +; RV32I-NEXT: li a1, 0 ; RV32I-NEXT: call __addsf3 ; RV32I-NEXT: mv s1, a0 ; RV32I-NEXT: mv a0, s3 @@ -1042,18 +1026,17 @@ define float @fnmadd_s_contract(float %a, float %b, float %c) nounwind { ; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill ; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill ; RV64I-NEXT: mv s0, a1 -; RV64I-NEXT: lui a1, %hi(.LCPI23_0) -; RV64I-NEXT: lw s1, %lo(.LCPI23_0)(a1) -; RV64I-NEXT: mv s2, a2 -; RV64I-NEXT: mv a1, s1 +; RV64I-NEXT: mv s1, a2 +; RV64I-NEXT: sext.w s2, zero +; RV64I-NEXT: mv a1, s2 ; RV64I-NEXT: call __addsf3 ; RV64I-NEXT: mv s3, a0 ; RV64I-NEXT: mv a0, s0 -; RV64I-NEXT: mv a1, s1 +; RV64I-NEXT: mv a1, s2 ; RV64I-NEXT: call __addsf3 ; RV64I-NEXT: mv s0, a0 -; RV64I-NEXT: mv a0, s2 -; RV64I-NEXT: mv a1, s1 +; RV64I-NEXT: mv a0, s1 +; RV64I-NEXT: mv a1, s2 ; RV64I-NEXT: call __addsf3 ; RV64I-NEXT: mv s1, a0 ; RV64I-NEXT: mv a0, s3 @@ -1097,20 +1080,18 @@ define float @fnmsub_s_contract(float %a, float %b, float %c) nounwind { ; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill ; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill ; RV32I-NEXT: mv s0, a1 -; RV32I-NEXT: lui a1, %hi(.LCPI24_0) -; RV32I-NEXT: lw s1, %lo(.LCPI24_0)(a1) -; RV32I-NEXT: mv s2, a2 -; RV32I-NEXT: mv a1, s1 +; RV32I-NEXT: mv s1, a2 +; RV32I-NEXT: li a1, 0 ; RV32I-NEXT: call __addsf3 ; RV32I-NEXT: mv s3, a0 ; RV32I-NEXT: mv a0, s0 -; RV32I-NEXT: mv a1, s1 +; RV32I-NEXT: li a1, 0 ; RV32I-NEXT: call __addsf3 ; RV32I-NEXT: mv a1, a0 ; RV32I-NEXT: mv a0, s3 ; RV32I-NEXT: call __mulsf3 ; RV32I-NEXT: mv a1, a0 -; RV32I-NEXT: mv a0, s2 +; RV32I-NEXT: mv a0, s1 ; RV32I-NEXT: call __subsf3 ; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload ; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload @@ -1129,20 +1110,19 @@ define float @fnmsub_s_contract(float %a, float %b, float %c) nounwind { ; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill ; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill ; RV64I-NEXT: mv s0, a1 -; RV64I-NEXT: lui a1, %hi(.LCPI24_0) -; RV64I-NEXT: lw s1, %lo(.LCPI24_0)(a1) -; RV64I-NEXT: mv s2, a2 -; RV64I-NEXT: mv a1, s1 +; RV64I-NEXT: mv s1, a2 +; RV64I-NEXT: sext.w s2, zero +; RV64I-NEXT: mv a1, s2 ; RV64I-NEXT: call __addsf3 ; RV64I-NEXT: mv s3, a0 ; RV64I-NEXT: mv a0, s0 -; RV64I-NEXT: mv a1, s1 +; RV64I-NEXT: mv a1, s2 ; RV64I-NEXT: call __addsf3 ; RV64I-NEXT: mv a1, a0 ; RV64I-NEXT: mv a0, s3 ; RV64I-NEXT: call __mulsf3 ; RV64I-NEXT: mv a1, a0 -; RV64I-NEXT: mv a0, s2 +; RV64I-NEXT: mv a0, s1 ; RV64I-NEXT: call __subsf3 ; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload ; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/vararg.ll b/llvm/test/CodeGen/RISCV/GlobalISel/vararg.ll index d9ddf655c283a..f43b255a679e3 100644 --- a/llvm/test/CodeGen/RISCV/GlobalISel/vararg.ll +++ b/llvm/test/CodeGen/RISCV/GlobalISel/vararg.ll @@ -437,8 +437,8 @@ define void @va1_caller() nounwind { ; LP64: # %bb.0: ; LP64-NEXT: addi sp, sp, -16 ; LP64-NEXT: sd ra, 8(sp) # 8-byte Folded Spill -; LP64-NEXT: lui a0, %hi(.LCPI3_0) -; LP64-NEXT: ld a1, %lo(.LCPI3_0)(a0) +; LP64-NEXT: li a0, 1023 +; LP64-NEXT: slli a1, a0, 52 ; LP64-NEXT: li a2, 2 ; LP64-NEXT: call va1 ; LP64-NEXT: ld ra, 8(sp) # 8-byte Folded Reload @@ -494,8 +494,8 @@ define void @va1_caller() nounwind { ; RV64-WITHFP-NEXT: sd ra, 8(sp) # 8-byte Folded Spill ; RV64-WITHFP-NEXT: sd s0, 0(sp) # 8-byte Folded Spill ; RV64-WITHFP-NEXT: addi s0, sp, 16 -; RV64-WITHFP-NEXT: lui a0, %hi(.LCPI3_0) -; RV64-WITHFP-NEXT: ld a1, %lo(.LCPI3_0)(a0) +; RV64-WITHFP-NEXT: li a0, 1023 +; RV64-WITHFP-NEXT: slli a1, a0, 52 ; RV64-WITHFP-NEXT: li a2, 2 ; RV64-WITHFP-NEXT: call va1 ; RV64-WITHFP-NEXT: ld ra, 8(sp) # 8-byte Folded Reload From 80f8c3b8668f8d77f31d15387fc2f54ce2b962e0 Mon Sep 17 00:00:00 2001 From: Shaoce SUN Date: Sat, 13 Sep 2025 14:16:48 +0800 Subject: [PATCH 2/6] Address comments --- .../RISCV/GISel/RISCVInstructionSelector.cpp | 35 ++++++++++++------- .../Target/RISCV/GISel/RISCVLegalizerInfo.cpp | 10 ++---- .../Target/RISCV/GISel/RISCVLegalizerInfo.h | 1 - .../RISCV/GISel/RISCVRegisterBankInfo.cpp | 5 ++- 4 files changed, 27 insertions(+), 24 deletions(-) diff --git a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp index 29633481b72be..bf067161463f4 100644 --- a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp +++ b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp @@ -740,24 +740,33 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) { const APFloat &FPimm = MI.getOperand(1).getFPImm()->getValueAPF(); APInt Imm = FPimm.bitcastToAPInt(); unsigned Size = MRI->getType(DstReg).getSizeInBits(); + + if (!Subtarget->hasStdExtF() && + (Size == 32 || (Size == 64 && Subtarget->is64Bit()))) { + // No fp extension, so we need to go through GPRs. + Register GPRReg = MRI->createVirtualRegister(&RISCV::GPRRegClass); + if (!materializeImm(GPRReg, Imm.getSExtValue(), MIB)) + return false; + + unsigned Opcode = + (Subtarget->is64Bit() && Size == 32) ? RISCV::ADDW : RISCV::ADD; + auto MV = MIB.buildInstr(Opcode, {DstReg}, {GPRReg, Register(RISCV::X0)}); + if (!MV.constrainAllUses(TII, TRI, RBI)) + return false; + + MI.eraseFromParent(); + return true; + } + if (Size == 16 || Size == 32 || (Size == 64 && Subtarget->is64Bit())) { Register GPRReg = MRI->createVirtualRegister(&RISCV::GPRRegClass); if (!materializeImm(GPRReg, Imm.getSExtValue(), MIB)) return false; - unsigned Opcode = RISCV::INIT_UNDEF; - MachineInstrBuilder FMV; - if (Subtarget->hasStdExtF() || Subtarget->hasStdExtD() || - Subtarget->hasStdExtZfh()) { - Opcode = Size == 64 ? RISCV::FMV_D_X - : Size == 32 ? RISCV::FMV_W_X - : RISCV::FMV_H_X; - FMV = MIB.buildInstr(Opcode, {DstReg}, {GPRReg}); - } else { - Opcode = - (Subtarget->is64Bit() && Size == 32) ? RISCV::ADDW : RISCV::ADD; - FMV = MIB.buildInstr(Opcode, {DstReg}, {GPRReg, Register(RISCV::X0)}); - } + unsigned Opcode = Size == 64 ? RISCV::FMV_D_X + : Size == 32 ? RISCV::FMV_W_X + : RISCV::FMV_H_X; + auto FMV = MIB.buildInstr(Opcode, {DstReg}, {GPRReg}); if (!FMV.constrainAllUses(TII, TRI, RBI)) return false; } else { diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp index 61543a28d80c2..7e984e6146452 100644 --- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp +++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp @@ -871,12 +871,6 @@ bool RISCVLegalizerInfo::shouldBeInConstantPool(const APInt &APImm, return !(!SeqLo.empty() && (SeqLo.size() + 2) <= STI.getMaxBuildIntsCost()); } -bool RISCVLegalizerInfo::shouldBeInFConstantPool(const APFloat &APImm) const { - if (APImm.isZero() || APImm.isExactlyValue(1.0)) - return false; - return true; -} - bool RISCVLegalizerInfo::legalizeVScale(MachineInstr &MI, MachineIRBuilder &MIB) const { const LLT XLenTy(STI.getXLenVT()); @@ -1368,7 +1362,9 @@ bool RISCVLegalizerInfo::legalizeCustom( return Helper.lowerAbsToMaxNeg(MI); case TargetOpcode::G_FCONSTANT: { const ConstantFP *ConstVal = MI.getOperand(1).getFPImm(); - if (!shouldBeInFConstantPool(ConstVal->getValue())) + bool ShouldOptForSize = MF.getFunction().hasOptSize(); + if (!shouldBeInConstantPool(ConstVal->getValue().bitcastToAPInt(), + ShouldOptForSize)) return true; return Helper.lowerFConstant(MI); } diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.h b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.h index bd6d1665849c8..4451866745194 100644 --- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.h +++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.h @@ -39,7 +39,6 @@ class RISCVLegalizerInfo : public LegalizerInfo { private: bool shouldBeInConstantPool(const APInt &APImm, bool ShouldOptForSize) const; - bool shouldBeInFConstantPool(const APFloat &APImm) const; bool legalizeShlAshrLshr(MachineInstr &MI, MachineIRBuilder &MIRBuilder, GISelChangeObserver &Observer) const; diff --git a/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp index b0d0ce7bdf529..6152de5840b05 100644 --- a/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp +++ b/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp @@ -220,9 +220,8 @@ RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { const TargetSubtargetInfo &STI = MF.getSubtarget(); const TargetRegisterInfo &TRI = *STI.getRegisterInfo(); - bool HasFPExt = STI.hasFeature(RISCV::FeatureStdExtF) || - STI.hasFeature(RISCV::FeatureStdExtD) || - STI.hasFeature(RISCV::FeatureStdExtZfh); + // D and Zfh extension implies F. + bool HasFPExt = STI.hasFeature(RISCV::FeatureStdExtF); unsigned GPRSize = getMaximumSize(RISCV::GPRBRegBankID); assert((GPRSize == 32 || GPRSize == 64) && "Unexpected GPR size"); From 81c637815fef2370ca3fdf48349ff9fe051f91cb Mon Sep 17 00:00:00 2001 From: Shaoce SUN Date: Sat, 13 Sep 2025 23:52:06 +0800 Subject: [PATCH 3/6] Remove extra ADD --- .../RISCV/GISel/RISCVInstructionSelector.cpp | 10 +- .../CodeGen/RISCV/GlobalISel/double-arith.ll | 104 ++++---- .../CodeGen/RISCV/GlobalISel/float-arith.ll | 238 ++++++++---------- llvm/test/CodeGen/RISCV/GlobalISel/vararg.ll | 8 +- 4 files changed, 162 insertions(+), 198 deletions(-) diff --git a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp index bf067161463f4..4f6062184edc2 100644 --- a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp +++ b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp @@ -743,15 +743,7 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) { if (!Subtarget->hasStdExtF() && (Size == 32 || (Size == 64 && Subtarget->is64Bit()))) { - // No fp extension, so we need to go through GPRs. - Register GPRReg = MRI->createVirtualRegister(&RISCV::GPRRegClass); - if (!materializeImm(GPRReg, Imm.getSExtValue(), MIB)) - return false; - - unsigned Opcode = - (Subtarget->is64Bit() && Size == 32) ? RISCV::ADDW : RISCV::ADD; - auto MV = MIB.buildInstr(Opcode, {DstReg}, {GPRReg, Register(RISCV::X0)}); - if (!MV.constrainAllUses(TII, TRI, RBI)) + if (!materializeImm(DstReg, Imm.getSExtValue(), MIB)) return false; MI.eraseFromParent(); diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/double-arith.ll b/llvm/test/CodeGen/RISCV/GlobalISel/double-arith.ll index c4dcf72ae6606..4246aa545dd0e 100644 --- a/llvm/test/CodeGen/RISCV/GlobalISel/double-arith.ll +++ b/llvm/test/CodeGen/RISCV/GlobalISel/double-arith.ll @@ -598,33 +598,31 @@ define double @fnmadd_d(double %a, double %b, double %c) nounwind { ; ; RV64I-LABEL: fnmadd_d: ; RV64I: # %bb.0: -; RV64I-NEXT: addi sp, sp, -48 -; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill -; RV64I-NEXT: sd s0, 32(sp) # 8-byte Folded Spill -; RV64I-NEXT: sd s1, 24(sp) # 8-byte Folded Spill -; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill -; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill +; RV64I-NEXT: addi sp, sp, -32 +; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill +; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill +; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill +; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill ; RV64I-NEXT: mv s0, a1 ; RV64I-NEXT: mv s1, a2 ; RV64I-NEXT: li a1, 0 ; RV64I-NEXT: call __adddf3 -; RV64I-NEXT: mv s3, a0 +; RV64I-NEXT: mv s2, a0 ; RV64I-NEXT: mv a0, s1 ; RV64I-NEXT: li a1, 0 ; RV64I-NEXT: call __adddf3 ; RV64I-NEXT: li a1, -1 ; RV64I-NEXT: slli a2, a1, 63 -; RV64I-NEXT: xor a1, s3, a2 +; RV64I-NEXT: xor a1, s2, a2 ; RV64I-NEXT: xor a2, a0, a2 ; RV64I-NEXT: mv a0, a1 ; RV64I-NEXT: mv a1, s0 ; RV64I-NEXT: call fma -; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload -; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload -; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload -; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload -; RV64I-NEXT: ld s3, 8(sp) # 8-byte Folded Reload -; RV64I-NEXT: addi sp, sp, 48 +; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload +; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload +; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload +; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload +; RV64I-NEXT: addi sp, sp, 32 ; RV64I-NEXT: ret %a_ = fadd double 0.0, %a %c_ = fadd double 0.0, %c @@ -705,33 +703,31 @@ define double @fnmadd_d_2(double %a, double %b, double %c) nounwind { ; ; RV64I-LABEL: fnmadd_d_2: ; RV64I: # %bb.0: -; RV64I-NEXT: addi sp, sp, -48 -; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill -; RV64I-NEXT: sd s0, 32(sp) # 8-byte Folded Spill -; RV64I-NEXT: sd s1, 24(sp) # 8-byte Folded Spill -; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill -; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill +; RV64I-NEXT: addi sp, sp, -32 +; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill +; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill +; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill +; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill ; RV64I-NEXT: mv s0, a0 ; RV64I-NEXT: mv a0, a1 ; RV64I-NEXT: mv s1, a2 ; RV64I-NEXT: li a1, 0 ; RV64I-NEXT: call __adddf3 -; RV64I-NEXT: mv s3, a0 +; RV64I-NEXT: mv s2, a0 ; RV64I-NEXT: mv a0, s1 ; RV64I-NEXT: li a1, 0 ; RV64I-NEXT: call __adddf3 ; RV64I-NEXT: li a1, -1 ; RV64I-NEXT: slli a2, a1, 63 -; RV64I-NEXT: xor a1, s3, a2 +; RV64I-NEXT: xor a1, s2, a2 ; RV64I-NEXT: xor a2, a0, a2 ; RV64I-NEXT: mv a0, s0 ; RV64I-NEXT: call fma -; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload -; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload -; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload -; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload -; RV64I-NEXT: ld s3, 8(sp) # 8-byte Folded Reload -; RV64I-NEXT: addi sp, sp, 48 +; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload +; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload +; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload +; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload +; RV64I-NEXT: addi sp, sp, 32 ; RV64I-NEXT: ret %b_ = fadd double 0.0, %b %c_ = fadd double 0.0, %c @@ -1178,17 +1174,16 @@ define double @fnmadd_d_contract(double %a, double %b, double %c) nounwind { ; ; RV64I-LABEL: fnmadd_d_contract: ; RV64I: # %bb.0: -; RV64I-NEXT: addi sp, sp, -48 -; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill -; RV64I-NEXT: sd s0, 32(sp) # 8-byte Folded Spill -; RV64I-NEXT: sd s1, 24(sp) # 8-byte Folded Spill -; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill -; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill +; RV64I-NEXT: addi sp, sp, -32 +; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill +; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill +; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill +; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill ; RV64I-NEXT: mv s0, a1 ; RV64I-NEXT: mv s1, a2 ; RV64I-NEXT: li a1, 0 ; RV64I-NEXT: call __adddf3 -; RV64I-NEXT: mv s3, a0 +; RV64I-NEXT: mv s2, a0 ; RV64I-NEXT: mv a0, s0 ; RV64I-NEXT: li a1, 0 ; RV64I-NEXT: call __adddf3 @@ -1197,7 +1192,7 @@ define double @fnmadd_d_contract(double %a, double %b, double %c) nounwind { ; RV64I-NEXT: li a1, 0 ; RV64I-NEXT: call __adddf3 ; RV64I-NEXT: mv s1, a0 -; RV64I-NEXT: mv a0, s3 +; RV64I-NEXT: mv a0, s2 ; RV64I-NEXT: mv a1, s0 ; RV64I-NEXT: call __muldf3 ; RV64I-NEXT: li a1, -1 @@ -1205,12 +1200,11 @@ define double @fnmadd_d_contract(double %a, double %b, double %c) nounwind { ; RV64I-NEXT: xor a0, a0, a1 ; RV64I-NEXT: mv a1, s1 ; RV64I-NEXT: call __subdf3 -; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload -; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload -; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload -; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload -; RV64I-NEXT: ld s3, 8(sp) # 8-byte Folded Reload -; RV64I-NEXT: addi sp, sp, 48 +; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload +; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload +; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload +; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload +; RV64I-NEXT: addi sp, sp, 32 ; RV64I-NEXT: ret %a_ = fadd double 0.0, %a ; avoid negation using xor %b_ = fadd double 0.0, %b ; avoid negation using xor @@ -1292,32 +1286,30 @@ define double @fnmsub_d_contract(double %a, double %b, double %c) nounwind { ; ; RV64I-LABEL: fnmsub_d_contract: ; RV64I: # %bb.0: -; RV64I-NEXT: addi sp, sp, -48 -; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill -; RV64I-NEXT: sd s0, 32(sp) # 8-byte Folded Spill -; RV64I-NEXT: sd s1, 24(sp) # 8-byte Folded Spill -; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill -; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill +; RV64I-NEXT: addi sp, sp, -32 +; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill +; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill +; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill +; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill ; RV64I-NEXT: mv s0, a1 ; RV64I-NEXT: mv s1, a2 ; RV64I-NEXT: li a1, 0 ; RV64I-NEXT: call __adddf3 -; RV64I-NEXT: mv s3, a0 +; RV64I-NEXT: mv s2, a0 ; RV64I-NEXT: mv a0, s0 ; RV64I-NEXT: li a1, 0 ; RV64I-NEXT: call __adddf3 ; RV64I-NEXT: mv a1, a0 -; RV64I-NEXT: mv a0, s3 +; RV64I-NEXT: mv a0, s2 ; RV64I-NEXT: call __muldf3 ; RV64I-NEXT: mv a1, a0 ; RV64I-NEXT: mv a0, s1 ; RV64I-NEXT: call __subdf3 -; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload -; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload -; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload -; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload -; RV64I-NEXT: ld s3, 8(sp) # 8-byte Folded Reload -; RV64I-NEXT: addi sp, sp, 48 +; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload +; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload +; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload +; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload +; RV64I-NEXT: addi sp, sp, 32 ; RV64I-NEXT: ret %a_ = fadd double 0.0, %a ; avoid negation using xor %b_ = fadd double 0.0, %b ; avoid negation using xor diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/float-arith.ll b/llvm/test/CodeGen/RISCV/GlobalISel/float-arith.ll index 763b6d6544747..3222849641baf 100644 --- a/llvm/test/CodeGen/RISCV/GlobalISel/float-arith.ll +++ b/llvm/test/CodeGen/RISCV/GlobalISel/float-arith.ll @@ -495,7 +495,7 @@ define float @fmsub_s(float %a, float %b, float %c) nounwind { ; RV64I-NEXT: mv s0, a0 ; RV64I-NEXT: mv s1, a1 ; RV64I-NEXT: mv a0, a2 -; RV64I-NEXT: sext.w a1, zero +; RV64I-NEXT: li a1, 0 ; RV64I-NEXT: call __addsf3 ; RV64I-NEXT: lui a2, 524288 ; RV64I-NEXT: xor a2, a0, a2 @@ -524,63 +524,58 @@ define float @fnmadd_s(float %a, float %b, float %c) nounwind { ; ; RV32I-LABEL: fnmadd_s: ; RV32I: # %bb.0: -; RV32I-NEXT: addi sp, sp, -32 -; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill -; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill -; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill -; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill -; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill +; RV32I-NEXT: addi sp, sp, -16 +; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill +; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill +; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill +; RV32I-NEXT: sw s2, 0(sp) # 4-byte Folded Spill ; RV32I-NEXT: mv s0, a1 ; RV32I-NEXT: mv s1, a2 ; RV32I-NEXT: li a1, 0 ; RV32I-NEXT: call __addsf3 -; RV32I-NEXT: mv s3, a0 +; RV32I-NEXT: mv s2, a0 ; RV32I-NEXT: mv a0, s1 ; RV32I-NEXT: li a1, 0 ; RV32I-NEXT: call __addsf3 ; RV32I-NEXT: lui a2, 524288 -; RV32I-NEXT: xor a1, s3, a2 +; RV32I-NEXT: xor a1, s2, a2 ; RV32I-NEXT: xor a2, a0, a2 ; RV32I-NEXT: mv a0, a1 ; RV32I-NEXT: mv a1, s0 ; RV32I-NEXT: call fmaf -; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload -; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload -; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload -; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload -; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload -; RV32I-NEXT: addi sp, sp, 32 +; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload +; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload +; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload +; RV32I-NEXT: lw s2, 0(sp) # 4-byte Folded Reload +; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret ; ; RV64I-LABEL: fnmadd_s: ; RV64I: # %bb.0: -; RV64I-NEXT: addi sp, sp, -48 -; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill -; RV64I-NEXT: sd s0, 32(sp) # 8-byte Folded Spill -; RV64I-NEXT: sd s1, 24(sp) # 8-byte Folded Spill -; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill -; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill +; RV64I-NEXT: addi sp, sp, -32 +; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill +; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill +; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill +; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill ; RV64I-NEXT: mv s0, a1 ; RV64I-NEXT: mv s1, a2 -; RV64I-NEXT: sext.w s2, zero -; RV64I-NEXT: mv a1, s2 +; RV64I-NEXT: li a1, 0 ; RV64I-NEXT: call __addsf3 -; RV64I-NEXT: mv s3, a0 +; RV64I-NEXT: mv s2, a0 ; RV64I-NEXT: mv a0, s1 -; RV64I-NEXT: mv a1, s2 +; RV64I-NEXT: li a1, 0 ; RV64I-NEXT: call __addsf3 ; RV64I-NEXT: lui a2, 524288 -; RV64I-NEXT: xor a1, s3, a2 +; RV64I-NEXT: xor a1, s2, a2 ; RV64I-NEXT: xor a2, a0, a2 ; RV64I-NEXT: mv a0, a1 ; RV64I-NEXT: mv a1, s0 ; RV64I-NEXT: call fmaf -; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload -; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload -; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload -; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload -; RV64I-NEXT: ld s3, 8(sp) # 8-byte Folded Reload -; RV64I-NEXT: addi sp, sp, 48 +; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload +; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload +; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload +; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload +; RV64I-NEXT: addi sp, sp, 32 ; RV64I-NEXT: ret %a_ = fadd float 0.0, %a %c_ = fadd float 0.0, %c @@ -601,63 +596,58 @@ define float @fnmadd_s_2(float %a, float %b, float %c) nounwind { ; ; RV32I-LABEL: fnmadd_s_2: ; RV32I: # %bb.0: -; RV32I-NEXT: addi sp, sp, -32 -; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill -; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill -; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill -; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill -; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill +; RV32I-NEXT: addi sp, sp, -16 +; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill +; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill +; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill +; RV32I-NEXT: sw s2, 0(sp) # 4-byte Folded Spill ; RV32I-NEXT: mv s0, a0 ; RV32I-NEXT: mv a0, a1 ; RV32I-NEXT: mv s1, a2 ; RV32I-NEXT: li a1, 0 ; RV32I-NEXT: call __addsf3 -; RV32I-NEXT: mv s3, a0 +; RV32I-NEXT: mv s2, a0 ; RV32I-NEXT: mv a0, s1 ; RV32I-NEXT: li a1, 0 ; RV32I-NEXT: call __addsf3 ; RV32I-NEXT: lui a2, 524288 -; RV32I-NEXT: xor a1, s3, a2 +; RV32I-NEXT: xor a1, s2, a2 ; RV32I-NEXT: xor a2, a0, a2 ; RV32I-NEXT: mv a0, s0 ; RV32I-NEXT: call fmaf -; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload -; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload -; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload -; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload -; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload -; RV32I-NEXT: addi sp, sp, 32 +; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload +; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload +; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload +; RV32I-NEXT: lw s2, 0(sp) # 4-byte Folded Reload +; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret ; ; RV64I-LABEL: fnmadd_s_2: ; RV64I: # %bb.0: -; RV64I-NEXT: addi sp, sp, -48 -; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill -; RV64I-NEXT: sd s0, 32(sp) # 8-byte Folded Spill -; RV64I-NEXT: sd s1, 24(sp) # 8-byte Folded Spill -; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill -; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill +; RV64I-NEXT: addi sp, sp, -32 +; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill +; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill +; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill +; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill ; RV64I-NEXT: mv s0, a0 ; RV64I-NEXT: mv a0, a1 ; RV64I-NEXT: mv s1, a2 -; RV64I-NEXT: sext.w s2, zero -; RV64I-NEXT: mv a1, s2 +; RV64I-NEXT: li a1, 0 ; RV64I-NEXT: call __addsf3 -; RV64I-NEXT: mv s3, a0 +; RV64I-NEXT: mv s2, a0 ; RV64I-NEXT: mv a0, s1 -; RV64I-NEXT: mv a1, s2 +; RV64I-NEXT: li a1, 0 ; RV64I-NEXT: call __addsf3 ; RV64I-NEXT: lui a2, 524288 -; RV64I-NEXT: xor a1, s3, a2 +; RV64I-NEXT: xor a1, s2, a2 ; RV64I-NEXT: xor a2, a0, a2 ; RV64I-NEXT: mv a0, s0 ; RV64I-NEXT: call fmaf -; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload -; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload -; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload -; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload -; RV64I-NEXT: ld s3, 8(sp) # 8-byte Folded Reload -; RV64I-NEXT: addi sp, sp, 48 +; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload +; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload +; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload +; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload +; RV64I-NEXT: addi sp, sp, 32 ; RV64I-NEXT: ret %b_ = fadd float 0.0, %b %c_ = fadd float 0.0, %c @@ -792,7 +782,7 @@ define float @fnmsub_s(float %a, float %b, float %c) nounwind { ; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill ; RV64I-NEXT: mv s0, a1 ; RV64I-NEXT: mv s1, a2 -; RV64I-NEXT: sext.w a1, zero +; RV64I-NEXT: li a1, 0 ; RV64I-NEXT: call __addsf3 ; RV64I-NEXT: lui a1, 524288 ; RV64I-NEXT: xor a0, a0, a1 @@ -849,7 +839,7 @@ define float @fnmsub_s_2(float %a, float %b, float %c) nounwind { ; RV64I-NEXT: mv s0, a0 ; RV64I-NEXT: mv a0, a1 ; RV64I-NEXT: mv s1, a2 -; RV64I-NEXT: sext.w a1, zero +; RV64I-NEXT: li a1, 0 ; RV64I-NEXT: call __addsf3 ; RV64I-NEXT: lui a1, 524288 ; RV64I-NEXT: xor a1, a0, a1 @@ -949,7 +939,7 @@ define float @fmsub_s_contract(float %a, float %b, float %c) nounwind { ; RV64I-NEXT: mv s0, a0 ; RV64I-NEXT: mv s1, a1 ; RV64I-NEXT: mv a0, a2 -; RV64I-NEXT: sext.w a1, zero +; RV64I-NEXT: li a1, 0 ; RV64I-NEXT: call __addsf3 ; RV64I-NEXT: mv s2, a0 ; RV64I-NEXT: mv a0, s0 @@ -983,17 +973,16 @@ define float @fnmadd_s_contract(float %a, float %b, float %c) nounwind { ; ; RV32I-LABEL: fnmadd_s_contract: ; RV32I: # %bb.0: -; RV32I-NEXT: addi sp, sp, -32 -; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill -; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill -; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill -; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill -; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill +; RV32I-NEXT: addi sp, sp, -16 +; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill +; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill +; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill +; RV32I-NEXT: sw s2, 0(sp) # 4-byte Folded Spill ; RV32I-NEXT: mv s0, a1 ; RV32I-NEXT: mv s1, a2 ; RV32I-NEXT: li a1, 0 ; RV32I-NEXT: call __addsf3 -; RV32I-NEXT: mv s3, a0 +; RV32I-NEXT: mv s2, a0 ; RV32I-NEXT: mv a0, s0 ; RV32I-NEXT: li a1, 0 ; RV32I-NEXT: call __addsf3 @@ -1002,56 +991,52 @@ define float @fnmadd_s_contract(float %a, float %b, float %c) nounwind { ; RV32I-NEXT: li a1, 0 ; RV32I-NEXT: call __addsf3 ; RV32I-NEXT: mv s1, a0 -; RV32I-NEXT: mv a0, s3 +; RV32I-NEXT: mv a0, s2 ; RV32I-NEXT: mv a1, s0 ; RV32I-NEXT: call __mulsf3 ; RV32I-NEXT: lui a1, 524288 ; RV32I-NEXT: xor a0, a0, a1 ; RV32I-NEXT: mv a1, s1 ; RV32I-NEXT: call __subsf3 -; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload -; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload -; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload -; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload -; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload -; RV32I-NEXT: addi sp, sp, 32 +; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload +; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload +; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload +; RV32I-NEXT: lw s2, 0(sp) # 4-byte Folded Reload +; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret ; ; RV64I-LABEL: fnmadd_s_contract: ; RV64I: # %bb.0: -; RV64I-NEXT: addi sp, sp, -48 -; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill -; RV64I-NEXT: sd s0, 32(sp) # 8-byte Folded Spill -; RV64I-NEXT: sd s1, 24(sp) # 8-byte Folded Spill -; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill -; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill +; RV64I-NEXT: addi sp, sp, -32 +; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill +; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill +; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill +; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill ; RV64I-NEXT: mv s0, a1 ; RV64I-NEXT: mv s1, a2 -; RV64I-NEXT: sext.w s2, zero -; RV64I-NEXT: mv a1, s2 +; RV64I-NEXT: li a1, 0 ; RV64I-NEXT: call __addsf3 -; RV64I-NEXT: mv s3, a0 +; RV64I-NEXT: mv s2, a0 ; RV64I-NEXT: mv a0, s0 -; RV64I-NEXT: mv a1, s2 +; RV64I-NEXT: li a1, 0 ; RV64I-NEXT: call __addsf3 ; RV64I-NEXT: mv s0, a0 ; RV64I-NEXT: mv a0, s1 -; RV64I-NEXT: mv a1, s2 +; RV64I-NEXT: li a1, 0 ; RV64I-NEXT: call __addsf3 ; RV64I-NEXT: mv s1, a0 -; RV64I-NEXT: mv a0, s3 +; RV64I-NEXT: mv a0, s2 ; RV64I-NEXT: mv a1, s0 ; RV64I-NEXT: call __mulsf3 ; RV64I-NEXT: lui a1, 524288 ; RV64I-NEXT: xor a0, a0, a1 ; RV64I-NEXT: mv a1, s1 ; RV64I-NEXT: call __subsf3 -; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload -; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload -; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload -; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload -; RV64I-NEXT: ld s3, 8(sp) # 8-byte Folded Reload -; RV64I-NEXT: addi sp, sp, 48 +; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload +; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload +; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload +; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload +; RV64I-NEXT: addi sp, sp, 32 ; RV64I-NEXT: ret %a_ = fadd float 0.0, %a ; avoid negation using xor %b_ = fadd float 0.0, %b ; avoid negation using xor @@ -1073,63 +1058,58 @@ define float @fnmsub_s_contract(float %a, float %b, float %c) nounwind { ; ; RV32I-LABEL: fnmsub_s_contract: ; RV32I: # %bb.0: -; RV32I-NEXT: addi sp, sp, -32 -; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill -; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill -; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill -; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill -; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill +; RV32I-NEXT: addi sp, sp, -16 +; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill +; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill +; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill +; RV32I-NEXT: sw s2, 0(sp) # 4-byte Folded Spill ; RV32I-NEXT: mv s0, a1 ; RV32I-NEXT: mv s1, a2 ; RV32I-NEXT: li a1, 0 ; RV32I-NEXT: call __addsf3 -; RV32I-NEXT: mv s3, a0 +; RV32I-NEXT: mv s2, a0 ; RV32I-NEXT: mv a0, s0 ; RV32I-NEXT: li a1, 0 ; RV32I-NEXT: call __addsf3 ; RV32I-NEXT: mv a1, a0 -; RV32I-NEXT: mv a0, s3 +; RV32I-NEXT: mv a0, s2 ; RV32I-NEXT: call __mulsf3 ; RV32I-NEXT: mv a1, a0 ; RV32I-NEXT: mv a0, s1 ; RV32I-NEXT: call __subsf3 -; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload -; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload -; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload -; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload -; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload -; RV32I-NEXT: addi sp, sp, 32 +; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload +; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload +; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload +; RV32I-NEXT: lw s2, 0(sp) # 4-byte Folded Reload +; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: ret ; ; RV64I-LABEL: fnmsub_s_contract: ; RV64I: # %bb.0: -; RV64I-NEXT: addi sp, sp, -48 -; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill -; RV64I-NEXT: sd s0, 32(sp) # 8-byte Folded Spill -; RV64I-NEXT: sd s1, 24(sp) # 8-byte Folded Spill -; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill -; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill +; RV64I-NEXT: addi sp, sp, -32 +; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill +; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill +; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill +; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill ; RV64I-NEXT: mv s0, a1 ; RV64I-NEXT: mv s1, a2 -; RV64I-NEXT: sext.w s2, zero -; RV64I-NEXT: mv a1, s2 +; RV64I-NEXT: li a1, 0 ; RV64I-NEXT: call __addsf3 -; RV64I-NEXT: mv s3, a0 +; RV64I-NEXT: mv s2, a0 ; RV64I-NEXT: mv a0, s0 -; RV64I-NEXT: mv a1, s2 +; RV64I-NEXT: li a1, 0 ; RV64I-NEXT: call __addsf3 ; RV64I-NEXT: mv a1, a0 -; RV64I-NEXT: mv a0, s3 +; RV64I-NEXT: mv a0, s2 ; RV64I-NEXT: call __mulsf3 ; RV64I-NEXT: mv a1, a0 ; RV64I-NEXT: mv a0, s1 ; RV64I-NEXT: call __subsf3 -; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload -; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload -; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload -; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload -; RV64I-NEXT: ld s3, 8(sp) # 8-byte Folded Reload -; RV64I-NEXT: addi sp, sp, 48 +; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload +; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload +; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload +; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload +; RV64I-NEXT: addi sp, sp, 32 ; RV64I-NEXT: ret %a_ = fadd float 0.0, %a ; avoid negation using xor %b_ = fadd float 0.0, %b ; avoid negation using xor diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/vararg.ll b/llvm/test/CodeGen/RISCV/GlobalISel/vararg.ll index f43b255a679e3..bb96ba7e5b1fb 100644 --- a/llvm/test/CodeGen/RISCV/GlobalISel/vararg.ll +++ b/llvm/test/CodeGen/RISCV/GlobalISel/vararg.ll @@ -437,8 +437,8 @@ define void @va1_caller() nounwind { ; LP64: # %bb.0: ; LP64-NEXT: addi sp, sp, -16 ; LP64-NEXT: sd ra, 8(sp) # 8-byte Folded Spill -; LP64-NEXT: li a0, 1023 -; LP64-NEXT: slli a1, a0, 52 +; LP64-NEXT: li a1, 1023 +; LP64-NEXT: slli a1, a1, 52 ; LP64-NEXT: li a2, 2 ; LP64-NEXT: call va1 ; LP64-NEXT: ld ra, 8(sp) # 8-byte Folded Reload @@ -494,8 +494,8 @@ define void @va1_caller() nounwind { ; RV64-WITHFP-NEXT: sd ra, 8(sp) # 8-byte Folded Spill ; RV64-WITHFP-NEXT: sd s0, 0(sp) # 8-byte Folded Spill ; RV64-WITHFP-NEXT: addi s0, sp, 16 -; RV64-WITHFP-NEXT: li a0, 1023 -; RV64-WITHFP-NEXT: slli a1, a0, 52 +; RV64-WITHFP-NEXT: li a1, 1023 +; RV64-WITHFP-NEXT: slli a1, a1, 52 ; RV64-WITHFP-NEXT: li a2, 2 ; RV64-WITHFP-NEXT: call va1 ; RV64-WITHFP-NEXT: ld ra, 8(sp) # 8-byte Folded Reload From 7c868d7449c1825ca8b77e2a419b00734f19c4af Mon Sep 17 00:00:00 2001 From: Shaoce SUN Date: Sun, 14 Sep 2025 02:46:42 +0800 Subject: [PATCH 4/6] Convert G_FCONSTANT to G_CONSTANT --- .../RISCV/GISel/RISCVInstructionSelector.cpp | 10 ------ .../Target/RISCV/GISel/RISCVLegalizerInfo.cpp | 22 +++++++++---- .../Target/RISCV/GISel/RISCVLegalizerInfo.h | 1 + .../RISCV/GISel/RISCVRegisterBankInfo.cpp | 32 ++++++++----------- 4 files changed, 31 insertions(+), 34 deletions(-) diff --git a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp index 4f6062184edc2..7df1b7e580002 100644 --- a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp +++ b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp @@ -740,16 +740,6 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) { const APFloat &FPimm = MI.getOperand(1).getFPImm()->getValueAPF(); APInt Imm = FPimm.bitcastToAPInt(); unsigned Size = MRI->getType(DstReg).getSizeInBits(); - - if (!Subtarget->hasStdExtF() && - (Size == 32 || (Size == 64 && Subtarget->is64Bit()))) { - if (!materializeImm(DstReg, Imm.getSExtValue(), MIB)) - return false; - - MI.eraseFromParent(); - return true; - } - if (Size == 16 || Size == 32 || (Size == 64 && Subtarget->is64Bit())) { Register GPRReg = MRI->createVirtualRegister(&RISCV::GPRRegClass); if (!materializeImm(GPRReg, Imm.getSExtValue(), MIB)) diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp index 7e984e6146452..5aa17bc9fe880 100644 --- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp +++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp @@ -871,6 +871,12 @@ bool RISCVLegalizerInfo::shouldBeInConstantPool(const APInt &APImm, return !(!SeqLo.empty() && (SeqLo.size() + 2) <= STI.getMaxBuildIntsCost()); } +bool RISCVLegalizerInfo::shouldBeInFConstantPool(const APFloat &APImm) const { + if (APImm.isZero() || APImm.isExactlyValue(1.0)) + return false; + return true; +} + bool RISCVLegalizerInfo::legalizeVScale(MachineInstr &MI, MachineIRBuilder &MIB) const { const LLT XLenTy(STI.getXLenVT()); @@ -1361,12 +1367,16 @@ bool RISCVLegalizerInfo::legalizeCustom( case TargetOpcode::G_ABS: return Helper.lowerAbsToMaxNeg(MI); case TargetOpcode::G_FCONSTANT: { - const ConstantFP *ConstVal = MI.getOperand(1).getFPImm(); - bool ShouldOptForSize = MF.getFunction().hasOptSize(); - if (!shouldBeInConstantPool(ConstVal->getValue().bitcastToAPInt(), - ShouldOptForSize)) - return true; - return Helper.lowerFConstant(MI); + const APFloat FVal = MI.getOperand(1).getFPImm()->getValueAPF(); + if (shouldBeInFConstantPool(FVal)) + return Helper.lowerFConstant(MI); + + // Convert G_FCONSTANT to G_CONSTANT. + Register DstReg = MI.getOperand(0).getReg(); + MIRBuilder.buildConstant(DstReg, FVal.bitcastToAPInt()); + + MI.eraseFromParent(); + return true; } case TargetOpcode::G_CONSTANT: { const Function &F = MF.getFunction(); diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.h b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.h index 4451866745194..bd6d1665849c8 100644 --- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.h +++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.h @@ -39,6 +39,7 @@ class RISCVLegalizerInfo : public LegalizerInfo { private: bool shouldBeInConstantPool(const APInt &APImm, bool ShouldOptForSize) const; + bool shouldBeInFConstantPool(const APFloat &APImm) const; bool legalizeShlAshrLshr(MachineInstr &MI, MachineIRBuilder &MIRBuilder, GISelChangeObserver &Observer) const; diff --git a/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp index 6152de5840b05..a082b18867666 100644 --- a/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp +++ b/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp @@ -112,8 +112,7 @@ using namespace llvm; RISCVRegisterBankInfo::RISCVRegisterBankInfo(unsigned HwMode) : RISCVGenRegisterBankInfo(HwMode) {} -static const RegisterBankInfo::ValueMapping * -getFPValueMapping(unsigned Size, bool HasFPExt = true) { +static const RegisterBankInfo::ValueMapping *getFPValueMapping(unsigned Size) { unsigned Idx; switch (Size) { default: @@ -122,10 +121,10 @@ getFPValueMapping(unsigned Size, bool HasFPExt = true) { Idx = RISCV::FPRB16Idx; break; case 32: - Idx = HasFPExt ? RISCV::FPRB32Idx : RISCV::GPRB32Idx; + Idx = RISCV::FPRB32Idx; break; case 64: - Idx = HasFPExt ? RISCV::FPRB64Idx : RISCV::GPRB64Idx; + Idx = RISCV::FPRB64Idx; break; } return &RISCV::ValueMappings[Idx]; @@ -220,9 +219,6 @@ RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { const TargetSubtargetInfo &STI = MF.getSubtarget(); const TargetRegisterInfo &TRI = *STI.getRegisterInfo(); - // D and Zfh extension implies F. - bool HasFPExt = STI.hasFeature(RISCV::FeatureStdExtF); - unsigned GPRSize = getMaximumSize(RISCV::GPRBRegBankID); assert((GPRSize == 32 || GPRSize == 64) && "Unexpected GPR size"); @@ -270,7 +266,7 @@ RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { if (Ty.isVector()) Mapping = getVRBValueMapping(Size.getKnownMinValue()); else if (isPreISelGenericFloatingPointOpcode(Opc)) - Mapping = getFPValueMapping(Size.getFixedValue(), HasFPExt); + Mapping = getFPValueMapping(Size.getFixedValue()); else Mapping = GPRValueMapping; @@ -305,7 +301,7 @@ RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { if (DstTy.isVector()) Mapping = getVRBValueMapping(DstMinSize); else if (anyUseOnlyUseFP(Dst, MRI, TRI)) - Mapping = getFPValueMapping(DstMinSize, HasFPExt); + Mapping = getFPValueMapping(DstMinSize); return getInstructionMapping(DefaultMappingID, /*Cost=*/1, Mapping, NumOperands); @@ -343,7 +339,7 @@ RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { // assume this was a floating point load in the IR. If it was // not, we would have had a bitcast before reaching that // instruction. - OpdsMapping[0] = getFPValueMapping(Size, HasFPExt); + OpdsMapping[0] = getFPValueMapping(Size); break; } @@ -371,7 +367,7 @@ RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { MachineInstr *DefMI = MRI.getVRegDef(MI.getOperand(0).getReg()); if (onlyDefinesFP(*DefMI, MRI, TRI)) - OpdsMapping[0] = getFPValueMapping(Ty.getSizeInBits(), HasFPExt); + OpdsMapping[0] = getFPValueMapping(Ty.getSizeInBits()); break; } case TargetOpcode::G_SELECT: { @@ -436,7 +432,7 @@ RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { const ValueMapping *Mapping = GPRValueMapping; if (NumFP >= 2) - Mapping = getFPValueMapping(Ty.getSizeInBits(), HasFPExt); + Mapping = getFPValueMapping(Ty.getSizeInBits()); OpdsMapping[0] = OpdsMapping[2] = OpdsMapping[3] = Mapping; break; @@ -448,13 +444,13 @@ RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { case RISCV::G_FCLASS: { LLT Ty = MRI.getType(MI.getOperand(1).getReg()); OpdsMapping[0] = GPRValueMapping; - OpdsMapping[1] = getFPValueMapping(Ty.getSizeInBits(), HasFPExt); + OpdsMapping[1] = getFPValueMapping(Ty.getSizeInBits()); break; } case TargetOpcode::G_SITOFP: case TargetOpcode::G_UITOFP: { LLT Ty = MRI.getType(MI.getOperand(0).getReg()); - OpdsMapping[0] = getFPValueMapping(Ty.getSizeInBits(), HasFPExt); + OpdsMapping[0] = getFPValueMapping(Ty.getSizeInBits()); OpdsMapping[1] = GPRValueMapping; break; } @@ -472,7 +468,7 @@ RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { LLT Ty = MRI.getType(MI.getOperand(0).getReg()); if (GPRSize == 32 && Ty.getSizeInBits() == 64) { assert(MF.getSubtarget().hasStdExtD()); - OpdsMapping[0] = getFPValueMapping(Ty.getSizeInBits(), HasFPExt); + OpdsMapping[0] = getFPValueMapping(Ty.getSizeInBits()); OpdsMapping[1] = GPRValueMapping; OpdsMapping[2] = GPRValueMapping; } @@ -485,7 +481,7 @@ RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { assert(MF.getSubtarget().hasStdExtD()); OpdsMapping[0] = GPRValueMapping; OpdsMapping[1] = GPRValueMapping; - OpdsMapping[2] = getFPValueMapping(Ty.getSizeInBits(), HasFPExt); + OpdsMapping[2] = getFPValueMapping(Ty.getSizeInBits()); } break; } @@ -499,7 +495,7 @@ RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { if ((GPRSize == 32 && ScalarTy.getSizeInBits() == 64) || onlyDefinesFP(*DefMI, MRI, TRI)) { assert(MF.getSubtarget().hasStdExtD()); - OpdsMapping[1] = getFPValueMapping(ScalarTy.getSizeInBits(), HasFPExt); + OpdsMapping[1] = getFPValueMapping(ScalarTy.getSizeInBits()); } else OpdsMapping[1] = GPRValueMapping; break; @@ -518,7 +514,7 @@ RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { OpdsMapping[Idx] = getVRBValueMapping(Ty.getSizeInBits().getKnownMinValue()); else if (isPreISelGenericFloatingPointOpcode(Opc)) - OpdsMapping[Idx] = getFPValueMapping(Ty.getSizeInBits(), HasFPExt); + OpdsMapping[Idx] = getFPValueMapping(Ty.getSizeInBits()); else OpdsMapping[Idx] = GPRValueMapping; } From a4eca167f9903ad6e0186ed07b079e38d41247df Mon Sep 17 00:00:00 2001 From: Shaoce SUN Date: Sun, 14 Sep 2025 05:53:26 +0800 Subject: [PATCH 5/6] Add test: constant pool test for 1234.5 --- .../CodeGen/RISCV/GlobalISel/constantpool.ll | 109 ++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/constantpool.ll b/llvm/test/CodeGen/RISCV/GlobalISel/constantpool.ll index 849bb13009e16..06beff85995f9 100644 --- a/llvm/test/CodeGen/RISCV/GlobalISel/constantpool.ll +++ b/llvm/test/CodeGen/RISCV/GlobalISel/constantpool.ll @@ -108,3 +108,112 @@ define void @constpool_f64(ptr %p) { store double 1.0, ptr %p ret void } + +define void @constpool_f32_1234_5(ptr %p) { +; RV32-SMALL-LABEL: constpool_f32_1234_5: +; RV32-SMALL: # %bb.0: +; RV32-SMALL-NEXT: lui a1, %hi(.LCPI2_0) +; RV32-SMALL-NEXT: lw a1, %lo(.LCPI2_0)(a1) +; RV32-SMALL-NEXT: sw a1, 0(a0) +; RV32-SMALL-NEXT: ret +; +; RV32-MEDIUM-LABEL: constpool_f32_1234_5: +; RV32-MEDIUM: # %bb.0: +; RV32-MEDIUM-NEXT: .Lpcrel_hi1: +; RV32-MEDIUM-NEXT: auipc a1, %pcrel_hi(.LCPI2_0) +; RV32-MEDIUM-NEXT: lw a1, %pcrel_lo(.Lpcrel_hi1)(a1) +; RV32-MEDIUM-NEXT: sw a1, 0(a0) +; RV32-MEDIUM-NEXT: ret +; +; RV32-PIC-LABEL: constpool_f32_1234_5: +; RV32-PIC: # %bb.0: +; RV32-PIC-NEXT: .Lpcrel_hi1: +; RV32-PIC-NEXT: auipc a1, %pcrel_hi(.LCPI2_0) +; RV32-PIC-NEXT: lw a1, %pcrel_lo(.Lpcrel_hi1)(a1) +; RV32-PIC-NEXT: sw a1, 0(a0) +; RV32-PIC-NEXT: ret +; +; RV64-SMALL-LABEL: constpool_f32_1234_5: +; RV64-SMALL: # %bb.0: +; RV64-SMALL-NEXT: lui a1, %hi(.LCPI2_0) +; RV64-SMALL-NEXT: lw a1, %lo(.LCPI2_0)(a1) +; RV64-SMALL-NEXT: sw a1, 0(a0) +; RV64-SMALL-NEXT: ret +; +; RV64-MEDIUM-LABEL: constpool_f32_1234_5: +; RV64-MEDIUM: # %bb.0: +; RV64-MEDIUM-NEXT: .Lpcrel_hi0: +; RV64-MEDIUM-NEXT: auipc a1, %pcrel_hi(.LCPI2_0) +; RV64-MEDIUM-NEXT: lw a1, %pcrel_lo(.Lpcrel_hi0)(a1) +; RV64-MEDIUM-NEXT: sw a1, 0(a0) +; RV64-MEDIUM-NEXT: ret +; +; RV64-PIC-LABEL: constpool_f32_1234_5: +; RV64-PIC: # %bb.0: +; RV64-PIC-NEXT: .Lpcrel_hi0: +; RV64-PIC-NEXT: auipc a1, %pcrel_hi(.LCPI2_0) +; RV64-PIC-NEXT: lw a1, %pcrel_lo(.Lpcrel_hi0)(a1) +; RV64-PIC-NEXT: sw a1, 0(a0) +; RV64-PIC-NEXT: ret + store float 1.234500e+03, ptr %p + ret void +} + +define void @constpool_f64_1234_5(ptr %p) { +; RV32-SMALL-LABEL: constpool_f64_1234_5: +; RV32-SMALL: # %bb.0: +; RV32-SMALL-NEXT: lui a1, %hi(.LCPI3_0) +; RV32-SMALL-NEXT: addi a1, a1, %lo(.LCPI3_0) +; RV32-SMALL-NEXT: lw a2, 0(a1) +; RV32-SMALL-NEXT: lw a1, 4(a1) +; RV32-SMALL-NEXT: sw a2, 0(a0) +; RV32-SMALL-NEXT: sw a1, 4(a0) +; RV32-SMALL-NEXT: ret +; +; RV32-MEDIUM-LABEL: constpool_f64_1234_5: +; RV32-MEDIUM: # %bb.0: +; RV32-MEDIUM-NEXT: .Lpcrel_hi2: +; RV32-MEDIUM-NEXT: auipc a1, %pcrel_hi(.LCPI3_0) +; RV32-MEDIUM-NEXT: addi a1, a1, %pcrel_lo(.Lpcrel_hi2) +; RV32-MEDIUM-NEXT: lw a2, 0(a1) +; RV32-MEDIUM-NEXT: lw a1, 4(a1) +; RV32-MEDIUM-NEXT: sw a2, 0(a0) +; RV32-MEDIUM-NEXT: sw a1, 4(a0) +; RV32-MEDIUM-NEXT: ret +; +; RV32-PIC-LABEL: constpool_f64_1234_5: +; RV32-PIC: # %bb.0: +; RV32-PIC-NEXT: .Lpcrel_hi2: +; RV32-PIC-NEXT: auipc a1, %pcrel_hi(.LCPI3_0) +; RV32-PIC-NEXT: addi a1, a1, %pcrel_lo(.Lpcrel_hi2) +; RV32-PIC-NEXT: lw a2, 0(a1) +; RV32-PIC-NEXT: lw a1, 4(a1) +; RV32-PIC-NEXT: sw a2, 0(a0) +; RV32-PIC-NEXT: sw a1, 4(a0) +; RV32-PIC-NEXT: ret +; +; RV64-SMALL-LABEL: constpool_f64_1234_5: +; RV64-SMALL: # %bb.0: +; RV64-SMALL-NEXT: lui a1, %hi(.LCPI3_0) +; RV64-SMALL-NEXT: ld a1, %lo(.LCPI3_0)(a1) +; RV64-SMALL-NEXT: sd a1, 0(a0) +; RV64-SMALL-NEXT: ret +; +; RV64-MEDIUM-LABEL: constpool_f64_1234_5: +; RV64-MEDIUM: # %bb.0: +; RV64-MEDIUM-NEXT: .Lpcrel_hi1: +; RV64-MEDIUM-NEXT: auipc a1, %pcrel_hi(.LCPI3_0) +; RV64-MEDIUM-NEXT: ld a1, %pcrel_lo(.Lpcrel_hi1)(a1) +; RV64-MEDIUM-NEXT: sd a1, 0(a0) +; RV64-MEDIUM-NEXT: ret +; +; RV64-PIC-LABEL: constpool_f64_1234_5: +; RV64-PIC: # %bb.0: +; RV64-PIC-NEXT: .Lpcrel_hi1: +; RV64-PIC-NEXT: auipc a1, %pcrel_hi(.LCPI3_0) +; RV64-PIC-NEXT: ld a1, %pcrel_lo(.Lpcrel_hi1)(a1) +; RV64-PIC-NEXT: sd a1, 0(a0) +; RV64-PIC-NEXT: ret + store double 1.234500e+03, ptr %p + ret void +} From a56f79a3116bac8e2de53c26a82fc816cca3525e Mon Sep 17 00:00:00 2001 From: Shaoce SUN Date: Sun, 14 Sep 2025 06:01:35 +0800 Subject: [PATCH 6/6] Add more cases in `shouldBeInFConstantPool` --- .../Target/RISCV/GISel/RISCVLegalizerInfo.cpp | 9 +++- .../CodeGen/RISCV/GlobalISel/constantpool.ll | 47 ++++++++----------- 2 files changed, 26 insertions(+), 30 deletions(-) diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp index 5aa17bc9fe880..82a571587cc77 100644 --- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp +++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp @@ -871,8 +871,13 @@ bool RISCVLegalizerInfo::shouldBeInConstantPool(const APInt &APImm, return !(!SeqLo.empty() && (SeqLo.size() + 2) <= STI.getMaxBuildIntsCost()); } -bool RISCVLegalizerInfo::shouldBeInFConstantPool(const APFloat &APImm) const { - if (APImm.isZero() || APImm.isExactlyValue(1.0)) +bool RISCVLegalizerInfo::shouldBeInFConstantPool(const APFloat &APF) const { + [[maybe_unused]] unsigned Size = APF.getSizeInBits(APF.getSemantics()); + assert((Size == 32 || Size == 64) && "Only support f32 and f64"); + + int64_t Imm = APF.bitcastToAPInt().getSExtValue(); + RISCVMatInt::InstSeq Seq = RISCVMatInt::generateInstSeq(Imm, STI); + if (Seq.size() <= STI.getMaxBuildIntsCost()) return false; return true; } diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/constantpool.ll b/llvm/test/CodeGen/RISCV/GlobalISel/constantpool.ll index 06beff85995f9..cee04492dc441 100644 --- a/llvm/test/CodeGen/RISCV/GlobalISel/constantpool.ll +++ b/llvm/test/CodeGen/RISCV/GlobalISel/constantpool.ll @@ -112,47 +112,37 @@ define void @constpool_f64(ptr %p) { define void @constpool_f32_1234_5(ptr %p) { ; RV32-SMALL-LABEL: constpool_f32_1234_5: ; RV32-SMALL: # %bb.0: -; RV32-SMALL-NEXT: lui a1, %hi(.LCPI2_0) -; RV32-SMALL-NEXT: lw a1, %lo(.LCPI2_0)(a1) +; RV32-SMALL-NEXT: lui a1, 280997 ; RV32-SMALL-NEXT: sw a1, 0(a0) ; RV32-SMALL-NEXT: ret ; ; RV32-MEDIUM-LABEL: constpool_f32_1234_5: ; RV32-MEDIUM: # %bb.0: -; RV32-MEDIUM-NEXT: .Lpcrel_hi1: -; RV32-MEDIUM-NEXT: auipc a1, %pcrel_hi(.LCPI2_0) -; RV32-MEDIUM-NEXT: lw a1, %pcrel_lo(.Lpcrel_hi1)(a1) +; RV32-MEDIUM-NEXT: lui a1, 280997 ; RV32-MEDIUM-NEXT: sw a1, 0(a0) ; RV32-MEDIUM-NEXT: ret ; ; RV32-PIC-LABEL: constpool_f32_1234_5: ; RV32-PIC: # %bb.0: -; RV32-PIC-NEXT: .Lpcrel_hi1: -; RV32-PIC-NEXT: auipc a1, %pcrel_hi(.LCPI2_0) -; RV32-PIC-NEXT: lw a1, %pcrel_lo(.Lpcrel_hi1)(a1) +; RV32-PIC-NEXT: lui a1, 280997 ; RV32-PIC-NEXT: sw a1, 0(a0) ; RV32-PIC-NEXT: ret ; ; RV64-SMALL-LABEL: constpool_f32_1234_5: ; RV64-SMALL: # %bb.0: -; RV64-SMALL-NEXT: lui a1, %hi(.LCPI2_0) -; RV64-SMALL-NEXT: lw a1, %lo(.LCPI2_0)(a1) +; RV64-SMALL-NEXT: lui a1, 280997 ; RV64-SMALL-NEXT: sw a1, 0(a0) ; RV64-SMALL-NEXT: ret ; ; RV64-MEDIUM-LABEL: constpool_f32_1234_5: ; RV64-MEDIUM: # %bb.0: -; RV64-MEDIUM-NEXT: .Lpcrel_hi0: -; RV64-MEDIUM-NEXT: auipc a1, %pcrel_hi(.LCPI2_0) -; RV64-MEDIUM-NEXT: lw a1, %pcrel_lo(.Lpcrel_hi0)(a1) +; RV64-MEDIUM-NEXT: lui a1, 280997 ; RV64-MEDIUM-NEXT: sw a1, 0(a0) ; RV64-MEDIUM-NEXT: ret ; ; RV64-PIC-LABEL: constpool_f32_1234_5: ; RV64-PIC: # %bb.0: -; RV64-PIC-NEXT: .Lpcrel_hi0: -; RV64-PIC-NEXT: auipc a1, %pcrel_hi(.LCPI2_0) -; RV64-PIC-NEXT: lw a1, %pcrel_lo(.Lpcrel_hi0)(a1) +; RV64-PIC-NEXT: lui a1, 280997 ; RV64-PIC-NEXT: sw a1, 0(a0) ; RV64-PIC-NEXT: ret store float 1.234500e+03, ptr %p @@ -172,9 +162,9 @@ define void @constpool_f64_1234_5(ptr %p) { ; ; RV32-MEDIUM-LABEL: constpool_f64_1234_5: ; RV32-MEDIUM: # %bb.0: -; RV32-MEDIUM-NEXT: .Lpcrel_hi2: +; RV32-MEDIUM-NEXT: .Lpcrel_hi1: ; RV32-MEDIUM-NEXT: auipc a1, %pcrel_hi(.LCPI3_0) -; RV32-MEDIUM-NEXT: addi a1, a1, %pcrel_lo(.Lpcrel_hi2) +; RV32-MEDIUM-NEXT: addi a1, a1, %pcrel_lo(.Lpcrel_hi1) ; RV32-MEDIUM-NEXT: lw a2, 0(a1) ; RV32-MEDIUM-NEXT: lw a1, 4(a1) ; RV32-MEDIUM-NEXT: sw a2, 0(a0) @@ -183,9 +173,9 @@ define void @constpool_f64_1234_5(ptr %p) { ; ; RV32-PIC-LABEL: constpool_f64_1234_5: ; RV32-PIC: # %bb.0: -; RV32-PIC-NEXT: .Lpcrel_hi2: +; RV32-PIC-NEXT: .Lpcrel_hi1: ; RV32-PIC-NEXT: auipc a1, %pcrel_hi(.LCPI3_0) -; RV32-PIC-NEXT: addi a1, a1, %pcrel_lo(.Lpcrel_hi2) +; RV32-PIC-NEXT: addi a1, a1, %pcrel_lo(.Lpcrel_hi1) ; RV32-PIC-NEXT: lw a2, 0(a1) ; RV32-PIC-NEXT: lw a1, 4(a1) ; RV32-PIC-NEXT: sw a2, 0(a0) @@ -194,24 +184,25 @@ define void @constpool_f64_1234_5(ptr %p) { ; ; RV64-SMALL-LABEL: constpool_f64_1234_5: ; RV64-SMALL: # %bb.0: -; RV64-SMALL-NEXT: lui a1, %hi(.LCPI3_0) -; RV64-SMALL-NEXT: ld a1, %lo(.LCPI3_0)(a1) +; RV64-SMALL-NEXT: lui a1, 517 +; RV64-SMALL-NEXT: addi a1, a1, -1627 +; RV64-SMALL-NEXT: slli a1, a1, 41 ; RV64-SMALL-NEXT: sd a1, 0(a0) ; RV64-SMALL-NEXT: ret ; ; RV64-MEDIUM-LABEL: constpool_f64_1234_5: ; RV64-MEDIUM: # %bb.0: -; RV64-MEDIUM-NEXT: .Lpcrel_hi1: -; RV64-MEDIUM-NEXT: auipc a1, %pcrel_hi(.LCPI3_0) -; RV64-MEDIUM-NEXT: ld a1, %pcrel_lo(.Lpcrel_hi1)(a1) +; RV64-MEDIUM-NEXT: lui a1, 517 +; RV64-MEDIUM-NEXT: addi a1, a1, -1627 +; RV64-MEDIUM-NEXT: slli a1, a1, 41 ; RV64-MEDIUM-NEXT: sd a1, 0(a0) ; RV64-MEDIUM-NEXT: ret ; ; RV64-PIC-LABEL: constpool_f64_1234_5: ; RV64-PIC: # %bb.0: -; RV64-PIC-NEXT: .Lpcrel_hi1: -; RV64-PIC-NEXT: auipc a1, %pcrel_hi(.LCPI3_0) -; RV64-PIC-NEXT: ld a1, %pcrel_lo(.Lpcrel_hi1)(a1) +; RV64-PIC-NEXT: lui a1, 517 +; RV64-PIC-NEXT: addi a1, a1, -1627 +; RV64-PIC-NEXT: slli a1, a1, 41 ; RV64-PIC-NEXT: sd a1, 0(a0) ; RV64-PIC-NEXT: ret store double 1.234500e+03, ptr %p