Re: [PATCH bpf-next v3 11/12] [do not merge] bpf: Track low-32 scalar equality across narrowing stack spills
From: Eduard Zingerman
Date: Fri Oct 30 2026 - 14:33:19 EST
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.
...