1; RUN: llc -O2 --mtriple=bpfel %s -o - | FileCheck %s 2 3; Generated from the following C code: 4; 5; #define __bpf_fastcall __attribute__((bpf_fastcall)) 6; 7; void quux(void *); 8; void bar(long) __bpf_fastcall; 9; void buz(long i, long j); 10; 11; void foo(long i, long j) { 12; long k; 13; bar(i); 14; bar(i); 15; buz(i, j); 16; quux(&k); 17; } 18; 19; Using the following command: 20; 21; clang --target=bpf -emit-llvm -O2 -S -o - t.c 22; 23; (unnecessary attrs removed maually) 24 25; Check that function marked with bpf_fastcall does not clobber R1-R5. 26; Check that spills/fills wrapping the call use and reuse lowest stack offsets. 27 28define dso_local void @foo(i64 noundef %i, i64 noundef %j) { 29entry: 30 %k = alloca i64, align 8 31 tail call void @bar(i64 noundef %i) #0 32 tail call void @bar(i64 noundef %i) #0 33 tail call void @buz(i64 noundef %i, i64 noundef %j) 34 call void @quux(ptr noundef nonnull %k) 35 ret void 36} 37 38; CHECK: # %bb.0: 39; CHECK-NEXT: r3 = r1 40; CHECK-NEXT: *(u64 *)(r10 - 16) = r2 41; CHECK-NEXT: *(u64 *)(r10 - 24) = r3 42; CHECK-NEXT: call bar 43; CHECK-NEXT: r3 = *(u64 *)(r10 - 24) 44; CHECK-NEXT: r2 = *(u64 *)(r10 - 16) 45; CHECK-NEXT: r1 = r3 46; CHECK-NEXT: *(u64 *)(r10 - 16) = r2 47; CHECK-NEXT: *(u64 *)(r10 - 24) = r3 48; CHECK-NEXT: call bar 49; CHECK-NEXT: r3 = *(u64 *)(r10 - 24) 50; CHECK-NEXT: r2 = *(u64 *)(r10 - 16) 51; CHECK-NEXT: r1 = r3 52; CHECK-NEXT: call buz 53; CHECK-NEXT: r1 = r10 54; CHECK-NEXT: r1 += -8 55; CHECK-NEXT: call quux 56; CHECK-NEXT: exit 57 58declare dso_local void @bar(i64 noundef) #0 59declare dso_local void @buz(i64 noundef, i64 noundef) 60declare dso_local void @quux(ptr noundef) 61 62attributes #0 = { "bpf_fastcall" } 63