Skip to content

noreturn functions save registers #23952

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
Uthedris opened this issue May 21, 2025 · 4 comments
Open

noreturn functions save registers #23952

Uthedris opened this issue May 21, 2025 · 4 comments
Labels
backend-llvm The LLVM backend outputs an LLVM IR Module. bug Observed behavior contradicts documented or intended behavior optimization upstream An issue with a third party project that Zig uses.
Milestone

Comments

@Uthedris
Copy link
Contributor

Uthedris commented May 21, 2025

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.

@Uthedris Uthedris added the bug Observed behavior contradicts documented or intended behavior label May 21, 2025
@alexrp alexrp added upstream An issue with a third party project that Zig uses. backend-llvm The LLVM backend outputs an LLVM IR Module. labels May 28, 2025
@alexrp alexrp added this to the unplanned milestone May 28, 2025
@alexrp
Copy link
Member

alexrp commented May 28, 2025

Please include an example of what you mean in the issue description.

@Uthedris
Copy link
Contributor Author

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.

@alexrp
Copy link
Member

alexrp commented May 28, 2025

Well, we set the noreturn LLVM IR attribute on functions that return noreturn in Zig, so this one's on LLVM.

@Uthedris
Copy link
Contributor Author

That seems to be it.

Just for everyones reference, this issue is addressed in llvm's bug report 55317

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend-llvm The LLVM backend outputs an LLVM IR Module. bug Observed behavior contradicts documented or intended behavior optimization upstream An issue with a third party project that Zig uses.
Projects
None yet
Development

No branches or pull requests

2 participants