Hi, Ruoyao, (I might not be able to reply to this thread till next Wed due to a short vacation).
First, some comments on opening bugs against Gcc: I took a look at the bug reports PR104817 and PR104820: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104820 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104817 I didn’t see a testing case and a script to repeat the error, so I cannot repeat the error at my side. So, in order for other people to help to study the bug, you need to provide a testing case and A script or detailed description on how to repeat the bug. In addition to that, it will be helpful if you can provide more details on what’ the root cause of the Issue from your study into the comment part of the bug report. > On Mar 11, 2022, at 11:29 AM, Xi Ruoyao <xry...@mengyan1223.wang> wrote: > > On Fri, 2022-03-11 at 16:08 +0000, Qing Zhao wrote: > >> Why there is “mthi $0” instruction, but there is NO emit_move_insn(HI, >> CONST_0)? >> Is such mismatch a bug? If not, why? >> >>> In theory it's possible >>> to emit the mthi instruction explicitly here though, but we'll need to >>> clear something NOT in need_zeroed_hardregs for MIPS anyway (see below). >> >> One question here, is there situation when only HI is cleared but LO is not >> cleared? > > No, if I interpret the document of -fzero_call_used_regs and > attribute((zero_call_used_regs(...))) correctly. A 2-reg multiplication > (or division) always set the value of both HI and LO. Richard has added > a comment for this in mips.cc: > >> 12868 /* After a multiplication or division, clobbering HI makes >> 1 the value of LO unpredictable, and vice versa. This means >> 2 that, for all interesting cases, HI and LO are effectively >> 3 a single register. >> 4 >> 5 We model this by requiring that any value that uses HI >> 6 also uses LO. */ > > This is also why the handling of emit_move_insn(HI, CONST_0) was > removed, I guess (the removal happened in the same commit adding this > comment). Okay. I see. Then the current handling for HI_REGNUM is reasonable. I suggest to add one assertion inside the handling of HI_REGNUM with proper comment: gcc_assertion (TEST_HARD_REG_BIT (need_zeroed_hardregs, LO_REGNUM)); to catch any unexpected bug. Richard, what’s your opinion on this? > > >>>> >> Okay, I see. So, each ST_REGi register is a 1-bit pseudo register? >> But physically each of them is 1-bit in a physical register? > > Yes. > >>> >>> Because there is no elegant way to clear one specific FCC bit in MIPS. >>> A "ctc1 $0, $25" instruction will zero them altogether. If we really >>> need to clear only one of them (let's say ST_REG3), we'll have to emit >>> something like >>> >>> mtc1 $0, $0 # zero FPR0 to ensure it won't contain sNaN >>> c.f.s $3, $0, $0 >>> >>> Then we'll still need to clobber FPR0 with zero. So anyway we'll have >>> to clear some registers not specified in need_zeroed_hardregs. >> >> So, “c.f.s” instruction can be used to clear ONLY one specific FCC bit? >> But you have to clear one FPR (floating pointer register?) first to avoid >> raising exception? >> My question here is: is there a case when only FCC need to be cleared but >> no FPR need to be cleared? > > Yes, for example: > > double a, b; > > struct x > { > double a, b; > }; > > struct x > f(void) > { > struct x x = > { > .a = a, > .b = b > }; > if (a < b) > x.a = x.b; > return x; > } > > It does not need to zero the two FPRs, as they contain the return value. > But a FCC bit needs to be cleared. Okay. > >> If NOT, then we can always pick one FPRi before c.f.s to avoid the >> issue you mentioned (We’ll have to clear some registers not specified >> in need_zeroed_hardregs). > > I'm now thinking: is there always at least one *GPR* which need to be > cleared? If it's true, let's say GPR $12, and fcc0 & fcc2 needs to be > cleared, we can use something like: So, you mean, in order to set one FCC bit to zero, we have to set another GPR or FPR to zero first? Otherwise an error might occur? Why? (This is unreasonable to me) do I miss anything here? Qing > cfc1 $12, $25 > andi $25, 5 > ctc1 $12, $25 > move $12, $0 > >>> And the question is: is it really allowed to return something other than >>> a subset of need_zeroed_hardregs for a TARGET_ZERO_CALL_USED_REGS hook? >> >> Although currently there is no assertion added to force this >> requirement, I still think that we should keep it. >> >> The “need_zeroed_hardregs” is computed based on >> >> 1. User’s request from command line option; >> 2. Data flow info of the routine; >> 3. Abi info of the target; >> >> If zero_call_used_regs target hook return registers out of >> “need_zeroed_hardregs” set, then it might out of the user’s exception, >> it should be considered as a bug, I think. > > I have the same concern. But now I'm too sleepy... Will try to improve > this tomorrow. > -- > Xi Ruoyao <xry...@mengyan1223.wang> > School of Aerospace Science and Technology, Xidian University