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.

Reply via email to