LLVM BPF pass SimplifyPatchable is used to do necessary
code conversion for CO-RE operations. When studying bpf
selftest 'exhandler', I found a corner case not handled properly.
The following is the C code, modified from original 'exhandler'
code.
int g; int test(struct t1 *p) { struct t2 *q = p->q; if (q) return 0; struct t3 *f = q->f; if (!f) g = 5; return 0; }
For code:
struct t3 *f = q->f; if (!f) ...
The IR before BPFMISimplifyPatchable pass looks like:
%5:gpr = LD_imm64 @"llvm.t2:0:8$0:1" %6:gpr = LDD killed %5:gpr, 0 %7:gpr = LDD killed %6:gpr, 0 JNE_ri killed %7:gpr, 0, %bb.3 JMP %bb.2
Note that compiler knows q = 0 based dataflow and value analysis.
The correct generated code after the pass should be
%5:gpr = LD_imm64 @"llvm.t2:0:8$0:1" %7:gpr = LDD killed %5:gpr, 0 JNE_ri killed %7:gpr, 0, %bb.3 JMP %bb.2
But the current implementation did further optimization for the
above code and generates
%5:gpr = LD_imm64 @"llvm.t2:0:8$0:1" JNE_ri killed %5:gpr, 0, %bb.3 JMP %bb.2
which is incorrect.
This patch added a cache to remember those load insns not associated
with CO-RE offset value and will skip these load insns during
transformation.
why gate only loads here?
The hunk below will apply to loads only anyway,
so this check looks unnecessary.
If both filter_loads checks (here and line 267) are necessary may be combine them into a helper function?