[PATCH] D157806: [BPF] Fix in/out argument constraints for CORE_MEM instructions
Eduard Zingerman via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Sun Aug 13 07:26:58 PDT 2023
eddyz87 created this revision.
Herald added a subscriber: hiraditya.
Herald added a project: All.
eddyz87 published this revision for review.
eddyz87 added a reviewer: yonghong-song.
eddyz87 added a comment.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.
Hi Yonghong,
Could you please take a look at this revision?
All BPF Kernel selftests are passing and there are no changes in the generated object files (I checked for cpuv4).
This is the reason for testbot failures reported <https://reviews.llvm.org/D140804#4578547> for D140804 <https://reviews.llvm.org/D140804>.
(The test case in D140804 <https://reviews.llvm.org/D140804> was written in a way that triggers this failure).
When LLVM is build with `LLVM_ENABLE_EXPENSIVE_CHECKS=ON` option the
following C code snippet:
struct t {
int a;
} __attribute__((preserve_access_index));
void test(struct t *t) {
t->a = 42;
}
Causes an assertion:
llvm
$ clang -g -O2 -c --target=bpf -mcpu=v2 t.c -o /dev/null
Function Live Ins: $r1 in %0
bb.0.entry:
liveins: $r1
DBG_VALUE $r1, $noreg, !"t", ...
%0:gpr = COPY $r1
DBG_VALUE %0:gpr, $noreg, !"t", ...
%1:gpr = LD_imm64 @"llvm.t:0:0$0:0"
%3:gpr = ADD_rr %0:gpr(tied-def 0), killed %1:gpr
%4:gpr = MOV_ri 42
CORE_MEM killed %4:gpr, 411, %0:gpr, @"llvm.t:0:0$0:0", ...
RET debug-location !25; t.c:7:1
*** Bad machine code: Explicit definition marked as use ***
- function: test
- basic block: %bb.0 entry (0x6210000d8a90)
- instruction: CORE_MEM killed %4:gpr, 411, %0:gpr, @"llvm.t:0:0$0:0", ...
- operand 0: killed %4:gpr
This happens because `CORE_MEM` instruction is defined to have output
operands:
tablegen
def CORE_MEM : TYPE_LD_ST<BPF_MEM.Value, BPF_W.Value,
(outs GPR:$dst),
(ins u64imm:$opcode, GPR:$src, u64imm:$offset),
"$dst = core_mem($opcode, $src, $offset)",
[]>;
As documented in [1]:
> By convention, the LLVM code generator orders instruction operands
> so that all register definitions come before the register uses, even
> on architectures that are normally printed in other orders.
In other words, the first argument for `CORE_MEM` is considered to be
a "def", while in reality it is "use":
llvm
%1:gpr = LD_imm64 @"llvm.t:0:0$0:0"
%3:gpr = ADD_rr %0:gpr(tied-def 0), killed %1:gpr
%4:gpr = MOV_ri 42
'---------------.
v
CORE_MEM killed %4:gpr, 411, %0:gpr, @"llvm.t:0:0$0:0", ...
Here is how `CORE_MEM` is constructed in
`BPFMISimplifyPatchable::checkADDrr()`:
cpp
BuildMI(*DefInst->getParent(), *DefInst, DefInst->getDebugLoc(), TII->get(COREOp))
.add(DefInst->getOperand(0)).addImm(Opcode).add(*BaseOp)
.addGlobalAddress(GVal);
Note that first operand is constructed as `.add(DefInst->getOperand(0))`.
For `LD{D,W,H,B}` instructions the `DefInst->getOperand(0)` is a
destination register of a load, so instruction is constructed in
accordance with `outs` declaration.
For `ST{D,W,H,B}` instructions the `DefInst->getOperand(0)` is a
source register of a store (value to be stored), so instruction
violates the `outs` declaration.
This commit fixes the issue by splitting `CORE_MEM` in two
instructions: `CORE_ST`, `CORE_LD` with correct `outs`
specifications. (+ same changes for `CORE_ALU32_MEM`).
[1] https://llvm.org/docs/CodeGenerator.html#the-machineinstr-class
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D157806
Files:
llvm/lib/Target/BPF/BPFInstrInfo.td
llvm/lib/Target/BPF/BPFMISimplifyPatchable.cpp
llvm/lib/Target/BPF/BTFDebug.cpp
llvm/test/CodeGen/BPF/CORE/offset-reloc-simplify-patchable-1.ll
llvm/test/CodeGen/BPF/CORE/offset-reloc-simplify-patchable-2.ll
llvm/test/CodeGen/BPF/CORE/offset-reloc-simplify-patchable-3.ll
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D157806.549672.patch
Type: text/x-patch
Size: 30520 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230813/e88ea749/attachment.bin>
More information about the llvm-commits
mailing list