1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
# For manual usage, not as a part of lit tests. Used for generating the following tests:
# cmpxchg-sm30.ll, cmpxchg-sm70.ll, cmpxchg-sm90.ll
from string import Template
from itertools import product
cmpxchg_func = Template(
"""define i$size @${success}_${failure}_i${size}_${addrspace}_${ptx_scope}(ptr${addrspace_cast} %addr, i$size %cmp, i$size %new) {
%pairold = cmpxchg ptr${addrspace_cast} %addr, i$size %cmp, i$size %new syncscope(\"${llvm_scope}\") $success $failure
ret i$size %new
}
"""
)
cmpxchg_func_no_scope = Template(
"""define i$size @${success}_${failure}_i${size}_${addrspace}(ptr${addrspace_cast} %addr, i$size %cmp, i$size %new) {
%pairold = cmpxchg ptr${addrspace_cast} %addr, i$size %cmp, i$size %new $success $failure
ret i$size %new
}
"""
)
run_statement = Template(
"""; RUN: llc < %s -march=nvptx64 -mcpu=sm_${sm} -mattr=+ptx${ptx} | FileCheck %s --check-prefix=SM${sm}
; RUN: %if ptxas %{ llc < %s -march=nvptx64 -mcpu=sm_${sm} -mattr=+ptx${ptx} | %ptxas-verify -arch=sm_${sm} %}
"""
)
def get_addrspace_cast(addrspace):
if addrspace == 0:
return ""
else:
return " addrspace({})".format(str(addrspace))
TESTS = [(60, 50), (70, 63), (90, 87)]
LLVM_SCOPES = ["", "block", "cluster", "device"]
SCOPE_LLVM_TO_PTX = {"": "sys", "block": "cta", "cluster": "cluster", "device": "gpu"}
SUCCESS_ORDERINGS = ["monotonic", "acquire", "release", "acq_rel", "seq_cst"]
FAILURE_ORDERINGS = ["monotonic", "acquire", "seq_cst"]
SIZES = [8, 16, 32, 64]
ADDRSPACES = [0, 1, 3]
ADDRSPACE_NUM_TO_ADDRSPACE = {0: "generic", 1: "global", 3: "shared"}
if __name__ == "__main__":
for sm, ptx in TESTS:
with open("cmpxchg-sm{}.ll".format(str(sm)), "w") as fp:
print(run_statement.substitute(sm=sm, ptx=ptx), file=fp)
# Our test space is: SIZES X SUCCESS_ORDERINGS X FAILURE_ORDERINGS X ADDRSPACES X LLVM_SCOPES
# This is very large, so we instead test 3 slices.
# First slice: are all orderings correctly supported, with and without emulation loops?
# set addrspace to global, scope to cta, generate all possible orderings, for all operation sizes
addrspace, llvm_scope = 1, "block"
for size, success, failure in product(
SIZES, SUCCESS_ORDERINGS, FAILURE_ORDERINGS
):
print(
cmpxchg_func.substitute(
success=success,
failure=failure,
size=size,
addrspace=ADDRSPACE_NUM_TO_ADDRSPACE[addrspace],
addrspace_cast=get_addrspace_cast(addrspace),
llvm_scope=llvm_scope,
ptx_scope=SCOPE_LLVM_TO_PTX[llvm_scope],
),
file=fp,
)
# Second slice: Are all scopes correctlly supported, with and without emulation loops?
# fix addrspace, ordering, generate all possible scopes, for operation sizes i8, i32
addrspace, success, failure = 1, "acq_rel", "acquire"
for size in [8, 32]:
print(
cmpxchg_func_no_scope.substitute(
success=success,
failure=failure,
size=size,
addrspace=ADDRSPACE_NUM_TO_ADDRSPACE[addrspace],
addrspace_cast=get_addrspace_cast(addrspace),
),
file=fp,
)
for llvm_scope in LLVM_SCOPES:
if sm < 90 and llvm_scope == "cluster":
continue
if llvm_scope == "block":
# skip (acq_rel, acquire, global, cta)
continue
print(
cmpxchg_func.substitute(
success=success,
failure=failure,
size=size,
addrspace=ADDRSPACE_NUM_TO_ADDRSPACE[addrspace],
addrspace_cast=get_addrspace_cast(addrspace),
llvm_scope=llvm_scope,
ptx_scope=SCOPE_LLVM_TO_PTX[llvm_scope],
),
file=fp,
)
# Third slice: Are all address spaces correctly supported?
# fix ordering, scope, generate all possible address spaces, for operation sizes i8, i32
success, failure, llvm_scope = "acq_rel", "acquire", "block"
for size, addrspace in product([8, 32], ADDRSPACES):
if addrspace == 1:
# skip (acq_rel, acquire, global, cta)
continue
print(
cmpxchg_func.substitute(
success=success,
failure=failure,
size=size,
addrspace=ADDRSPACE_NUM_TO_ADDRSPACE[addrspace],
addrspace_cast=get_addrspace_cast(addrspace),
llvm_scope=llvm_scope,
ptx_scope=SCOPE_LLVM_TO_PTX[llvm_scope],
),
file=fp,
)
|