https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126454

            Bug ID: 126454
           Summary: RISCV: cm.popretz pass deletes "li a0,0" and gives
                    wrong return value
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: rtl-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: alexey.lapshin at espressif dot com
  Target Milestone: ---

On RISC-V with Zcmp enabled, GCC miscompiles a function that ends with a call
whose first argument is 0 and whose return value is returned. The popretz RTL
pass turns the epilogue cm.popret into cm.popretz and deletes the li a0,0 insn,
but that insn is the argument setup for the preceding call, not a return-value
assignment.

Two things break at once: the callee receives garbage in a0 instead of 0, and
the caller returns 0 instead of the callee's result.

Reproducer https://godbolt.org/z/4vxcvfjME:

// test.c
// compile: gcc -Os -march=rv32i_zcmp
int callee(int a, int *p);
int wrapper(int mode)
{
    int local = mode;
    return callee(0, &local);
}

Reply via email to