Skip to content

Commit e4db1f2

Browse files
author
Yonghong Song
committed
[BPF] Add functionality/btf selftests for memory ordering cases
The following test cases are added: - all memory ordering and its asm codes with -mcpu=v3 - all memory ordering and its asm codes with -mcpu=v1 Note that __c11_atomic_fetch_{sub,and,or,xor} for 32bit won't work for -mcpu=v1. Also at -mcpu=v1, no return value allowed for 64bit __sync_fetch_and_add. - at -mcpu=v1, __c11_atomic_fetch_sub() for 64bit with relaxed memory ordering, the xaddd insn will be used so return value is not supported. Otherwise, it will work fine if return value is not used. This aligns to __c11_atomic_fetch_add() for 64bit with relaxed memory ordering at -mcpu=v1. - BTF test with _Atomic types in different cases.
1 parent ae0dcd5 commit e4db1f2

File tree

6 files changed

+1632
-0
lines changed

6 files changed

+1632
-0
lines changed

llvm/test/CodeGen/BPF/BTF/atomics.ll

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
; RUN: llc -march=bpfel -mcpu=v3 -filetype=obj -o %t1 %s
2+
; RUN: llvm-objcopy --dump-section='.BTF'=%t2 %t1
3+
; RUN: %python %p/print_btf.py %t2 | FileCheck -check-prefixes=CHECK %s
4+
;
5+
; Source:
6+
; #include <stdatomic.h>
7+
; struct gstruct_t {
8+
; _Atomic int a;
9+
; } gstruct;
10+
; extern _Atomic int ext;
11+
; _Atomic int gbl;
12+
; _Atomic int *pgbl;
13+
; volatile _Atomic int vvar;
14+
; _Atomic int foo(_Atomic int a1, _Atomic int *p1) {
15+
; (void)__c11_atomic_fetch_add(&gstruct.a, 1, memory_order_relaxed);
16+
; (void)__c11_atomic_fetch_add(&ext, 1, memory_order_relaxed);
17+
; (void)__c11_atomic_fetch_add(&gbl, 1, memory_order_relaxed);
18+
; (void)__c11_atomic_fetch_add(pgbl, 1, memory_order_relaxed);
19+
; (void)__c11_atomic_fetch_add(&vvar, 1, memory_order_relaxed);
20+
; (void)__c11_atomic_fetch_add(p1, 1, memory_order_relaxed);
21+
;
22+
; return a1;
23+
; }
24+
25+
target triple = "bpf"
26+
27+
%struct.gstruct_t = type { i32 }
28+
29+
@gstruct = dso_local global %struct.gstruct_t zeroinitializer, align 4, !dbg !0
30+
@ext = external dso_local global i32, align 4, !dbg !26
31+
@gbl = dso_local global i32 0, align 4, !dbg !16
32+
@pgbl = dso_local local_unnamed_addr global ptr null, align 8, !dbg !20
33+
@vvar = dso_local global i32 0, align 4, !dbg !23
34+
35+
; Function Attrs: mustprogress nofree norecurse nounwind willreturn
36+
define dso_local i32 @foo(i32 returned %a1, ptr nocapture noundef %p1) local_unnamed_addr #0 !dbg !37 {
37+
entry:
38+
#dbg_value(i32 %a1, !41, !DIExpression(), !43)
39+
#dbg_value(ptr %p1, !42, !DIExpression(), !43)
40+
%0 = atomicrmw add ptr @gstruct, i32 1 monotonic, align 4, !dbg !44
41+
%1 = atomicrmw add ptr @ext, i32 1 monotonic, align 4, !dbg !45
42+
%2 = atomicrmw add ptr @gbl, i32 1 monotonic, align 4, !dbg !46
43+
%3 = load ptr, ptr @pgbl, align 8, !dbg !47, !tbaa !48
44+
%4 = atomicrmw add ptr %3, i32 1 monotonic, align 4, !dbg !52
45+
%5 = atomicrmw volatile add ptr @vvar, i32 1 monotonic, align 4, !dbg !53
46+
%6 = atomicrmw add ptr %p1, i32 1 monotonic, align 4, !dbg !54
47+
ret i32 %a1, !dbg !55
48+
}
49+
50+
; CHECK: [1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED
51+
; CHECK-NEXT: [2] PTR '(anon)' type_id=1
52+
; CHECK-NEXT: [3] FUNC_PROTO '(anon)' ret_type_id=1 vlen=2
53+
; CHECK-NEXT: 'a1' type_id=1
54+
; CHECK-NEXT: 'p1' type_id=2
55+
; CHECK-NEXT: [4] FUNC 'foo' type_id=3 linkage=global
56+
; CHECK-NEXT: [5] STRUCT 'gstruct_t' size=4 vlen=1
57+
; CHECK-NEXT: 'a' type_id=1 bits_offset=0
58+
; CHECK-NEXT: [6] VAR 'gstruct' type_id=5, linkage=global
59+
; CHECK-NEXT: [7] VAR 'ext' type_id=1, linkage=extern
60+
; CHECK-NEXT: [8] VAR 'gbl' type_id=1, linkage=global
61+
; CHECK-NEXT: [9] VAR 'pgbl' type_id=2, linkage=global
62+
; CHECK-NEXT: [10] VOLATILE '(anon)' type_id=1
63+
; CHECK-NEXT: [11] VAR 'vvar' type_id=10, linkage=global
64+
; CHECK-NEXT: [12] DATASEC '.bss' size=0 vlen=4
65+
; CHECK-NEXT: type_id=6 offset=0 size=4
66+
; CHECK-NEXT: type_id=8 offset=0 size=4
67+
; CHECK-NEXT: type_id=9 offset=0 size=8
68+
; CHECK-NEXT: type_id=11 offset=0 size=4
69+
70+
attributes #0 = { mustprogress nofree norecurse nounwind willreturn "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="v3" }
71+
72+
!llvm.dbg.cu = !{!2}
73+
!llvm.module.flags = !{!31, !32, !33, !34, !35}
74+
!llvm.ident = !{!36}
75+
76+
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
77+
!1 = distinct !DIGlobalVariable(name: "gstruct", scope: !2, file: !3, line: 4, type: !28, isLocal: false, isDefinition: true)
78+
!2 = distinct !DICompileUnit(language: DW_LANG_C11, file: !3, producer: "clang version 20.0.0git ([email protected]:yonghong-song/llvm-project.git a7bdb883df5731338d84603c60210d93c86f0870)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !15, splitDebugInlining: false, nameTableKind: None)
79+
!3 = !DIFile(filename: "atomics.c", directory: "/tmp/home/yhs/tests/result/atomics", checksumkind: CSK_MD5, checksum: "cabe3f3bfcfa90a93ff6d959be6e563a")
80+
!4 = !{!5}
81+
!5 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "memory_order", file: !6, line: 68, baseType: !7, size: 32, elements: !8)
82+
!6 = !DIFile(filename: "work/yhs/llvm-project/llvm/build/install/lib/clang/20/include/stdatomic.h", directory: "/home/yhs", checksumkind: CSK_MD5, checksum: "f17199a988fe91afffaf0f943ef87096")
83+
!7 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned)
84+
!8 = !{!9, !10, !11, !12, !13, !14}
85+
!9 = !DIEnumerator(name: "memory_order_relaxed", value: 0)
86+
!10 = !DIEnumerator(name: "memory_order_consume", value: 1)
87+
!11 = !DIEnumerator(name: "memory_order_acquire", value: 2)
88+
!12 = !DIEnumerator(name: "memory_order_release", value: 3)
89+
!13 = !DIEnumerator(name: "memory_order_acq_rel", value: 4)
90+
!14 = !DIEnumerator(name: "memory_order_seq_cst", value: 5)
91+
!15 = !{!0, !16, !20, !23, !26}
92+
!16 = !DIGlobalVariableExpression(var: !17, expr: !DIExpression())
93+
!17 = distinct !DIGlobalVariable(name: "gbl", scope: !2, file: !3, line: 6, type: !18, isLocal: false, isDefinition: true)
94+
!18 = !DIDerivedType(tag: DW_TAG_atomic_type, baseType: !19)
95+
!19 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
96+
!20 = !DIGlobalVariableExpression(var: !21, expr: !DIExpression())
97+
!21 = distinct !DIGlobalVariable(name: "pgbl", scope: !2, file: !3, line: 7, type: !22, isLocal: false, isDefinition: true)
98+
!22 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !18, size: 64)
99+
!23 = !DIGlobalVariableExpression(var: !24, expr: !DIExpression())
100+
!24 = distinct !DIGlobalVariable(name: "vvar", scope: !2, file: !3, line: 8, type: !25, isLocal: false, isDefinition: true)
101+
!25 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !18)
102+
!26 = !DIGlobalVariableExpression(var: !27, expr: !DIExpression())
103+
!27 = distinct !DIGlobalVariable(name: "ext", scope: !2, file: !3, line: 5, type: !18, isLocal: false, isDefinition: false)
104+
!28 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "gstruct_t", file: !3, line: 2, size: 32, elements: !29)
105+
!29 = !{!30}
106+
!30 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !28, file: !3, line: 3, baseType: !18, size: 32)
107+
!31 = !{i32 7, !"Dwarf Version", i32 5}
108+
!32 = !{i32 2, !"Debug Info Version", i32 3}
109+
!33 = !{i32 1, !"wchar_size", i32 4}
110+
!34 = !{i32 7, !"frame-pointer", i32 2}
111+
!35 = !{i32 7, !"debug-info-assignment-tracking", i1 true}
112+
!36 = !{!"clang version 20.0.0git ([email protected]:yonghong-song/llvm-project.git a7bdb883df5731338d84603c60210d93c86f0870)"}
113+
!37 = distinct !DISubprogram(name: "foo", scope: !3, file: !3, line: 9, type: !38, scopeLine: 9, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !40)
114+
!38 = !DISubroutineType(types: !39)
115+
!39 = !{!18, !18, !22}
116+
!40 = !{!41, !42}
117+
!41 = !DILocalVariable(name: "a1", arg: 1, scope: !37, file: !3, line: 9, type: !18)
118+
!42 = !DILocalVariable(name: "p1", arg: 2, scope: !37, file: !3, line: 9, type: !22)
119+
!43 = !DILocation(line: 0, scope: !37)
120+
!44 = !DILocation(line: 10, column: 9, scope: !37)
121+
!45 = !DILocation(line: 11, column: 9, scope: !37)
122+
!46 = !DILocation(line: 12, column: 9, scope: !37)
123+
!47 = !DILocation(line: 13, column: 32, scope: !37)
124+
!48 = !{!49, !49, i64 0}
125+
!49 = !{!"any pointer", !50, i64 0}
126+
!50 = !{!"omnipotent char", !51, i64 0}
127+
!51 = !{!"Simple C/C++ TBAA"}
128+
!52 = !DILocation(line: 13, column: 9, scope: !37)
129+
!53 = !DILocation(line: 14, column: 9, scope: !37)
130+
!54 = !DILocation(line: 15, column: 9, scope: !37)
131+
!55 = !DILocation(line: 17, column: 3, scope: !37)

0 commit comments

Comments
 (0)