public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Eduard Zingerman <eddyz87@gmail.com>
To: Hao Sun <sunhao.th@gmail.com>, bpf@vger.kernel.org
Cc: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org,
	 john.fastabend@gmail.com, martin.lau@linux.dev,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH] bpf: Simplify tnum_step()
Date: Thu, 19 Mar 2026 00:24:50 -0700	[thread overview]
Message-ID: <9a6dd99e31bae75da12eaa18ddc7424534d13621.camel@gmail.com> (raw)
In-Reply-To: <20260318171906.53174-1-hao.sun@inf.ethz.ch>

On Wed, 2026-03-18 at 18:19 +0100, Hao Sun wrote:
> Simplify tnum_step() from a 10-variable algorithm into a straight
> line sequence of bitwise operations.
> 
> tnum_step(): Given a tnum `(tval, tmask)` where `tval & tmask == 0`,
> and a value `z` with `tval ≤ z < (tval | tmask)`, find the smallest
> `r > z`, a tnum-satisfying value, i.e., `r & ~tmask == tval`.
> 
> Every tnum-satisfying value has the form tval | s where s is a subset
> of tmask bits (s & ~tmask == 0).  Since tval and tmask are disjoint:
> 
>     tval | s  =  tval + s
> 
> Similarly z = tval + d where d = z - tval, so r > z becomes:
> 
>     tval + s  >  tval + d
>     s > d
> 
> The problem reduces to: find the smallest s, a subset of tmask, such
> that s > d.
> 
> Notice that `s` must be a subset of tmask, the problem now is simplified.
> 
> The mask bits of `d` form a "counter" that we want to increment by one,
> but the counter has gaps at the fixed-bit positions.  A normal +1 would
> stop at the first 0-bit it meets; we need it to skip over fixed-bit
> gaps and land on the next mask bit.
> 
> Step 1 -- plug the gaps:
> 
>     d | carry_mask | ~tmask
> 
>   - ~tmask fills all fixed-bit positions with 1.
>   - carry_mask = (1 << fls64(d & ~tmask)) - 1 fills all positions
>     (including mask positions) below the highest non-mask bit of d.
> 
> After this, the only remaining 0s are mask bits above the highest
> non-mask bit of d where d is also 0 -- exactly the positions where
> the carry can validly land.
> 
> Step 2 -- increment:
> 
>     (d | carry_mask | ~tmask) + 1
> 
> Adding 1 flips all trailing 1s to 0 and sets the first 0 to 1.  Since
> every gap has been plugged, that first 0 is guaranteed to be a mask bit
> above all non-mask bits of d.
> 
> Step 3 -- mask:
> 
>     ((d | carry_mask | ~tmask) + 1) & tmask
> 
> Strip the scaffolding, keeping only mask bits.  Call the result inc.
> 
> Step 4 -- result:
> 
>     tval | inc
> 
> Reattach the fixed bits.
> 
> A simple 8-bit example:
>     tmask:        1  1  0  1  0  1  1  0
>     d:            1  0  1  0  0  0  1  0     (d = 162)
>                         ^
>                         non-mask 1 at bit 5
> 
> With carry_mask = 0b00111111 (smeared from bit 5):
> 
>     d|carry|~tm   1  0  1  1  1  1  1  1
>     + 1           1  1  0  0  0  0  0  0
>     & tmask       1  1  0  0  0  0  0  0
> 
> The patch passes my local test: test_verifier, test_prog for
> `-t verifier` and `-t reg_bounds`.
> 
> Signed-off-by: Hao Sun <hao.sun@inf.ethz.ch>

I hacked a cbmc test in [1] and the checker says that the new function
performs according to specification (and identically to old function).

[1] https://github.com/eddyz87/tnum-step-verif/blob/master/main.c

Acked-by: Eduard Zingerman <eddyz87@gmail.com>

[...]

  parent reply	other threads:[~2026-03-19  7:24 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-18 17:19 [PATCH] bpf: Simplify tnum_step() Hao Sun
2026-03-19  5:22 ` Shung-Hsi Yu
2026-03-19  9:01   ` Hao Sun
2026-03-19  9:35     ` Paul Chaignon
2026-03-19 13:12       ` Hao Sun
2026-03-19 13:24         ` Paul Chaignon
2026-03-20  2:04       ` Shung-Hsi Yu
2026-03-19  7:24 ` Eduard Zingerman [this message]
2026-03-19  9:02   ` Hao Sun
2026-03-19  8:17 ` Kumar Kartikeya Dwivedi
2026-03-19  9:06   ` Hao Sun
2026-03-19 17:38     ` Eduard Zingerman
2026-03-19 19:41       ` Hao Sun

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=9a6dd99e31bae75da12eaa18ddc7424534d13621.camel@gmail.com \
    --to=eddyz87@gmail.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=john.fastabend@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=martin.lau@linux.dev \
    --cc=sunhao.th@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox