https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126454
--- Comment #5 from Drea Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Luke Wren from comment #4)
> Stopping the backtrack when encountering a call is enough to fix the
> MicroPython regression for me:
>
> --- a/gcc/config/riscv/riscv-opt-popretz.cc
> +++ b/gcc/config/riscv/riscv-opt-popretz.cc
> @@ -217,12 +217,15 @@ pass_combine_popretz::execute (function *fn)
> for (rtx_insn *def_insn = PREV_INSN (popret_insn);
> def_insn && def_insn != PREV_INSN (BB_HEAD (bb));
> def_insn = PREV_INSN (def_insn))
> {
> if (!INSN_P (def_insn))
> continue;
> + /* a0 is not preserved across calls: */
> + if (CALL_P (def_insn))
> + break;
> rtx def_pat = PATTERN (def_insn);
> if (GET_CODE (def_pat) == USE
> && REG_P (XEXP (def_pat, 0))
> && REGNO (XEXP (def_pat, 0)) == A0_REGNUM)
> {
> a0_reg = XEXP (def_pat, 0);
That is conseratively correct.
The real fix is to use something different from reg_referenced_p which also
handles implict clobbers of the call. (sometimes calls don't clobber a0).