[Bug target/112478] riscv: asm clobbers not honored
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112478 --- Comment #7 from Michael T. Kloos --- Thank you, Kito Cheng. I really appreciate it.
[Bug target/112478] riscv: asm clobbers not honored
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112478 Michael T. Kloos changed: What|Removed |Added Status|RESOLVED|UNCONFIRMED Resolution|INVALID |--- --- Comment #5 from Michael T. Kloos --- I disagree. To quote you: "You're using an ASM to implement a call. That means your asm is responsible for dealing with all ABI issues, including saving/restoring registers around the call. Essentially GCC has no visibility into what your ASM does. It's just a text string that gets passed through to the assembler." Exactly. I did handle that. I specified all register clobbers in either the outputs or clobber list of the asm statement. The %ra register is specified in the clobber list. GCC is not honoring that clobber. That is a regression in GCCs behavior. Of course, it would be possible to write an asm statement that GCC could not work around, such as if you clobbered every register so it could not track the stack pointer. That is a known limitation, will throw an error, and is not what we are talking about. Playing around with these ABI "special" registers inside inline asm is certainly not unheard of. There are many posts on the internet where such tricks are discussed and GCC supports them. If you are familiar with the ABI and are designing architecture specific code, it can be a great optimization. This change is a regression. It breaks any code that relies on this feature. Even if we conceded that clobbering the link register is not supported in GCC asm clobber lists, which I don't, you still can't shift the blame to me because the package that broke is not my code. It broke libgcc, GCC's own internals. The sample code that I provided is just a minimal way to reproduce the bug, but it's based on these parts of your own source code: > include/longlong.h > libgcc/config/riscv/muldi3.S > libgcc/config/riscv/multi3.c On riscv64 (The symbols get redefined on 64 vs 32 bit): > multi3 calls __muluw3() > __muluw3 is defined as a macro inside "include/longlong.h" > __muluw3 becomes an asm call statement that calls __muldi3. Beyond that, I have not attempted to further experiment with listing other registers as asm clobbers and playing around with the edge cases of this bug. I don't know if the clobbers of anything else was broken. I picked up on the case of ra, specifically, because it broke libgcc. I know you don't want to take the time to work on this. But if you are going to dismiss someone out of hand, at least take the time to read and understand their concerns. I went over the libgcc breakage in my original post.
[Bug target/112478] riscv: asm clobbers not honored
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112478 --- Comment #3 from Michael T. Kloos --- Created attachment 56560 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=56560&action=edit Sample program to reproduce the bug I have created and attached a small simple program which shows the bug. If compiled with an earlier version of GCC, it runs fine. If compiled with a later version, after the aforementioned commit, it goes into an infinite loop. The problem is that the ra register clobber is not being honored. You can see the difference in objdump disassembly of the the call_invert_and_sum() function. Here is the disassembly of the good version: 000101e0 : 101e0: ff010113add sp,sp,-16 101e4: 00112623sw ra,12(sp) 101e8: f21ff0efjal 10108 101ec: 00c12083lw ra,12(sp) 101f0: 01010113add sp,sp,16 101f4: 8067ret Here is the disassembly of the bad version: 000101e0 : 101e0: f29ff0efjal 10108 101e4: 8067ret This should make it very clear why the program gets trapped in an infinite loop in the second example.
[Bug target/112478] riscv: asm clobbers not honored
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112478 --- Comment #1 from Michael T. Kloos --- Added Andrew Waterman to CC list
[Bug c/112478] New: riscv: asm clobbers not honored
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112478 Bug ID: 112478 Summary: riscv: asm clobbers not honored Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: Michael at MichaelKloos dot com Target Milestone: --- A recent commit (bisected): 71f906498ada9ec2780660b03bd6e27a93ad350c RISC-V: far-branch: Handle far jumps and branches for functions larger than 1MB Seems to have broken call inline asm clobbers for for the $ra register. I attempted to build a riscv32-rv32ia3-linux-musl cross compiler on a x86_64-pc-linux-gnu system. I succeeded in building the compiler and using it to build my target binary. However, the target binary was crashing. On inspection, I discovered that __muldi3 from libgcc was calling __mulsi3, but not saving the ra (link) register. Upon return from __mulsi3, an infinate loop was entered between the reentry point and the end of the function, as the return instruction was now pointing back at the reentry point. The intermediate code formed a loop that moved and loaded data off the stack pointer until the program segfaulted. libgcc makes the call to __mulsi3 with inline assembly and sets ra as one of the clobbered registers. Some of the configure options used are --disable-multilib --with-arch=rv32ia --with-abi=ilp32 --enable-checking=none --enable-checking=none is there to work around another build-time bug which I will file separately. If you need more information, let me know.