[PATCH RFC 1/2] LoongArch: BPF: Eliminate zero-extension for memory load operations

From: Tiezhu Yang

Date: Sat Jul 11 2026 - 06:17:07 EST


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 <yangtiezhu@xxxxxxxxxxx>
---
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 69bc30f88c44..b8cef3ea5c6d 100644
--- a/arch/loongarch/net/bpf_jit.c
+++ b/arch/loongarch/net/bpf_jit.c
@@ -579,6 +579,14 @@ static int emit_atomic_ld_st(const struct bpf_insn *insn, struct jit_ctx *ctx)
break;
}
emit_insn(ctx, dbar, 0b10100);
+
+ /*
+ * If our 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(code) != BPF_DW && insn_is_zext(&insn[1]))
+ return 1;
break;
/* store_release(dst_reg + off16, src_reg) */
case BPF_STORE_REL:
@@ -1318,6 +1326,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 our 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 */
@@ -2397,6 +2413,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