[WebAssembly] Implement prolog/epilog insertion and FrameIndex elimination
[oota-llvm.git] / test / CodeGen / WebAssembly / userstack.ll
1 ; RUN: llc < %s -asm-verbose=false | FileCheck %s
2 ; RUN: llc < %s -asm-verbose=false -fast-isel | FileCheck %s
3
4
5 target datalayout = "e-p:32:32-i64:64-n32:64-S128"
6 target triple = "wasm32-unknown-unknown"
7
8 ; CHECK-LABEL: alloca32:
9 define void @alloca32() {
10  ; CHECK: i32.const [[L1:.+]]=, __stack_pointer
11  ; CHECK-NEXT: i32.load [[L1]]=, 0([[L1]])
12  ; CHECK-NEXT: i32.const [[L2:.+]]=, 16
13  ; CHECK-NEXT: i32.sub [[SP:.+]]=, [[L1]], [[L2]]
14  %retval = alloca i32
15  ; CHECK: i32.const $push[[L3:.+]]=, 0
16  ; CHECK: i32.store {{.*}}=, 12([[SP]]), $pop[[L3]]
17  store i32 0, i32* %retval
18  ; CHECK: i32.const [[L4:.+]]=, 16
19  ; CHECK-NEXT: i32.add [[SP]]=, [[SP]], [[L4]]
20  ; CHECK-NEXT: i32.const [[L5:.+]]=, __stack_pointer
21  ; CHECK-NEXT: i32.store [[SP]]=, 0([[L5]]), [[SP]]
22  ret void
23 }
24
25 ; CHECK-LABEL: alloca3264:
26 define void @alloca3264() {
27  ; CHECK: i32.const [[L1:.+]]=, __stack_pointer
28  ; CHECK-NEXT: i32.load [[L1]]=, 0([[L1]])
29  ; CHECK-NEXT: i32.const [[L2:.+]]=, 16
30  ; CHECK-NEXT: i32.sub [[SP:.+]]=, [[L1]], [[L2]]
31  %r1 = alloca i32
32  %r2 = alloca double
33  ; CHECK: i32.const $push[[L3:.+]]=, 0
34  ; CHECK: i32.store {{.*}}=, 12([[SP]]), $pop[[L3]]
35  store i32 0, i32* %r1
36  ; CHECK: i64.const $push[[L4:.+]]=, 0
37  ; CHECK: i64.store {{.*}}=, 0([[SP]]), $pop[[L4]]
38  store double 0.0, double* %r2
39  ; CHECK: i32.const [[L4:.+]]=, 16
40  ; CHECK-NEXT: i32.add [[SP]]=, [[SP]], [[L4]]
41  ; CHECK-NEXT: i32.const [[L5:.+]]=, __stack_pointer
42  ; CHECK-NEXT: i32.store [[SP]]=, 0([[L5]]), [[SP]]
43  ret void
44 }
45
46 define void @allocarray() {
47  ; CHECK: i32.const [[L1:.+]]=, __stack_pointer
48  ; CHECK-NEXT: i32.load [[L1]]=, 0([[L1]])
49  ; CHECK-NEXT: i32.const [[L2:.+]]=, 32
50  ; CHECK-NEXT: i32.sub [[SP:.+]]=, [[L1]], [[L2]]
51  %r = alloca [5 x i32]
52  ; CHECK: i32.const $push[[L3:.+]]=, 1
53  ; CHECK: i32.store {{.*}}=, 12([[SP]]), $pop[[L3]]
54  %p = getelementptr [5 x i32], [5 x i32]* %r, i32 0, i32 0
55  store i32 1, i32* %p
56  ; CHECK: i32.const $push[[L4:.+]]=, 4
57  ; CHECK: i32.const [[L5:.+]]=, 12
58  ; CHECK: i32.add [[L5]]=, [[SP]], [[L5]]
59  ; CHECK: i32.add $push[[L6:.+]]=, [[L5]], $pop[[L4]]
60  ; CHECK: i32.store {{.*}}=, 0($pop[[L6]]), ${{.+}}
61  %p2 = getelementptr [5 x i32], [5 x i32]* %r, i32 0, i32 1
62  store i32 1, i32* %p2
63  ; CHECK: i32.const [[L7:.+]]=, 32
64  ; CHECK-NEXT: i32.add [[SP]]=, [[SP]], [[L7]]
65  ; CHECK-NEXT: i32.const [[L8:.+]]=, __stack_pointer
66  ; CHECK-NEXT: i32.store [[SP]]=, 0([[L7]]), [[SP]]
67  ret void
68 }
69
70 ; TODO: test aligned alloc