[PATCH 1/2] x86: optimize XCHG to MOV for same-register forms
Sam James
sam@gentoo.org
Thu Jul 2 06:45:11 GMT 2026
Jan Beulich <jbeulich@suse.com> writes:
> On 02.07.2026 08:06, Sam James wrote:
>> Jan Beulich <jbeulich@suse.com> writes:
>>
>>> MOV requires far less execution resources.
>>
>> In case anyone ends up stumbling upon this and wonders why Valgrind
>> stopped working, it needs adjusting for this change:
>> https://bugs.kde.org/522533.
>
> So the instruction bytes quoted there:
>
> IR: unhandled instruction bytes: 0x48 0xC1 0xC7 0x3 0x48 0xC1 0xC7 0xD 0x48 0xC1
>
> are really unrelated to the issue? That's the earlier ROLs afaict ...
>
AFAICT yes! I found this surprising too but it's the only difference
in the object.
> What is that code doing anyway?
Mark explained it to me yesterday as (any errors mine in paraphrasing)..
We die in vg_preloaded.c:129 which is:
void * VG_NOTIFY_ON_LOAD(ifunc_wrapper) (void)
...
/* Call the original indirect function and get it's result */
VALGRIND_GET_ORIG_FN(fn); /* <-- */
CALL_FN_W_v(result, fn);
which is VALGRIND_GET_NR_CONTEXT:
#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
{ volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
volatile unsigned int __addr; \
__asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
/* %EAX = guest_NRADDR */ \
"xchgl %%ecx,%%ecx" \
: "=a" (__addr) \
: \
: "cc", "memory" \
); \
_zzq_orig->nraddr = __addr; \
}
and the rols are the _S_I_P macro:
#define __SPECIAL_INSTRUCTION_PREAMBLE \
"roll $3, %%edi ; roll $13, %%edi\n\t" \
"roll $29, %%edi ; roll $19, %%edi\n\t"
but what I don't understand is why it ends up seeing that. I think when
it sees _S_I_P, it is supposed to rewrite it (?), but I am not an expert on
valgrind's VEX interpreter at all.
> And why is -O passed to gas there, when specific
> insn selection matters?
That's just because it's one of the things I test in some runs. I'll
filter it out for Valgrind as I agree it makes no sense there, but
another problem happens when Valgrind itself is built without it, but
e.g. systemd has -Wa,-O2:
vex amd64->IR: unhandled instruction bytes: 0x48 0xC1 0xC7 0x3 0x48 0xC1 0xC7 0xD 0x48 0xC1
vex amd64->IR: REX=0 REX.W=0 REX.R=0 REX.X=0 REX.B=0
vex amd64->IR: VEX=0 VEX.L=0 VEX.nVVVV=0x0 ESC=NONE
vex amd64->IR: PFX.66=0 PFX.F2=0 PFX.F3=0
==720097== valgrind: Unrecognised instruction at address 0x491cf5b.
==720097== at 0x491CF5B: cleanup_pools (in /usr/lib64/libsystemd.so.0.44.0)
==720097== by 0x400C061: _dl_call_fini (dl-call_fini.c:43)
==720097== by 0x401098F: _dl_fini (dl-fini.c:120)
==720097== by 0x4B8E7CF: __run_exit_handlers (exit.c:118)
==720097== by 0x4B8E8BB: exit (exit.c:148)
==720097== by 0x4B6F290: (below main) (libc_start_call_main.h:83)
==720097== Your program just tried to execute an instruction that Valgrind
==720097== did not recognise. There are two possible reasons for this.
==720097== 1. Your program has a bug and erroneously jumped to a non-code
==720097== location. If you are running Memcheck and you just saw a
==720097== warning about a bad jump, it's probably your program's fault.
==720097== 2. The instruction is legitimate but Valgrind doesn't handle it,
==720097== i.e. it's Valgrind's fault. If you think this is the case or
==720097== you are not sure, please let us know and we'll try to fix it.
==720097== Either way, Valgrind will now raise a SIGILL signal which will
==720097== probably kill your program.
==720097==
==720097== Process terminating with default action of signal 4 (SIGILL): dumping core
==720097== Illegal opcode at address 0x491CF5B
==720097== at 0x491CF5B: cleanup_pools (in /usr/lib64/libsystemd.so.0.44.0)
==720097== by 0x400C061: _dl_call_fini (dl-call_fini.c:43)
==720097== by 0x401098F: _dl_fini (dl-fini.c:120)
==720097== by 0x4B8E7CF: __run_exit_handlers (exit.c:118)
==720097== by 0x4B8E8BB: exit (exit.c:148)
==720097== by 0x4B6F290: (below main) (libc_start_call_main.h:83)
so Valgrind still needs to be able to interpret the pattern anyway.
>
> Jan
sam
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 418 bytes
Desc: not available
URL: <https://sourceware.org/pipermail/binutils/attachments/20260702/50ee793c/attachment-0001.sig>
More information about the Binutils
mailing list