On Wed, 9 Nov 2022, Philipp Tomsich wrote: > > To give a specific example that will be problematic if you go far enough > > down > > the road of matching MIPS64 behavior: > > > > long f(void) > > { > > int x; > > asm("" : "=r"(x)); > > return x; > > } > > > > here GCC (unlike LLVM) omits sign extension of 'x', assuming that asm output > > must have been sign-extended to 64 bits by the programmer. > > In fact, with the proposed patch (but also without it), GCC will sign-extend: > f: > sext.w a0,a0 > ret > .size f, .-f
I'm aware. I said "will be problematic if ...", meaning that GCC omits sign extension when targeting MIPS64, and if you match MIPS64 behavior on RISC-V, you'll get in that situation as well. > To make sure that this is not just an extension to promote the int to > long for the function return, I next added another empty asm to > consume 'x'. > This clearly shows that the extension is performed to postprocess the > output of the asm-statement: > > f: > # ./asm2.c:4: asm("" : "=r"(x)); > sext.w a0,a0 # x, x > # ./asm2.c:5: asm("" : : "r"(x)); > # ./asm2.c:7: } > ret No, you cannot distinguish post-processing the output of the first asm vs. pre-processing the input of the second asm. Try asm("" : "+r"(x)); as the second asm instead, and you'll get f: # t.c:17: asm("" : "=r"(x)); # t.c:18: asm("" : "+r"(x)); # t.c:20: } sext.w a0,a0 #, x ret If it helps, here's a Compiler Explorer link comparing with MIPS64: https://godbolt.org/z/7eobvdKdK Alexander