On Tue, 2026-10-20 at 09:19 -0700, Vineet Gupta wrote:
> A spill narrower than its source stores the source's low 32 bits, so the
> slot is their zero-extension -- the mov relation, in the store direction:
> 
>   r6 = ...                  /* full 64-bit unknown */
>   *(u32 *)(r10 - 8) = r6;   /* slot holds r6's low 32 bits */
>   if w6 != 0 goto ...       /* not taken: r6's low 32 bits are 0 */
>   r2 = *(u32 *)(r10 - 8);
>   if r2 == 0 goto ...       /* not deduced today */
> 
> A store never sign-extends, so BPF_REG_LINK_ZEXT is the only kind that
> arises. save_register_state() copies the source whole, including bounds
> for bits the store did not write, so the slot must be truncated before
> the kind goes on it -- otherwise the first sync_linked_regs() intersects
> the correctly rebuilt low half against those stale bounds and empties
> the slot.
> 
> Only one order pays. sync_linked_regs() walks spilled slots, so narrowing
> while the value is still on the stack narrows the slot and the fill copies
> an already narrowed value. Filling first does not benefit: the fill is a
> mov, and a mov drops a zero-extending link.
> 
> Posted, not proposed. This is the direction asked for, implemented and
> measured, and the measurement says do not take it. Against the ten patches
> before it, on 441 cilium/katran/fb/sched_ext objects, 1467 programs:
> 
>   verdicts      no change at all
>   total_insns   102 changed, 63 worse, +84,450 (+0.34%)
>                   +59,616 (+57.2%)  104,160 -> 163,776  test_file_open
>                   +19,784 (+89.7%)   22,053 ->  41,837  rusty_enqueue
>                    +2,688 (+40.6%)    6,626 ->   9,314  layered_enqueue
>   total_states   64 changed, 63 worse

I'd still prefer to keep things symmetric.
Instruction budget should be less of a concert for 7.5,
as far as I understand.

...

Reply via email to