Has bugs when optimizing save/restore CSRs by changing CSR_XLEN_F32_Interrupt

As GCC 12.2 does, Interrupt handler only saves Fa & Ft regs, not include Fs regs.
By changing RISCVCallingConv.td like this:

// Same as CSR_Interrupt, but including all 32-bit FP registers.
def CSR_XLEN_F32_Interrupt: CalleeSavedRegs<(add X1,
    (sequence "X%u", 3, 9),
    (sequence "X%u", 10, 11),
    (sequence "X%u", 12, 17),
    (sequence "X%u", 18, 27),
    (sequence "X%u", 28, 31),
    (sequence "F%u_F", 0, 7),
    (sequence "F%u_F", 10, 11),
    (sequence "F%u_F", 12, 17),
    (sequence "F%u_F", 28, 31))>;

I get the wrong result, which is different with gcc’s,

  60025e:	dcf6                	sw	t4,120(sp)
  600260:	dafa                	sw	t5,116(sp)
  600262:	d8fe                	sw	t6,112(sp)
  600264:	f682                	fsw	ft0,108(sp)
  600266:	f486                	fsw	ft1,104(sp)
  600268:	f28a                	fsw	ft2,100(sp)
  60026a:	f08e                	fsw	ft3,96(sp)
  60026c:	ee92                	fsw	ft4,92(sp)
  60026e:	ec96                	fsw	ft5,88(sp)
  600270:	ea9a                	fsw	ft6,84(sp)
  600272:	e89e                	fsw	ft7,80(sp)
  600274:	e6aa                	fsw	fa0,76(sp)
  600276:	e4ae                	fsw	fa1,72(sp)
  600278:	e2b2                	fsw	fa2,68(sp)
  60027a:	e0b6                	fsw	fa3,64(sp)
  60027c:	fe3a                	fsw	fa4,60(sp)
  60027e:	fc3e                	fsw	fa5,56(sp)
  600280:	fa42                	fsw	fa6,52(sp)
  600282:	f846                	fsw	fa7,48(sp)
  600284:	f672                	fsw	ft8,44(sp)
  600286:	f476                	fsw	ft9,40(sp)
  600288:	f27a                	fsw	ft10,36(sp)
  60028a:	f07e                	fsw	ft11,32(sp)
  60028c:	6541                	lui	a0,0x10
  60028e:	00052503          	lw	a0,0(a0) # 10000 <a>
  600292:	65c1                	lui	a1,0x10
  600294:	0045a407          	flw	fs0,4(a1) # 10004 <b>
  600298:	d00574d3          	fcvt.s.w	fs1,a0
  60029c:	40a00537          	lui	a0,0x40a00
  6002a0:	f0050953          	fmv.w.x	fs2,a0
  6002a4:	49247443          	fmadd.s	fs0,fs0,fs2,fs1
  6002a8:	b881a027          	fsw	fs0,-1152(gp) # 10380 <c>
  6002ac:	3791                	jal	6001f0 <foo>
  6002ae:	50ba                	lw	ra,172(sp)
  6002b0:	52aa                	lw	t0,168(sp)
  6002b2:	531a                	lw	t1,164(sp)
  6002b4:	538a                	lw	t2,160(sp)
  6002b6:	457a                	lw	a0,156(sp)
  6002b8:	45ea                	lw	a1,152(sp)

In the prelogue, It indeed does not save Fs regs, but uses Fs reg in the rest program.
While gcc 12.2 only uses Fa/Ft regs.

I think the issue is in RISCVFrameLowering::determineCalleeSaves. This is blindly forcing all FP registers to be saved for interrupt handlers with calls.

    if (Subtarget.hasStdExtF()) {                                                
                                                                                 
      // If interrupt is enabled, this list contains all FP registers.           
      const MCPhysReg * Regs = MF.getRegInfo().getCalleeSavedRegs();             
                                                                                 
      for (unsigned i = 0; Regs[i]; ++i)                                         
        if (RISCV::FPR16RegClass.contains(Regs[i]) ||                            
            RISCV::FPR32RegClass.contains(Regs[i]) ||                            
            RISCV::FPR64RegClass.contains(Regs[i]))                              
          SavedRegs.set(Regs[i]);                                                
    }

I’m working on a fix

Thanks a lot.
Here I add some more information.
source code:

volatile int a = 3;
volatile float b = 3.3;
volatile float c;
void foo(){

c = a + b * 4;
}
void __attribute__((interrupt("machine"))) timer_isr(){
	 c = a + b * 5;
     foo();
}

Dis Asm code from LLVM 18

  60028c:	6541                	lui	a0,0x10
  60028e:	00052503          	lw	a0,0(a0) # 10000 <a>
  600292:	65c1                	lui	a1,0x10
  600294:	0045a407          	flw	fs0,4(a1) # 10004 <b>
  600298:	d00574d3          	fcvt.s.w	fs1,a0
  60029c:	40a00537          	lui	a0,0x40a00
  6002a0:	f0050953          	fmv.w.x	fs2,a0
  6002a4:	49247443          	fmadd.s	fs0,fs0,fs2,fs1
  6002a8:	b881a027          	fsw	fs0,-1152(gp) # 10380 <c>
  6002ac:	3791                	jal	6001f0 <foo>

Dis Asm code from GCC 12.2

  60027e:	1100                	addi	s0,sp,160
  600280:	67c1                	lui	a5,0x10
  600282:	0047a783          	lw	a5,4(a5) # 10004 <a>
  600286:	d007f753          	fcvt.s.w	fa4,a5
  60028a:	67c1                	lui	a5,0x10
  60028c:	0007a787          	flw	fa5,0(a5) # 10000 <b>
  600290:	006017b7          	lui	a5,0x601
  600294:	0ac7a687          	flw	fa3,172(a5) # 6010ac <Device_init+0xdc>
  600298:	70d7f7c3          	fmadd.s	fa5,fa5,fa3,fa4
  60029c:	b0f1a027          	fsw	fa5,-1280(gp) # 10300 <c>
  6002a0:	3785                	jal	600200 <foo>