1; RUN: llc -O2 --mtriple=bpfel -mcpu=v1 %s -o - | FileCheck %s 2 3; Generated from the following C code: 4; 5; #define __bpf_fastcall __attribute__((bpf_fastcall)) 6; 7; void bar(void) __bpf_fastcall; 8; void buz(long i, long j); 9; 10; void foo(long i, long j, long k, long l) { 11; bar(); 12; if (k > 42l) 13; buz(i, 1); 14; else 15; buz(1, j); 16; } 17; 18; Using the following command: 19; 20; clang --target=bpf -emit-llvm -O2 -S -o - t.c 21; 22; (unnecessary attrs removed maually) 23 24; Check that function marked with bpf_fastcall does not clobber R1-R5. 25; Use R1 in one branch following call and R2 in another branch following call. 26 27define dso_local void @foo(i64 noundef %i, i64 noundef %j, i64 noundef %k, i64 noundef %l) { 28entry: 29 tail call void @bar() #0 30 %cmp = icmp sgt i64 %k, 42 31 br i1 %cmp, label %if.then, label %if.else 32 33if.then: 34 tail call void @buz(i64 noundef %i, i64 noundef 1) 35 br label %if.end 36 37if.else: 38 tail call void @buz(i64 noundef 1, i64 noundef %j) 39 br label %if.end 40 41if.end: 42 ret void 43} 44 45; CHECK: foo: # @foo 46; CHECK: # %bb.0: # %entry 47; CHECK-NEXT: *(u64 *)(r10 - 8) = r1 48; CHECK-NEXT: *(u64 *)(r10 - 16) = r2 49; CHECK-NEXT: *(u64 *)(r10 - 24) = r3 50; CHECK-NEXT: call bar 51; CHECK-NEXT: r3 = *(u64 *)(r10 - 24) 52; CHECK-NEXT: r2 = *(u64 *)(r10 - 16) 53; CHECK-NEXT: r1 = *(u64 *)(r10 - 8) 54; CHECK-NEXT: r4 = 43 55; CHECK-NEXT: if r4 s> r3 goto [[ELSE:.*]] 56; CHECK-NEXT: # %bb.1: # %if.then 57; CHECK-NEXT: r2 = 1 58; CHECK-NEXT: goto [[END:.*]] 59; CHECK-NEXT: [[ELSE]]: # %if.else 60; CHECK-NEXT: r1 = 1 61; CHECK-NEXT: [[END]]: # %if.end 62; CHECK-NEXT: call buz 63; CHECK-NEXT: exit 64 65declare dso_local void @bar() #0 66declare dso_local void @buz(i64 noundef, i64 noundef) 67 68attributes #0 = { "bpf_fastcall" } 69