llvm.org GIT mirror llvm / 24efa5d
[WebAssembly] Convert the remaining unit tests to the new wasm-object-file target. To facilitate this, add a new hidden command-line option to disable the explicit-locals pass. That causes llc to emit invalid code that doesn't have all locals converted to get_local/set_local, however it simplifies testwriting in many cases. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@296540 91177308-0d34-0410-b5e6-96231b3b80d8 Dan Gohman 3 years ago
38 changed file(s) with 262 addition(s) and 222 deletion(s). Raw diff Collapse all Expand all
149149 floating-point constants.
150150
151151 //===---------------------------------------------------------------------===//
152
153 The function @dynamic_alloca_redzone in test/CodeGen/WebAssembly/userstack.ll
154 ends up with a tee_local in its prolog which has an unused result, requiring
155 an extra drop:
156
157 get_global $push8=, 0
158 tee_local $push9=, 1, $pop8
159 drop $pop9
160 [...]
161
162 The prologue code initially thinks it needs an FP register, but later it
163 turns out to be unneeded, so one could either approach this by being more
164 clever about not inserting code for an FP in the first place, or optimizing
165 away the copy later.
166
167 //===---------------------------------------------------------------------===//
3030
3131 #define DEBUG_TYPE "wasm-explicit-locals"
3232
33 // A command-line option to disable this pass. Note that this produces output
34 // which is not valid WebAssembly, though it may be more convenient for writing
35 // LLVM unit tests with.
36 static cl::opt DisableWebAssemblyExplicitLocals(
37 "disable-wasm-explicit-locals", cl::ReallyHidden,
38 cl::desc("WebAssembly: Disable emission of get_local/set_local."),
39 cl::init(false));
40
3341 namespace {
3442 class WebAssemblyExplicitLocals final : public MachineFunctionPass {
3543 StringRef getPassName() const override {
162170 DEBUG(dbgs() << "********** Make Locals Explicit **********\n"
163171 "********** Function: "
164172 << MF.getName() << '\n');
173
174 // Disable this pass if directed to do so.
175 if (DisableWebAssemblyExplicitLocals)
176 return false;
165177
166178 // Disable this pass if we aren't doing direct wasm object emission.
167179 if (MF.getSubtarget()
None ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
0 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
11
22 ; Test folding constant offsets and symbols into load and store addresses under
33 ; a variety of circumstances.
44
55 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
6 target triple = "wasm32-unknown-unknown"
6 target triple = "wasm32-unknown-unknown-wasm"
77
88 @g = external global [0 x i32], align 4
99
None ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -verify-machineinstrs | FileCheck %s
1 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -verify-machineinstrs -fast-isel | FileCheck %s
0 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -verify-machineinstrs | FileCheck %s
1 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -verify-machineinstrs -fast-isel | FileCheck %s
22
33 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
4 target triple = "wasm32-unknown-unknown"
4 target triple = "wasm32-unknown-unknown-wasm"
55
66 %SmallStruct = type { i32 }
77 %OddStruct = type { i32, i8, i32 }
2222 ; CHECK-LABEL: byval_arg
2323 define void @byval_arg(%SmallStruct* %ptr) {
2424 ; CHECK: .param i32
25 ; CHECK: i32.const $push[[L4:.+]]=, 0
2625 ; Subtract 16 from SP (SP is 16-byte aligned)
27 ; CHECK: i32.const $push[[L1:.+]]=, 0
28 ; CHECK-NEXT: i32.load $push[[L2:.+]]=, __stack_pointer($pop[[L1]])
26 ; CHECK-NEXT: get_global $push[[L2:.+]]=, 0
2927 ; CHECK-NEXT: i32.const $push[[L3:.+]]=, 16
3028 ; CHECK-NEXT: i32.sub $push[[L11:.+]]=, $pop[[L2]], $pop[[L3]]
3129 ; Ensure SP is stored back before the call
3230 ; CHECK-NEXT: tee_local $push[[L10:.+]]=, $[[SP:.+]]=, $pop[[L11]]{{$}}
33 ; CHECK-NEXT: i32.store __stack_pointer($pop[[L4]]), $pop[[L10]]{{$}}
31 ; CHECK-NEXT: set_global 0, $pop[[L10]]{{$}}
3432 ; Copy the SmallStruct argument to the stack (SP+12, original SP-4)
3533 ; CHECK-NEXT: i32.load $push[[L0:.+]]=, 0($0)
3634 ; CHECK-NEXT: i32.store 12($[[SP]]), $pop[[L0]]
4038 ; CHECK-NEXT: call ext_byval_func@FUNCTION, $pop[[ARG]]{{$}}
4139 call void @ext_byval_func(%SmallStruct* byval %ptr)
4240 ; Restore the stack
43 ; CHECK-NEXT: i32.const $push[[L7:.+]]=, 0
4441 ; CHECK-NEXT: i32.const $push[[L6:.+]]=, 16
4542 ; CHECK-NEXT: i32.add $push[[L8:.+]]=, $[[SP]], $pop[[L6]]
46 ; CHECK-NEXT: i32.store __stack_pointer($pop[[L7]]), $pop[[L8]]
43 ; CHECK-NEXT: set_global 0, $pop[[L8]]
4744 ; CHECK-NEXT: return
4845 ret void
4946 }
5552 ; CHECK: i32.const $push[[L1:.+]]=, 16
5653 ; CHECK-NEXT: i32.sub $push[[L11:.+]]=, {{.+}}, $pop[[L1]]
5754 ; CHECK-NEXT: tee_local $push[[L10:.+]]=, $[[SP:.+]]=, $pop[[L11]]{{$}}
58 ; CHECK-NEXT: i32.store __stack_pointer($pop{{.+}}), $pop[[L10]]{{$}}
55 ; CHECK-NEXT: set_global 0, $pop[[L10]]{{$}}
5956 ; Copy the SmallStruct argument to the stack (SP+8, original SP-8)
6057 ; CHECK-NEXT: i32.load $push[[L0:.+]]=, 0($0){{$}}
6158 ; CHECK-NEXT: i32.store 8($[[SP]]), $pop[[L0]]{{$}}
7471 ; CHECK: i32.const $push[[L1:.+]]=, 16
7572 ; CHECK-NEXT: i32.sub $push[[L14:.+]]=, {{.+}}, $pop[[L1]]
7673 ; CHECK-NEXT: tee_local $push[[L13:.+]]=, $[[SP:.+]]=, $pop[[L14]]
77 ; CHECK-NEXT: i32.store {{.+}}, $pop[[L13]]
74 ; CHECK-NEXT: set_global 0, $pop[[L13]]
7875 ; Copy the AlignedStruct argument to the stack (SP+0, original SP-16)
7976 ; Just check the last load/store pair of the memcpy
8077 ; CHECK: i64.load $push[[L4:.+]]=, 0($0)
112109
113110 ; Call memcpy for "big" byvals.
114111 ; CHECK-LABEL: big_byval:
115 ; CHECK: i32.const $push[[L4:.+]]=, 0
116 ; CHECK: i32.const $push[[L1:.+]]=, 0
117 ; CHECK-NEXT: i32.load $push[[L2:.+]]=, __stack_pointer($pop[[L1]])
112 ; CHECK: get_global $push[[L2:.+]]=, 0{{$}}
118113 ; CHECK-NEXT: i32.const $push[[L3:.+]]=, 131072
119114 ; CHECK-NEXT: i32.sub $push[[L11:.+]]=, $pop[[L2]], $pop[[L3]]
120115 ; CHECK-NEXT: tee_local $push[[L10:.+]]=, $[[SP:.+]]=, $pop[[L11]]{{$}}
121 ; CHECK-NEXT: i32.store __stack_pointer($pop[[L4]]), $pop[[L10]]{{$}}
116 ; CHECK-NEXT: set_global 0, $pop[[L10]]{{$}}
122117 ; CHECK-NEXT: i32.const $push[[L0:.+]]=, 131072
123118 ; CHECK-NEXT: i32.call $push[[L11:.+]]=, memcpy@FUNCTION, $[[SP]], ${{.+}}, $pop{{.+}}
124119 ; CHECK-NEXT: tee_local $push[[L9:.+]]=, $[[SP:.+]]=, $pop[[L11]]{{$}}
None ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-block-placement -verify-machineinstrs -fast-isel=false -machine-sink-split-probability-threshold=0 -cgp-freq-ratio-to-skip-merge=1000 | FileCheck %s
1 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -tail-dup-placement=0 -verify-machineinstrs -fast-isel=false -machine-sink-split-probability-threshold=0 -cgp-freq-ratio-to-skip-merge=1000 | FileCheck -check-prefix=OPT %s
0 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -disable-block-placement -verify-machineinstrs -fast-isel=false -machine-sink-split-probability-threshold=0 -cgp-freq-ratio-to-skip-merge=1000 | FileCheck %s
1 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -tail-dup-placement=0 -verify-machineinstrs -fast-isel=false -machine-sink-split-probability-threshold=0 -cgp-freq-ratio-to-skip-merge=1000 | FileCheck -check-prefix=OPT %s
22
33 ; Test the CFG stackifier pass.
44
66 ; optnone test.
77
88 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
9 target triple = "wasm32-unknown-unknown"
9 target triple = "wasm32-unknown-unknown-wasm"
1010
1111 declare void @something()
1212
11431143 ; optnone to disable optimizations to test this case.
11441144
11451145 ; CHECK-LABEL: test13:
1146 ; CHECK-NEXT: .local i32{{$}}
11471146 ; CHECK-NEXT: block {{$}}
11481147 ; CHECK-NEXT: block {{$}}
11491148 ; CHECK: br_if 0, $pop0{{$}}
11601159 ; CHECK-NEXT: end_block{{$}}
11611160 ; CHECK-NEXT: unreachable{{$}}
11621161 ; OPT-LABEL: test13:
1163 ; OPT-NEXT: .local i32{{$}}
11641162 ; OPT-NEXT: block {{$}}
11651163 ; OPT-NEXT: block {{$}}
11661164 ; OPT: br_if 0, $pop0{{$}}
None ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
0 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
11
22 ; Test that basic conversion operations assemble as expected.
33
44 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
5 target triple = "wasm32-unknown-unknown"
5 target triple = "wasm32-unknown-unknown-wasm"
66
77 ; CHECK-LABEL: i32_wrap_i64:
88 ; CHECK-NEXT: .param i64{{$}}
0 ; This tests that llc accepts all valid WebAssembly CPUs.
11
2 ; RUN: llc < %s -asm-verbose=false -mtriple=wasm32-unknown-unknown -mcpu=mvp 2>&1 | FileCheck %s
3 ; RUN: llc < %s -asm-verbose=false -mtriple=wasm64-unknown-unknown -mcpu=mvp 2>&1 | FileCheck %s
4 ; RUN: llc < %s -asm-verbose=false -mtriple=wasm32-unknown-unknown -mcpu=generic 2>&1 | FileCheck %s
5 ; RUN: llc < %s -asm-verbose=false -mtriple=wasm64-unknown-unknown -mcpu=generic 2>&1 | FileCheck %s
6 ; RUN: llc < %s -asm-verbose=false -mtriple=wasm32-unknown-unknown -mcpu=bleeding-edge 2>&1 | FileCheck %s
7 ; RUN: llc < %s -asm-verbose=false -mtriple=wasm64-unknown-unknown -mcpu=bleeding-edge 2>&1 | FileCheck %s
8 ; RUN: llc < %s -asm-verbose=false -mtriple=wasm32-unknown-unknown -mcpu=invalidcpu 2>&1 | FileCheck %s --check-prefix=INVALID
9 ; RUN: llc < %s -asm-verbose=false -mtriple=wasm64-unknown-unknown -mcpu=invalidcpu 2>&1 | FileCheck %s --check-prefix=INVALID
2 ; RUN: llc < %s -asm-verbose=false -mtriple=wasm32-unknown-unknown-wasm -mcpu=mvp 2>&1 | FileCheck %s
3 ; RUN: llc < %s -asm-verbose=false -mtriple=wasm64-unknown-unknown-wasm -mcpu=mvp 2>&1 | FileCheck %s
4 ; RUN: llc < %s -asm-verbose=false -mtriple=wasm32-unknown-unknown-wasm -mcpu=generic 2>&1 | FileCheck %s
5 ; RUN: llc < %s -asm-verbose=false -mtriple=wasm64-unknown-unknown-wasm -mcpu=generic 2>&1 | FileCheck %s
6 ; RUN: llc < %s -asm-verbose=false -mtriple=wasm32-unknown-unknown-wasm -mcpu=bleeding-edge 2>&1 | FileCheck %s
7 ; RUN: llc < %s -asm-verbose=false -mtriple=wasm64-unknown-unknown-wasm -mcpu=bleeding-edge 2>&1 | FileCheck %s
8 ; RUN: llc < %s -asm-verbose=false -mtriple=wasm32-unknown-unknown-wasm -mcpu=invalidcpu 2>&1 | FileCheck %s --check-prefix=INVALID
9 ; RUN: llc < %s -asm-verbose=false -mtriple=wasm64-unknown-unknown-wasm -mcpu=invalidcpu 2>&1 | FileCheck %s --check-prefix=INVALID
1010
1111 ; CHECK-NOT: is not a recognized processor for this target
1212 ; INVALID: {{.+}} is not a recognized processor for this target
None ; RUN: llc < %s -O0 -verify-machineinstrs -mtriple=wasm32-unknown-unknown | FileCheck %s
0 ; RUN: llc < %s -O0 -verify-machineinstrs -mtriple=wasm32-unknown-unknown-wasm | FileCheck %s
11
22 ; CHECK: BB#0
33 ; CHECK: #DEBUG_VALUE: usage:self <- %vreg4
0 ; RUN: llc < %s -asm-verbose=false \
11 ; RUN: -fast-isel -fast-isel-abort=1 -verify-machineinstrs \
2 ; RUN: -disable-wasm-explicit-locals \
23 ; RUN: | FileCheck %s
34
45 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
5 target triple = "wasm32-unknown-unknown"
6 target triple = "wasm32-unknown-unknown-wasm"
67
78 ; This tests very minimal fast-isel functionality.
89
None ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
0 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
11
22 ; Test that the frem instruction works.
33
44 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
5 target triple = "wasm32-unknown-unknown"
5 target triple = "wasm32-unknown-unknown-wasm"
66
77 ; CHECK-LABEL: frem32:
88 ; CHECK-NEXT: .param f32, f32{{$}}
None ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
0 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
11
22 ; Test that basic functions assemble as expected.
33
44 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
5 target triple = "wasm32-unknown-unknown"
5 target triple = "wasm32-unknown-unknown-wasm"
66
77 ; CHECK-LABEL: f0:
88 ; CHECK: return{{$}}
9 ; CHECK: .endfunc{{$}}
9 ; CHECK: end_function{{$}}
1010 ; CHECK: .size f0,
1111 define void @f0() {
1212 ret void
None ; RUN: llc < %s -asm-verbose=false | FileCheck %s
0 ; RUN: llc < %s -asm-verbose=false -disable-wasm-explicit-locals | FileCheck %s
11
22 ; Test that function pointer casts are replaced with wrappers.
33
44 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
5 target triple = "wasm32-unknown-unknown"
5 target triple = "wasm32-unknown-unknown-wasm"
66
77 ; CHECK-LABEL: test:
88 ; CHECK-NEXT: call .Lbitcast@FUNCTION{{$}}
1919 ; CHECK-NEXT: call foo2@FUNCTION{{$}}
2020 ; CHECK-NEXT: call foo1@FUNCTION{{$}}
2121 ; CHECK-NEXT: call foo3@FUNCTION{{$}}
22 ; CHECK-NEXT: .endfunc
22 ; CHECK-NEXT: end_function
2323
2424 ; CHECK-LABEL: test_varargs:
25 ; CHECK-NEXT: .local i32
26 ; CHECK: store
25 ; CHECK: set_global
2726 ; CHECK: i32.const $push[[L3:[0-9]+]]=, 0{{$}}
2827 ; CHECK-NEXT: call vararg@FUNCTION, $pop[[L3]]{{$}}
2928 ; CHECK-NEXT: i32.const $push[[L4:[0-9]+]]=, 0{{$}}
3130 ; CHECK-NEXT: call plain@FUNCTION, $[[L5]]{{$}}
3231
3332 ; CHECK-LABEL: .Lbitcast:
34 ; CHECK-NEXT: .local i32
3533 ; CHECK-NEXT: call has_i32_arg@FUNCTION, $0{{$}}
36 ; CHECK-NEXT: .endfunc
34 ; CHECK-NEXT: end_function
3735
3836 ; CHECK-LABEL: .Lbitcast.1:
3937 ; CHECK-NEXT: call $drop=, has_i32_ret@FUNCTION{{$}}
40 ; CHECK-NEXT: .endfunc
38 ; CHECK-NEXT: end_function
4139
4240 ; CHECK-LABEL: .Lbitcast.2:
4341 ; CHECK-NEXT: .param i32
4442 ; CHECK-NEXT: call foo0@FUNCTION{{$}}
45 ; CHECK-NEXT: .endfunc
43 ; CHECK-NEXT: end_function
4644
4745 ; CHECK-LABEL: .Lbitcast.3:
4846 ; CHECK-NEXT: .result i32
49 ; CHECK-NEXT: .local i32
5047 ; CHECK-NEXT: call foo1@FUNCTION{{$}}
5148 ; CHECK-NEXT: copy_local $push0=, $0
52 ; CHECK-NEXT: .endfunc
49 ; CHECK-NEXT: end_function
5350
5451 declare void @has_i32_arg(i32)
5552 declare i32 @has_i32_ret()
None ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
0 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
11
22 ; Test that globals assemble as expected.
33
44 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
5 target triple = "wasm32-unknown-unknown"
5 target triple = "wasm32-unknown-unknown-wasm"
66
77 ; CHECK-NOT: llvm.used
88 ; CHECK-NOT: llvm.metadata
4141 @ud = internal global i32 undef
4242
4343 ; CHECK: .type nil,@object
44 ; CHECK-NEXT: .lcomm nil,4,2{{$}}
44 ; CHECK: .p2align 2
45 ; CHECK: nil:
46 ; CHECK: .int32 0
47 ; CHECK: .size nil, 4
4548 @nil = internal global i32 zeroinitializer
4649
4750 ; CHECK: .type z,@object
48 ; CHECK-NEXT: .lcomm z,4,2{{$}}
51 ; CHECK: .p2align 2
52 ; CHECK: z:
53 ; CHECK: .int32 0
54 ; CHECK: .size z, 4
4955 @z = internal global i32 0
5056
51 ; CHECK-NEXT: .type one,@object
52 ; CHECK-NEXT: .p2align 2{{$}}
57 ; CHECK: .type one,@object
58 ; CHECK: .p2align 2{{$}}
5359 ; CHECK-NEXT: one:
5460 ; CHECK-NEXT: .int32 1{{$}}
5561 ; CHECK-NEXT: .size one, 4{{$}}
7783 @ud64 = internal global i64 undef
7884
7985 ; CHECK: .type nil64,@object
80 ; CHECK: .lcomm nil64,8,3{{$}}
86 ; CHECK: .p2align 3{{$}}
87 ; CHECK-NEXT: nil64:
88 ; CHECK-NEXT: .int64 0{{$}}
89 ; CHECK-NEXT: .size nil64, 8{{$}}
8190 @nil64 = internal global i64 zeroinitializer
8291
8392 ; CHECK: .type z64,@object
84 ; CHECK: .lcomm z64,8,3{{$}}
93 ; CHECK: .p2align 3{{$}}
94 ; CHECK-NEXT: z64:
95 ; CHECK-NEXT: .int64 0{{$}}
96 ; CHECK-NEXT: .size z64, 8{{$}}
8597 @z64 = internal global i64 0
8698
8799 ; CHECK: .type twoP32,@object
106118 @f32ud = internal global float undef
107119
108120 ; CHECK: .type f32nil,@object
109 ; CHECK: .lcomm f32nil,4,2{{$}}
121 ; CHECK: .p2align 2{{$}}
122 ; CHECK-NEXT: f32nil:
123 ; CHECK-NEXT: .int32 0{{$}}
124 ; CHECK-NEXT: .size f32nil, 4{{$}}
110125 @f32nil = internal global float zeroinitializer
111126
112127 ; CHECK: .type f32z,@object
113 ; CHECK: .lcomm f32z,4,2{{$}}
128 ; CHECK: .p2align 2{{$}}
129 ; CHECK-NEXT: f32z:
130 ; CHECK-NEXT: .int32 0{{$}}
131 ; CHECK-NEXT: .size f32z, 4{{$}}
114132 @f32z = internal global float 0.0
115133
116134 ; CHECK: .type f32nz,@object
135153 @f64ud = internal global double undef
136154
137155 ; CHECK: .type f64nil,@object
138 ; CHECK: .lcomm f64nil,8,3{{$}}
156 ; CHECK: .p2align 3{{$}}
157 ; CHECK-NEXT: f64nil:
158 ; CHECK-NEXT: .int64 0{{$}}
159 ; CHECK-NEXT: .size f64nil, 8{{$}}
139160 @f64nil = internal global double zeroinitializer
140161
141162 ; CHECK: .type f64z,@object
142 ; CHECK: .lcomm f64z,8,3{{$}}
163 ; CHECK: .p2align 3{{$}}
164 ; CHECK-NEXT: f64z:
165 ; CHECK-NEXT: .int64 0{{$}}
166 ; CHECK-NEXT: .size f64z, 8{{$}}
143167 @f64z = internal global double 0.0
144168
145169 ; CHECK: .type f64nz,@object
167191
168192 ; Constant global.
169193 ; CHECK: .type rom,@object{{$}}
170 ; CHECK: .section .rodata,"a",@progbits{{$}}
194 ; CHECK: .section .rodata.rom,
171195 ; CHECK: .globl rom{{$}}
172196 ; CHECK: .p2align 4{{$}}
173197 ; CHECK: rom:
176200 @rom = constant [128 x i32] zeroinitializer, align 16
177201
178202 ; CHECK: .type array,@object
179 ; CHECK-NEXT: array:
203 ; CHECK: array:
180204 ; CHECK-NEXT: .skip 8
181205 ; CHECK-NEXT: .size array, 8
182206 ; CHECK: .type pointer_to_array,@object
183 ; CHECK-NEXT: .section .data.rel.ro,"aw",@progbits
207 ; CHECK-NEXT: .section .data.rel.ro.pointer_to_array,
184208 ; CHECK-NEXT: .globl pointer_to_array
185209 ; CHECK-NEXT: .p2align 2
186210 ; CHECK-NEXT: pointer_to_array:
None ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
0 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
11
22 ; Test loads and stores with custom alignment values.
33
44 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
5 target triple = "wasm32-unknown-unknown"
5 target triple = "wasm32-unknown-unknown-wasm"
66
77 ; CHECK-LABEL: ldi32_a1:
88 ; CHECK-NEXT: .param i32{{$}}
None ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
0 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
11
22 ; Test loads and stores with custom alignment values.
33
44 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
5 target triple = "wasm32-unknown-unknown"
5 target triple = "wasm32-unknown-unknown-wasm"
66
77 ; CHECK-LABEL: ldi64_a1:
88 ; CHECK-NEXT: .param i32{{$}}
None ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -no-integrated-as | FileCheck %s
0 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -no-integrated-as | FileCheck %s
11
22 ; Test basic inline assembly. Pass -no-integrated-as since these aren't
33 ; actually valid assembly syntax.
44
55 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
6 target triple = "wasm32-unknown-unknown"
6 target triple = "wasm32-unknown-unknown-wasm"
77
88 ; CHECK-LABEL: foo:
99 ; CHECK-NEXT: .param i32{{$}}
3232
3333 ; CHECK-LABEL: imm:
3434 ; CHECK-NEXT: .result i32{{$}}
35 ; CHECK-NEXT: .local i32{{$}}
3635 ; CHECK-NEXT: #APP{{$}}
3736 ; CHECK-NEXT: # $0 = ccc(42){{$}}
3837 ; CHECK-NEXT: #NO_APP{{$}}
None ; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-block-placement | FileCheck %s
0 ; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-block-placement -disable-wasm-explicit-locals | FileCheck %s
11
22 ; Test irreducible CFG handling.
33
44 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
5 target triple = "wasm32-unknown-unknown"
5 target triple = "wasm32-unknown-unknown-wasm"
66
77 ; A simple loop with two entries.
88
None ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
0 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
11
22 ; Test various types and operators that need to be legalized.
33
44 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
5 target triple = "wasm32-unknown-unknown"
5 target triple = "wasm32-unknown-unknown-wasm"
66
77 ; CHECK-LABEL: shl_i3:
88 ; CHECK: i32.const $push0=, 7{{$}}
None ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
0 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
11
22 ; Test that extending loads are assembled properly.
33
44 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
5 target triple = "wasm32-unknown-unknown"
5 target triple = "wasm32-unknown-unknown-wasm"
66
77 ; CHECK-LABEL: sext_i8_i32:
88 ; CHECK: i32.load8_s $push0=, 0($0){{$}}
None ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
0 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
11
22 ; Test that i1 extending loads and truncating stores are assembled properly.
33
44 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
5 target triple = "wasm32-unknown-unknown"
5 target triple = "wasm32-unknown-unknown-wasm"
66
77 ; CHECK-LABEL: load_u_i1_i32:
88 ; CHECK: i32.load8_u $push[[NUM0:[0-9]+]]=, 0($0){{$}}
None ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -tail-dup-placement=0 | FileCheck %s
0 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -tail-dup-placement=0 | FileCheck %s
11
22 ; Test memcpy, memmove, and memset intrinsics.
33
44 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
5 target triple = "wasm32-unknown-unknown"
5 target triple = "wasm32-unknown-unknown-wasm"
66
77 declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture readonly, i32, i32, i1)
88 declare void @llvm.memmove.p0i8.p0i8.i32(i8* nocapture, i8* nocapture readonly, i32, i32, i1)
None ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
0 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
11
22 ; Test that basic memory operations assemble as expected with 32-bit addresses.
33
44 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
5 target triple = "wasm32-unknown-unknown"
5 target triple = "wasm32-unknown-unknown-wasm"
66
77 declare i32 @llvm.wasm.current.memory.i32() nounwind readonly
88 declare i32 @llvm.wasm.grow.memory.i32(i32) nounwind
None ; RUN: llc < %s -asm-verbose=false | FileCheck %s
0 ; RUN: llc < %s -asm-verbose=false -disable-wasm-explicit-locals | FileCheck %s
11
22 ; Test constant load and store address offsets.
33
44 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
5 target triple = "wasm32-unknown-unknown"
5 target triple = "wasm32-unknown-unknown-wasm"
66
77 ; With an nuw add, we can fold an offset.
88
None ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -verify-machineinstrs | FileCheck %s
0 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -verify-machineinstrs | FileCheck %s
11
22 ; Test that phis are lowered.
33
44 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
5 target triple = "wasm32-unknown-unknown"
5 target triple = "wasm32-unknown-unknown-wasm"
66
77 ; Basic phi triangle.
88
None ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -verify-machineinstrs | FileCheck %s
0 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -verify-machineinstrs | FileCheck %s
11
22 ; Test the register stackifier pass.
33
44 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
5 target triple = "wasm32-unknown-unknown"
5 target triple = "wasm32-unknown-unknown-wasm"
66
77 ; No because of pointer aliasing.
88
125125
126126 ; CHECK-LABEL: multiple_uses:
127127 ; CHECK: .param i32, i32, i32{{$}}
128 ; CHECK-NEXT: .local i32{{$}}
129128 ; CHECK-NEXT: block {{$}}
130129 ; CHECK-NEXT: i32.load $push[[NUM0:[0-9]+]]=, 0($2){{$}}
131130 ; CHECK-NEXT: tee_local $push[[NUM1:[0-9]+]]=, $3=, $pop[[NUM0]]{{$}}
448447
449448 ; CHECK-LABEL: stackpointer_dependency:
450449 ; CHECK: call {{.+}}, stackpointer_callee@FUNCTION,
451 ; CHECK: i32.const $push[[L0:.+]]=, 0
452 ; CHECK-NEXT: i32.store __stack_pointer($pop[[L0]]),
450 ; CHECK-NEXT: set_global 0,
453451 declare i32 @stackpointer_callee(i8* readnone, i8* readnone)
454452 declare i8* @llvm.frameaddress(i32)
455453 define i32 @stackpointer_dependency(i8* readnone) {
11 ; RUN: llc < %s -asm-verbose=false -fast-isel -fast-isel-abort=1 | FileCheck %s
22
33 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
4 target triple = "wasm32-unknown-unknown"
4 target triple = "wasm32-unknown-unknown-wasm"
55
66 ; CHECK-LABEL: return_i32:
77 ; CHECK-NEXT: .param i32{{$}}
88 ; CHECK-NEXT: .result i32{{$}}
9 ; CHECK-NEXT: copy_local $push0=, $0
10 ; CHECK-NEXT: .endfunc{{$}}
9 ; CHECK-NEXT: get_local $push0=, 0
10 ; CHECK-NEXT: end_function{{$}}
1111 define i32 @return_i32(i32 %p) {
1212 ret i32 %p
1313 }
1818 ; CHECK-NEXT: return $pop[[L0]]{{$}}
1919 ; CHECK: store
2020 ; CHECK-NEXT: i32.const $push{{[^,]+}}=, 3{{$}}
21 ; CHECK-NEXT: .endfunc{{$}}
21 ; CHECK-NEXT: end_function{{$}}
2222 define i32 @return_i32_twice(i32 %a) {
2323 %b = icmp ne i32 %a, 0
2424 br i1 %b, label %true, label %false
11 ; RUN: llc < %s -asm-verbose=false -fast-isel -fast-isel-abort=1 | FileCheck %s
22
33 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
4 target triple = "wasm32-unknown-unknown"
4 target triple = "wasm32-unknown-unknown-wasm"
55
66 ; CHECK-LABEL: return_void:
7 ; CHECK-NEXT: .endfunc{{$}}
7 ; CHECK-NEXT: end_function{{$}}
88 define void @return_void() {
99 ret void
1010 }
1313 ; CHECK: store
1414 ; CHECK-NEXT: return{{$}}
1515 ; CHECK: store
16 ; CHECK-NEXT: .endfunc{{$}}
16 ; CHECK-NEXT: end_function{{$}}
1717 define void @return_void_twice(i32 %a) {
1818 %b = icmp ne i32 %a, 0
1919 br i1 %b, label %true, label %false
None ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
0 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
11
22 ; Test that the "returned" attribute is optimized effectively.
33
44 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
5 target triple = "wasm32-unknown-unknown"
5 target triple = "wasm32-unknown-unknown-wasm"
66
77 ; CHECK-LABEL: _Z3foov:
88 ; CHECK-NEXT: .result i32{{$}}
None ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
1 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -fast-isel -fast-isel-abort=1 | FileCheck %s
0 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
1 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -fast-isel -fast-isel-abort=1 | FileCheck %s
22
33 ; Test that wasm select instruction is selected from LLVM select instruction.
44
55 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
6 target triple = "wasm32-unknown-unknown"
6 target triple = "wasm32-unknown-unknown-wasm"
77
88 ; CHECK-LABEL: select_i32_bool:
99 ; CHECK-NEXT: .param i32, i32, i32{{$}}
None ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
0 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
11
22 ; Test zeroext and signext ABI keywords
33
44 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
5 target triple = "wasm32-unknown-unknown"
5 target triple = "wasm32-unknown-unknown-wasm"
66
77 ; CHECK-LABEL: z2s_func:
88 ; CHECK-NEXT: .param i32{{$}}
None ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -mattr=+simd128 | FileCheck %s --check-prefixes CHECK,SIMD128
1 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -mattr=+simd128 -fast-isel | FileCheck %s --check-prefixes CHECK,SIMD128
2 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -mattr=-simd128 | FileCheck %s --check-prefixes CHECK,NO-SIMD128
3 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -mattr=-simd128 -fast-isel | FileCheck %s --check-prefixes CHECK,NO-SIMD128
0 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -mattr=+simd128 | FileCheck %s --check-prefixes CHECK,SIMD128
1 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -mattr=+simd128 -fast-isel | FileCheck %s --check-prefixes CHECK,SIMD128
2 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -mattr=-simd128 | FileCheck %s --check-prefixes CHECK,NO-SIMD128
3 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -mattr=-simd128 -fast-isel | FileCheck %s --check-prefixes CHECK,NO-SIMD128
44
55 ; Test that basic SIMD128 arithmetic operations assemble as expected.
66
77 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
8 target triple = "wasm32-unknown-unknown"
8 target triple = "wasm32-unknown-unknown-wasm"
99
1010 declare i32 @llvm.ctlz.i32(i32, i1)
1111 declare i32 @llvm.cttz.i32(i32, i1)
None ; RUN: llc < %s -asm-verbose=false | FileCheck %s
0 ; RUN: llc < %s -asm-verbose=false -disable-wasm-explicit-locals | FileCheck %s
11
22 ; Test that truncating stores are assembled properly.
33
44 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
5 target triple = "wasm32-unknown-unknown"
5 target triple = "wasm32-unknown-unknown-wasm"
66
77 ; CHECK-LABEL: trunc_i8_i32:
88 ; CHECK: i32.store8 0($0), $1{{$}}
44 ; conversions are implemented.
55
66 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
7 target triple = "wasm32-unknown-unknown"
7 target triple = "wasm32-unknown-unknown-wasm"
88
99 ; CHECK-LABEL: test:
1010 ; CHECK-NEXT: i32.const $push[[L0:[0-9]+]]=, 0{{$}}
1111 ; CHECK-NEXT: call has_i64_arg@FUNCTION, $pop[[L0]]{{$}}
12 ; CHECK-NEXT: i32.call $drop=, has_i64_ret@FUNCTION{{$}}
13 ; CHECK-NEXT: .endfunc
12 ; CHECK-NEXT: i32.call $push{{[0-9]+}}=, has_i64_ret@FUNCTION{{$}}
13 ; CHECK-NEXT: drop
14 ; CHECK-NEXT: end_function
1415
1516 ; CHECK-NOT: .Lbitcast
1617
None ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
0 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
11
22 ; Make sure that argument offsets are correct even if some arguments are unused.
33
44 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
5 target triple = "wasm32-unknown-unknown"
5 target triple = "wasm32-unknown-unknown-wasm"
66
77 ; CHECK-LABEL: unused_first:
88 ; CHECK-NEXT: .param i32, i32{{$}}
0 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
11
22 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
3 target triple = "wasm32-unknown-unknown"
3 target triple = "wasm32-unknown-unknown-wasm"
44
55 declare void @ext_func(i64* %ptr)
66 declare void @ext_func_i32(i32* %ptr)
99 ; Check that there is an extra local for the stack pointer.
1010 ; CHECK: .local i32{{$}}
1111 define void @alloca32() noredzone {
12 ; CHECK: i32.const $push[[L4:.+]]=, 0{{$}}
13 ; CHECK: i32.const $push[[L1:.+]]=, 0{{$}}
14 ; CHECK-NEXT: i32.load $push[[L2:.+]]=, __stack_pointer($pop[[L1]])
12 ; CHECK-NEXT: get_global $push[[L2:.+]]=, 0{{$}}
1513 ; CHECK-NEXT: i32.const $push[[L3:.+]]=, 16
1614 ; CHECK-NEXT: i32.sub $push[[L9:.+]]=, $pop[[L2]], $pop[[L3]]
17 ; CHECK-NEXT: tee_local $push[[L8:.+]]=, $[[SP:.+]]=, $pop[[L9]]{{$}}
18 ; CHECK-NEXT: i32.store __stack_pointer($pop[[L4]]), $pop[[L8]]{{$}}
15 ; CHECK-NEXT: tee_local $push[[L8:.+]]=, [[SP:.+]], $pop[[L9]]{{$}}
16 ; CHECK-NEXT: set_global 0, $pop[[L8]]{{$}}
1917 %retval = alloca i32
18 ; CHECK: get_local $push[[L4:.+]]=, [[SP]]{{$}}
2019 ; CHECK: i32.const $push[[L0:.+]]=, 0
21 ; CHECK: i32.store 12($[[SP]]), $pop[[L0]]
20 ; CHECK: i32.store 12($pop[[L4]]), $pop[[L0]]
2221 store i32 0, i32* %retval
23 ; CHECK: i32.const $push[[L6:.+]]=, 0
22 ; CHECK: get_local $push[[L6:.+]]=, [[SP]]{{$}}
2423 ; CHECK-NEXT: i32.const $push[[L5:.+]]=, 16
25 ; CHECK-NEXT: i32.add $push[[L7:.+]]=, $[[SP]], $pop[[L5]]
26 ; CHECK-NEXT: i32.store __stack_pointer($pop[[L6]]), $pop[[L7]]
24 ; CHECK-NEXT: i32.add $push[[L7:.+]]=, $pop[[L6]], $pop[[L5]]
25 ; CHECK-NEXT: set_global 0, $pop[[L7]]
2726 ret void
2827 }
2928
3029 ; CHECK-LABEL: alloca3264:
3130 ; CHECK: .local i32{{$}}
3231 define void @alloca3264() {
33 ; CHECK: i32.const $push[[L2:.+]]=, 0{{$}}
34 ; CHECK-NEXT: i32.load $push[[L3:.+]]=, __stack_pointer($pop[[L2]])
32 ; CHECK: get_global $push[[L3:.+]]=, 0{{$}}
3533 ; CHECK-NEXT: i32.const $push[[L4:.+]]=, 16
3634 ; CHECK-NEXT: i32.sub $push[[L6:.+]]=, $pop[[L3]], $pop[[L4]]
37 ; CHECK-NEXT: tee_local $push[[L5:.+]]=, $[[SP:.+]]=, $pop[[L6]]
35 ; CHECK-NEXT: tee_local $push[[L5:.+]]=, [[SP:.+]], $pop[[L6]]
3836 %r1 = alloca i32
3937 %r2 = alloca double
4038 ; CHECK-NEXT: i32.const $push[[L0:.+]]=, 0
4139 ; CHECK-NEXT: i32.store 12($pop[[L5]]), $pop[[L0]]
4240 store i32 0, i32* %r1
41 ; CHECK-NEXT: get_local $push[[L2:.+]]=, [[SP]]{{$}}
4342 ; CHECK-NEXT: i64.const $push[[L1:.+]]=, 0
44 ; CHECK-NEXT: i64.store 0($[[SP]]), $pop[[L1]]
43 ; CHECK-NEXT: i64.store 0($pop[[L2]]), $pop[[L1]]
4544 store double 0.0, double* %r2
4645 ; CHECK-NEXT: return
4746 ret void
5049 ; CHECK-LABEL: allocarray:
5150 ; CHECK: .local i32{{$}}
5251 define void @allocarray() {
53 ; CHECK: i32.const $push[[L6:.+]]=, 0{{$}}
54 ; CHECK: i32.const $push[[L3:.+]]=, 0{{$}}
55 ; CHECK-NEXT: i32.load $push[[L4:.+]]=, __stack_pointer($pop[[L3]])
52 ; CHECK-NEXT: get_global $push[[L4:.+]]=, 0{{$}}
5653 ; CHECK-NEXT: i32.const $push[[L5:.+]]=, 144{{$}}
5754 ; CHECK-NEXT: i32.sub $push[[L12:.+]]=, $pop[[L4]], $pop[[L5]]
58 ; CHECK-NEXT: tee_local $push[[L11:.+]]=, $0=, $pop[[L12]]
59 ; CHECK-NEXT: i32.store __stack_pointer($pop[[L6]]), $pop[[L11]]
55 ; CHECK-NEXT: tee_local $push[[L11:.+]]=, 0, $pop[[L12]]
56 ; CHECK-NEXT: set_global 0, $pop[[L11]]
6057 %r = alloca [33 x i32]
6158
6259 ; CHECK: i32.const $push{{.+}}=, 24
63 ; CHECK-NEXT: i32.add $push[[L3:.+]]=, $[[SP]], $pop{{.+}}
60 ; CHECK-NEXT: i32.add $push[[L3:.+]]=, $pop{{.+}}, $pop{{.+}}
6461 ; CHECK-NEXT: i32.const $push[[L1:.+]]=, 1{{$}}
6562 ; CHECK-NEXT: i32.store 0($pop[[L3]]), $pop[[L1]]{{$}}
63 ; CHECK-NEXT: get_local $push[[L4:.+]]=, 0{{$}}
6664 ; CHECK-NEXT: i32.const $push[[L10:.+]]=, 1{{$}}
67 ; CHECK-NEXT: i32.store 12(${{.+}}), $pop[[L10]]{{$}}
65 ; CHECK-NEXT: i32.store 12($pop[[L4]]), $pop[[L10]]{{$}}
6866 %p = getelementptr [33 x i32], [33 x i32]* %r, i32 0, i32 0
6967 store i32 1, i32* %p
7068 %p2 = getelementptr [33 x i32], [33 x i32]* %r, i32 0, i32 3
7169 store i32 1, i32* %p2
7270
73 ; CHECK: i32.const $push[[L9:.+]]=, 0{{$}}
71 ; CHECK-NEXT: get_local $push[[L2:.+]]=, [[SP]]{{$}}
7472 ; CHECK-NEXT: i32.const $push[[L7:.+]]=, 144
75 ; CHECK-NEXT: i32.add $push[[L8:.+]]=, $[[SP]], $pop[[L7]]
76 ; CHECK-NEXT: i32.store __stack_pointer($pop[[L9]]), $pop[[L8]]
73 ; CHECK-NEXT: i32.add $push[[L8:.+]]=, $pop[[L2]], $pop[[L7]]
74 ; CHECK-NEXT: set_global 0, $pop[[L8]]
7775 ret void
7876 }
7977
8179 define void @non_mem_use(i8** %addr) {
8280 ; CHECK: i32.const $push[[L2:.+]]=, 48
8381 ; CHECK-NEXT: i32.sub $push[[L12:.+]]=, {{.+}}, $pop[[L2]]
84 ; CHECK-NEXT: tee_local $push[[L11:.+]]=, $[[SP:.+]]=, $pop[[L12]]
85 ; CHECK-NEXT: i32.store {{.+}}, $pop[[L11]]
82 ; CHECK-NEXT: tee_local $push[[L11:.+]]=, [[SP:.+]], $pop[[L12]]
83 ; CHECK-NEXT: set_global 0, $pop[[L11]]
8684 %buf = alloca [27 x i8], align 16
8785 %r = alloca i64
8886 %r2 = alloca i64
8987 ; %r is at SP+8
88 ; CHECK: get_local $push[[L3:.+]]=, [[SP]]
9089 ; CHECK: i32.const $push[[OFF:.+]]=, 8
91 ; CHECK-NEXT: i32.add $push[[ARG1:.+]]=, $[[SP]], $pop[[OFF]]
90 ; CHECK-NEXT: i32.add $push[[ARG1:.+]]=, $pop[[L3]], $pop[[OFF]]
9291 ; CHECK-NEXT: call ext_func@FUNCTION, $pop[[ARG1]]
9392 call void @ext_func(i64* %r)
9493 ; %r2 is at SP+0, no add needed
95 ; CHECK-NEXT: call ext_func@FUNCTION, $[[SP]]
94 ; CHECK: get_local $push[[L4:.+]]=, [[SP]]
95 ; CHECK-NEXT: call ext_func@FUNCTION, $pop[[L4]]
9696 call void @ext_func(i64* %r2)
9797 ; Use as a value, but in a store
9898 ; %buf is at SP+16
99 ; CHECK: get_local $push[[L5:.+]]=, [[SP]]
99100 ; CHECK: i32.const $push[[OFF:.+]]=, 16
100 ; CHECK-NEXT: i32.add $push[[VAL:.+]]=, $[[SP]], $pop[[OFF]]
101 ; CHECK-NEXT: i32.store 0($0), $pop[[VAL]]
101 ; CHECK-NEXT: i32.add $push[[VAL:.+]]=, $pop[[L5]], $pop[[OFF]]
102 ; CHECK-NEXT: i32.store 0($pop{{.+}}), $pop[[VAL]]
102103 %gep = getelementptr inbounds [27 x i8], [27 x i8]* %buf, i32 0, i32 0
103104 store i8* %gep, i8** %addr
104105 ret void
107108 ; CHECK-LABEL: allocarray_inbounds:
108109 ; CHECK: .local i32{{$}}
109110 define void @allocarray_inbounds() {
110 ; CHECK: i32.const $push[[L5:.+]]=, 0{{$}}
111 ; CHECK: i32.const $push[[L2:.+]]=, 0{{$}}
112 ; CHECK-NEXT: i32.load $push[[L3:.+]]=, __stack_pointer($pop[[L2]])
111 ; CHECK: get_global $push[[L3:.+]]=, 0{{$}}
113112 ; CHECK-NEXT: i32.const $push[[L4:.+]]=, 32{{$}}
114113 ; CHECK-NEXT: i32.sub $push[[L11:.+]]=, $pop[[L3]], $pop[[L4]]
115 ; CHECK-NEXT: tee_local $push[[L10:.+]]=, $[[SP:.+]]=, $pop[[L11]]
116 ; CHECK-NEXT: i32.store __stack_pointer($pop[[L5]]), $pop[[L10]]{{$}}
114 ; CHECK-NEXT: tee_local $push[[L10:.+]]=, [[SP:.+]], $pop[[L11]]
115 ; CHECK-NEXT: set_global 0, $pop[[L10]]{{$}}
117116 %r = alloca [5 x i32]
118117 ; CHECK: i32.const $push[[L3:.+]]=, 1
119118 ; CHECK-DAG: i32.store 24(${{.+}}), $pop[[L3]]
125124 store i32 1, i32* %p2
126125 call void @ext_func(i64* null);
127126 ; CHECK: call ext_func
128 ; CHECK: i32.const $push[[L6:.+]]=, 0{{$}}
129 ; CHECK-NEXT: i32.const $push[[L5:.+]]=, 32{{$}}
127 ; CHECK: i32.const $push[[L5:.+]]=, 32{{$}}
130128 ; CHECK-NEXT: i32.add $push[[L7:.+]]=, ${{.+}}, $pop[[L5]]
131 ; CHECK-NEXT: i32.store __stack_pointer($pop[[L6]]), $pop[[L7]]
129 ; CHECK-NEXT: set_global 0, $pop[[L7]]
132130 ret void
133131 }
134132
135133 ; CHECK-LABEL: dynamic_alloca:
136134 define void @dynamic_alloca(i32 %alloc) {
137 ; CHECK: i32.const $push[[L7:.+]]=, 0{{$}}
138 ; CHECK: i32.const $push[[L1:.+]]=, 0{{$}}
139 ; CHECK-NEXT: i32.load $push[[L13:.+]]=, __stack_pointer($pop[[L1]])
135 ; CHECK: get_global $push[[L13:.+]]=, 0{{$}}
140136 ; CHECK-NEXT: tee_local $push[[L12:.+]]=, [[SP:.+]], $pop[[L13]]{{$}}
141137 ; Target independent codegen bumps the stack pointer.
142138 ; CHECK: i32.sub
143139 ; Check that SP is written back to memory after decrement
144 ; CHECK: i32.store __stack_pointer($pop{{.+}}),
140 ; CHECK: set_global 0,
145141 %r = alloca i32, i32 %alloc
146142 ; Target-independent codegen also calculates the store addr
147143 ; CHECK: call ext_func_i32@FUNCTION
148144 call void @ext_func_i32(i32* %r)
149 ; CHECK: i32.const $push[[L3:.+]]=, 0{{$}}
150 ; CHECK: i32.store __stack_pointer($pop[[L3]]), $pop{{.+}}
145 ; CHECK: set_global 0, $pop{{.+}}
151146 ret void
152147 }
153148
154149 ; CHECK-LABEL: dynamic_alloca_redzone:
155150 define void @dynamic_alloca_redzone(i32 %alloc) {
156 ; CHECK: i32.const $push[[L8:.+]]=, 0{{$}}
157 ; CHECK-NEXT: i32.load $push[[L13:.+]]=, __stack_pointer($pop[[L1]])
151 ; CHECK: get_global $push[[L13:.+]]=, 0{{$}}
158152 ; CHECK-NEXT: tee_local $push[[L12:.+]]=, [[SP:.+]], $pop[[L13]]{{$}}
159 ; CHECK-NEXT: copy_local [[FP:.+]]=, $pop[[L12]]{{$}}
160153 ; Target independent codegen bumps the stack pointer
161154 ; CHECK: i32.sub
162155 %r = alloca i32, i32 %alloc
163 ; CHECK-NEXT: tee_local $push[[L8:.+]]=, $0=, $pop
164 ; CHECK-NEXT: copy_local $drop=, $pop[[L8]]{{$}}
156 ; CHECK-NEXT: tee_local $push[[L8:.+]]=, {{.+}}, $pop
157 ; CHECK: get_local $push[[L7:.+]]=, 0{{$}}
165158 ; CHECK-NEXT: i32.const $push[[L6:.+]]=, 0{{$}}
166 ; CHECK-NEXT: i32.store 0($0), $pop[[L6]]{{$}}
159 ; CHECK-NEXT: i32.store 0($pop[[L7]]), $pop[[L6]]{{$}}
167160 store i32 0, i32* %r
168161 ; CHECK-NEXT: return
169162 ret void
172165 ; CHECK-LABEL: dynamic_static_alloca:
173166 define void @dynamic_static_alloca(i32 %alloc) noredzone {
174167 ; Decrement SP in the prolog by the static amount and writeback to memory.
175 ; CHECK: i32.const $push[[L13:.+]]=, 0{{$}}
176 ; CHECK: i32.const $push[[L10:.+]]=, 0{{$}}
177 ; CHECK-NEXT: i32.load $push[[L11:.+]]=, __stack_pointer($pop[[L10]])
168 ; CHECK: get_global $push[[L11:.+]]=, 0{{$}}
178169 ; CHECK-NEXT: i32.const $push[[L12:.+]]=, 16
179170 ; CHECK-NEXT: i32.sub $push[[L23:.+]]=, $pop[[L11]], $pop[[L12]]
180 ; CHECK-NEXT: tee_local $push[[L22:.+]]=, $[[SP:.+]]=, $pop[[L23]]
181 ; CHECK-NEXT: i32.store __stack_pointer($pop{{.+}}), $pop[[L22]]
171 ; CHECK-NEXT: tee_local $push[[L22:.+]]=, [[SP:.+]], $pop[[L23]]
172 ; CHECK-NEXT: set_global 0, $pop[[L22]]
182173
183174 ; Alloc and write to a static alloca
184 ; CHECK: copy_local $push[[L21:.+]]=, $[[SP]]
185 ; CHECK-NEXT: tee_local $push[[pushedFP:.+]]=, $[[FP:.+]]=, $pop[[L21]]
175 ; CHECK: get_local $push[[L21:.+]]=, [[SP:.+]]
176 ; CHECK-NEXT: tee_local $push[[pushedFP:.+]]=, [[FP:.+]], $pop[[L21]]
186177 ; CHECK-NEXT: i32.const $push[[L0:.+]]=, 101
187178 ; CHECK-NEXT: i32.store [[static_offset:.+]]($pop[[pushedFP]]), $pop[[L0]]
188179 %static = alloca i32
190181
191182 ; Decrement SP in the body by the dynamic amount.
192183 ; CHECK: i32.sub
193 ; CHECK: tee_local $push{{.+}}=, $[[dynamic_local:.+]]=, $pop{{.+}}
194 ; CHECK: i32.store __stack_pointer
184 ; CHECK: tee_local $push[[L16:.+]]=, [[dynamic_local:.+]], $pop{{.+}}
185 ; CHECK: tee_local $push[[L15:.+]]=, [[other:.+]], $pop[[L16]]{{$}}
186 ; CHECK: set_global 0, $pop[[L15]]{{$}}
195187 %dynamic = alloca i32, i32 %alloc
196188
197189 ; Ensure we don't modify the frame pointer after assigning it.
198190 ; CHECK-NOT: $[[FP]]=
199191
200192 ; Ensure the static address doesn't change after modifying the stack pointer.
193 ; CHECK: get_local $push[[L17:.+]]=, [[FP]]
201194 ; CHECK: i32.const $push[[L7:.+]]=, 102
202 ; CHECK-NEXT: i32.store [[static_offset]]($[[FP]]), $pop[[L7]]
195 ; CHECK-NEXT: i32.store [[static_offset]]($pop[[L17]]), $pop[[L7]]
196 ; CHECK-NEXT: get_local $push[[L9:.+]]=, [[dynamic_local]]{{$}}
203197 ; CHECK-NEXT: i32.const $push[[L8:.+]]=, 103
204 ; CHECK-NEXT: i32.store 0($[[dynamic_local]]), $pop[[L8]]
198 ; CHECK-NEXT: i32.store 0($pop[[L9]]), $pop[[L8]]
205199 store volatile i32 102, i32* %static
206200 store volatile i32 103, i32* %dynamic
207201
208202 ; Decrement SP in the body by the dynamic amount.
209203 ; CHECK: i32.sub
210 ; CHECK: tee_local $push{{.+}}=, $[[dynamic2_local:.+]]=, $pop{{.+}}
204 ; CHECK: tee_local $push{{.+}}=, [[dynamic2_local:.+]], $pop{{.+}}
211205 %dynamic.2 = alloca i32, i32 %alloc
212206
213207 ; CHECK-NOT: $[[FP]]=
214208
215209 ; Ensure neither the static nor dynamic address changes after the second
216210 ; modification of the stack pointer.
211 ; CHECK: get_local $push[[L22:.+]]=, [[FP]]
217212 ; CHECK: i32.const $push[[L9:.+]]=, 104
218 ; CHECK-NEXT: i32.store [[static_offset]]($[[FP]]), $pop[[L9]]
213 ; CHECK-NEXT: i32.store [[static_offset]]($pop[[L22]]), $pop[[L9]]
214 ; CHECK-NEXT: get_local $push[[L23:.+]]=, [[dynamic_local]]
219215 ; CHECK-NEXT: i32.const $push[[L10:.+]]=, 105
220 ; CHECK-NEXT: i32.store 0($[[dynamic_local]]), $pop[[L10]]
216 ; CHECK-NEXT: i32.store 0($pop[[L23]]), $pop[[L10]]
217 ; CHECK-NEXT: get_local $push[[L23:.+]]=, [[dynamic2_local]]
221218 ; CHECK-NEXT: i32.const $push[[L11:.+]]=, 106
222 ; CHECK-NEXT: i32.store 0($[[dynamic2_local]]), $pop[[L11]]
219 ; CHECK-NEXT: i32.store 0($pop[[L23]]), $pop[[L11]]
223220 store volatile i32 104, i32* %static
224221 store volatile i32 105, i32* %dynamic
225222 store volatile i32 106, i32* %dynamic.2
226223
227224 ; Writeback to memory.
228 ; CHECK: i32.const $push[[L17:.+]]=, 16
229 ; CHECK-NEXT: i32.add $push[[L18:.+]]=, $[[FP]], $pop[[L17]]
230 ; CHECK-NEXT: i32.store __stack_pointer($pop{{.+}}), $pop[[L18]]
225 ; CHECK: get_local $push[[L24:.+]]=, [[FP]]{{$}}
226 ; CHECK: i32.const $push[[L18:.+]]=, 16
227 ; CHECK-NEXT: i32.add $push[[L19:.+]]=, $pop[[L24]], $pop[[L18]]
228 ; CHECK-NEXT: set_global 0, $pop[[L19]]
231229 ret void
232230 }
233231
236234
237235 ; CHECK-LABEL: llvm_stack_builtins:
238236 define void @llvm_stack_builtins(i32 %alloc) noredzone {
239 ; CHECK: i32.load $push[[L11:.+]]=, __stack_pointer($pop{{.+}})
240 ; CHECK-NEXT: tee_local $push[[L10:.+]]=, ${{.+}}=, $pop[[L11]]
241 ; CHECK-NEXT: copy_local $[[STACK:.+]]=, $pop[[L10]]
237 ; CHECK: get_global $push[[L11:.+]]=, 0{{$}}
238 ; CHECK-NEXT: tee_local $push[[L10:.+]]=, {{.+}}, $pop[[L11]]
239 ; CHECK-NEXT: set_local [[STACK:.+]], $pop[[L10]]
242240 %stack = call i8* @llvm.stacksave()
243241
244242 ; Ensure we don't reassign the stacksave local
245 ; CHECK-NOT: $[[STACK]]=
243 ; CHECK-NOT: set_local [[STACK]],
246244 %dynamic = alloca i32, i32 %alloc
247245
248 ; CHECK: i32.store __stack_pointer($pop{{.+}}), $[[STACK]]
246 ; CHECK: get_local $push[[L12:.+]]=, [[STACK]]
247 ; CHECK-NEXT: set_global 0, $pop[[L12]]
249248 call void @llvm.stackrestore(i8* %stack)
250249
251250 ret void
256255 ; moved after the stack pointer was updated for the dynamic alloca.
257256 ; CHECK-LABEL: dynamic_alloca_nouse:
258257 define void @dynamic_alloca_nouse(i32 %alloc) noredzone {
259 ; CHECK: i32.load $push[[L11:.+]]=, __stack_pointer($pop{{.+}})
260 ; CHECK-NEXT: tee_local $push[[L10:.+]]=, ${{.+}}=, $pop[[L11]]
261 ; CHECK-NEXT: copy_local $[[FP:.+]]=, $pop[[L10]]
258 ; CHECK: get_global $push[[L11:.+]]=, 0{{$}}
259 ; CHECK-NEXT: tee_local $push[[L10:.+]]=, {{.+}}, $pop[[L11]]
260 ; CHECK-NEXT: set_local [[FP:.+]], $pop[[L10]]
262261 %dynamic = alloca i32, i32 %alloc
263262
264 ; CHECK-NOT: $[[FP]]=,
265
266 ; CHECK: i32.store __stack_pointer($pop{{.+}}), $[[FP]]
263 ; CHECK-NOT: set_local [[FP]],
264
265 ; CHECK: get_local $push[[L12:.+]]=, [[FP]]
266 ; CHECK-NEXT: set_global 0, $pop[[L12]]
267267 ret void
268268 }
269269
277277 %addr = alloca i32
278278 ; CHECK: i32.const $push[[OFF:.+]]=, 12
279279 ; CHECK-NEXT: i32.add $push[[ADDR:.+]]=, $pop[[L3]], $pop[[OFF]]
280 ; CHECK-NEXT: copy_local [[COPY:.+]]=, $pop[[ADDR]]
280 ; CHECK-NEXT: set_local [[COPY:.+]], $pop[[ADDR]]
281281 br label %body
282282 body:
283283 %a = phi i32* [%addr, %entry], [%b, %body]
284284 store i32 1, i32* %a
285 ; CHECK: i32.store 0([[COPY]]),
285 ; CHECK: get_local $push[[L12:.+]]=, [[COPY]]
286 ; CHECK: i32.store 0($pop[[L12]]),
286287 br i1 %cond, label %body, label %exit
287288 exit:
288289 ret void
293294
294295 ; Test __builtin_frame_address(0).
295296 ; CHECK-LABEL: frameaddress_0:
296 ; CHECK: i32.const $push[[L0:.+]]=, 0{{$}}
297 ; CHECK-NEXT: i32.load $push[[L3:.+]]=, __stack_pointer($pop[[L0]])
298 ; CHECK-NEXT: copy_local $push[[L4:.+]]=, $pop[[L3]]{{$}}
299 ; CHECK-NEXT: tee_local $push[[L2:.+]]=, $[[FP:.+]]=, $pop[[L4]]{{$}}
297 ; CHECK: get_global $push[[L3:.+]]=, 0{{$}}
298 ; CHECK-NEXT: tee_local $push[[L2:.+]]=, [[FP:.+]], $pop[[L3]]{{$}}
300299 ; CHECK-NEXT: call use_i8_star@FUNCTION, $pop[[L2]]
301 ; CHECK-NEXT: i32.const $push[[L1:.+]]=, 0{{$}}
302 ; CHECK-NEXT: i32.store __stack_pointer($pop[[L1]]), $[[FP]]
300 ; CHECK-NEXT: get_local $push[[L5:.+]]=, [[FP]]
301 ; CHECK-NEXT: set_global 0, $pop[[L5]]
303302 define void @frameaddress_0() {
304303 %t = call i8* @llvm.frameaddress(i32 0)
305304 call void @use_i8_star(i8* %t)
320319
321320 ; Test a stack address passed to an inline asm.
322321 ; CHECK-LABEL: inline_asm:
323 ; CHECK: __stack_pointer
322 ; CHECK: get_global {{.+}}, 0{{$}}
324323 ; CHECK: #APP
325324 ; CHECK-NEXT: # %{{[0-9]+}}{{$}}
326325 ; CHECK-NEXT: #NO_APP
None ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -verify-machineinstrs | FileCheck %s
0 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -verify-machineinstrs | FileCheck %s
11
22 ; Test varargs constructs.
33
44 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
5 target triple = "wasm32-unknown-unknown"
5 target triple = "wasm32-unknown-unknown-wasm"
66
77 ; Test va_start.
88
5151 ; CHECK-LABEL: arg_i8:
5252 ; CHECK-NEXT: .param i32{{$}}
5353 ; CHECK-NEXT: .result i32{{$}}
54 ; CHECK-NEXT: .local i32{{$}}
5554 ; CHECK-NEXT: i32.load $push[[NUM0:[0-9]+]]=, 0($0){{$}}
5655 ; CHECK-NEXT: tee_local $push[[NUM1:[0-9]+]]=, $1=, $pop[[NUM0]]{{$}}
5756 ; CHECK-NEXT: i32.const $push[[NUM2:[0-9]+]]=, 4{{$}}
7069 ; CHECK-LABEL: arg_i32:
7170 ; CHECK-NEXT: .param i32{{$}}
7271 ; CHECK-NEXT: .result i32{{$}}
73 ; CHECK-NEXT: .local i32{{$}}
7472 ; CHECK-NEXT: i32.load $push[[NUM0:[0-9]+]]=, 0($0){{$}}
7573 ; CHECK-NEXT: i32.const $push[[NUM1:[0-9]+]]=, 3{{$}}
7674 ; CHECK-NEXT: i32.add $push[[NUM2:[0-9]+]]=, $pop[[NUM0]], $pop[[NUM1]]{{$}}
9290
9391 ; CHECK-LABEL: arg_i128:
9492 ; CHECK-NEXT: .param i32, i32{{$}}
95 ; CHECK-NEXT: .local
9693 ; CHECK: i32.and
9794 ; CHECK: i64.load
9895 ; CHECK: i64.load
122119 ; disabling it.
123120
124121 ; CHECK-LABEL: caller_some
125 ; CHECK: i32.store
126 ; CHECK: i64.store
122 ; CHECK-DAG: i32.store
123 ; CHECK-DAG: i64.store
127124 define void @caller_some() {
128125 call void (...) @callee(i32 0, double 2.0)
129126 ret void
None ; RUN: llc < %s -asm-verbose=false | FileCheck %s --check-prefix=TYPEINFONAME
1 ; RUN: llc < %s -asm-verbose=false | FileCheck %s --check-prefix=VTABLE
2 ; RUN: llc < %s -asm-verbose=false | FileCheck %s --check-prefix=TYPEINFO
0 ; RUN: llc < %s -asm-verbose=false -disable-wasm-explicit-locals | FileCheck %s --check-prefix=TYPEINFONAME
1 ; RUN: llc < %s -asm-verbose=false -disable-wasm-explicit-locals | FileCheck %s --check-prefix=VTABLE
2 ; RUN: llc < %s -asm-verbose=false -disable-wasm-explicit-locals | FileCheck %s --check-prefix=TYPEINFO
33
44 ; Test that simple vtables assemble as expected.
55 ;
1111 ; Each with a virtual dtor and method foo.
1212
1313 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
14 target triple = "wasm32-unknown-unknown"
14 target triple = "wasm32-unknown-unknown-wasm"
1515
1616 %struct.A = type { i32 (...)** }
1717 %struct.B = type { %struct.A }
3535 @_ZTS1D = constant [3 x i8] c"1D\00"
3636
3737 ; VTABLE: .type _ZTV1A,@object
38 ; VTABLE-NEXT: .section .data.rel.ro,"aw",@progbits
38 ; VTABLE-NEXT: .section .data.rel.ro._ZTV1A,
3939 ; VTABLE-NEXT: .globl _ZTV1A
4040 ; VTABLE-LABEL: _ZTV1A:
4141 ; VTABLE-NEXT: .int32 0
4646 ; VTABLE-NEXT: .size _ZTV1A, 20
4747 @_ZTV1A = constant [5 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTI1A to i8*), i8* bitcast (%struct.A* (%struct.A*)* @_ZN1AD2Ev to i8*), i8* bitcast (void (%struct.A*)* @_ZN1AD0Ev to i8*), i8* bitcast (void (%struct.A*)* @_ZN1A3fooEv to i8*)], align 4
4848 ; VTABLE: .type _ZTV1B,@object
49 ; VTABLE-NEXT: .section .data.rel.ro._ZTV1B,
4950 ; VTABLE-NEXT: .globl _ZTV1B
5051 ; VTABLE-LABEL: _ZTV1B:
5152 ; VTABLE-NEXT: .int32 0
5657 ; VTABLE-NEXT: .size _ZTV1B, 20
5758 @_ZTV1B = constant [5 x i8*] [i8* null, i8* bitcast ({ i8*, i8*, i8* }* @_ZTI1B to i8*), i8* bitcast (%struct.A* (%struct.A*)* @_ZN1AD2Ev to i8*), i8* bitcast (void (%struct.B*)* @_ZN1BD0Ev to i8*), i8* bitcast (void (%struct.B*)* @_ZN1B3fooEv to i8*)], align 4
5859 ; VTABLE: .type _ZTV1C,@object
60 ; VTABLE-NEXT: .section .data.rel.ro._ZTV1C,
5961 ; VTABLE-NEXT: .globl _ZTV1C
6062 ; VTABLE-LABEL: _ZTV1C:
6163 ; VTABLE-NEXT: .int32 0
6668 ; VTABLE-NEXT: .size _ZTV1C, 20
6769 @_ZTV1C = constant [5 x i8*] [i8* null, i8* bitcast ({ i8*, i8*, i8* }* @_ZTI1C to i8*), i8* bitcast (%struct.A* (%struct.A*)* @_ZN1AD2Ev to i8*), i8* bitcast (void (%struct.C*)* @_ZN1CD0Ev to i8*), i8* bitcast (void (%struct.C*)* @_ZN1C3fooEv to i8*)], align 4
6870 ; VTABLE: .type _ZTV1D,@object
71 ; VTABLE-NEXT: .section .data.rel.ro._ZTV1D,
6972 ; VTABLE-NEXT: .globl _ZTV1D
7073 ; VTABLE-LABEL: _ZTV1D:
7174 ; VTABLE-NEXT: .int32 0
None ; RUN: llc < %s -verify-machineinstrs -mtriple=wasm32-unknown-unknown | FileCheck %s
1 ; RUN: llc < %s -verify-machineinstrs -mtriple=wasm32-unknown-unknown -fast-isel | FileCheck --check-prefix=CHECK-FAST %s
0 ; RUN: llc < %s -verify-machineinstrs -mtriple=wasm32-unknown-unknown-wasm | FileCheck %s
1 ; RUN: llc < %s -verify-machineinstrs -mtriple=wasm32-unknown-unknown-wasm -fast-isel | FileCheck --check-prefix=CHECK-FAST %s
22 ; CHECK: #DEBUG_VALUE: decode:i <- [%vreg
33 ; CHECK: #DEBUG_VALUE: decode:v <- [%vreg
44 ; CHECK: DW_TAG_variable
88
99 source_filename = "test/DebugInfo/WebAssembly/dbg-declare.ll"
1010 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
11 target triple = "wasm32-unknown-unknown"
11 target triple = "wasm32-unknown-unknown-wasm"
1212
1313 @key = external global [15 x i8], align 1
1414