On Thu, Oct 8, 2026 at 6:33 AM Naveen
<[email protected]> wrote:
>
> The x86 backend misses an optimization for a zero-extended HImode
> unsigned minimum with a constant. Add an HImode conditional-move
> pattern that preserves the flags dependency and use it in a new
> zero-extension splitter.
>
> This allows x86-64 to use a HImode conditional move and avoids the
> redundant zero-extension instruction.
No, HImode conditional move writes only the low 16 bits if the
condition is true; the upper bits are preserved either way. If the
condition is false, nothing changes.
f:
movl $255, %eax # 17 [c=4 l=5] *movhi_internal/1
cmpw %ax, %di # 18 [c=4 l=3] *cmphi_1/0
cmova %eax, %edi # 21 [c=4 l=3] *movsicc_noc/1
movzwl %di, %eax # 7 [c=4 l=3] *zero_extendhisi2/0
ret # 24 [c=0 l=1] simple_return_internal
cmova %eax, %edi (32-bit) means:
- If the condition holds, edi = 255, fully defined.
- If it doesn't, edi keeps its old value. Bits 31:16 are whatever the
caller left there, since the ABI doesn't guarantee they are zero. The
32-bit form only clears bits 63:32.
cmovaw %ax, %di would be worse. Bits 63:16 are preserved on both
paths, so the garbage survives in the not-taken case.
Also, a 16-bit conditional move leaves a partial-register merge
dependency on the old destination value (the same false-dependency
issue as other 16-bit writes), so compilers usually avoid cmovw and
promote to cmovl where the upper bits are don't-care.
Uros.