1 ; RUN: llc < %s -mattr=+reference-types -stop-after=wasm-ref-type-mem2local | FileCheck %s
2 ; RUN: llc < %s -stop-after=wasm-ref-type-mem2local | FileCheck %s --check-prefix=ATTR
4 target triple = "wasm32-unknown-unknown"
6 %externref = type ptr addrspace(10)
7 %funcref = type ptr addrspace(20)
9 declare %externref @get_externref()
10 declare %funcref @get_funcref()
11 declare i32 @get_i32()
12 declare void @take_externref(%externref)
13 declare void @take_funcref(%funcref)
14 declare void @take_i32(i32)
16 ; Reference type allocas should be moved to addrspace(1)
17 ; CHECK-LABEL: @test_ref_type_mem2local
18 define void @test_ref_type_mem2local() {
20 %alloc.externref = alloca %externref, align 1
21 %eref = call %externref @get_externref()
22 store %externref %eref, ptr %alloc.externref, align 1
23 %eref.loaded = load %externref, ptr %alloc.externref, align 1
24 call void @take_externref(%externref %eref.loaded)
25 ; CHECK: %alloc.externref.var = alloca ptr addrspace(10), align 1, addrspace(1)
26 ; CHECK-NEXT: %eref = call ptr addrspace(10) @get_externref()
27 ; CHECK-NEXT: store ptr addrspace(10) %eref, ptr addrspace(1) %alloc.externref.var, align 1
28 ; CHECK-NEXT: %eref.loaded = load ptr addrspace(10), ptr addrspace(1) %alloc.externref.var, align 1
29 ; CHECK-NEXT: call void @take_externref(ptr addrspace(10) %eref.loaded)
31 %alloc.funcref = alloca %funcref, align 1
32 %fref = call %funcref @get_funcref()
33 store %funcref %fref, ptr %alloc.funcref, align 1
34 %fref.loaded = load %funcref, ptr %alloc.funcref, align 1
35 call void @take_funcref(%funcref %fref.loaded)
36 ; CHECK-NEXT: %alloc.funcref.var = alloca ptr addrspace(20), align 1, addrspace(1)
37 ; CHECK-NEXT: %fref = call ptr addrspace(20) @get_funcref()
38 ; CHECK-NEXT: store ptr addrspace(20) %fref, ptr addrspace(1) %alloc.funcref.var, align 1
39 ; CHECK-NEXT: %fref.loaded = load ptr addrspace(20), ptr addrspace(1) %alloc.funcref.var, align 1
40 ; CHECK-NEXT: call void @take_funcref(ptr addrspace(20) %fref.loaded)
45 ; POD type allocas should stay the same
46 ; CHECK-LABEL: @test_pod_type
47 define void @test_pod_type() {
49 %alloc.i32 = alloca i32
50 %i32 = call i32 @get_i32()
51 store i32 %i32, ptr %alloc.i32
52 %i32.loaded = load i32, ptr %alloc.i32
53 call void @take_i32(i32 %i32.loaded)
54 ; CHECK: %alloc.i32 = alloca i32, align 4{{$}}
55 ; CHECK-NOT: alloca i32 {{.*}} addrspace(1)
60 ; The same function as test_ref_type_mem2local, but here +reference-types is
61 ; given in the function attribute.
62 ; Reference type allocas should be moved to addrspace(1)
63 ; ATTR-LABEL: @test_ref_type_mem2local_func_attr
64 define void @test_ref_type_mem2local_func_attr() #0 {
66 %alloc.externref = alloca %externref, align 1
67 %eref = call %externref @get_externref()
68 store %externref %eref, ptr %alloc.externref, align 1
69 %eref.loaded = load %externref, ptr %alloc.externref, align 1
70 call void @take_externref(%externref %eref.loaded)
71 ; ATTR: %alloc.externref.var = alloca ptr addrspace(10), align 1, addrspace(1)
72 ; ATTR-NEXT: %eref = call ptr addrspace(10) @get_externref()
73 ; ATTR-NEXT: store ptr addrspace(10) %eref, ptr addrspace(1) %alloc.externref.var, align 1
74 ; ATTR-NEXT: %eref.loaded = load ptr addrspace(10), ptr addrspace(1) %alloc.externref.var, align 1
75 ; ATTR-NEXT: call void @take_externref(ptr addrspace(10) %eref.loaded)
77 %alloc.funcref = alloca %funcref, align 1
78 %fref = call %funcref @get_funcref()
79 store %funcref %fref, ptr %alloc.funcref, align 1
80 %fref.loaded = load %funcref, ptr %alloc.funcref, align 1
81 call void @take_funcref(%funcref %fref.loaded)
82 ; ATTR-NEXT: %alloc.funcref.var = alloca ptr addrspace(20), align 1, addrspace(1)
83 ; ATTR-NEXT: %fref = call ptr addrspace(20) @get_funcref()
84 ; ATTR-NEXT: store ptr addrspace(20) %fref, ptr addrspace(1) %alloc.funcref.var, align 1
85 ; ATTR-NEXT: %fref.loaded = load ptr addrspace(20), ptr addrspace(1) %alloc.funcref.var, align 1
86 ; ATTR-NEXT: call void @take_funcref(ptr addrspace(20) %fref.loaded)
91 attributes #0 = { "target-features"="+reference-types" }