[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH] x86: correct asm() constraints when dealing with immediate selector values
On 09.09.2021 21:31, Andrew Cooper wrote: > On 09/09/2021 15:56, Jan Beulich wrote: >> asm() constraints need to fit both the intended insn(s) which the >> respective operands are going to be used with as well as the actual kind >> of value specified. "m" (alone) together with a constant, however, leads >> to gcc saying >> >> error: memory input <N> is not directly addressable >> >> while clang complains >> >> error: invalid lvalue in asm input for constraint 'm' >> >> And rightly so - in order to access a memory operand, an address needs >> to be specified to the insn. In some cases it might be possible for a >> compiler to synthesize a memory operand holding the requested constant, >> but I think any solution there would have sharp edges. > > It's precisely what happens in the other uses of constants which you > haven't adjusted below. Constants are fine if being propagated into a > static inline which has properly typed parameters. > > Or are you saying automatic spilling when a width isn't necessarily known? > >> If "m" alone doesn't work with constants, it is at best pointless (and >> perhaps misleading or even risky - the compiler might decide to actually >> pick "m" and not try very hard to find a suitable register) to specify >> it alongside "r". >> >> Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> > > I'm slightly surprised you didn't spot and comment about what Clang does > with this. > > https://godbolt.org/z/M4nrerrWM > > For "rm" (0), clang really does spill the constant into a global and > generate a rip-relative mov to fs, which is especially funny considering > the rejection of "m" as a constraint. > > Clang even spills "rm" (local) into a global, while "m" (local) does > come from the stack. Which leads to a lack of diagnosing bad code, in e.g.: void movq(unsigned val) { // asm volatile ( "movq %0, %%xmm0" :: "r" (0) ); // asm volatile ( "movq %0, %%xmm0" :: "m" (0) ); asm volatile ( "movq %0, %%xmm0" :: "rm" (0) ); } The "r" variant gets diagnosed (at the assembly stage, as a 32-bit GPR is invalid as an operand to MOVQ). The "rm" variant gets compiled to a 64-bit memory access of a 32-bit memory location. Jan
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |