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

From: Tiezhu Yang

Date: Mon Jul 27 2026 - 23:21:57 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 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