In BPF instruction set [1] load and store instructions are the same
for both ALU and ALU64 modes. Current STW/STW32, STH/STH32, STB/STB32,
LDW/LDW32, LDH/LDH32, LDB/LDB32 instructions have identical byte-code
representations pairwise.
However, at assembly level current BPF backend has different
syntactical representations for these instructions, e.g.:
in -mcpu=v2 mode: r0 = *(u32 *)(r1 + 42) vs in -mcpu=v3 mode: w0 = *(u32 *)(r1 + 42)
This discrepancy is discussed in recent LKML mail thread [2].
This commit removes ST*32/LD*32 instructions replacing those with
64-bit versions combined with EXTRACT_SUBREG when appropriate,
thus removing the notational difference.
E.g. for the code snippet below:
void bar(unsigned int *a, unsigned int *b) { *a = *b; }
Results of clang -O2 -mcpu=v3 --target=bpf -S -o - t.c change as
follows:
before after ------ ----- w2 = *(u32 *)(r2 + 0) r2 = *(u32 *)(r2 + 0) *(u32 *)(r1 + 0) = w2 *(u32 *)(r1 + 0) = r2
[1] https://www.kernel.org/doc/html/latest/bpf/instruction-set.html#load-and-store-instructions
[2] https://lore.kernel.org/bpf/87ila7dhmp.fsf@oracle.com/
If I understand correctly, the asm syntax w5 = *(u8 *)(r0 + 0) is not supported any more with this patch. That means, if users write inline asm in their code like
The inline asm can be successfully compiled with llvm17/llvm16 etc. but will
fail compilation with llvm18 (with this patch). Is this what we want?