[llvm] 2fca0ef - [BPF] fix sub-register handling for bpf_fastcall (#110618)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Oct 1 11:20:26 PDT 2024
Author: eddyz87
Date: 2024-10-01T21:20:22+03:00
New Revision: 2fca0effb4e1cbb620b7f21e9b867198ba20028a
URL: https://github.com/llvm/llvm-project/commit/2fca0effb4e1cbb620b7f21e9b867198ba20028a
DIFF: https://github.com/llvm/llvm-project/commit/2fca0effb4e1cbb620b7f21e9b867198ba20028a.diff
LOG: [BPF] fix sub-register handling for bpf_fastcall (#110618)
bpf_fastcall induced spill/fill pairs should be generated for
sub-register as well as for sub-registers. At the moment this is not the
case, e.g.:
$ cat t.c
extern int foo(void) __attribute__((bpf_fastcall));
int bar(int a) {
foo();
return a;
}
$ clang --target=bpf -mcpu=v3 -O2 -S t.c -o -
...
call foo
w0 = w1
exit
Modify BPFMIPeephole.cpp:collectBPFFastCalls() to check sub-registers
liveness and thus produce correct code for example above:
*(u64 *)(r10 - 8) = r1
call foo
r1 = *(u64 *)(r10 - 8)
w0 = w1
exit
Added:
llvm/test/CodeGen/BPF/bpf-fastcall-4.ll
llvm/test/CodeGen/BPF/bpf-fastcall-5.ll
Modified:
llvm/lib/Target/BPF/BPFMIPeephole.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Target/BPF/BPFMIPeephole.cpp b/llvm/lib/Target/BPF/BPFMIPeephole.cpp
index c41eab319dbb9b..2b17f2aaefe2bf 100644
--- a/llvm/lib/Target/BPF/BPFMIPeephole.cpp
+++ b/llvm/lib/Target/BPF/BPFMIPeephole.cpp
@@ -618,7 +618,9 @@ static void collectBPFFastCalls(const TargetRegisterInfo *TRI,
if (MI.isCall()) {
unsigned LiveCallerSavedRegs = 0;
for (MCRegister R : CallerSavedRegs) {
- bool DoSpillFill = !MI.definesRegister(R, TRI) && LiveRegs.contains(R);
+ bool DoSpillFill = false;
+ for (MCPhysReg SR : TRI->subregs(R))
+ DoSpillFill |= !MI.definesRegister(SR, TRI) && LiveRegs.contains(SR);
if (!DoSpillFill)
continue;
LiveCallerSavedRegs |= 1 << R;
diff --git a/llvm/test/CodeGen/BPF/bpf-fastcall-4.ll b/llvm/test/CodeGen/BPF/bpf-fastcall-4.ll
new file mode 100644
index 00000000000000..4f0c9fc94aa9df
--- /dev/null
+++ b/llvm/test/CodeGen/BPF/bpf-fastcall-4.ll
@@ -0,0 +1,35 @@
+; RUN: llc -O2 --march=bpfel %s -o - | FileCheck %s
+
+; Generated from the following C code:
+;
+; extern int foo(void) __attribute__((bpf_fastcall));
+;
+; int bar(int a) {
+; foo();
+; return a;
+; }
+;
+; Using the following command:
+;
+; clang --target=bpf -emit-llvm -O2 -S -o - t.c
+;
+; (unnecessary attrs removed maually)
+
+; Check that function marked with bpf_fastcall does not clobber W1-W5.
+
+define dso_local i32 @bar(i32 %a) {
+entry:
+ %call = tail call i32 @foo() #0
+ ret i32 %a
+}
+
+; CHECK: # %bb.0:
+; CHECK-NEXT: *(u64 *)(r10 - 8) = r1
+; CHECK-NEXT: call foo
+; CHECK-NEXT: r1 = *(u64 *)(r10 - 8)
+; CHECK-NEXT: w0 = w1
+; CHECK-NEXT: exit
+
+declare dso_local i32 @foo() #0
+
+attributes #0 = { "bpf_fastcall" }
diff --git a/llvm/test/CodeGen/BPF/bpf-fastcall-5.ll b/llvm/test/CodeGen/BPF/bpf-fastcall-5.ll
new file mode 100644
index 00000000000000..608ab4a0bb0cfd
--- /dev/null
+++ b/llvm/test/CodeGen/BPF/bpf-fastcall-5.ll
@@ -0,0 +1,35 @@
+; RUN: llc -O2 --march=bpfel %s -o - | FileCheck %s
+
+; Generated from the following C code:
+;
+; extern int foo(void) __attribute__((bpf_fastcall));
+;
+; int bar(int a, int b, int c, int d, int e) {
+; foo();
+; return e;
+; }
+;
+; Using the following command:
+;
+; clang --target=bpf -emit-llvm -O2 -S -o - t.c
+;
+; (unnecessary attrs removed maually)
+
+; Check that function marked with bpf_fastcall does not clobber W1-W5.
+
+define dso_local i32 @bar(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e) {
+entry:
+ %call = tail call i32 @foo() #0
+ ret i32 %e
+}
+
+; CHECK: # %bb.0:
+; CHECK-NEXT: *(u64 *)(r10 - 8) = r5
+; CHECK-NEXT: call foo
+; CHECK-NEXT: r5 = *(u64 *)(r10 - 8)
+; CHECK-NEXT: w0 = w5
+; CHECK-NEXT: exit
+
+declare dso_local i32 @foo() #0
+
+attributes #0 = { "bpf_fastcall" }
More information about the llvm-commits
mailing list