1; RUN: opt -O2 -mtriple=bpf-pc-linux %s | llvm-dis > %t1 2; RUN: llc %t1 -o - | FileCheck %s 3; Source: 4; struct t1 { 5; long a; 6; }; 7; struct t2 { 8; long a; 9; long b; 10; }; 11; __attribute__((always_inline)) 12; static long foo1(struct t2 a1, struct t1 a2, struct t1 a3, struct t1 a4, 13; struct t1 a5, struct t2 a6) { 14; return a1.a + a2.a + a3.a + a4.a + a5.a + a6.a; 15; } 16; long foo2(struct t2 a1, struct t2 a2, struct t1 a3) { 17; return foo1(a1, a3, a3, a3, a3, a2); 18; } 19; Compilation flags: 20; clang -target bpf -O2 -S -emit-llvm -Xclang -disable-llvm-passes t.c 21 22%struct.t2 = type { i64, i64 } 23%struct.t1 = type { i64 } 24 25; Function Attrs: nounwind 26define dso_local i64 @foo2([2 x i64] %a1.coerce, [2 x i64] %a2.coerce, i64 %a3.coerce) #0 { 27entry: 28 %a1 = alloca %struct.t2, align 8 29 %a2 = alloca %struct.t2, align 8 30 %a3 = alloca %struct.t1, align 8 31 store [2 x i64] %a1.coerce, ptr %a1, align 8 32 store [2 x i64] %a2.coerce, ptr %a2, align 8 33 %coerce.dive = getelementptr inbounds %struct.t1, ptr %a3, i32 0, i32 0 34 store i64 %a3.coerce, ptr %coerce.dive, align 8 35 %0 = load [2 x i64], ptr %a1, align 8 36 %coerce.dive1 = getelementptr inbounds %struct.t1, ptr %a3, i32 0, i32 0 37 %1 = load i64, ptr %coerce.dive1, align 8 38 %coerce.dive2 = getelementptr inbounds %struct.t1, ptr %a3, i32 0, i32 0 39 %2 = load i64, ptr %coerce.dive2, align 8 40 %coerce.dive3 = getelementptr inbounds %struct.t1, ptr %a3, i32 0, i32 0 41 %3 = load i64, ptr %coerce.dive3, align 8 42 %coerce.dive4 = getelementptr inbounds %struct.t1, ptr %a3, i32 0, i32 0 43 %4 = load i64, ptr %coerce.dive4, align 8 44 %5 = load [2 x i64], ptr %a2, align 8 45 %call = call i64 @foo1([2 x i64] %0, i64 %1, i64 %2, i64 %3, i64 %4, [2 x i64] %5) 46 ret i64 %call 47; CHECK: r0 = r3 48; CHECK-NEXT: r0 += r1 49; CHECK-NEXT: r5 <<= 2 50; CHECK-NEXT: r0 += r5 51; CHECK-NEXT: exit 52} 53 54; Function Attrs: alwaysinline nounwind 55define internal i64 @foo1([2 x i64] %a1.coerce, i64 %a2.coerce, i64 %a3.coerce, i64 %a4.coerce, i64 %a5.coerce, [2 x i64] %a6.coerce) #1 { 56entry: 57 %a1 = alloca %struct.t2, align 8 58 %a2 = alloca %struct.t1, align 8 59 %a3 = alloca %struct.t1, align 8 60 %a4 = alloca %struct.t1, align 8 61 %a5 = alloca %struct.t1, align 8 62 %a6 = alloca %struct.t2, align 8 63 store [2 x i64] %a1.coerce, ptr %a1, align 8 64 %coerce.dive = getelementptr inbounds %struct.t1, ptr %a2, i32 0, i32 0 65 store i64 %a2.coerce, ptr %coerce.dive, align 8 66 %coerce.dive1 = getelementptr inbounds %struct.t1, ptr %a3, i32 0, i32 0 67 store i64 %a3.coerce, ptr %coerce.dive1, align 8 68 %coerce.dive2 = getelementptr inbounds %struct.t1, ptr %a4, i32 0, i32 0 69 store i64 %a4.coerce, ptr %coerce.dive2, align 8 70 %coerce.dive3 = getelementptr inbounds %struct.t1, ptr %a5, i32 0, i32 0 71 store i64 %a5.coerce, ptr %coerce.dive3, align 8 72 store [2 x i64] %a6.coerce, ptr %a6, align 8 73 %a = getelementptr inbounds %struct.t2, ptr %a1, i32 0, i32 0 74 %0 = load i64, ptr %a, align 8, !tbaa !3 75 %a7 = getelementptr inbounds %struct.t1, ptr %a2, i32 0, i32 0 76 %1 = load i64, ptr %a7, align 8, !tbaa !8 77 %add = add nsw i64 %0, %1 78 %a8 = getelementptr inbounds %struct.t1, ptr %a3, i32 0, i32 0 79 %2 = load i64, ptr %a8, align 8, !tbaa !8 80 %add9 = add nsw i64 %add, %2 81 %a10 = getelementptr inbounds %struct.t1, ptr %a4, i32 0, i32 0 82 %3 = load i64, ptr %a10, align 8, !tbaa !8 83 %add11 = add nsw i64 %add9, %3 84 %a12 = getelementptr inbounds %struct.t1, ptr %a5, i32 0, i32 0 85 %4 = load i64, ptr %a12, align 8, !tbaa !8 86 %add13 = add nsw i64 %add11, %4 87 %a14 = getelementptr inbounds %struct.t2, ptr %a6, i32 0, i32 0 88 %5 = load i64, ptr %a14, align 8, !tbaa !3 89 %add15 = add nsw i64 %add13, %5 90 ret i64 %add15 91} 92 93attributes #0 = { nounwind "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } 94attributes #1 = { alwaysinline nounwind "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } 95 96!llvm.module.flags = !{!0, !1} 97!llvm.ident = !{!2} 98 99!0 = !{i32 1, !"wchar_size", i32 4} 100!1 = !{i32 7, !"frame-pointer", i32 2} 101!2 = !{!"clang version 16.0.0 (https://github.com/llvm/llvm-project.git 9385660f4ca87d074410a84df89faca313afcb5a)"} 102!3 = !{!4, !5, i64 0} 103!4 = !{!"t2", !5, i64 0, !5, i64 8} 104!5 = !{!"long", !6, i64 0} 105!6 = !{!"omnipotent char", !7, i64 0} 106!7 = !{!"Simple C/C++ TBAA"} 107!8 = !{!9, !5, i64 0} 108!9 = !{!"t1", !5, i64 0} 109