|
1 | 1 | if :AMDGPU in LLVM.backends()
|
| 2 | + |
| 3 | +# XXX: generic `sink` generates an instruction selection error |
| 4 | +sink_gcn(i) = sink(i, Val(5)) |
| 5 | + |
2 | 6 | @testset "IR" begin
|
3 | 7 |
|
4 | 8 | @testset "kernel calling convention" begin
|
5 |
| - kernel() = return |
| 9 | + mod = @eval module $(gensym()) |
| 10 | + kernel() = return |
| 11 | + end |
6 | 12 |
|
7 | 13 | @test @filecheck begin
|
8 | 14 | check"CHECK-NOT: amdgpu_kernel"
|
9 |
| - GCN.code_llvm(kernel, Tuple{}; dump_module=true) |
| 15 | + GCN.code_llvm(mod.kernel, Tuple{}; dump_module=true) |
10 | 16 | end
|
11 | 17 |
|
12 | 18 | @test @filecheck begin
|
13 | 19 | check"CHECK: amdgpu_kernel"
|
14 |
| - GCN.code_llvm(kernel, Tuple{}; dump_module=true, kernel=true) |
| 20 | + GCN.code_llvm(mod.kernel, Tuple{}; dump_module=true, kernel=true) |
15 | 21 | end
|
16 | 22 | end
|
17 | 23 |
|
|
21 | 27 | @testset "assembly" begin
|
22 | 28 |
|
23 | 29 | @testset "skip scalar trap" begin
|
24 |
| - workitem_idx_x() = ccall("llvm.amdgcn.workitem.id.x", llvmcall, Int32, ()) |
25 |
| - trap() = ccall("llvm.trap", llvmcall, Nothing, ()) |
26 |
| - function kernel() |
27 |
| - if workitem_idx_x() > 1 |
28 |
| - trap() |
| 30 | + mod = @eval module $(gensym()) |
| 31 | + workitem_idx_x() = ccall("llvm.amdgcn.workitem.id.x", llvmcall, Int32, ()) |
| 32 | + trap() = ccall("llvm.trap", llvmcall, Nothing, ()) |
| 33 | + |
| 34 | + function kernel() |
| 35 | + if workitem_idx_x() > 1 |
| 36 | + trap() |
| 37 | + end |
| 38 | + return |
29 | 39 | end
|
30 |
| - return |
31 | 40 | end
|
32 | 41 |
|
33 | 42 | @test @filecheck begin
|
| 43 | + check"CHECK-LABEL: {{.*kernel.*}}:" |
34 | 44 | check"CHECK: s_trap 2"
|
35 |
| - GCN.code_native(kernel, Tuple{}) |
| 45 | + GCN.code_native(mod.kernel, Tuple{}) |
36 | 46 | end
|
| 47 | + # XXX |
37 | 48 | @test_skip occursin("s_cbranch_execz", asm)
|
38 | 49 | if Base.libllvm_version < v"9"
|
39 | 50 | @test_broken occursin("v_readfirstlane", asm)
|
|
43 | 54 | @testset "child functions" begin
|
44 | 55 | # we often test using @noinline child functions, so test whether these survive
|
45 | 56 | # (despite not having side-effects)
|
46 |
| - @noinline child(i) = sink_gcn(i) |
47 |
| - function parent(i) |
48 |
| - child(i) |
49 |
| - return |
| 57 | + mod = @eval module $(gensym()) |
| 58 | + import ..sink_gcn |
| 59 | + @noinline child(i) = sink_gcn(i) |
| 60 | + function parent(i) |
| 61 | + child(i) |
| 62 | + return |
| 63 | + end |
50 | 64 | end
|
51 | 65 |
|
52 | 66 | @test @filecheck begin
|
| 67 | + check"CHECK-LABEL: {{.*parent.*}}:" |
53 | 68 | check"CHECK: s_add_u32{{.*(julia|j)_child_.*}}@rel32@"
|
54 | 69 | check"CHECK: s_addc_u32{{.*(julia|j)_child_.*}}@rel32@"
|
55 |
| - GCN.code_native(parent, Tuple{Int64}; dump_module=true) |
| 70 | + GCN.code_native(mod.parent, Tuple{Int64}; dump_module=true) |
56 | 71 | end
|
57 | 72 | end
|
58 | 73 |
|
59 | 74 | @testset "kernel functions" begin
|
60 |
| - @noinline nonentry(i) = sink_gcn(i) |
61 |
| - function entry(i) |
62 |
| - nonentry(i) |
63 |
| - return |
| 75 | + mod = @eval module $(gensym()) |
| 76 | + import ..sink_gcn |
| 77 | + @noinline nonentry(i) = sink_gcn(i) |
| 78 | + function entry(i) |
| 79 | + nonentry(i) |
| 80 | + return |
| 81 | + end |
64 | 82 | end
|
65 | 83 |
|
66 | 84 | @test @filecheck begin
|
67 | 85 | check"CHECK-NOT: .amdhsa_kernel {{.*}}nonentry"
|
68 | 86 | check"CHECK: .type {{.*nonentry.*}},@function"
|
69 | 87 | check"CHECK: .amdhsa_kernel {{.*entry.*}}"
|
70 |
| - GCN.code_native(entry, Tuple{Int64}; dump_module=true, kernel=true) |
| 88 | + GCN.code_native(mod.entry, Tuple{Int64}; dump_module=true, kernel=true) |
71 | 89 | end
|
72 | 90 | end
|
73 | 91 |
|
|
76 | 94 | # the child only being present once
|
77 | 95 |
|
78 | 96 | mod = @eval module $(gensym())
|
79 |
| - export child, parent1, parent2 |
80 |
| - |
| 97 | + import ..sink_gcn |
81 | 98 | @noinline child(i) = sink_gcn(i)
|
82 | 99 | function parent1(i)
|
83 | 100 | child(i)
|
|
105 | 122 | # in the case of two child functions
|
106 | 123 |
|
107 | 124 | mod = @eval module $(gensym())
|
108 |
| - export parent1, parent2, child1, child2 |
109 |
| - |
| 125 | + import ..sink_gcn |
110 | 126 | @noinline child1(i) = sink_gcn(i)
|
111 | 127 | @noinline child2(i) = sink_gcn(i+1)
|
112 | 128 | function parent1(i)
|
@@ -138,49 +154,57 @@ end
|
138 | 154 |
|
139 | 155 | # NOTE: Int32 to test for #49
|
140 | 156 |
|
141 |
| - function kernel(out) |
142 |
| - wid, lane = fldmod1(unsafe_load(out), Int32(32)) |
143 |
| - unsafe_store!(out, wid) |
144 |
| - return |
| 157 | + mod = @eval module $(gensym()) |
| 158 | + function kernel(out) |
| 159 | + wid, lane = fldmod1(unsafe_load(out), Int32(32)) |
| 160 | + unsafe_store!(out, wid) |
| 161 | + return |
| 162 | + end |
145 | 163 | end
|
146 | 164 |
|
147 | 165 | @test @filecheck begin
|
| 166 | + check"CHECK-LABEL: {{.*kernel.*}}:" |
148 | 167 | check"CHECK-NOT: jl_throw"
|
149 | 168 | check"CHECK-NOT: jl_invoke"
|
150 |
| - GCN.code_native(kernel, Tuple{Ptr{Int32}}) |
| 169 | + GCN.code_native(mod.kernel, Tuple{Ptr{Int32}}) |
151 | 170 | end
|
152 | 171 | end
|
153 | 172 |
|
154 | 173 | @testset "LLVM intrinsics" begin
|
155 | 174 | # issue #13 (a): cannot select trunc
|
156 |
| - function kernel(x) |
157 |
| - unsafe_trunc(Int, x) |
158 |
| - return |
| 175 | + mod = @eval module $(gensym()) |
| 176 | + function kernel(x) |
| 177 | + unsafe_trunc(Int, x) |
| 178 | + return |
| 179 | + end |
159 | 180 | end
|
160 |
| - GCN.code_native(devnull, kernel, Tuple{Float64}) |
| 181 | + GCN.code_native(devnull, mod.kernel, Tuple{Float64}) |
161 | 182 | @test "We did not crash!" != ""
|
162 | 183 | end
|
163 | 184 |
|
164 | 185 | # FIXME: _ZNK4llvm14TargetLowering20scalarizeVectorStoreEPNS_11StoreSDNodeERNS_12SelectionDAGE
|
165 | 186 | false && @testset "exception arguments" begin
|
166 |
| - function kernel(a) |
167 |
| - unsafe_store!(a, trunc(Int, unsafe_load(a))) |
168 |
| - return |
| 187 | + mod = @eval module $(gensym()) |
| 188 | + function kernel(a) |
| 189 | + unsafe_store!(a, trunc(Int, unsafe_load(a))) |
| 190 | + return |
| 191 | + end |
169 | 192 | end
|
170 | 193 |
|
171 |
| - GCN.code_native(devnull, kernel, Tuple{Ptr{Float64}}) |
| 194 | + GCN.code_native(devnull, mod.kernel, Tuple{Ptr{Float64}}) |
172 | 195 | end
|
173 | 196 |
|
174 | 197 | # FIXME: in function julia_inner_18528 void (%jl_value_t addrspace(10)*): invalid addrspacecast
|
175 | 198 | false && @testset "GC and TLS lowering" begin
|
176 | 199 | mod = @eval module $(gensym())
|
| 200 | + import ..sink_gcn |
177 | 201 | mutable struct PleaseAllocate
|
178 | 202 | y::Csize_t
|
179 | 203 | end
|
180 | 204 |
|
181 | 205 | # common pattern in Julia 0.7: outlined throw to avoid a GC frame in the calling code
|
182 | 206 | @noinline function inner(x)
|
183 |
| - sink(x.y) |
| 207 | + sink_gcn(x.y) |
184 | 208 | nothing
|
185 | 209 | end
|
186 | 210 |
|
@@ -219,21 +243,24 @@ false && @testset "GC and TLS lowering" begin
|
219 | 243 | end
|
220 | 244 |
|
221 | 245 | @testset "float boxes" begin
|
222 |
| - function kernel(a,b) |
223 |
| - c = Int32(a) |
224 |
| - # the conversion to Int32 may fail, in which case the input Float32 is boxed in order to |
225 |
| - # pass it to the @nospecialize exception constructor. we should really avoid that (eg. |
226 |
| - # by avoiding @nospecialize, or optimize the unused arguments away), but for now the box |
227 |
| - # should just work. |
228 |
| - unsafe_store!(b, c) |
229 |
| - return |
| 246 | + mod = @eval module $(gensym()) |
| 247 | + function kernel(a,b) |
| 248 | + c = Int32(a) |
| 249 | + # the conversion to Int32 may fail, in which case the input Float32 is boxed in order to |
| 250 | + # pass it to the @nospecialize exception constructor. we should really avoid that (eg. |
| 251 | + # by avoiding @nospecialize, or optimize the unused arguments away), but for now the box |
| 252 | + # should just work. |
| 253 | + unsafe_store!(b, c) |
| 254 | + return |
| 255 | + end |
230 | 256 | end
|
231 | 257 |
|
232 | 258 | @test @filecheck begin
|
| 259 | + check"CHECK-LABEL: define void @{{.*kernel.*}}" |
233 | 260 | check"CHECK: jl_box_float32"
|
234 |
| - GCN.code_llvm(kernel, Tuple{Float32,Ptr{Float32}}) |
| 261 | + GCN.code_llvm(mod.kernel, Tuple{Float32,Ptr{Float32}}) |
235 | 262 | end
|
236 |
| - GCN.code_native(devnull, kernel, Tuple{Float32,Ptr{Float32}}) |
| 263 | + GCN.code_native(devnull, mod.kernel, Tuple{Float32,Ptr{Float32}}) |
237 | 264 | end
|
238 | 265 |
|
239 | 266 | end
|
|
0 commit comments