Skip to content

Commit 40402d0

Browse files
committed
Add label checks and refactor functions into modules.
1 parent ee3ba8f commit 40402d0

File tree

6 files changed

+422
-301
lines changed

6 files changed

+422
-301
lines changed

test/bpf.jl

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,68 @@
11
@testset "No-op" begin
2-
kernel() = 0
2+
mod = @eval module $(gensym())
3+
kernel() = 0
4+
end
35

46
@test @filecheck begin
7+
check"CHECK-LABEL: julia_kernel_{{[0-9_]*}}:"
58
check"CHECK: r0 = 0"
69
check"CHECK-NEXT: exit"
7-
BPF.code_native(kernel, ())
10+
BPF.code_native(mod.kernel, ())
811
end
912
end
1013
@testset "Return argument" begin
11-
kernel(x) = x
14+
mod = @eval module $(gensym())
15+
kernel(x) = x
16+
end
1217

1318
@test @filecheck begin
19+
check"CHECK-LABEL: julia_kernel_{{[0-9_]*}}:"
1420
check"CHECK: r0 = r1"
1521
check"CHECK-NEXT: exit"
16-
BPF.code_native(kernel, (UInt64,))
22+
BPF.code_native(mod.kernel, (UInt64,))
1723
end
1824
end
1925
@testset "Addition" begin
20-
kernel(x) = x+1
26+
mod = @eval module $(gensym())
27+
kernel(x) = x+1
28+
end
2129

2230
@test @filecheck begin
31+
check"CHECK-LABEL: julia_kernel_{{[0-9_]*}}:"
2332
check"CHECK: r0 = r1"
2433
check"CHECK-NEXT: r0 += 1"
2534
check"CHECK-NEXT: exit"
26-
BPF.code_native(kernel, (UInt64,))
35+
BPF.code_native(mod.kernel, (UInt64,))
2736
end
2837
end
2938
@testset "Errors" begin
30-
kernel(x) = fakefunc(x)
39+
mod = @eval module $(gensym())
40+
kernel(x) = fakefunc(x)
41+
end
3142

32-
@test_throws GPUCompiler.InvalidIRError BPF.code_execution(kernel, (UInt64,))
43+
@test_throws GPUCompiler.InvalidIRError BPF.code_execution(mod.kernel, (UInt64,))
3344
end
3445
@testset "Function Pointers" begin
3546
@testset "valid" begin
36-
goodcall(x) = Base.llvmcall("%2 = call i64 inttoptr (i64 3 to i64 (i64)*)(i64 %0)\nret i64 %2", Int, Tuple{Int}, x)
37-
kernel(x) = goodcall(x)
47+
mod = @eval module $(gensym())
48+
goodcall(x) = Base.llvmcall("%2 = call i64 inttoptr (i64 3 to i64 (i64)*)(i64 %0)\nret i64 %2", Int, Tuple{Int}, x)
49+
kernel(x) = goodcall(x)
50+
end
3851

3952
@test @filecheck begin
53+
check"CHECK-LABEL: julia_kernel_{{[0-9_]*}}:"
4054
check"CHECK: call"
4155
check"CHECK-NEXT: exit"
42-
BPF.code_native(kernel, (Int,))
56+
BPF.code_native(mod.kernel, (Int,))
4357
end
4458
end
59+
4560
@testset "invalid" begin
46-
badcall(x) = Base.llvmcall("%2 = call i64 inttoptr (i64 3000 to i64 (i64)*)(i64 %0)\nret i64 %2", Int, Tuple{Int}, x)
47-
kernel(x) = badcall(x)
61+
mod = @eval module $(gensym())
62+
badcall(x) = Base.llvmcall("%2 = call i64 inttoptr (i64 3000 to i64 (i64)*)(i64 %0)\nret i64 %2", Int, Tuple{Int}, x)
63+
kernel(x) = badcall(x)
64+
end
4865

49-
@test_throws GPUCompiler.InvalidIRError BPF.code_execution(kernel, (Int,))
66+
@test_throws GPUCompiler.InvalidIRError BPF.code_execution(mod.kernel, (Int,))
5067
end
5168
end

test/gcn.jl

Lines changed: 75 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,23 @@
11
if :AMDGPU in LLVM.backends()
2+
3+
# XXX: generic `sink` generates an instruction selection error
4+
sink_gcn(i) = sink(i, Val(5))
5+
26
@testset "IR" begin
37

48
@testset "kernel calling convention" begin
5-
kernel() = return
9+
mod = @eval module $(gensym())
10+
kernel() = return
11+
end
612

713
@test @filecheck begin
814
check"CHECK-NOT: amdgpu_kernel"
9-
GCN.code_llvm(kernel, Tuple{}; dump_module=true)
15+
GCN.code_llvm(mod.kernel, Tuple{}; dump_module=true)
1016
end
1117

1218
@test @filecheck begin
1319
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)
1521
end
1622
end
1723

@@ -21,19 +27,24 @@ end
2127
@testset "assembly" begin
2228

2329
@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
2939
end
30-
return
3140
end
3241

3342
@test @filecheck begin
43+
check"CHECK-LABEL: {{.*kernel.*}}:"
3444
check"CHECK: s_trap 2"
35-
GCN.code_native(kernel, Tuple{})
45+
GCN.code_native(mod.kernel, Tuple{})
3646
end
47+
# XXX
3748
@test_skip occursin("s_cbranch_execz", asm)
3849
if Base.libllvm_version < v"9"
3950
@test_broken occursin("v_readfirstlane", asm)
@@ -43,31 +54,38 @@ end
4354
@testset "child functions" begin
4455
# we often test using @noinline child functions, so test whether these survive
4556
# (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
5064
end
5165

5266
@test @filecheck begin
67+
check"CHECK-LABEL: {{.*parent.*}}:"
5368
check"CHECK: s_add_u32{{.*(julia|j)_child_.*}}@rel32@"
5469
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)
5671
end
5772
end
5873

5974
@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
6482
end
6583

6684
@test @filecheck begin
6785
check"CHECK-NOT: .amdhsa_kernel {{.*}}nonentry"
6886
check"CHECK: .type {{.*nonentry.*}},@function"
6987
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)
7189
end
7290
end
7391

@@ -76,8 +94,7 @@ end
7694
# the child only being present once
7795

7896
mod = @eval module $(gensym())
79-
export child, parent1, parent2
80-
97+
import ..sink_gcn
8198
@noinline child(i) = sink_gcn(i)
8299
function parent1(i)
83100
child(i)
@@ -105,8 +122,7 @@ end
105122
# in the case of two child functions
106123

107124
mod = @eval module $(gensym())
108-
export parent1, parent2, child1, child2
109-
125+
import ..sink_gcn
110126
@noinline child1(i) = sink_gcn(i)
111127
@noinline child2(i) = sink_gcn(i+1)
112128
function parent1(i)
@@ -138,49 +154,57 @@ end
138154

139155
# NOTE: Int32 to test for #49
140156

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
145163
end
146164

147165
@test @filecheck begin
166+
check"CHECK-LABEL: {{.*kernel.*}}:"
148167
check"CHECK-NOT: jl_throw"
149168
check"CHECK-NOT: jl_invoke"
150-
GCN.code_native(kernel, Tuple{Ptr{Int32}})
169+
GCN.code_native(mod.kernel, Tuple{Ptr{Int32}})
151170
end
152171
end
153172

154173
@testset "LLVM intrinsics" begin
155174
# 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
159180
end
160-
GCN.code_native(devnull, kernel, Tuple{Float64})
181+
GCN.code_native(devnull, mod.kernel, Tuple{Float64})
161182
@test "We did not crash!" != ""
162183
end
163184

164185
# FIXME: _ZNK4llvm14TargetLowering20scalarizeVectorStoreEPNS_11StoreSDNodeERNS_12SelectionDAGE
165186
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
169192
end
170193

171-
GCN.code_native(devnull, kernel, Tuple{Ptr{Float64}})
194+
GCN.code_native(devnull, mod.kernel, Tuple{Ptr{Float64}})
172195
end
173196

174197
# FIXME: in function julia_inner_18528 void (%jl_value_t addrspace(10)*): invalid addrspacecast
175198
false && @testset "GC and TLS lowering" begin
176199
mod = @eval module $(gensym())
200+
import ..sink_gcn
177201
mutable struct PleaseAllocate
178202
y::Csize_t
179203
end
180204

181205
# common pattern in Julia 0.7: outlined throw to avoid a GC frame in the calling code
182206
@noinline function inner(x)
183-
sink(x.y)
207+
sink_gcn(x.y)
184208
nothing
185209
end
186210

@@ -219,21 +243,24 @@ false && @testset "GC and TLS lowering" begin
219243
end
220244

221245
@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
230256
end
231257

232258
@test @filecheck begin
259+
check"CHECK-LABEL: define void @{{.*kernel.*}}"
233260
check"CHECK: jl_box_float32"
234-
GCN.code_llvm(kernel, Tuple{Float32,Ptr{Float32}})
261+
GCN.code_llvm(mod.kernel, Tuple{Float32,Ptr{Float32}})
235262
end
236-
GCN.code_native(devnull, kernel, Tuple{Float32,Ptr{Float32}})
263+
GCN.code_native(devnull, mod.kernel, Tuple{Float32,Ptr{Float32}})
237264
end
238265

239266
end

0 commit comments

Comments
 (0)