Skip to content

Commit 2fca0ef

Browse files
authored
[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
1 parent f957d08 commit 2fca0ef

File tree

3 files changed

+73
-1
lines changed

3 files changed

+73
-1
lines changed

llvm/lib/Target/BPF/BPFMIPeephole.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,9 @@ static void collectBPFFastCalls(const TargetRegisterInfo *TRI,
618618
if (MI.isCall()) {
619619
unsigned LiveCallerSavedRegs = 0;
620620
for (MCRegister R : CallerSavedRegs) {
621-
bool DoSpillFill = !MI.definesRegister(R, TRI) && LiveRegs.contains(R);
621+
bool DoSpillFill = false;
622+
for (MCPhysReg SR : TRI->subregs(R))
623+
DoSpillFill |= !MI.definesRegister(SR, TRI) && LiveRegs.contains(SR);
622624
if (!DoSpillFill)
623625
continue;
624626
LiveCallerSavedRegs |= 1 << R;
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
; RUN: llc -O2 --march=bpfel %s -o - | FileCheck %s
2+
3+
; Generated from the following C code:
4+
;
5+
; extern int foo(void) __attribute__((bpf_fastcall));
6+
;
7+
; int bar(int a) {
8+
; foo();
9+
; return a;
10+
; }
11+
;
12+
; Using the following command:
13+
;
14+
; clang --target=bpf -emit-llvm -O2 -S -o - t.c
15+
;
16+
; (unnecessary attrs removed maually)
17+
18+
; Check that function marked with bpf_fastcall does not clobber W1-W5.
19+
20+
define dso_local i32 @bar(i32 %a) {
21+
entry:
22+
%call = tail call i32 @foo() #0
23+
ret i32 %a
24+
}
25+
26+
; CHECK: # %bb.0:
27+
; CHECK-NEXT: *(u64 *)(r10 - 8) = r1
28+
; CHECK-NEXT: call foo
29+
; CHECK-NEXT: r1 = *(u64 *)(r10 - 8)
30+
; CHECK-NEXT: w0 = w1
31+
; CHECK-NEXT: exit
32+
33+
declare dso_local i32 @foo() #0
34+
35+
attributes #0 = { "bpf_fastcall" }
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
; RUN: llc -O2 --march=bpfel %s -o - | FileCheck %s
2+
3+
; Generated from the following C code:
4+
;
5+
; extern int foo(void) __attribute__((bpf_fastcall));
6+
;
7+
; int bar(int a, int b, int c, int d, int e) {
8+
; foo();
9+
; return e;
10+
; }
11+
;
12+
; Using the following command:
13+
;
14+
; clang --target=bpf -emit-llvm -O2 -S -o - t.c
15+
;
16+
; (unnecessary attrs removed maually)
17+
18+
; Check that function marked with bpf_fastcall does not clobber W1-W5.
19+
20+
define dso_local i32 @bar(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e) {
21+
entry:
22+
%call = tail call i32 @foo() #0
23+
ret i32 %e
24+
}
25+
26+
; CHECK: # %bb.0:
27+
; CHECK-NEXT: *(u64 *)(r10 - 8) = r5
28+
; CHECK-NEXT: call foo
29+
; CHECK-NEXT: r5 = *(u64 *)(r10 - 8)
30+
; CHECK-NEXT: w0 = w5
31+
; CHECK-NEXT: exit
32+
33+
declare dso_local i32 @foo() #0
34+
35+
attributes #0 = { "bpf_fastcall" }

0 commit comments

Comments
 (0)