x86: Disable XCHG to MOV optimization
Checks
| Context |
Check |
Description |
| linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 |
success
|
Build passed
|
| linaro-tcwg-bot/tcwg_binutils_build--master-arm |
success
|
Build passed
|
| linaro-tcwg-bot/tcwg_binutils_check--master-aarch64 |
success
|
Test passed
|
| linaro-tcwg-bot/tcwg_binutils_check--master-arm |
success
|
Test passed
|
Commit Message
Hi,
I am going to check this patch into master as well as 2.47 branch.
I added optimize_for_unsafe, which is 0, and moved XCHG to MOV
optimization under it. We can add something like -Ounsafe later.
Comments
On 13.07.2026 14:08, H.J. Lu wrote:
> I am going to check this patch into master as well as 2.47 branch.
> I added optimize_for_unsafe, which is 0, and moved XCHG to MOV
> optimization under it. We can add something like -Ounsafe later.
But this is wrong, the optimization itself isn't unsafe. Please can we
not rush things for master, and go the easy (revert) route for 2.47?
Jan
On Mon, Jul 13, 2026 at 11:03 PM Jan Beulich <jbeulich@suse.com> wrote:
>
> On 13.07.2026 14:08, H.J. Lu wrote:
> > I am going to check this patch into master as well as 2.47 branch.
> > I added optimize_for_unsafe, which is 0, and moved XCHG to MOV
> > optimization under it. We can add something like -Ounsafe later.
>
> But this is wrong, the optimization itself isn't unsafe. Please can we
You can change it to a different name. But -O on master must work with
today's valgrind.
> not rush things for master, and go the easy (revert) route for 2.47?
>
For 2.47, there should be tests to verify that -O doesn't change
XCHG to MOV.
On 13.07.2026 17:10, H.J. Lu wrote:
> On Mon, Jul 13, 2026 at 11:03 PM Jan Beulich <jbeulich@suse.com> wrote:
>>
>> On 13.07.2026 14:08, H.J. Lu wrote:
>>> I am going to check this patch into master as well as 2.47 branch.
>>> I added optimize_for_unsafe, which is 0, and moved XCHG to MOV
>>> optimization under it. We can add something like -Ounsafe later.
>>
>> But this is wrong, the optimization itself isn't unsafe. Please can we
>
> You can change it to a different name. But -O on master must work with
> today's valgrind.
That's your position. I continue to fail to see why -O needs to work on
anything (valgrind or not) that depends on getting to see specific
encodings for certain insns. Such uses of -O are simply wrong. Undoing
the change on the branch is, as previously indicated, merely to give them
some time to adjust their machinery.
Jan
On Mon, Jul 13, 2026 at 11:20 PM Jan Beulich <jbeulich@suse.com> wrote:
>
> On 13.07.2026 17:10, H.J. Lu wrote:
> > On Mon, Jul 13, 2026 at 11:03 PM Jan Beulich <jbeulich@suse.com> wrote:
> >>
> >> On 13.07.2026 14:08, H.J. Lu wrote:
> >>> I am going to check this patch into master as well as 2.47 branch.
> >>> I added optimize_for_unsafe, which is 0, and moved XCHG to MOV
> >>> optimization under it. We can add something like -Ounsafe later.
> >>
> >> But this is wrong, the optimization itself isn't unsafe. Please can we
> >
> > You can change it to a different name. But -O on master must work with
> > today's valgrind.
>
> That's your position. I continue to fail to see why -O needs to work on
> anything (valgrind or not) that depends on getting to see specific
> encodings for certain insns. Such uses of -O are simply wrong. Undoing
You can add a different option. -O should work for all applications today.
> the change on the branch is, as previously indicated, merely to give them
> some time to adjust their machinery.
>
> Jan
On 13.07.2026 17:31, H.J. Lu wrote:
> On Mon, Jul 13, 2026 at 11:20 PM Jan Beulich <jbeulich@suse.com> wrote:
>>
>> On 13.07.2026 17:10, H.J. Lu wrote:
>>> On Mon, Jul 13, 2026 at 11:03 PM Jan Beulich <jbeulich@suse.com> wrote:
>>>>
>>>> On 13.07.2026 14:08, H.J. Lu wrote:
>>>>> I am going to check this patch into master as well as 2.47 branch.
>>>>> I added optimize_for_unsafe, which is 0, and moved XCHG to MOV
>>>>> optimization under it. We can add something like -Ounsafe later.
>>>>
>>>> But this is wrong, the optimization itself isn't unsafe. Please can we
>>>
>>> You can change it to a different name. But -O on master must work with
>>> today's valgrind.
>>
>> That's your position. I continue to fail to see why -O needs to work on
>> anything (valgrind or not) that depends on getting to see specific
>> encodings for certain insns. Such uses of -O are simply wrong. Undoing
>
> You can add a different option. -O should work for all applications today.
Again - no. It simply can't. (Ftaod when I say -O in this discussion, I
generally mean all its forms.)
Jan
On Mon, Jul 13, 2026 at 11:42 PM Jan Beulich <jbeulich@suse.com> wrote:
>
> On 13.07.2026 17:31, H.J. Lu wrote:
> > On Mon, Jul 13, 2026 at 11:20 PM Jan Beulich <jbeulich@suse.com> wrote:
> >>
> >> On 13.07.2026 17:10, H.J. Lu wrote:
> >>> On Mon, Jul 13, 2026 at 11:03 PM Jan Beulich <jbeulich@suse.com> wrote:
> >>>>
> >>>> On 13.07.2026 14:08, H.J. Lu wrote:
> >>>>> I am going to check this patch into master as well as 2.47 branch.
> >>>>> I added optimize_for_unsafe, which is 0, and moved XCHG to MOV
> >>>>> optimization under it. We can add something like -Ounsafe later.
> >>>>
> >>>> But this is wrong, the optimization itself isn't unsafe. Please can we
> >>>
> >>> You can change it to a different name. But -O on master must work with
> >>> today's valgrind.
> >>
> >> That's your position. I continue to fail to see why -O needs to work on
> >> anything (valgrind or not) that depends on getting to see specific
> >> encodings for certain insns. Such uses of -O are simply wrong. Undoing
> >
> > You can add a different option. -O should work for all applications today.
>
> Again - no. It simply can't. (Ftaod when I say -O in this discussion, I
> generally mean all its forms.)
>
My original design goal of -O is 100% safe for any applications. It
is too bad we don't agree on it. Here is the final patch I am checking
in.
On Mon, Jul 13, 2026 at 05:20:14PM +0200, Jan Beulich wrote:
> On 13.07.2026 17:10, H.J. Lu wrote:
> > On Mon, Jul 13, 2026 at 11:03 PM Jan Beulich <jbeulich@suse.com> wrote:
> >>
> >> On 13.07.2026 14:08, H.J. Lu wrote:
> >>> I am going to check this patch into master as well as 2.47 branch.
> >>> I added optimize_for_unsafe, which is 0, and moved XCHG to MOV
> >>> optimization under it. We can add something like -Ounsafe later.
> >>
> >> But this is wrong, the optimization itself isn't unsafe. Please can we
> >
> > You can change it to a different name. But -O on master must work with
> > today's valgrind.
>
> That's your position. I continue to fail to see why -O needs to work on
> anything (valgrind or not) that depends on getting to see specific
> encodings for certain insns. Such uses of -O are simply wrong. Undoing
> the change on the branch is, as previously indicated, merely to give them
> some time to adjust their machinery.
x86 does have multiple encodings for the same instruction. For
example, "mov %al,%bl" in att mode can be encoded as 88 c3 or 8a d8.
Fun trivia: this can and has been used to encode secret messages in
x86 code, one bit of data in each gpr to gpr move.
Another example, in 32-bit att "mov 0,%eax" can be encoded as
a1 00 00 00 00 or 8b 05 00 00 00 00. Programmers would likely be
upset, and rightly so, if gas chose the second longer encoding.
"xchg %eax,%eax" can also be encoded two ways, 90 or 87 c0. Most
people reading this list would recognise the first as also being the
encoding for an x86 "nop" instruction.
FWIW, my opinion is that "xchg %ecx,%ecx" and the like are special
encodings of nops. Just as gas assumes the programmer knows what they
are doing and does not remove a "nop", gas also should not change a
special nop into some other form of nop.
On 13.07.2026 22:55, H.J. Lu wrote:
> On Mon, Jul 13, 2026 at 11:42 PM Jan Beulich <jbeulich@suse.com> wrote:
>>
>> On 13.07.2026 17:31, H.J. Lu wrote:
>>> On Mon, Jul 13, 2026 at 11:20 PM Jan Beulich <jbeulich@suse.com> wrote:
>>>>
>>>> On 13.07.2026 17:10, H.J. Lu wrote:
>>>>> On Mon, Jul 13, 2026 at 11:03 PM Jan Beulich <jbeulich@suse.com> wrote:
>>>>>>
>>>>>> On 13.07.2026 14:08, H.J. Lu wrote:
>>>>>>> I am going to check this patch into master as well as 2.47 branch.
>>>>>>> I added optimize_for_unsafe, which is 0, and moved XCHG to MOV
>>>>>>> optimization under it. We can add something like -Ounsafe later.
>>>>>>
>>>>>> But this is wrong, the optimization itself isn't unsafe. Please can we
>>>>>
>>>>> You can change it to a different name. But -O on master must work with
>>>>> today's valgrind.
>>>>
>>>> That's your position. I continue to fail to see why -O needs to work on
>>>> anything (valgrind or not) that depends on getting to see specific
>>>> encodings for certain insns. Such uses of -O are simply wrong. Undoing
>>>
>>> You can add a different option. -O should work for all applications today.
>>
>> Again - no. It simply can't. (Ftaod when I say -O in this discussion, I
>> generally mean all its forms.)
>
> My original design goal of -O is 100% safe for any applications. It
> is too bad we don't agree on it. Here is the final patch I am checking
> in.
So you really think committing patches under dispute is acceptable? I, for
one, consider this a process violation. Not that this would have been the
first time, though. Nick, may I ask for your take here?
Jan
On 14.07.2026 05:03, Alan Modra wrote:
> On Mon, Jul 13, 2026 at 05:20:14PM +0200, Jan Beulich wrote:
>> On 13.07.2026 17:10, H.J. Lu wrote:
>>> On Mon, Jul 13, 2026 at 11:03 PM Jan Beulich <jbeulich@suse.com> wrote:
>>>>
>>>> On 13.07.2026 14:08, H.J. Lu wrote:
>>>>> I am going to check this patch into master as well as 2.47 branch.
>>>>> I added optimize_for_unsafe, which is 0, and moved XCHG to MOV
>>>>> optimization under it. We can add something like -Ounsafe later.
>>>>
>>>> But this is wrong, the optimization itself isn't unsafe. Please can we
>>>
>>> You can change it to a different name. But -O on master must work with
>>> today's valgrind.
>>
>> That's your position. I continue to fail to see why -O needs to work on
>> anything (valgrind or not) that depends on getting to see specific
>> encodings for certain insns. Such uses of -O are simply wrong. Undoing
>> the change on the branch is, as previously indicated, merely to give them
>> some time to adjust their machinery.
>
> x86 does have multiple encodings for the same instruction. For
> example, "mov %al,%bl" in att mode can be encoded as 88 c3 or 8a d8.
> Fun trivia: this can and has been used to encode secret messages in
> x86 code, one bit of data in each gpr to gpr move.
>
> Another example, in 32-bit att "mov 0,%eax" can be encoded as
> a1 00 00 00 00 or 8b 05 00 00 00 00. Programmers would likely be
> upset, and rightly so, if gas chose the second longer encoding.
>
> "xchg %eax,%eax" can also be encoded two ways, 90 or 87 c0. Most
> people reading this list would recognise the first as also being the
> encoding for an x86 "nop" instruction.
>
> FWIW, my opinion is that "xchg %ecx,%ecx" and the like are special
> encodings of nops. Just as gas assumes the programmer knows what they
> are doing and does not remove a "nop", gas also should not change a
> special nop into some other form of nop.
If we followed that, we should undo this optimization altogether, and
perhaps tweak a few others (effectively-NOP forms of LEA come to mind).
Putting it under the guard of a variable named
optimize_for_disabled_optimizations (which isn't even a boolean) is
definitely unhelpful.
Jan
On Tue, Jul 14, 2026 at 1:55 PM Jan Beulich <jbeulich@suse.com> wrote:
>
> On 14.07.2026 05:03, Alan Modra wrote:
> > On Mon, Jul 13, 2026 at 05:20:14PM +0200, Jan Beulich wrote:
> >> On 13.07.2026 17:10, H.J. Lu wrote:
> >>> On Mon, Jul 13, 2026 at 11:03 PM Jan Beulich <jbeulich@suse.com> wrote:
> >>>>
> >>>> On 13.07.2026 14:08, H.J. Lu wrote:
> >>>>> I am going to check this patch into master as well as 2.47 branch.
> >>>>> I added optimize_for_unsafe, which is 0, and moved XCHG to MOV
> >>>>> optimization under it. We can add something like -Ounsafe later.
> >>>>
> >>>> But this is wrong, the optimization itself isn't unsafe. Please can we
> >>>
> >>> You can change it to a different name. But -O on master must work with
> >>> today's valgrind.
> >>
> >> That's your position. I continue to fail to see why -O needs to work on
> >> anything (valgrind or not) that depends on getting to see specific
> >> encodings for certain insns. Such uses of -O are simply wrong. Undoing
> >> the change on the branch is, as previously indicated, merely to give them
> >> some time to adjust their machinery.
> >
> > x86 does have multiple encodings for the same instruction. For
> > example, "mov %al,%bl" in att mode can be encoded as 88 c3 or 8a d8.
> > Fun trivia: this can and has been used to encode secret messages in
> > x86 code, one bit of data in each gpr to gpr move.
> >
> > Another example, in 32-bit att "mov 0,%eax" can be encoded as
> > a1 00 00 00 00 or 8b 05 00 00 00 00. Programmers would likely be
> > upset, and rightly so, if gas chose the second longer encoding.
> >
> > "xchg %eax,%eax" can also be encoded two ways, 90 or 87 c0. Most
> > people reading this list would recognise the first as also being the
> > encoding for an x86 "nop" instruction.
> >
> > FWIW, my opinion is that "xchg %ecx,%ecx" and the like are special
> > encodings of nops. Just as gas assumes the programmer knows what they
> > are doing and does not remove a "nop", gas also should not change a
> > special nop into some other form of nop.
>
> If we followed that, we should undo this optimization altogether, and
> perhaps tweak a few others (effectively-NOP forms of LEA come to mind).
> Putting it under the guard of a variable named
> optimize_for_disabled_optimizations (which isn't even a boolean) is
> definitely unhelpful.
>
This is done on purpose. You can even optimize out "XCHG REG64, REG64"
and "MOV REG64, REG64" when optimize_for_disabled_optimizations > N.
> From: H.J. Lu <hjl.tools@gmail.com>
> Sent: Tuesday, July 14, 2026 6:02 PM
>
> On Tue, Jul 14, 2026 at 1:55 PM Jan Beulich <jbeulich@suse.com> wrote:
> >
> > On 14.07.2026 05:03, Alan Modra wrote:
> > > On Mon, Jul 13, 2026 at 05:20:14PM +0200, Jan Beulich wrote:
> > >> On 13.07.2026 17:10, H.J. Lu wrote:
> > >>> On Mon, Jul 13, 2026 at 11:03 PM Jan Beulich <jbeulich@suse.com>
> wrote:
> > >>>>
> > >>>> On 13.07.2026 14:08, H.J. Lu wrote:
> > >>>>> I am going to check this patch into master as well as 2.47 branch.
> > >>>>> I added optimize_for_unsafe, which is 0, and moved XCHG to MOV
> > >>>>> optimization under it. We can add something like -Ounsafe later.
> > >>>>
> > >>>> But this is wrong, the optimization itself isn't unsafe. Please can we
> > >>>
> > >>> You can change it to a different name. But -O on master must work with
> > >>> today's valgrind.
> > >>
> > >> That's your position. I continue to fail to see why -O needs to work on
> > >> anything (valgrind or not) that depends on getting to see specific
> > >> encodings for certain insns. Such uses of -O are simply wrong. Undoing
> > >> the change on the branch is, as previously indicated, merely to give them
> > >> some time to adjust their machinery.
> > >
> > > x86 does have multiple encodings for the same instruction. For
> > > example, "mov %al,%bl" in att mode can be encoded as 88 c3 or 8a d8.
> > > Fun trivia: this can and has been used to encode secret messages in
> > > x86 code, one bit of data in each gpr to gpr move.
> > >
> > > Another example, in 32-bit att "mov 0,%eax" can be encoded as
> > > a1 00 00 00 00 or 8b 05 00 00 00 00. Programmers would likely be
> > > upset, and rightly so, if gas chose the second longer encoding.
> > >
> > > "xchg %eax,%eax" can also be encoded two ways, 90 or 87 c0. Most
> > > people reading this list would recognise the first as also being the
> > > encoding for an x86 "nop" instruction.
> > >
> > > FWIW, my opinion is that "xchg %ecx,%ecx" and the like are special
> > > encodings of nops. Just as gas assumes the programmer knows what they
> > > are doing and does not remove a "nop", gas also should not change a
> > > special nop into some other form of nop.
> >
> > If we followed that, we should undo this optimization altogether, and
> > perhaps tweak a few others (effectively-NOP forms of LEA come to mind).
> > Putting it under the guard of a variable named
> > optimize_for_disabled_optimizations (which isn't even a boolean) is
> > definitely unhelpful.
> >
>
> This is done on purpose. You can even optimize out "XCHG REG64, REG64"
> and "MOV REG64, REG64" when optimize_for_disabled_optimizations > N.
>
I have no objection to revert or move this optimization to another option
for now. But I am still confused after that long thread and this and would
like to ask for an answer here. What is a safe optimization?
In Valgrind case, they are redirecting some nop encoding to another
meaning and using -O. I personally don't think it is a legal usage and should
be prohibited or at least notice toolchain when doing that. But since it
has been widely used, they report that and we need to undo the change.
But there are tons of applications in the world, nobody knows if anyone
has redirected something else and the optimization we do unintentionally
break them. Thus, all the optimizations changing the encoding could be
unsafe. It is not ideal to rely on others reporting to us to determine if
something is safe or not.
We really need a clear answer for the bound. It seems vague for me.
Thx,
Haochen
On Wed, Jul 15, 2026 at 10:52 AM Jiang, Haochen <haochen.jiang@intel.com> wrote:
>
> > From: H.J. Lu <hjl.tools@gmail.com>
> > Sent: Tuesday, July 14, 2026 6:02 PM
> >
> > On Tue, Jul 14, 2026 at 1:55 PM Jan Beulich <jbeulich@suse.com> wrote:
> > >
> > > On 14.07.2026 05:03, Alan Modra wrote:
> > > > On Mon, Jul 13, 2026 at 05:20:14PM +0200, Jan Beulich wrote:
> > > >> On 13.07.2026 17:10, H.J. Lu wrote:
> > > >>> On Mon, Jul 13, 2026 at 11:03 PM Jan Beulich <jbeulich@suse.com>
> > wrote:
> > > >>>>
> > > >>>> On 13.07.2026 14:08, H.J. Lu wrote:
> > > >>>>> I am going to check this patch into master as well as 2.47 branch.
> > > >>>>> I added optimize_for_unsafe, which is 0, and moved XCHG to MOV
> > > >>>>> optimization under it. We can add something like -Ounsafe later.
> > > >>>>
> > > >>>> But this is wrong, the optimization itself isn't unsafe. Please can we
> > > >>>
> > > >>> You can change it to a different name. But -O on master must work with
> > > >>> today's valgrind.
> > > >>
> > > >> That's your position. I continue to fail to see why -O needs to work on
> > > >> anything (valgrind or not) that depends on getting to see specific
> > > >> encodings for certain insns. Such uses of -O are simply wrong. Undoing
> > > >> the change on the branch is, as previously indicated, merely to give them
> > > >> some time to adjust their machinery.
> > > >
> > > > x86 does have multiple encodings for the same instruction. For
> > > > example, "mov %al,%bl" in att mode can be encoded as 88 c3 or 8a d8.
> > > > Fun trivia: this can and has been used to encode secret messages in
> > > > x86 code, one bit of data in each gpr to gpr move.
> > > >
> > > > Another example, in 32-bit att "mov 0,%eax" can be encoded as
> > > > a1 00 00 00 00 or 8b 05 00 00 00 00. Programmers would likely be
> > > > upset, and rightly so, if gas chose the second longer encoding.
> > > >
> > > > "xchg %eax,%eax" can also be encoded two ways, 90 or 87 c0. Most
> > > > people reading this list would recognise the first as also being the
> > > > encoding for an x86 "nop" instruction.
> > > >
> > > > FWIW, my opinion is that "xchg %ecx,%ecx" and the like are special
> > > > encodings of nops. Just as gas assumes the programmer knows what they
> > > > are doing and does not remove a "nop", gas also should not change a
> > > > special nop into some other form of nop.
> > >
> > > If we followed that, we should undo this optimization altogether, and
> > > perhaps tweak a few others (effectively-NOP forms of LEA come to mind).
> > > Putting it under the guard of a variable named
> > > optimize_for_disabled_optimizations (which isn't even a boolean) is
> > > definitely unhelpful.
> > >
> >
> > This is done on purpose. You can even optimize out "XCHG REG64, REG64"
> > and "MOV REG64, REG64" when optimize_for_disabled_optimizations > N.
> >
>
> I have no objection to revert or move this optimization to another option
> for now. But I am still confused after that long thread and this and would
> like to ask for an answer here. What is a safe optimization?
>
> In Valgrind case, they are redirecting some nop encoding to another
> meaning and using -O. I personally don't think it is a legal usage and should
> be prohibited or at least notice toolchain when doing that. But since it
> has been widely used, they report that and we need to undo the change.
> But there are tons of applications in the world, nobody knows if anyone
> has redirected something else and the optimization we do unintentionally
> break them. Thus, all the optimizations changing the encoding could be
> unsafe. It is not ideal to rely on others reporting to us to determine if
> something is safe or not.
>
> We really need a clear answer for the bound. It seems vague for me.
>
It is intentionally vague so that the assembler can implement all
kinds of optimizations. One can use -O on any applications and
everything should work as expected.
The question is what to do when we find out that an optimization
breaks an application. We should evaluate it case by case.
--
H.J.
On Tue, Jul 14, 2026 at 07:55:35AM +0200, Jan Beulich wrote:
> On 14.07.2026 05:03, Alan Modra wrote:
> > On Mon, Jul 13, 2026 at 05:20:14PM +0200, Jan Beulich wrote:
> >> On 13.07.2026 17:10, H.J. Lu wrote:
> >>> On Mon, Jul 13, 2026 at 11:03 PM Jan Beulich <jbeulich@suse.com> wrote:
> >>>>
> >>>> On 13.07.2026 14:08, H.J. Lu wrote:
> >>>>> I am going to check this patch into master as well as 2.47 branch.
> >>>>> I added optimize_for_unsafe, which is 0, and moved XCHG to MOV
> >>>>> optimization under it. We can add something like -Ounsafe later.
> >>>>
> >>>> But this is wrong, the optimization itself isn't unsafe. Please can we
> >>>
> >>> You can change it to a different name. But -O on master must work with
> >>> today's valgrind.
> >>
> >> That's your position. I continue to fail to see why -O needs to work on
> >> anything (valgrind or not) that depends on getting to see specific
> >> encodings for certain insns. Such uses of -O are simply wrong. Undoing
> >> the change on the branch is, as previously indicated, merely to give them
> >> some time to adjust their machinery.
> >
> > x86 does have multiple encodings for the same instruction. For
> > example, "mov %al,%bl" in att mode can be encoded as 88 c3 or 8a d8.
> > Fun trivia: this can and has been used to encode secret messages in
> > x86 code, one bit of data in each gpr to gpr move.
> >
> > Another example, in 32-bit att "mov 0,%eax" can be encoded as
> > a1 00 00 00 00 or 8b 05 00 00 00 00. Programmers would likely be
> > upset, and rightly so, if gas chose the second longer encoding.
> >
> > "xchg %eax,%eax" can also be encoded two ways, 90 or 87 c0. Most
> > people reading this list would recognise the first as also being the
> > encoding for an x86 "nop" instruction.
> >
> > FWIW, my opinion is that "xchg %ecx,%ecx" and the like are special
> > encodings of nops. Just as gas assumes the programmer knows what they
> > are doing and does not remove a "nop", gas also should not change a
> > special nop into some other form of nop.
>
> If we followed that, we should undo this optimization altogether,
Yes. I'm of the opinion that nops should be treated with care,
precisely because they "do nothing". They can be used to implement a
special purpose machine instruction that on newer hardare actually
does something, but on older hardware is a nop. One example that I'm
familiar with is the power9 "exser" instruction, which on older
hardware does nothing. (The encoding is ori r31,r31,0, and the usual
powerpc nop is ori r0,r0,0.)
> and
> perhaps tweak a few others (effectively-NOP forms of LEA come to mind).
Perhaps. I don't have a strong opinion on those, although I lean toward
excluding lea (%rM),%rN from the mov transformation when rM is equal
to rN. I do think extreme care should be taken with instructions that
are closely related to the architecture "nop" instruction.
> Putting it under the guard of a variable named
> optimize_for_disabled_optimizations (which isn't even a boolean) is
> definitely unhelpful.
>
> Jan
On 15.07.2026 05:50, H.J. Lu wrote:
> On Wed, Jul 15, 2026 at 10:52 AM Jiang, Haochen <haochen.jiang@intel.com> wrote:
>>
>>> From: H.J. Lu <hjl.tools@gmail.com>
>>> Sent: Tuesday, July 14, 2026 6:02 PM
>>>
>>> On Tue, Jul 14, 2026 at 1:55 PM Jan Beulich <jbeulich@suse.com> wrote:
>>>>
>>>> On 14.07.2026 05:03, Alan Modra wrote:
>>>>> On Mon, Jul 13, 2026 at 05:20:14PM +0200, Jan Beulich wrote:
>>>>>> On 13.07.2026 17:10, H.J. Lu wrote:
>>>>>>> On Mon, Jul 13, 2026 at 11:03 PM Jan Beulich <jbeulich@suse.com>
>>> wrote:
>>>>>>>>
>>>>>>>> On 13.07.2026 14:08, H.J. Lu wrote:
>>>>>>>>> I am going to check this patch into master as well as 2.47 branch.
>>>>>>>>> I added optimize_for_unsafe, which is 0, and moved XCHG to MOV
>>>>>>>>> optimization under it. We can add something like -Ounsafe later.
>>>>>>>>
>>>>>>>> But this is wrong, the optimization itself isn't unsafe. Please can we
>>>>>>>
>>>>>>> You can change it to a different name. But -O on master must work with
>>>>>>> today's valgrind.
>>>>>>
>>>>>> That's your position. I continue to fail to see why -O needs to work on
>>>>>> anything (valgrind or not) that depends on getting to see specific
>>>>>> encodings for certain insns. Such uses of -O are simply wrong. Undoing
>>>>>> the change on the branch is, as previously indicated, merely to give them
>>>>>> some time to adjust their machinery.
>>>>>
>>>>> x86 does have multiple encodings for the same instruction. For
>>>>> example, "mov %al,%bl" in att mode can be encoded as 88 c3 or 8a d8.
>>>>> Fun trivia: this can and has been used to encode secret messages in
>>>>> x86 code, one bit of data in each gpr to gpr move.
>>>>>
>>>>> Another example, in 32-bit att "mov 0,%eax" can be encoded as
>>>>> a1 00 00 00 00 or 8b 05 00 00 00 00. Programmers would likely be
>>>>> upset, and rightly so, if gas chose the second longer encoding.
>>>>>
>>>>> "xchg %eax,%eax" can also be encoded two ways, 90 or 87 c0. Most
>>>>> people reading this list would recognise the first as also being the
>>>>> encoding for an x86 "nop" instruction.
>>>>>
>>>>> FWIW, my opinion is that "xchg %ecx,%ecx" and the like are special
>>>>> encodings of nops. Just as gas assumes the programmer knows what they
>>>>> are doing and does not remove a "nop", gas also should not change a
>>>>> special nop into some other form of nop.
>>>>
>>>> If we followed that, we should undo this optimization altogether, and
>>>> perhaps tweak a few others (effectively-NOP forms of LEA come to mind).
>>>> Putting it under the guard of a variable named
>>>> optimize_for_disabled_optimizations (which isn't even a boolean) is
>>>> definitely unhelpful.
>>>>
>>>
>>> This is done on purpose. You can even optimize out "XCHG REG64, REG64"
>>> and "MOV REG64, REG64" when optimize_for_disabled_optimizations > N.
>>>
>>
>> I have no objection to revert or move this optimization to another option
>> for now. But I am still confused after that long thread and this and would
>> like to ask for an answer here. What is a safe optimization?
>>
>> In Valgrind case, they are redirecting some nop encoding to another
>> meaning and using -O. I personally don't think it is a legal usage and should
>> be prohibited or at least notice toolchain when doing that. But since it
>> has been widely used, they report that and we need to undo the change.
>> But there are tons of applications in the world, nobody knows if anyone
>> has redirected something else and the optimization we do unintentionally
>> break them. Thus, all the optimizations changing the encoding could be
>> unsafe. It is not ideal to rely on others reporting to us to determine if
>> something is safe or not.
Thanks for calling this out again.
>> We really need a clear answer for the bound. It seems vague for me.
>
> It is intentionally vague so that the assembler can implement all
> kinds of optimizations. One can use -O on any applications and
> everything should work as expected.
>
> The question is what to do when we find out that an optimization
> breaks an application. We should evaluate it case by case.
No. Some (at least) rough rules need to be established up front.
Jan
On 15.07.2026 06:29, Alan Modra wrote:
> On Tue, Jul 14, 2026 at 07:55:35AM +0200, Jan Beulich wrote:
>> On 14.07.2026 05:03, Alan Modra wrote:
>>> On Mon, Jul 13, 2026 at 05:20:14PM +0200, Jan Beulich wrote:
>>>> On 13.07.2026 17:10, H.J. Lu wrote:
>>>>> On Mon, Jul 13, 2026 at 11:03 PM Jan Beulich <jbeulich@suse.com> wrote:
>>>>>>
>>>>>> On 13.07.2026 14:08, H.J. Lu wrote:
>>>>>>> I am going to check this patch into master as well as 2.47 branch.
>>>>>>> I added optimize_for_unsafe, which is 0, and moved XCHG to MOV
>>>>>>> optimization under it. We can add something like -Ounsafe later.
>>>>>>
>>>>>> But this is wrong, the optimization itself isn't unsafe. Please can we
>>>>>
>>>>> You can change it to a different name. But -O on master must work with
>>>>> today's valgrind.
>>>>
>>>> That's your position. I continue to fail to see why -O needs to work on
>>>> anything (valgrind or not) that depends on getting to see specific
>>>> encodings for certain insns. Such uses of -O are simply wrong. Undoing
>>>> the change on the branch is, as previously indicated, merely to give them
>>>> some time to adjust their machinery.
>>>
>>> x86 does have multiple encodings for the same instruction. For
>>> example, "mov %al,%bl" in att mode can be encoded as 88 c3 or 8a d8.
>>> Fun trivia: this can and has been used to encode secret messages in
>>> x86 code, one bit of data in each gpr to gpr move.
>>>
>>> Another example, in 32-bit att "mov 0,%eax" can be encoded as
>>> a1 00 00 00 00 or 8b 05 00 00 00 00. Programmers would likely be
>>> upset, and rightly so, if gas chose the second longer encoding.
>>>
>>> "xchg %eax,%eax" can also be encoded two ways, 90 or 87 c0. Most
>>> people reading this list would recognise the first as also being the
>>> encoding for an x86 "nop" instruction.
>>>
>>> FWIW, my opinion is that "xchg %ecx,%ecx" and the like are special
>>> encodings of nops. Just as gas assumes the programmer knows what they
>>> are doing and does not remove a "nop", gas also should not change a
>>> special nop into some other form of nop.
>>
>> If we followed that, we should undo this optimization altogether,
>
> Yes. I'm of the opinion that nops should be treated with care,
> precisely because they "do nothing". They can be used to implement a
> special purpose machine instruction that on newer hardare actually
> does something, but on older hardware is a nop. One example that I'm
> familiar with is the power9 "exser" instruction, which on older
> hardware does nothing. (The encoding is ori r31,r31,0, and the usual
> powerpc nop is ori r0,r0,0.)
Well, for that x86 has dedicated a range of opcodes (0f 18 ... 0f 1f).
We surely wouldn't want to touch these in the optimizer, yet at the same
time these also cannot be specified by source (unless using .insn, which
again we'd leave alone altogether).
>> and
>> perhaps tweak a few others (effectively-NOP forms of LEA come to mind).
>
> Perhaps. I don't have a strong opinion on those, although I lean toward
> excluding lea (%rM),%rN from the mov transformation when rM is equal
> to rN. I do think extreme care should be taken with instructions that
> are closely related to the architecture "nop" instruction.
I'll see about doing this then, and I'll also check what other NOP-
equivalent patterns we presently transform (I expect there are quite a
few).
Jan
On Wed, Jul 15, 2026 at 2:23 PM Jan Beulich <jbeulich@suse.com> wrote:
>
> On 15.07.2026 05:50, H.J. Lu wrote:
> > On Wed, Jul 15, 2026 at 10:52 AM Jiang, Haochen <haochen.jiang@intel.com> wrote:
> >>
> >>> From: H.J. Lu <hjl.tools@gmail.com>
> >>> Sent: Tuesday, July 14, 2026 6:02 PM
> >>>
> >>> On Tue, Jul 14, 2026 at 1:55 PM Jan Beulich <jbeulich@suse.com> wrote:
> >>>>
> >>>> On 14.07.2026 05:03, Alan Modra wrote:
> >>>>> On Mon, Jul 13, 2026 at 05:20:14PM +0200, Jan Beulich wrote:
> >>>>>> On 13.07.2026 17:10, H.J. Lu wrote:
> >>>>>>> On Mon, Jul 13, 2026 at 11:03 PM Jan Beulich <jbeulich@suse.com>
> >>> wrote:
> >>>>>>>>
> >>>>>>>> On 13.07.2026 14:08, H.J. Lu wrote:
> >>>>>>>>> I am going to check this patch into master as well as 2.47 branch.
> >>>>>>>>> I added optimize_for_unsafe, which is 0, and moved XCHG to MOV
> >>>>>>>>> optimization under it. We can add something like -Ounsafe later.
> >>>>>>>>
> >>>>>>>> But this is wrong, the optimization itself isn't unsafe. Please can we
> >>>>>>>
> >>>>>>> You can change it to a different name. But -O on master must work with
> >>>>>>> today's valgrind.
> >>>>>>
> >>>>>> That's your position. I continue to fail to see why -O needs to work on
> >>>>>> anything (valgrind or not) that depends on getting to see specific
> >>>>>> encodings for certain insns. Such uses of -O are simply wrong. Undoing
> >>>>>> the change on the branch is, as previously indicated, merely to give them
> >>>>>> some time to adjust their machinery.
> >>>>>
> >>>>> x86 does have multiple encodings for the same instruction. For
> >>>>> example, "mov %al,%bl" in att mode can be encoded as 88 c3 or 8a d8.
> >>>>> Fun trivia: this can and has been used to encode secret messages in
> >>>>> x86 code, one bit of data in each gpr to gpr move.
> >>>>>
> >>>>> Another example, in 32-bit att "mov 0,%eax" can be encoded as
> >>>>> a1 00 00 00 00 or 8b 05 00 00 00 00. Programmers would likely be
> >>>>> upset, and rightly so, if gas chose the second longer encoding.
> >>>>>
> >>>>> "xchg %eax,%eax" can also be encoded two ways, 90 or 87 c0. Most
> >>>>> people reading this list would recognise the first as also being the
> >>>>> encoding for an x86 "nop" instruction.
> >>>>>
> >>>>> FWIW, my opinion is that "xchg %ecx,%ecx" and the like are special
> >>>>> encodings of nops. Just as gas assumes the programmer knows what they
> >>>>> are doing and does not remove a "nop", gas also should not change a
> >>>>> special nop into some other form of nop.
> >>>>
> >>>> If we followed that, we should undo this optimization altogether, and
> >>>> perhaps tweak a few others (effectively-NOP forms of LEA come to mind).
> >>>> Putting it under the guard of a variable named
> >>>> optimize_for_disabled_optimizations (which isn't even a boolean) is
> >>>> definitely unhelpful.
> >>>>
> >>>
> >>> This is done on purpose. You can even optimize out "XCHG REG64, REG64"
> >>> and "MOV REG64, REG64" when optimize_for_disabled_optimizations > N.
> >>>
> >>
> >> I have no objection to revert or move this optimization to another option
> >> for now. But I am still confused after that long thread and this and would
> >> like to ask for an answer here. What is a safe optimization?
> >>
> >> In Valgrind case, they are redirecting some nop encoding to another
> >> meaning and using -O. I personally don't think it is a legal usage and should
> >> be prohibited or at least notice toolchain when doing that. But since it
> >> has been widely used, they report that and we need to undo the change.
> >> But there are tons of applications in the world, nobody knows if anyone
> >> has redirected something else and the optimization we do unintentionally
> >> break them. Thus, all the optimizations changing the encoding could be
> >> unsafe. It is not ideal to rely on others reporting to us to determine if
> >> something is safe or not.
>
> Thanks for calling this out again.
>
> >> We really need a clear answer for the bound. It seems vague for me.
> >
> > It is intentionally vague so that the assembler can implement all
> > kinds of optimizations. One can use -O on any applications and
> > everything should work as expected.
> >
> > The question is what to do when we find out that an optimization
> > breaks an application. We should evaluate it case by case.
>
> No. Some (at least) rough rules need to be established up front.
>
Many optimizations have been implemented without any explicit
rules. So far we only run into the "XCHG to MOV" issue. We
are having this discussion only because the "XCHG to MOV"
optimization wasn't disabled fast enough.
The only rule for me is that -O can be used safely on any applications.
On 15.07.2026 09:37, H.J. Lu wrote:
> On Wed, Jul 15, 2026 at 2:23 PM Jan Beulich <jbeulich@suse.com> wrote:
>>
>> On 15.07.2026 05:50, H.J. Lu wrote:
>>> On Wed, Jul 15, 2026 at 10:52 AM Jiang, Haochen <haochen.jiang@intel.com> wrote:
>>>>
>>>>> From: H.J. Lu <hjl.tools@gmail.com>
>>>>> Sent: Tuesday, July 14, 2026 6:02 PM
>>>>>
>>>>> On Tue, Jul 14, 2026 at 1:55 PM Jan Beulich <jbeulich@suse.com> wrote:
>>>>>>
>>>>>> On 14.07.2026 05:03, Alan Modra wrote:
>>>>>>> On Mon, Jul 13, 2026 at 05:20:14PM +0200, Jan Beulich wrote:
>>>>>>>> On 13.07.2026 17:10, H.J. Lu wrote:
>>>>>>>>> On Mon, Jul 13, 2026 at 11:03 PM Jan Beulich <jbeulich@suse.com>
>>>>> wrote:
>>>>>>>>>>
>>>>>>>>>> On 13.07.2026 14:08, H.J. Lu wrote:
>>>>>>>>>>> I am going to check this patch into master as well as 2.47 branch.
>>>>>>>>>>> I added optimize_for_unsafe, which is 0, and moved XCHG to MOV
>>>>>>>>>>> optimization under it. We can add something like -Ounsafe later.
>>>>>>>>>>
>>>>>>>>>> But this is wrong, the optimization itself isn't unsafe. Please can we
>>>>>>>>>
>>>>>>>>> You can change it to a different name. But -O on master must work with
>>>>>>>>> today's valgrind.
>>>>>>>>
>>>>>>>> That's your position. I continue to fail to see why -O needs to work on
>>>>>>>> anything (valgrind or not) that depends on getting to see specific
>>>>>>>> encodings for certain insns. Such uses of -O are simply wrong. Undoing
>>>>>>>> the change on the branch is, as previously indicated, merely to give them
>>>>>>>> some time to adjust their machinery.
>>>>>>>
>>>>>>> x86 does have multiple encodings for the same instruction. For
>>>>>>> example, "mov %al,%bl" in att mode can be encoded as 88 c3 or 8a d8.
>>>>>>> Fun trivia: this can and has been used to encode secret messages in
>>>>>>> x86 code, one bit of data in each gpr to gpr move.
>>>>>>>
>>>>>>> Another example, in 32-bit att "mov 0,%eax" can be encoded as
>>>>>>> a1 00 00 00 00 or 8b 05 00 00 00 00. Programmers would likely be
>>>>>>> upset, and rightly so, if gas chose the second longer encoding.
>>>>>>>
>>>>>>> "xchg %eax,%eax" can also be encoded two ways, 90 or 87 c0. Most
>>>>>>> people reading this list would recognise the first as also being the
>>>>>>> encoding for an x86 "nop" instruction.
>>>>>>>
>>>>>>> FWIW, my opinion is that "xchg %ecx,%ecx" and the like are special
>>>>>>> encodings of nops. Just as gas assumes the programmer knows what they
>>>>>>> are doing and does not remove a "nop", gas also should not change a
>>>>>>> special nop into some other form of nop.
>>>>>>
>>>>>> If we followed that, we should undo this optimization altogether, and
>>>>>> perhaps tweak a few others (effectively-NOP forms of LEA come to mind).
>>>>>> Putting it under the guard of a variable named
>>>>>> optimize_for_disabled_optimizations (which isn't even a boolean) is
>>>>>> definitely unhelpful.
>>>>>>
>>>>>
>>>>> This is done on purpose. You can even optimize out "XCHG REG64, REG64"
>>>>> and "MOV REG64, REG64" when optimize_for_disabled_optimizations > N.
>>>>>
>>>>
>>>> I have no objection to revert or move this optimization to another option
>>>> for now. But I am still confused after that long thread and this and would
>>>> like to ask for an answer here. What is a safe optimization?
>>>>
>>>> In Valgrind case, they are redirecting some nop encoding to another
>>>> meaning and using -O. I personally don't think it is a legal usage and should
>>>> be prohibited or at least notice toolchain when doing that. But since it
>>>> has been widely used, they report that and we need to undo the change.
>>>> But there are tons of applications in the world, nobody knows if anyone
>>>> has redirected something else and the optimization we do unintentionally
>>>> break them. Thus, all the optimizations changing the encoding could be
>>>> unsafe. It is not ideal to rely on others reporting to us to determine if
>>>> something is safe or not.
>>
>> Thanks for calling this out again.
>>
>>>> We really need a clear answer for the bound. It seems vague for me.
>>>
>>> It is intentionally vague so that the assembler can implement all
>>> kinds of optimizations. One can use -O on any applications and
>>> everything should work as expected.
>>>
>>> The question is what to do when we find out that an optimization
>>> breaks an application. We should evaluate it case by case.
>>
>> No. Some (at least) rough rules need to be established up front.
>>
>
> Many optimizations have been implemented without any explicit
> rules. So far we only run into the "XCHG to MOV" issue. We
> are having this discussion only because the "XCHG to MOV"
> optimization wasn't disabled fast enough.
>
> The only rule for me is that -O can be used safely on any applications.
In which case we need to rip out all optimizations (assuming you mean all
forms of -O, which I think you do, since elsewhere you said the same more
explicitly also for e.g. -Os).
You did notice though that I'm not the only one who isn't sharing this
position of yours. Optimization _can_ break code using trickery. That's
to be expected, and people playing tricks need to stay away from enabling
optimization. We simply can't make that "safe".
Jan
On Wed, Jul 15, 2026 at 3:46 PM Jan Beulich <jbeulich@suse.com> wrote:
>
> On 15.07.2026 09:37, H.J. Lu wrote:
> > On Wed, Jul 15, 2026 at 2:23 PM Jan Beulich <jbeulich@suse.com> wrote:
> >>
> >> On 15.07.2026 05:50, H.J. Lu wrote:
> >>> On Wed, Jul 15, 2026 at 10:52 AM Jiang, Haochen <haochen.jiang@intel.com> wrote:
> >>>>
> >>>>> From: H.J. Lu <hjl.tools@gmail.com>
> >>>>> Sent: Tuesday, July 14, 2026 6:02 PM
> >>>>>
> >>>>> On Tue, Jul 14, 2026 at 1:55 PM Jan Beulich <jbeulich@suse.com> wrote:
> >>>>>>
> >>>>>> On 14.07.2026 05:03, Alan Modra wrote:
> >>>>>>> On Mon, Jul 13, 2026 at 05:20:14PM +0200, Jan Beulich wrote:
> >>>>>>>> On 13.07.2026 17:10, H.J. Lu wrote:
> >>>>>>>>> On Mon, Jul 13, 2026 at 11:03 PM Jan Beulich <jbeulich@suse.com>
> >>>>> wrote:
> >>>>>>>>>>
> >>>>>>>>>> On 13.07.2026 14:08, H.J. Lu wrote:
> >>>>>>>>>>> I am going to check this patch into master as well as 2.47 branch.
> >>>>>>>>>>> I added optimize_for_unsafe, which is 0, and moved XCHG to MOV
> >>>>>>>>>>> optimization under it. We can add something like -Ounsafe later.
> >>>>>>>>>>
> >>>>>>>>>> But this is wrong, the optimization itself isn't unsafe. Please can we
> >>>>>>>>>
> >>>>>>>>> You can change it to a different name. But -O on master must work with
> >>>>>>>>> today's valgrind.
> >>>>>>>>
> >>>>>>>> That's your position. I continue to fail to see why -O needs to work on
> >>>>>>>> anything (valgrind or not) that depends on getting to see specific
> >>>>>>>> encodings for certain insns. Such uses of -O are simply wrong. Undoing
> >>>>>>>> the change on the branch is, as previously indicated, merely to give them
> >>>>>>>> some time to adjust their machinery.
> >>>>>>>
> >>>>>>> x86 does have multiple encodings for the same instruction. For
> >>>>>>> example, "mov %al,%bl" in att mode can be encoded as 88 c3 or 8a d8.
> >>>>>>> Fun trivia: this can and has been used to encode secret messages in
> >>>>>>> x86 code, one bit of data in each gpr to gpr move.
> >>>>>>>
> >>>>>>> Another example, in 32-bit att "mov 0,%eax" can be encoded as
> >>>>>>> a1 00 00 00 00 or 8b 05 00 00 00 00. Programmers would likely be
> >>>>>>> upset, and rightly so, if gas chose the second longer encoding.
> >>>>>>>
> >>>>>>> "xchg %eax,%eax" can also be encoded two ways, 90 or 87 c0. Most
> >>>>>>> people reading this list would recognise the first as also being the
> >>>>>>> encoding for an x86 "nop" instruction.
> >>>>>>>
> >>>>>>> FWIW, my opinion is that "xchg %ecx,%ecx" and the like are special
> >>>>>>> encodings of nops. Just as gas assumes the programmer knows what they
> >>>>>>> are doing and does not remove a "nop", gas also should not change a
> >>>>>>> special nop into some other form of nop.
> >>>>>>
> >>>>>> If we followed that, we should undo this optimization altogether, and
> >>>>>> perhaps tweak a few others (effectively-NOP forms of LEA come to mind).
> >>>>>> Putting it under the guard of a variable named
> >>>>>> optimize_for_disabled_optimizations (which isn't even a boolean) is
> >>>>>> definitely unhelpful.
> >>>>>>
> >>>>>
> >>>>> This is done on purpose. You can even optimize out "XCHG REG64, REG64"
> >>>>> and "MOV REG64, REG64" when optimize_for_disabled_optimizations > N.
> >>>>>
> >>>>
> >>>> I have no objection to revert or move this optimization to another option
> >>>> for now. But I am still confused after that long thread and this and would
> >>>> like to ask for an answer here. What is a safe optimization?
> >>>>
> >>>> In Valgrind case, they are redirecting some nop encoding to another
> >>>> meaning and using -O. I personally don't think it is a legal usage and should
> >>>> be prohibited or at least notice toolchain when doing that. But since it
> >>>> has been widely used, they report that and we need to undo the change.
> >>>> But there are tons of applications in the world, nobody knows if anyone
> >>>> has redirected something else and the optimization we do unintentionally
> >>>> break them. Thus, all the optimizations changing the encoding could be
> >>>> unsafe. It is not ideal to rely on others reporting to us to determine if
> >>>> something is safe or not.
> >>
> >> Thanks for calling this out again.
> >>
> >>>> We really need a clear answer for the bound. It seems vague for me.
> >>>
> >>> It is intentionally vague so that the assembler can implement all
> >>> kinds of optimizations. One can use -O on any applications and
> >>> everything should work as expected.
> >>>
> >>> The question is what to do when we find out that an optimization
> >>> breaks an application. We should evaluate it case by case.
> >>
> >> No. Some (at least) rough rules need to be established up front.
> >>
> >
> > Many optimizations have been implemented without any explicit
> > rules. So far we only run into the "XCHG to MOV" issue. We
> > are having this discussion only because the "XCHG to MOV"
> > optimization wasn't disabled fast enough.
> >
> > The only rule for me is that -O can be used safely on any applications.
>
> In which case we need to rip out all optimizations (assuming you mean all
> forms of -O, which I think you do, since elsewhere you said the same more
> explicitly also for e.g. -Os).
Please show me a binutils bug report for the broken application because
of using -O with today's binutils master branch.
> You did notice though that I'm not the only one who isn't sharing this
> position of yours. Optimization _can_ break code using trickery. That's
> to be expected, and people playing tricks need to stay away from enabling
> optimization. We simply can't make that "safe".
>
GNU assembler is used by GCC to generate binaries. GCC may not
always generate the optimal encoding. That is why I added -O to
assembler in the first place. There is no point in adding it if it isn't safe.
We can't break applications because of some assembler optimizations.
On 15.07.2026 10:17, H.J. Lu wrote:
> On Wed, Jul 15, 2026 at 3:46 PM Jan Beulich <jbeulich@suse.com> wrote:
>> On 15.07.2026 09:37, H.J. Lu wrote:
>>> The only rule for me is that -O can be used safely on any applications.
>>
>> In which case we need to rip out all optimizations (assuming you mean all
>> forms of -O, which I think you do, since elsewhere you said the same more
>> explicitly also for e.g. -Os).
>
> Please show me a binutils bug report for the broken application because
> of using -O with today's binutils master branch.
>
>> You did notice though that I'm not the only one who isn't sharing this
>> position of yours. Optimization _can_ break code using trickery. That's
>> to be expected, and people playing tricks need to stay away from enabling
>> optimization. We simply can't make that "safe".
>
> GNU assembler is used by GCC to generate binaries. GCC may not
> always generate the optimal encoding. That is why I added -O to
> assembler in the first place. There is no point in adding it if it isn't safe.
> We can't break applications because of some assembler optimizations.
As said - I will, once time permits (later this week hopefully).
Jan
> -----Original Message-----
> From: Jan Beulich <jbeulich@suse.com>
> Sent: Wednesday, July 15, 2026 3:47 PM
> To: H.J. Lu <hjl.tools@gmail.com>
> Cc: Jiang, Haochen <haochen.jiang@intel.com>; Alan Modra
> <amodra@gmail.com>; Binutils <binutils@sourceware.org>; Nick Clifton
> <nickc@redhat.com>
> Subject: Re: [PATCH] x86: Disable XCHG to MOV optimization
>
> On 15.07.2026 09:37, H.J. Lu wrote:
> > On Wed, Jul 15, 2026 at 2:23 PM Jan Beulich <jbeulich@suse.com> wrote:
> >>
> >> On 15.07.2026 05:50, H.J. Lu wrote:
> >>> On Wed, Jul 15, 2026 at 10:52 AM Jiang, Haochen
> <haochen.jiang@intel.com> wrote:
> >>>>
> >>>>> From: H.J. Lu <hjl.tools@gmail.com>
> >>>>> Sent: Tuesday, July 14, 2026 6:02 PM
> >>>>>
> >>>>> On Tue, Jul 14, 2026 at 1:55 PM Jan Beulich <jbeulich@suse.com>
> wrote:
> >>>>>>
> >>>>>> On 14.07.2026 05:03, Alan Modra wrote:
> >>>>>>> On Mon, Jul 13, 2026 at 05:20:14PM +0200, Jan Beulich wrote:
> >>>>>>>> On 13.07.2026 17:10, H.J. Lu wrote:
> >>>>>>>>> On Mon, Jul 13, 2026 at 11:03 PM Jan Beulich
> >>>>>>>>> <jbeulich@suse.com>
> >>>>> wrote:
> >>>>>>>>>>
> >>>>>>>>>> On 13.07.2026 14:08, H.J. Lu wrote:
> >>>>>>>>>>> I am going to check this patch into master as well as 2.47 branch.
> >>>>>>>>>>> I added optimize_for_unsafe, which is 0, and moved XCHG to
> >>>>>>>>>>> MOV optimization under it. We can add something like -Ounsafe
> later.
> >>>>>>>>>>
> >>>>>>>>>> But this is wrong, the optimization itself isn't unsafe.
> >>>>>>>>>> Please can we
> >>>>>>>>>
> >>>>>>>>> You can change it to a different name. But -O on master must
> >>>>>>>>> work with today's valgrind.
> >>>>>>>>
> >>>>>>>> That's your position. I continue to fail to see why -O needs to
> >>>>>>>> work on anything (valgrind or not) that depends on getting to
> >>>>>>>> see specific encodings for certain insns. Such uses of -O are
> >>>>>>>> simply wrong. Undoing the change on the branch is, as
> >>>>>>>> previously indicated, merely to give them some time to adjust their
> machinery.
> >>>>>>>
> >>>>>>> x86 does have multiple encodings for the same instruction. For
> >>>>>>> example, "mov %al,%bl" in att mode can be encoded as 88 c3 or 8a
> d8.
> >>>>>>> Fun trivia: this can and has been used to encode secret messages
> >>>>>>> in
> >>>>>>> x86 code, one bit of data in each gpr to gpr move.
> >>>>>>>
> >>>>>>> Another example, in 32-bit att "mov 0,%eax" can be encoded as
> >>>>>>> a1 00 00 00 00 or 8b 05 00 00 00 00. Programmers would likely
> >>>>>>> be upset, and rightly so, if gas chose the second longer encoding.
> >>>>>>>
> >>>>>>> "xchg %eax,%eax" can also be encoded two ways, 90 or 87 c0.
> >>>>>>> Most people reading this list would recognise the first as also
> >>>>>>> being the encoding for an x86 "nop" instruction.
> >>>>>>>
> >>>>>>> FWIW, my opinion is that "xchg %ecx,%ecx" and the like are
> >>>>>>> special encodings of nops. Just as gas assumes the programmer
> >>>>>>> knows what they are doing and does not remove a "nop", gas also
> >>>>>>> should not change a special nop into some other form of nop.
> >>>>>>
> >>>>>> If we followed that, we should undo this optimization altogether,
> >>>>>> and perhaps tweak a few others (effectively-NOP forms of LEA come to
> mind).
> >>>>>> Putting it under the guard of a variable named
> >>>>>> optimize_for_disabled_optimizations (which isn't even a boolean)
> >>>>>> is definitely unhelpful.
> >>>>>>
> >>>>>
> >>>>> This is done on purpose. You can even optimize out "XCHG REG64,
> REG64"
> >>>>> and "MOV REG64, REG64" when optimize_for_disabled_optimizations >
> N.
> >>>>>
> >>>>
> >>>> I have no objection to revert or move this optimization to another
> >>>> option for now. But I am still confused after that long thread and
> >>>> this and would like to ask for an answer here. What is a safe
> optimization?
> >>>>
> >>>> In Valgrind case, they are redirecting some nop encoding to another
> >>>> meaning and using -O. I personally don't think it is a legal usage
> >>>> and should be prohibited or at least notice toolchain when doing
> >>>> that. But since it has been widely used, they report that and we need to
> undo the change.
> >>>> But there are tons of applications in the world, nobody knows if
> >>>> anyone has redirected something else and the optimization we do
> >>>> unintentionally break them. Thus, all the optimizations changing
> >>>> the encoding could be unsafe. It is not ideal to rely on others
> >>>> reporting to us to determine if something is safe or not.
> >>
> >> Thanks for calling this out again.
> >>
> >>>> We really need a clear answer for the bound. It seems vague for me.
> >>>
> >>> It is intentionally vague so that the assembler can implement all
> >>> kinds of optimizations. One can use -O on any applications and
> >>> everything should work as expected.
> >>>
> >>> The question is what to do when we find out that an optimization
> >>> breaks an application. We should evaluate it case by case.
> >>
> >> No. Some (at least) rough rules need to be established up front.
> >>
> >
> > Many optimizations have been implemented without any explicit
> > rules. So far we only run into the "XCHG to MOV" issue. We
> > are having this discussion only because the "XCHG to MOV"
> > optimization wasn't disabled fast enough.
> >
> > The only rule for me is that -O can be used safely on any applications.
>
> In which case we need to rip out all optimizations (assuming you mean all
> forms of -O, which I think you do, since elsewhere you said the same more
> explicitly also for e.g. -Os).
>
> You did notice though that I'm not the only one who isn't sharing this position
> of yours. Optimization _can_ break code using trickery. That's to be expected,
> and people playing tricks need to stay away from enabling optimization. We
> simply can't make that "safe".
>
As H.J. noted, XCHG→MOV is the only issue we've hit so far. That leans toward handling real problems as they come up rather than writing a full rulebook up front. Many of these optimizations are old and grew over time, so there's probably no single clean rule to pull out of them. Turning off a specific one when it actually breaks something — as we're doing here — seems like the practical path.
Regards,
Lili.
> Jan
> From: Jan Beulich <jbeulich@suse.com>
> Sent: Wednesday, July 15, 2026 4:20 PM
>
> On 15.07.2026 10:17, H.J. Lu wrote:
> > On Wed, Jul 15, 2026 at 3:46 PM Jan Beulich <jbeulich@suse.com> wrote:
> >> On 15.07.2026 09:37, H.J. Lu wrote:
> >>> The only rule for me is that -O can be used safely on any applications.
> >>
> >> In which case we need to rip out all optimizations (assuming you mean all
> >> forms of -O, which I think you do, since elsewhere you said the same more
> >> explicitly also for e.g. -Os).
> >
> > Please show me a binutils bug report for the broken application because
> > of using -O with today's binutils master branch.
> >
> >> You did notice though that I'm not the only one who isn't sharing this
> >> position of yours. Optimization _can_ break code using trickery. That's
> >> to be expected, and people playing tricks need to stay away from enabling
> >> optimization. We simply can't make that "safe".
> >
> > GNU assembler is used by GCC to generate binaries. GCC may not
> > always generate the optimal encoding. That is why I added -O to
> > assembler in the first place. There is no point in adding it if it isn't safe.
> > We can't break applications because of some assembler optimizations.
>
I believe the very first problem here is if the application is doing what it should
do. I don't think Valgrind is doing the safe things by redirecting the instruction
meaning. We could not guarantee their self-defined behavior to be consistent
version to version. And we should not judge if an optimization is safe or not due
to unsafe behavior by other applications.
So that is why I suppose we still need a clearer rule for future work. It is always
frustrating for someone doing the job but thrown into rubbish bin because of
some unsafe behavior from other applications that sometimes we don't even
know and we could not control.
Thx,
Haochen
On Wed, Jul 15, 2026 at 4:42 PM Jiang, Haochen <haochen.jiang@intel.com> wrote:
>
> > From: Jan Beulich <jbeulich@suse.com>
> > Sent: Wednesday, July 15, 2026 4:20 PM
> >
> > On 15.07.2026 10:17, H.J. Lu wrote:
> > > On Wed, Jul 15, 2026 at 3:46 PM Jan Beulich <jbeulich@suse.com> wrote:
> > >> On 15.07.2026 09:37, H.J. Lu wrote:
> > >>> The only rule for me is that -O can be used safely on any applications.
> > >>
> > >> In which case we need to rip out all optimizations (assuming you mean all
> > >> forms of -O, which I think you do, since elsewhere you said the same more
> > >> explicitly also for e.g. -Os).
> > >
> > > Please show me a binutils bug report for the broken application because
> > > of using -O with today's binutils master branch.
> > >
> > >> You did notice though that I'm not the only one who isn't sharing this
> > >> position of yours. Optimization _can_ break code using trickery. That's
> > >> to be expected, and people playing tricks need to stay away from enabling
> > >> optimization. We simply can't make that "safe".
> > >
> > > GNU assembler is used by GCC to generate binaries. GCC may not
> > > always generate the optimal encoding. That is why I added -O to
> > > assembler in the first place. There is no point in adding it if it isn't safe.
> > > We can't break applications because of some assembler optimizations.
> >
>
> I believe the very first problem here is if the application is doing what it should
> do. I don't think Valgrind is doing the safe things by redirecting the instruction
> meaning. We could not guarantee their self-defined behavior to be consistent
> version to version. And we should not judge if an optimization is safe or not due
> to unsafe behavior by other applications.
>
> So that is why I suppose we still need a clearer rule for future work. It is always
> frustrating for someone doing the job but thrown into rubbish bin because of
> some unsafe behavior from other applications that sometimes we don't even
> know and we could not control.
>
Assembler optimization essentially second-guesses what the programmers
or compilers really want to do. So far we have guessed most correctly
with only one exception so far. When you ask for the second-guessing
rules, it is hard to have a complete list. If the list is too narrow,
it limits what
we can optimize. If the list is wide open, it doesn't mean much.
As for the wasted efforts, no one can second-guess 100% correctly.
If you can't live with it, don't second-guess.
On 15.07.2026 10:17, H.J. Lu wrote:
> GNU assembler is used by GCC to generate binaries. GCC may not
> always generate the optimal encoding. That is why I added -O to
> assembler in the first place. There is no point in adding it if it isn't safe.
> We can't break applications because of some assembler optimizations.
So this kind of thing will break with any optimization changing encoding
size:
test eax, eax
jnz $+9
test rcx, 0x21
(Intel syntax for all examples, as that's what I'm more used to.)
This clearly breaks as well:
test eax, eax
jz 1f+2
1: test bx, 0x21
As does this:
test ecx, ecx
jz $+4
mov rcx, 0xc9634890
While all of these may look contrived, I've seen code (not written by
myself) doing similar things. A construct branching into the middle of
an insn was (transiently) even considered to address one of the many
speculation issues we've seen over the last 8+ years.
Jan
On Fri, Jul 17, 2026 at 4:44 PM Jan Beulich <jbeulich@suse.com> wrote:
>
> On 15.07.2026 10:17, H.J. Lu wrote:
> > GNU assembler is used by GCC to generate binaries. GCC may not
> > always generate the optimal encoding. That is why I added -O to
> > assembler in the first place. There is no point in adding it if it isn't safe.
> > We can't break applications because of some assembler optimizations.
>
> So this kind of thing will break with any optimization changing encoding
> size:
>
> test eax, eax
> jnz $+9
> test rcx, 0x21
>
> (Intel syntax for all examples, as that's what I'm more used to.)
>
> This clearly breaks as well:
>
> test eax, eax
> jz 1f+2
> 1: test bx, 0x21
>
> As does this:
>
> test ecx, ecx
> jz $+4
> mov rcx, 0xc9634890
>
> While all of these may look contrived, I've seen code (not written by
> myself) doing similar things. A construct branching into the middle of
> an insn was (transiently) even considered to address one of the many
> speculation issues we've seen over the last 8+ years.
That is why I meant case by case. There are similar codes in i686 glibc.
When I added CET support, I had to deal with it:
commit be9ccd27c09ee76c5397125bfa0fefae318a2996
Author: H.J. Lu <hjl.tools@gmail.com>
AuthorDate: Tue Jul 17 16:11:13 2018 -0700
Commit: H.J. Lu <hjl.tools@gmail.com>
CommitDate: Tue Jul 17 16:11:44 2018 -0700
i386: Add _CET_ENDBR to indirect jump targets in add_n.S/sub_n.S
i386 add_n.S and sub_n.S use a trick to implement jump tables with LEA.
We can't use conditional branches nor normal jump tables since jump
table entries use EFLAGS set by jump table index. This patch adds
_CET_ENDBR to indirect jump targets and adjust destination for
_CET_ENDBR.
So far assembler optimizations haven't caused any issues for these
kinds of codes. But changing LEA encoding length may cause issues.
On 17.07.2026 11:22, H.J. Lu wrote:
> On Fri, Jul 17, 2026 at 4:44 PM Jan Beulich <jbeulich@suse.com> wrote:
>>
>> On 15.07.2026 10:17, H.J. Lu wrote:
>>> GNU assembler is used by GCC to generate binaries. GCC may not
>>> always generate the optimal encoding. That is why I added -O to
>>> assembler in the first place. There is no point in adding it if it isn't safe.
>>> We can't break applications because of some assembler optimizations.
>>
>> So this kind of thing will break with any optimization changing encoding
>> size:
>>
>> test eax, eax
>> jnz $+9
>> test rcx, 0x21
>>
>> (Intel syntax for all examples, as that's what I'm more used to.)
>>
>> This clearly breaks as well:
>>
>> test eax, eax
>> jz 1f+2
>> 1: test bx, 0x21
>>
>> As does this:
>>
>> test ecx, ecx
>> jz $+4
>> mov rcx, 0xc9634890
>>
>> While all of these may look contrived, I've seen code (not written by
>> myself) doing similar things. A construct branching into the middle of
>> an insn was (transiently) even considered to address one of the many
>> speculation issues we've seen over the last 8+ years.
>
> That is why I meant case by case.
Well, I've now given you a case where the very first optimizations that
were introduced break. Are you now agreeing that we need to rip them all
out again? Or else is "case by case" yet more subjective than I understood
so far, perhaps as in "H.J.'s optimizations are always okay, while Jan's
never are"?
Jan
On Fri, Jul 17, 2026 at 7:02 PM Jan Beulich <jbeulich@suse.com> wrote:
>
> On 17.07.2026 11:22, H.J. Lu wrote:
> > On Fri, Jul 17, 2026 at 4:44 PM Jan Beulich <jbeulich@suse.com> wrote:
> >>
> >> On 15.07.2026 10:17, H.J. Lu wrote:
> >>> GNU assembler is used by GCC to generate binaries. GCC may not
> >>> always generate the optimal encoding. That is why I added -O to
> >>> assembler in the first place. There is no point in adding it if it isn't safe.
> >>> We can't break applications because of some assembler optimizations.
> >>
> >> So this kind of thing will break with any optimization changing encoding
> >> size:
> >>
> >> test eax, eax
> >> jnz $+9
> >> test rcx, 0x21
> >>
> >> (Intel syntax for all examples, as that's what I'm more used to.)
> >>
> >> This clearly breaks as well:
> >>
> >> test eax, eax
> >> jz 1f+2
> >> 1: test bx, 0x21
> >>
> >> As does this:
> >>
> >> test ecx, ecx
> >> jz $+4
> >> mov rcx, 0xc9634890
> >>
> >> While all of these may look contrived, I've seen code (not written by
> >> myself) doing similar things. A construct branching into the middle of
> >> an insn was (transiently) even considered to address one of the many
> >> speculation issues we've seen over the last 8+ years.
> >
> > That is why I meant case by case.
>
> Well, I've now given you a case where the very first optimizations that
> were introduced break. Are you now agreeing that we need to rip them all
The primary goal of -O is to have shorter encoding. Clearly you shouldn't
use it on codes which depend on encoding length. In this case, -O0 or
.noopt should be used to totally turn off encoding optimization.
> out again? Or else is "case by case" yet more subjective than I understood
> so far, perhaps as in "H.J.'s optimizations are always okay, while Jan's
> never are"?
>
I assume that you didn't mean it.
On 17.07.2026 22:24, H.J. Lu wrote:
> On Fri, Jul 17, 2026 at 7:02 PM Jan Beulich <jbeulich@suse.com> wrote:
>>
>> On 17.07.2026 11:22, H.J. Lu wrote:
>>> On Fri, Jul 17, 2026 at 4:44 PM Jan Beulich <jbeulich@suse.com> wrote:
>>>>
>>>> On 15.07.2026 10:17, H.J. Lu wrote:
>>>>> GNU assembler is used by GCC to generate binaries. GCC may not
>>>>> always generate the optimal encoding. That is why I added -O to
>>>>> assembler in the first place. There is no point in adding it if it isn't safe.
>>>>> We can't break applications because of some assembler optimizations.
>>>>
>>>> So this kind of thing will break with any optimization changing encoding
>>>> size:
>>>>
>>>> test eax, eax
>>>> jnz $+9
>>>> test rcx, 0x21
>>>>
>>>> (Intel syntax for all examples, as that's what I'm more used to.)
>>>>
>>>> This clearly breaks as well:
>>>>
>>>> test eax, eax
>>>> jz 1f+2
>>>> 1: test bx, 0x21
>>>>
>>>> As does this:
>>>>
>>>> test ecx, ecx
>>>> jz $+4
>>>> mov rcx, 0xc9634890
>>>>
>>>> While all of these may look contrived, I've seen code (not written by
>>>> myself) doing similar things. A construct branching into the middle of
>>>> an insn was (transiently) even considered to address one of the many
>>>> speculation issues we've seen over the last 8+ years.
>>>
>>> That is why I meant case by case.
>>
>> Well, I've now given you a case where the very first optimizations that
>> were introduced break. Are you now agreeing that we need to rip them all
>
> The primary goal of -O is to have shorter encoding. Clearly you shouldn't
> use it on codes which depend on encoding length. In this case, -O0 or
> .noopt should be used to totally turn off encoding optimization.
Which then would also go as far as the use in valgrind. Feels like we're
moving in circles.
See how Alan has proposed an objective rule: Leave no-operation patterns
alone. As iirc indicated in reply there, I'm intending to make a patch to
that effect. There's one other patch I'd like to finish and submit first,
as leveraging what it does may then become an option.
>> out again? Or else is "case by case" yet more subjective than I understood
>> so far, perhaps as in "H.J.'s optimizations are always okay, while Jan's
>> never are"?
>
> I assume that you didn't mean it.
Well, short of any objective criteria, that's how I can't help feeling it
is being treated right now.
Jan
On Mon, Jul 20, 2026 at 2:43 PM Jan Beulich <jbeulich@suse.com> wrote:
>
> On 17.07.2026 22:24, H.J. Lu wrote:
> > On Fri, Jul 17, 2026 at 7:02 PM Jan Beulich <jbeulich@suse.com> wrote:
> >>
> >> On 17.07.2026 11:22, H.J. Lu wrote:
> >>> On Fri, Jul 17, 2026 at 4:44 PM Jan Beulich <jbeulich@suse.com> wrote:
> >>>>
> >>>> On 15.07.2026 10:17, H.J. Lu wrote:
> >>>>> GNU assembler is used by GCC to generate binaries. GCC may not
> >>>>> always generate the optimal encoding. That is why I added -O to
> >>>>> assembler in the first place. There is no point in adding it if it isn't safe.
> >>>>> We can't break applications because of some assembler optimizations.
> >>>>
> >>>> So this kind of thing will break with any optimization changing encoding
> >>>> size:
> >>>>
> >>>> test eax, eax
> >>>> jnz $+9
> >>>> test rcx, 0x21
> >>>>
> >>>> (Intel syntax for all examples, as that's what I'm more used to.)
> >>>>
> >>>> This clearly breaks as well:
> >>>>
> >>>> test eax, eax
> >>>> jz 1f+2
> >>>> 1: test bx, 0x21
> >>>>
> >>>> As does this:
> >>>>
> >>>> test ecx, ecx
> >>>> jz $+4
> >>>> mov rcx, 0xc9634890
> >>>>
> >>>> While all of these may look contrived, I've seen code (not written by
> >>>> myself) doing similar things. A construct branching into the middle of
> >>>> an insn was (transiently) even considered to address one of the many
> >>>> speculation issues we've seen over the last 8+ years.
> >>>
> >>> That is why I meant case by case.
> >>
> >> Well, I've now given you a case where the very first optimizations that
> >> were introduced break. Are you now agreeing that we need to rip them all
> >
> > The primary goal of -O is to have shorter encoding. Clearly you shouldn't
> > use it on codes which depend on encoding length. In this case, -O0 or
> > .noopt should be used to totally turn off encoding optimization.
>
> Which then would also go as far as the use in valgrind. Feels like we're
> moving in circles.
>
> See how Alan has proposed an objective rule: Leave no-operation patterns
> alone. As iirc indicated in reply there, I'm intending to make a patch to
This should work for valgrind.
> that effect. There's one other patch I'd like to finish and submit first,
> as leveraging what it does may then become an option.
>
> >> out again? Or else is "case by case" yet more subjective than I understood
> >> so far, perhaps as in "H.J.'s optimizations are always okay, while Jan's
> >> never are"?
> >
> > I assume that you didn't mean it.
>
> Well, short of any objective criteria, that's how I can't help feeling it
> is being treated right now.
>
Were you implying that "XCHG to MOV optimization" was
the only optimization you have done so far? That is what
"while Jan's never are" tells me.
On 20.07.2026 08:47, H.J. Lu wrote:
> On Mon, Jul 20, 2026 at 2:43 PM Jan Beulich <jbeulich@suse.com> wrote:
>>
>> On 17.07.2026 22:24, H.J. Lu wrote:
>>> On Fri, Jul 17, 2026 at 7:02 PM Jan Beulich <jbeulich@suse.com> wrote:
>>>>
>>>> On 17.07.2026 11:22, H.J. Lu wrote:
>>>>> On Fri, Jul 17, 2026 at 4:44 PM Jan Beulich <jbeulich@suse.com> wrote:
>>>>>>
>>>>>> On 15.07.2026 10:17, H.J. Lu wrote:
>>>>>>> GNU assembler is used by GCC to generate binaries. GCC may not
>>>>>>> always generate the optimal encoding. That is why I added -O to
>>>>>>> assembler in the first place. There is no point in adding it if it isn't safe.
>>>>>>> We can't break applications because of some assembler optimizations.
>>>>>>
>>>>>> So this kind of thing will break with any optimization changing encoding
>>>>>> size:
>>>>>>
>>>>>> test eax, eax
>>>>>> jnz $+9
>>>>>> test rcx, 0x21
>>>>>>
>>>>>> (Intel syntax for all examples, as that's what I'm more used to.)
>>>>>>
>>>>>> This clearly breaks as well:
>>>>>>
>>>>>> test eax, eax
>>>>>> jz 1f+2
>>>>>> 1: test bx, 0x21
>>>>>>
>>>>>> As does this:
>>>>>>
>>>>>> test ecx, ecx
>>>>>> jz $+4
>>>>>> mov rcx, 0xc9634890
>>>>>>
>>>>>> While all of these may look contrived, I've seen code (not written by
>>>>>> myself) doing similar things. A construct branching into the middle of
>>>>>> an insn was (transiently) even considered to address one of the many
>>>>>> speculation issues we've seen over the last 8+ years.
>>>>>
>>>>> That is why I meant case by case.
>>>>
>>>> Well, I've now given you a case where the very first optimizations that
>>>> were introduced break. Are you now agreeing that we need to rip them all
>>>
>>> The primary goal of -O is to have shorter encoding. Clearly you shouldn't
>>> use it on codes which depend on encoding length. In this case, -O0 or
>>> .noopt should be used to totally turn off encoding optimization.
>>
>> Which then would also go as far as the use in valgrind. Feels like we're
>> moving in circles.
>>
>> See how Alan has proposed an objective rule: Leave no-operation patterns
>> alone. As iirc indicated in reply there, I'm intending to make a patch to
>
> This should work for valgrind.
You're still tied to this particular case. Yes, it'll help their present case.
Yet that it not the motivation for the rule. And there may be another form of
optimization later on that may break valgrind again. I'd like to avoid having
all the same discussion another time, hence why I'm demanding objective
criteria.
>> that effect. There's one other patch I'd like to finish and submit first,
>> as leveraging what it does may then become an option.
>>
>>>> out again? Or else is "case by case" yet more subjective than I understood
>>>> so far, perhaps as in "H.J.'s optimizations are always okay, while Jan's
>>>> never are"?
>>>
>>> I assume that you didn't mean it.
>>
>> Well, short of any objective criteria, that's how I can't help feeling it
>> is being treated right now.
>
> Were you implying that "XCHG to MOV optimization" was
> the only optimization you have done so far? That is what
> "while Jan's never are" tells me.
It's not the first time we discuss an optimization, iirc. Sadly, in cases
where I explicitly request feedback, I'm generally getting none (true not
just for optimizations, though).
Jan
From 14307c8fc8d46a422328a8b8a2024cec5b3fe157 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Sun, 12 Jul 2026 18:24:42 +0800
Subject: [PATCH] x86: Disable XCHG to MOV optimization
The -O option was added to x86 assembler by
commit b6f8c7c45229a8a5405079e586bfbaad396d2cbe
Author: H.J. Lu <hjl.tools@gmail.com>
Date: Tue Feb 27 07:36:33 2018 -0800
x86: Add -O[2|s] assembler command-line options
On x86, some instructions have alternate shorter encodings:
1. When the upper 32 bits of destination registers of
andq $imm31, %r64
testq $imm31, %r64
xorq %r64, %r64
subq %r64, %r64
known to be zero, we can encode them without the REX_W bit:
andl $imm31, %r32
testl $imm31, %r32
xorl %r32, %r32
subl %r32, %r32
This optimization is enabled with -O, -O2 and -Os.
2. Since 0xb0 mov with 32-bit destination registers zero-extends 32-bit
immediate to 64-bit destination register, we can use it to encode 64-bit
mov with 32-bit immediates. This optimization is enabled with -O, -O2
and -Os.
3. Since the upper bits of destination registers of VEX128 and EVEX128
instructions are extended to zero, if all bits of destination registers
of AVX256 or AVX512 instructions are zero, we can use VEX128 or EVEX128
encoding to encode AVX256 or AVX512 instructions. When 2 source
registers are identical, AVX256 and AVX512 andn and xor instructions:
VOP %reg, %reg, %dest_reg
can be encoded with
VOP128 %reg, %reg, %dest_reg
This optimization is enabled with -O2 and -Os.
4. 16-bit, 32-bit and 64-bit register tests with immediate may be
encoded as 8-bit register test with immediate. This optimization is
enabled with -Os.
These optimizations were intended for compiler generated assembly codes.
The optimization changes may take a long time to be put into GCC. The
similar SSE move encoding optimization for GCC was first proposed in
Feb, 2019:
https://gcc.gnu.org/pipermail/gcc-patches/2019-February/516941.html
It finally went in Mar, 2020:
commit 5358e8f5800daa0012fc9d06705d64bbb21fa07b
Author: H.J. Lu <hjl.tools@gmail.com>
Date: Thu Mar 5 16:45:05 2020 -0800
i386: Properly encode vector registers in vector move
Such optimizations are useful for compiler generated codes since they
work with released versions of GCC which don't have such optimized
encoding. We assume that it is safe to use on compiler generated codes.
When we are informed that an assembler optimization introduces a
significant drawback, we will investigate its drawbacks and benefits.
If its drawbacks outweigh its benefits, such optimization should be
removed.
commit 1c3c3e4b3c2ac2eed9abcbce0b9cba1be10ed3f0
Author: Jan Beulich <jbeulich@suse.com>
Date: Fri Jun 19 09:47:21 2026 +0200
x86: optimize XCHG to MOV for same-register forms
breaks valgrind:
https://bugs.kde.org/show_bug.cgi?id=522533
"xchgl %ecx,%ecx" in VALGRIND_GET_NR_CONTEXT, which is defined in
/usr/include/valgrind/valgrind.h:
#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; \
}
has special meanings and shouldn't be changed by assembler even when
assembler optimization is enabled. Since there are no any evidences
to show its benefits, we can't say that it is useful at all. This
patch removes this optimization.
gas/
PR gas/34343
* config/tc-i386.c (optimize_for_unsafe): New.
(optimize_encoding): Optimize "xchg %rN, %rN" to "mov %rN, %rN"
only if optimize_for_unsafe isn't 0.
* testsuite/gas/i386/optimize-2b.d: Updated.
* testsuite/gas/i386/x86-64-optimize-3b.d: Likewise.
Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
---
gas/config/tc-i386.c | 5 ++++-
gas/testsuite/gas/i386/optimize-2b.d | 6 +++---
gas/testsuite/gas/i386/x86-64-optimize-3b.d | 8 ++++----
3 files changed, 11 insertions(+), 8 deletions(-)
@@ -848,6 +848,9 @@ static int optimize = 0;
*/
static int optimize_for_space = 0;
+/* Optimizations which may be unsafe. Disabled for now. */
+static int optimize_for_unsafe = 0;
+
/* Register prefix used for error message. */
static const char *register_prefix = "%";
@@ -5177,7 +5180,7 @@ optimize_encoding (void)
i.seg[0] = NULL;
}
- if (!optimize_for_space
+ if (optimize_for_unsafe
&& i.tm.mnem_off == MN_xchg
&& i.reg_operands == 2
&& i.op[0].regs == i.op[1].regs)
@@ -25,9 +25,9 @@ Disassembly of section .text:
+[a-f0-9]+: 85 f6 test %esi,%esi
+[a-f0-9]+: 87 0a xchg %ecx,\(%edx\)
+[a-f0-9]+: 87 11 xchg %edx,\(%ecx\)
- +[a-f0-9]+: 88 c9 mov %cl,%cl
- +[a-f0-9]+: 66 8b d2 mov %dx,%dx
- +[a-f0-9]+: 89 ff mov %edi,%edi
+ +[a-f0-9]+: 86 c9 xchg %cl,%cl
+ +[a-f0-9]+: 66 87 d2 xchg %dx,%dx
+ +[a-f0-9]+: 87 ff xchg %edi,%edi
+[a-f0-9]+: 66 98 cbtw
+[a-f0-9]+: 66 98 cbtw
+[a-f0-9]+: 98 cwtl
@@ -81,10 +81,10 @@ Disassembly of section .text:
+[a-f0-9]+: 66 85 f6 test %si,%si
+[a-f0-9]+: 09 ff or %edi,%edi
+[a-f0-9]+: 4d 85 c0 test %r8,%r8
- +[a-f0-9]+: d5 50 88 c9 mov %r17b,%r17b
- +[a-f0-9]+: 66 45 8b c0 mov %r8w,%r8w
- +[a-f0-9]+: 89 c0 mov %eax,%eax
- +[a-f0-9]+: 4d 89 ff mov %r15,%r15
+ +[a-f0-9]+: d5 50 86 c9 xchg %r17b,%r17b
+ +[a-f0-9]+: 66 45 87 c0 xchg %r8w,%r8w
+ +[a-f0-9]+: 87 c0 xchg %eax,%eax
+ +[a-f0-9]+: 4d 87 ff xchg %r15,%r15
+[a-f0-9]+: 66 98 cbtw
+[a-f0-9]+: 66 98 cbtw
+[a-f0-9]+: 98 cwtl
--
2.55.0