noreturn functions save registers
Zig Version
0.15.0-dev.558+9279ff888
Steps to Reproduce and Observed Behavior
Compile a function with a return type of noreturn. The generated code saves various registers.
Tested on compiler for rp2350 arm and riscv.
Expected Behavior
noreturn functions should not save registers.
Since the function cannot return, there is no reason to save existing registers, so doing so just wastes stack space. This is especially a problem when writing code for small embedded processors or other situation where stack space is at a premium.
Please include an example of what you mean in the issue description.
When compiling the function:
fn taskA() noreturn {
while (true) {
std.log.debug("{s}TaskA -- Top of loop -- waiting for event", .{scheduler.platform.debugCore()});
scheduler.waitForEvent(0x01, true);
std.log.debug("{s}TaskA -- Send Event to charlie", .{scheduler.platform.debugCore()});
scheduler.signalEvent(.charlie, 0x01);
}
}
We get:
420011c4 <main_esp32_c3.taskA>:
420011c4: 7139 addi sp,sp,-64
420011c6: de06 sw ra,60(sp)
420011c8: dc22 sw s0,56(sp)
420011ca: da26 sw s1,52(sp)
420011cc: d84a sw s2,48(sp)
420011ce: d64e sw s3,44(sp)
420011d0: d452 sw s4,40(sp)
420011d2: d256 sw s5,36(sp)
420011d4: d05a sw s6,32(sp)
420011d6: ce5e sw s7,28(sp)
420011d8: cc62 sw s8,24(sp)
420011da: ca66 sw s9,20(sp)
420011dc: c86a sw s10,16(sp)
420011de: c66e sw s11,12(sp)
420011e0: 0080 addi s0,sp,64
420011e2: 4d01 li s10,0
420011e4: 6ac1 lui s5,0x10
420011e6: 1afd addi s5,s5,-1 # ffff <.Lline_table_start0+0xadfc>
420011e8: 3fc80537 lui a0,0x3fc80
420011ec: 52452903 lw s2,1316(a0) # 3fc80524 <.L__unnamed_1+0x4>
420011f0: 52052d83 lw s11,1312(a0)
420011f4: 3fc80b37 lui s6,0x3fc80
420011f8: 25ab0b13 addi s6,s6,602 # 3fc8025a <__anon_6056>
.
.
.
All those saved registers are unnecessary. The function is "noreturn" so what are the registers saved for. Normally they would be restored on return, but that will never happen.
Well, we set the noreturn LLVM IR attribute on functions that return noreturn in Zig, so this one's on LLVM.
That seems to be it.
Just for everyones reference, this issue is addressed in llvm's bug report 55317