@@ -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