Skip to content

Commit 14b4356

Browse files
authored
[RISCV] Separate more of scalar FP in CC_RISCV. NFC (#107908)
Scalar FP calling convention has gotten more complicated with recent changes to Zfinx/Zdinx, proposed addition of a GPRF16 register class, and using customReg for f16/bf16 and other FP types small than XLen. The previous code tried to share a single getReg and getMem call for many different cases. This patch separates all the FP register handling to the top of the function with their own getReg calls. The only exception is f64 with XLen==32, when we are out of FPRs or not able to use FPRs due to ABI. The way I've structured this, we no longer need to correct the LocVT for FP back to ValVT before the call to getMem.
1 parent 2cfdcfb commit 14b4356

File tree

1 file changed

+36
-36
lines changed

1 file changed

+36
-36
lines changed

llvm/lib/Target/RISCV/RISCVCallingConv.cpp

Lines changed: 36 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -299,44 +299,57 @@ bool llvm::CC_RISCV(unsigned ValNo, MVT ValVT, MVT LocVT,
299299
break;
300300
}
301301

302-
// FPR16, FPR32, and FPR64 alias each other.
303-
if (State.getFirstUnallocated(ArgFPR32s) == std::size(ArgFPR32s)) {
304-
UseGPRForF16_F32 = true;
305-
UseGPRForF64 = true;
302+
if ((LocVT == MVT::f16 || LocVT == MVT::bf16) && !UseGPRForF16_F32) {
303+
if (MCRegister Reg = State.AllocateReg(ArgFPR16s)) {
304+
State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
305+
return false;
306+
}
306307
}
307308

308-
// From this point on, rely on UseGPRForF16_F32, UseGPRForF64 and
309-
// similar local variables rather than directly checking against the target
310-
// ABI.
309+
if (LocVT == MVT::f32 && !UseGPRForF16_F32) {
310+
if (MCRegister Reg = State.AllocateReg(ArgFPR32s)) {
311+
State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
312+
return false;
313+
}
314+
}
315+
316+
if (LocVT == MVT::f64 && !UseGPRForF64) {
317+
if (MCRegister Reg = State.AllocateReg(ArgFPR64s)) {
318+
State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
319+
return false;
320+
}
321+
}
311322

312323
ArrayRef<MCPhysReg> ArgGPRs = RISCV::getArgGPRs(ABI);
313324

314-
if ((ValVT == MVT::f32 && XLen == 32 && Subtarget.hasStdExtZfinx()) ||
315-
(ValVT == MVT::f64 && XLen == 64 && Subtarget.hasStdExtZdinx())) {
325+
// Zfinx/Zdinx use GPR without a bitcast when possible.
326+
if ((LocVT == MVT::f32 && XLen == 32 && Subtarget.hasStdExtZfinx()) ||
327+
(LocVT == MVT::f64 && XLen == 64 && Subtarget.hasStdExtZdinx())) {
316328
if (MCRegister Reg = State.AllocateReg(ArgGPRs)) {
317329
State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
318330
return false;
319331
}
320332
}
321333

322-
if (UseGPRForF16_F32 && (ValVT == MVT::f16 || ValVT == MVT::bf16 ||
323-
(ValVT == MVT::f32 && XLen == 64))) {
324-
MCRegister Reg = State.AllocateReg(ArgGPRs);
325-
if (Reg) {
334+
// FP smaller than XLen, uses custom GPR.
335+
if (LocVT == MVT::f16 || LocVT == MVT::bf16 ||
336+
(LocVT == MVT::f32 && XLen == 64)) {
337+
if (MCRegister Reg = State.AllocateReg(ArgGPRs)) {
326338
LocVT = XLenVT;
327339
State.addLoc(
328340
CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
329341
return false;
330342
}
331343
}
332344

333-
if (UseGPRForF16_F32 &&
334-
(ValVT == MVT::f16 || ValVT == MVT::bf16 || ValVT == MVT::f32)) {
335-
LocVT = XLenVT;
336-
LocInfo = CCValAssign::BCvt;
337-
} else if (UseGPRForF64 && XLen == 64 && ValVT == MVT::f64) {
338-
LocVT = MVT::i64;
339-
LocInfo = CCValAssign::BCvt;
345+
// Bitcast FP to GPR if we can use a GPR register.
346+
if ((XLen == 32 && LocVT == MVT::f32) || (XLen == 64 && LocVT == MVT::f64)) {
347+
if (MCRegister Reg = State.AllocateReg(ArgGPRs)) {
348+
LocVT = XLenVT;
349+
LocInfo = CCValAssign::BCvt;
350+
State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
351+
return false;
352+
}
340353
}
341354

342355
// If this is a variadic argument, the RISC-V calling convention requires
@@ -368,7 +381,7 @@ bool llvm::CC_RISCV(unsigned ValNo, MVT ValVT, MVT LocVT,
368381

369382
// Handle passing f64 on RV32D with a soft float ABI or when floating point
370383
// registers are exhausted.
371-
if (UseGPRForF64 && XLen == 32 && ValVT == MVT::f64) {
384+
if (XLen == 32 && LocVT == MVT::f64) {
372385
assert(PendingLocs.empty() && "Can't lower f64 if it is split");
373386
// Depending on available argument GPRS, f64 may be passed in a pair of
374387
// GPRs, split between a GPR and the stack, or passed completely on the
@@ -430,13 +443,7 @@ bool llvm::CC_RISCV(unsigned ValNo, MVT ValVT, MVT LocVT,
430443
unsigned StoreSizeBytes = XLen / 8;
431444
Align StackAlign = Align(XLen / 8);
432445

433-
if ((ValVT == MVT::f16 || ValVT == MVT::bf16) && !UseGPRForF16_F32)
434-
Reg = State.AllocateReg(ArgFPR16s);
435-
else if (ValVT == MVT::f32 && !UseGPRForF16_F32)
436-
Reg = State.AllocateReg(ArgFPR32s);
437-
else if (ValVT == MVT::f64 && !UseGPRForF64)
438-
Reg = State.AllocateReg(ArgFPR64s);
439-
else if (ValVT.isVector() || ValVT.isRISCVVectorTuple()) {
446+
if (ValVT.isVector() || ValVT.isRISCVVectorTuple()) {
440447
Reg = allocateRVVReg(ValVT, ValNo, State, TLI);
441448
if (Reg) {
442449
// Fixed-length vectors are located in the corresponding scalable-vector
@@ -489,7 +496,7 @@ bool llvm::CC_RISCV(unsigned ValNo, MVT ValVT, MVT LocVT,
489496
return false;
490497
}
491498

492-
assert((!UseGPRForF16_F32 || !UseGPRForF64 || LocVT == XLenVT ||
499+
assert(((ValVT.isFloatingPoint() && !ValVT.isVector()) || LocVT == XLenVT ||
493500
(TLI.getSubtarget().hasVInstructions() &&
494501
(ValVT.isVector() || ValVT.isRISCVVectorTuple()))) &&
495502
"Expected an XLenVT or vector types at this stage");
@@ -499,13 +506,6 @@ bool llvm::CC_RISCV(unsigned ValNo, MVT ValVT, MVT LocVT,
499506
return false;
500507
}
501508

502-
// When a scalar floating-point value is passed on the stack, no
503-
// bit-conversion is needed.
504-
if (ValVT.isFloatingPoint() && LocInfo != CCValAssign::Indirect) {
505-
assert(!ValVT.isVector());
506-
LocVT = ValVT;
507-
LocInfo = CCValAssign::Full;
508-
}
509509
State.addLoc(CCValAssign::getMem(ValNo, ValVT, StackOffset, LocVT, LocInfo));
510510
return false;
511511
}

0 commit comments

Comments
 (0)