[PATCH v1 2/2] LoongArch: BPF: Eliminate zero-extension for memory load operations
Tiezhu Yang <[email protected]> Tue, 28 Jul 2026 11:16:15 +0800
| Newsgroups | dev.linux.lists.loongarch,org.kernel.vger.bpf,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
The unsigned memory load instructions naturally clear the upper 32 bits of the destination register during sub-word and word memory accesses. Add a look-ahead optimization for the load instructions by checking the next instruction. This is achieved by overwriting bpf_jit_needs_zext() to return true. If insn_is_zext() detects a redundant zero-extension, return 1 to inform the outer build_body() to skip the instruction. For normal loads, this look-ahead is safely restricted to unsigned modes (!sign_extend) to preserve signed contexts. With this patch, directly reduce the final JITted image size. Signed-off-by: Tiezhu Yang <[email protected]> --- arch/loongarch/net/bpf_jit.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c index 4c54e57455ae..417b69b7ec4a 100644 --- a/arch/loongarch/net/bpf_jit.c +++ b/arch/loongarch/net/bpf_jit.c @@ -554,6 +554,14 @@ static int emit_atomic_ld_st(const struct bpf_insn *insn, struct jit_ctx *ctx) break; } emit_insn(ctx, dbar, 0b10100); + + /* + * If the next insn is a redundant zext, return 1 to tell + * build_body() to skip it, as atomic load-acquires always + * zero-extend sub-word results. + */ + if (BPF_SIZE(insn->code) != BPF_DW && insn_is_zext(&insn[1])) + return 1; break; /* store_release(dst_reg + off16, src_reg) */ case BPF_STORE_REL: @@ -1303,6 +1311,14 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext ret = add_exception_handler(insn, ctx, dst); if (ret) return ret; + + /* + * If the next insn is a redundant zext, and this is a standard + * unsigned sub-word load where hardware already zero-extends, + * return 1 to tell build_body() to skip it. + */ + if (BPF_SIZE(code) != BPF_DW && !sign_extend && insn_is_zext(&insn[1])) + return 1; break; /* *(size *)(dst + off) = imm */ @@ -2383,6 +2399,11 @@ bool bpf_jit_supports_subprog_tailcalls(void) return true; } +bool bpf_jit_needs_zext(void) +{ + return true; +} + bool bpf_jit_inlines_helper_call(s32 imm) { switch (imm) { -- 2.42.0