Skip to content

Commit 4fda286

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 f9b8eaf commit 4fda286

File tree

7 files changed

+1680
-0
lines changed

7 files changed

+1680
-0
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// REQUIRES: bpf-registered-target
2+
// RUN: %clang_cc1 -triple bpf -emit-llvm -disable-llvm-passes -debug-info-kind=limited %s -o - | FileCheck %s
3+
4+
#define __tag1 __attribute__((btf_type_tag("tag1")))
5+
int _Atomic __tag1 *g1;
6+
volatile int _Atomic __tag1 *g2;
7+
8+
// CHECK: distinct !DIGlobalVariable(name: "g1", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[PTR1:[0-9]+]]
9+
// CHECK: distinct !DIGlobalVariable(name: "g2", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[PTR2:[0-9]+]]
10+
// CHECK: ![[PTR2]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[BASE2:[0-9]+]], size: [[#]], annotations: ![[ANNOT:[0-9]+]])
11+
// CHECK: ![[BASE2]] = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: ![[BASE1:[0-9]+]])
12+
// CHECK: ![[BASE1]] = !DIDerivedType(tag: DW_TAG_atomic_type, baseType: ![[BASIC:[0-9]+]])
13+
// CHECK: ![[BASIC]] = !DIBasicType(name: "int", size: [[#]], encoding: DW_ATE_signed)
14+
// CHECK: ![[ANNOT]] = !{![[ENTRY:[0-9]+]]}
15+
// CHECK: ![[ENTRY]] = !{!"btf_type_tag", !"tag1"}
16+
// CHECK: ![[PTR1]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[BASE1]], size: [[#]], annotations: ![[ANNOT]])

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

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

0 commit comments

Comments
 (0)