On 23 Feb 2026, at 15:57, Jan Beulich <jbeulich@xxxxxxxx> wrote:
On
23.02.2026 11:04, Edwin Török wrote:
clang would duplicate the loop body and end up with a double definition
of the symbol:
```
/tmp/test_x86_emulator-0f3576.s:27823: Error: symbol `vmovsh_to_mem' is already defined
/tmp/test_x86_emulator-0f3576.s:27825: Error: symbol `.Lvmovsh_to_mem_end' is already defined
```
This is a valid transformation, that even GCC might do, see
https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Volatile-1 which
says that `%=` should be used instead. However the C code here also
needs to know the name of the label, so I don't immediately see how to
solve that.
For now mark the loop variable `volatile` to prevent the optimization as a
workaround.
(another way to fix this could be to move the loop body into a function,
but a compiler might inline it, or specialize it, leading to the same problem)
Hmm,
moving decl and asm() out of the loop wouldn't really work. One option
would
be to extend the long-pending [1] to also cover test_x86_emulator.c.
Another
might be to make the upper loop bound not a literal 2, but one
loaded
from memory, suitably arranged for the compiler to not be able to
const-propagate
the value.
But
I wonder how many other transformations the compiler could do, causing
the
same issue elsewhere. Maybe we need to overhaul how this instruction
instantiation
works. (I further wonder how many such issues are lurking in
the
many patches I have out for review, plus the yet further ones I didn't
post
yet to not pointlessly increase the pile.)
I thought more about the %= I mentioned above. Maybe instead of using a C extern to refer to the label inside the inline assembly,
the inline assembly should store the address of that label into a C pointer that is an output parameter of the assembly.
Something like:
decl would do: uint8_t *my_instruction, *my_instruction_end;
put insn would do: asm volatile(“my_instruction%=:” …. “my_instruction_end%=:” ... store into my_instruction the value of my_instruction%= and my_instruction_end the value of my_instruction_end%=)
(The label prefix is not needed, but I assume would be very useful for debugging, so you can find these in gdb/etc.)
Although I’d have to see whether that last part would be possible and what the syntax for it would be, considering that put_insn typically has its own output parameters already.
--- a/tools/tests/x86_emulator/test_x86_emulator.c
+++ b/tools/tests/x86_emulator/test_x86_emulator.c
@@ -5248,7 +5248,7 @@ int main(int argc, char **argv)
memset(res + 3, ~0, 8);
regs.eax = (unsigned long)res;
regs.ecx = ~0;
- for ( i = 0; i < 2; ++i )
+ for (volatile int i = 0; i < 2; ++i )
Even
if we went with this as a workaround, style should please not be screwed
up.
Also,
whichever the workaround, I think a comment wants leaving.
And
then I don't think it is a good idea to introduce a shadowing induction
variable.
Thanks, I’ll update as suggested if I can’t find another solution.
Best regards,
—Edwin