1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 11:02:59 +02:00

[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.

llvm-svn: 296540
This commit is contained in:
Dan Gohman 2017-02-28 23:37:04 +00:00
parent 482a2e2483
commit 4c8bd4af88
38 changed files with 261 additions and 221 deletions

View File

@ -150,3 +150,19 @@ Add support for mergeable sections in the Wasm writer, such as for strings and
floating-point constants.
//===---------------------------------------------------------------------===//
The function @dynamic_alloca_redzone in test/CodeGen/WebAssembly/userstack.ll
ends up with a tee_local in its prolog which has an unused result, requiring
an extra drop:
get_global $push8=, 0
tee_local $push9=, 1, $pop8
drop $pop9
[...]
The prologue code initially thinks it needs an FP register, but later it
turns out to be unneeded, so one could either approach this by being more
clever about not inserting code for an FP in the first place, or optimizing
away the copy later.
//===---------------------------------------------------------------------===//

View File

@ -31,6 +31,14 @@ using namespace llvm;
#define DEBUG_TYPE "wasm-explicit-locals"
// A command-line option to disable this pass. Note that this produces output
// which is not valid WebAssembly, though it may be more convenient for writing
// LLVM unit tests with.
static cl::opt<bool> DisableWebAssemblyExplicitLocals(
"disable-wasm-explicit-locals", cl::ReallyHidden,
cl::desc("WebAssembly: Disable emission of get_local/set_local."),
cl::init(false));
namespace {
class WebAssemblyExplicitLocals final : public MachineFunctionPass {
StringRef getPassName() const override {
@ -164,6 +172,10 @@ bool WebAssemblyExplicitLocals::runOnMachineFunction(MachineFunction &MF) {
"********** Function: "
<< MF.getName() << '\n');
// Disable this pass if directed to do so.
if (DisableWebAssemblyExplicitLocals)
return false;
// Disable this pass if we aren't doing direct wasm object emission.
if (MF.getSubtarget<WebAssemblySubtarget>()
.getTargetTriple().isOSBinFormatELF())

View File

@ -1,10 +1,10 @@
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
; Test folding constant offsets and symbols into load and store addresses under
; a variety of circumstances.
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
target triple = "wasm32-unknown-unknown-wasm"
@g = external global [0 x i32], align 4

View File

@ -1,8 +1,8 @@
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -verify-machineinstrs | FileCheck %s
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -verify-machineinstrs -fast-isel | FileCheck %s
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -verify-machineinstrs | FileCheck %s
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -verify-machineinstrs -fast-isel | FileCheck %s
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
target triple = "wasm32-unknown-unknown-wasm"
%SmallStruct = type { i32 }
%OddStruct = type { i32, i8, i32 }
@ -23,15 +23,13 @@ declare void @ext_byval_func_empty(%EmptyStruct* byval)
; CHECK-LABEL: byval_arg
define void @byval_arg(%SmallStruct* %ptr) {
; CHECK: .param i32
; CHECK: i32.const $push[[L4:.+]]=, 0
; Subtract 16 from SP (SP is 16-byte aligned)
; CHECK: i32.const $push[[L1:.+]]=, 0
; CHECK-NEXT: i32.load $push[[L2:.+]]=, __stack_pointer($pop[[L1]])
; CHECK-NEXT: get_global $push[[L2:.+]]=, 0
; CHECK-NEXT: i32.const $push[[L3:.+]]=, 16
; CHECK-NEXT: i32.sub $push[[L11:.+]]=, $pop[[L2]], $pop[[L3]]
; Ensure SP is stored back before the call
; CHECK-NEXT: tee_local $push[[L10:.+]]=, $[[SP:.+]]=, $pop[[L11]]{{$}}
; CHECK-NEXT: i32.store __stack_pointer($pop[[L4]]), $pop[[L10]]{{$}}
; CHECK-NEXT: set_global 0, $pop[[L10]]{{$}}
; Copy the SmallStruct argument to the stack (SP+12, original SP-4)
; CHECK-NEXT: i32.load $push[[L0:.+]]=, 0($0)
; CHECK-NEXT: i32.store 12($[[SP]]), $pop[[L0]]
@ -41,10 +39,9 @@ define void @byval_arg(%SmallStruct* %ptr) {
; CHECK-NEXT: call ext_byval_func@FUNCTION, $pop[[ARG]]{{$}}
call void @ext_byval_func(%SmallStruct* byval %ptr)
; Restore the stack
; CHECK-NEXT: i32.const $push[[L7:.+]]=, 0
; CHECK-NEXT: i32.const $push[[L6:.+]]=, 16
; CHECK-NEXT: i32.add $push[[L8:.+]]=, $[[SP]], $pop[[L6]]
; CHECK-NEXT: i32.store __stack_pointer($pop[[L7]]), $pop[[L8]]
; CHECK-NEXT: set_global 0, $pop[[L8]]
; CHECK-NEXT: return
ret void
}
@ -56,7 +53,7 @@ define void @byval_arg_align8(%SmallStruct* %ptr) {
; CHECK: i32.const $push[[L1:.+]]=, 16
; CHECK-NEXT: i32.sub $push[[L11:.+]]=, {{.+}}, $pop[[L1]]
; CHECK-NEXT: tee_local $push[[L10:.+]]=, $[[SP:.+]]=, $pop[[L11]]{{$}}
; CHECK-NEXT: i32.store __stack_pointer($pop{{.+}}), $pop[[L10]]{{$}}
; CHECK-NEXT: set_global 0, $pop[[L10]]{{$}}
; Copy the SmallStruct argument to the stack (SP+8, original SP-8)
; CHECK-NEXT: i32.load $push[[L0:.+]]=, 0($0){{$}}
; CHECK-NEXT: i32.store 8($[[SP]]), $pop[[L0]]{{$}}
@ -75,7 +72,7 @@ define void @byval_arg_double(%AlignedStruct* %ptr) {
; CHECK: i32.const $push[[L1:.+]]=, 16
; CHECK-NEXT: i32.sub $push[[L14:.+]]=, {{.+}}, $pop[[L1]]
; CHECK-NEXT: tee_local $push[[L13:.+]]=, $[[SP:.+]]=, $pop[[L14]]
; CHECK-NEXT: i32.store {{.+}}, $pop[[L13]]
; CHECK-NEXT: set_global 0, $pop[[L13]]
; Copy the AlignedStruct argument to the stack (SP+0, original SP-16)
; Just check the last load/store pair of the memcpy
; CHECK: i64.load $push[[L4:.+]]=, 0($0)
@ -113,13 +110,11 @@ define void @byval_empty_callee(%EmptyStruct* byval %ptr) {
; Call memcpy for "big" byvals.
; CHECK-LABEL: big_byval:
; CHECK: i32.const $push[[L4:.+]]=, 0
; CHECK: i32.const $push[[L1:.+]]=, 0
; CHECK-NEXT: i32.load $push[[L2:.+]]=, __stack_pointer($pop[[L1]])
; CHECK: get_global $push[[L2:.+]]=, 0{{$}}
; CHECK-NEXT: i32.const $push[[L3:.+]]=, 131072
; CHECK-NEXT: i32.sub $push[[L11:.+]]=, $pop[[L2]], $pop[[L3]]
; CHECK-NEXT: tee_local $push[[L10:.+]]=, $[[SP:.+]]=, $pop[[L11]]{{$}}
; CHECK-NEXT: i32.store __stack_pointer($pop[[L4]]), $pop[[L10]]{{$}}
; CHECK-NEXT: set_global 0, $pop[[L10]]{{$}}
; CHECK-NEXT: i32.const $push[[L0:.+]]=, 131072
; CHECK-NEXT: i32.call $push[[L11:.+]]=, memcpy@FUNCTION, $[[SP]], ${{.+}}, $pop{{.+}}
; CHECK-NEXT: tee_local $push[[L9:.+]]=, $[[SP:.+]]=, $pop[[L11]]{{$}}

View File

@ -1,5 +1,5 @@
; 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
; 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
; 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
; 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
; Test the CFG stackifier pass.
@ -7,7 +7,7 @@
; optnone test.
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
target triple = "wasm32-unknown-unknown-wasm"
declare void @something()
@ -1144,7 +1144,6 @@ bb7:
; optnone to disable optimizations to test this case.
; CHECK-LABEL: test13:
; CHECK-NEXT: .local i32{{$}}
; CHECK-NEXT: block {{$}}
; CHECK-NEXT: block {{$}}
; CHECK: br_if 0, $pop0{{$}}
@ -1161,7 +1160,6 @@ bb7:
; CHECK-NEXT: end_block{{$}}
; CHECK-NEXT: unreachable{{$}}
; OPT-LABEL: test13:
; OPT-NEXT: .local i32{{$}}
; OPT-NEXT: block {{$}}
; OPT-NEXT: block {{$}}
; OPT: br_if 0, $pop0{{$}}

View File

@ -1,9 +1,9 @@
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
; Test that basic conversion operations assemble as expected.
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
target triple = "wasm32-unknown-unknown-wasm"
; CHECK-LABEL: i32_wrap_i64:
; CHECK-NEXT: .param i64{{$}}

View File

@ -1,13 +1,13 @@
; This tests that llc accepts all valid WebAssembly CPUs.
; RUN: llc < %s -asm-verbose=false -mtriple=wasm32-unknown-unknown -mcpu=mvp 2>&1 | FileCheck %s
; RUN: llc < %s -asm-verbose=false -mtriple=wasm64-unknown-unknown -mcpu=mvp 2>&1 | FileCheck %s
; RUN: llc < %s -asm-verbose=false -mtriple=wasm32-unknown-unknown -mcpu=generic 2>&1 | FileCheck %s
; RUN: llc < %s -asm-verbose=false -mtriple=wasm64-unknown-unknown -mcpu=generic 2>&1 | FileCheck %s
; RUN: llc < %s -asm-verbose=false -mtriple=wasm32-unknown-unknown -mcpu=bleeding-edge 2>&1 | FileCheck %s
; RUN: llc < %s -asm-verbose=false -mtriple=wasm64-unknown-unknown -mcpu=bleeding-edge 2>&1 | FileCheck %s
; RUN: llc < %s -asm-verbose=false -mtriple=wasm32-unknown-unknown -mcpu=invalidcpu 2>&1 | FileCheck %s --check-prefix=INVALID
; RUN: llc < %s -asm-verbose=false -mtriple=wasm64-unknown-unknown -mcpu=invalidcpu 2>&1 | FileCheck %s --check-prefix=INVALID
; RUN: llc < %s -asm-verbose=false -mtriple=wasm32-unknown-unknown-wasm -mcpu=mvp 2>&1 | FileCheck %s
; RUN: llc < %s -asm-verbose=false -mtriple=wasm64-unknown-unknown-wasm -mcpu=mvp 2>&1 | FileCheck %s
; RUN: llc < %s -asm-verbose=false -mtriple=wasm32-unknown-unknown-wasm -mcpu=generic 2>&1 | FileCheck %s
; RUN: llc < %s -asm-verbose=false -mtriple=wasm64-unknown-unknown-wasm -mcpu=generic 2>&1 | FileCheck %s
; RUN: llc < %s -asm-verbose=false -mtriple=wasm32-unknown-unknown-wasm -mcpu=bleeding-edge 2>&1 | FileCheck %s
; RUN: llc < %s -asm-verbose=false -mtriple=wasm64-unknown-unknown-wasm -mcpu=bleeding-edge 2>&1 | FileCheck %s
; RUN: llc < %s -asm-verbose=false -mtriple=wasm32-unknown-unknown-wasm -mcpu=invalidcpu 2>&1 | FileCheck %s --check-prefix=INVALID
; RUN: llc < %s -asm-verbose=false -mtriple=wasm64-unknown-unknown-wasm -mcpu=invalidcpu 2>&1 | FileCheck %s --check-prefix=INVALID
; CHECK-NOT: is not a recognized processor for this target
; INVALID: {{.+}} is not a recognized processor for this target

View File

@ -1,4 +1,4 @@
; RUN: llc < %s -O0 -verify-machineinstrs -mtriple=wasm32-unknown-unknown | FileCheck %s
; RUN: llc < %s -O0 -verify-machineinstrs -mtriple=wasm32-unknown-unknown-wasm | FileCheck %s
; CHECK: BB#0
; CHECK: #DEBUG_VALUE: usage:self <- %vreg4

View File

@ -1,9 +1,10 @@
; RUN: llc < %s -asm-verbose=false \
; RUN: -fast-isel -fast-isel-abort=1 -verify-machineinstrs \
; RUN: -disable-wasm-explicit-locals \
; RUN: | FileCheck %s
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
target triple = "wasm32-unknown-unknown-wasm"
; This tests very minimal fast-isel functionality.

View File

@ -1,9 +1,9 @@
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
; Test that the frem instruction works.
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
target triple = "wasm32-unknown-unknown-wasm"
; CHECK-LABEL: frem32:
; CHECK-NEXT: .param f32, f32{{$}}

View File

@ -1,13 +1,13 @@
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
; Test that basic functions assemble as expected.
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
target triple = "wasm32-unknown-unknown-wasm"
; CHECK-LABEL: f0:
; CHECK: return{{$}}
; CHECK: .endfunc{{$}}
; CHECK: end_function{{$}}
; CHECK: .size f0,
define void @f0() {
ret void

View File

@ -1,9 +1,9 @@
; RUN: llc < %s -asm-verbose=false | FileCheck %s
; RUN: llc < %s -asm-verbose=false -disable-wasm-explicit-locals | FileCheck %s
; Test that function pointer casts are replaced with wrappers.
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
target triple = "wasm32-unknown-unknown-wasm"
; CHECK-LABEL: test:
; CHECK-NEXT: call .Lbitcast@FUNCTION{{$}}
@ -20,11 +20,10 @@ target triple = "wasm32-unknown-unknown"
; CHECK-NEXT: call foo2@FUNCTION{{$}}
; CHECK-NEXT: call foo1@FUNCTION{{$}}
; CHECK-NEXT: call foo3@FUNCTION{{$}}
; CHECK-NEXT: .endfunc
; CHECK-NEXT: end_function
; CHECK-LABEL: test_varargs:
; CHECK-NEXT: .local i32
; CHECK: store
; CHECK: set_global
; CHECK: i32.const $push[[L3:[0-9]+]]=, 0{{$}}
; CHECK-NEXT: call vararg@FUNCTION, $pop[[L3]]{{$}}
; CHECK-NEXT: i32.const $push[[L4:[0-9]+]]=, 0{{$}}
@ -32,25 +31,23 @@ target triple = "wasm32-unknown-unknown"
; CHECK-NEXT: call plain@FUNCTION, $[[L5]]{{$}}
; CHECK-LABEL: .Lbitcast:
; CHECK-NEXT: .local i32
; CHECK-NEXT: call has_i32_arg@FUNCTION, $0{{$}}
; CHECK-NEXT: .endfunc
; CHECK-NEXT: end_function
; CHECK-LABEL: .Lbitcast.1:
; CHECK-NEXT: call $drop=, has_i32_ret@FUNCTION{{$}}
; CHECK-NEXT: .endfunc
; CHECK-NEXT: end_function
; CHECK-LABEL: .Lbitcast.2:
; CHECK-NEXT: .param i32
; CHECK-NEXT: call foo0@FUNCTION{{$}}
; CHECK-NEXT: .endfunc
; CHECK-NEXT: end_function
; CHECK-LABEL: .Lbitcast.3:
; CHECK-NEXT: .result i32
; CHECK-NEXT: .local i32
; CHECK-NEXT: call foo1@FUNCTION{{$}}
; CHECK-NEXT: copy_local $push0=, $0
; CHECK-NEXT: .endfunc
; CHECK-NEXT: end_function
declare void @has_i32_arg(i32)
declare i32 @has_i32_ret()

View File

@ -1,9 +1,9 @@
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
; Test that globals assemble as expected.
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
target triple = "wasm32-unknown-unknown-wasm"
; CHECK-NOT: llvm.used
; CHECK-NOT: llvm.metadata
@ -42,15 +42,21 @@ define i8* @call_memcpy(i8* %p, i8* nocapture readonly %q, i32 %n) {
@ud = internal global i32 undef
; CHECK: .type nil,@object
; CHECK-NEXT: .lcomm nil,4,2{{$}}
; CHECK: .p2align 2
; CHECK: nil:
; CHECK: .int32 0
; CHECK: .size nil, 4
@nil = internal global i32 zeroinitializer
; CHECK: .type z,@object
; CHECK-NEXT: .lcomm z,4,2{{$}}
; CHECK: .p2align 2
; CHECK: z:
; CHECK: .int32 0
; CHECK: .size z, 4
@z = internal global i32 0
; CHECK-NEXT: .type one,@object
; CHECK-NEXT: .p2align 2{{$}}
; CHECK: .type one,@object
; CHECK: .p2align 2{{$}}
; CHECK-NEXT: one:
; CHECK-NEXT: .int32 1{{$}}
; CHECK-NEXT: .size one, 4{{$}}
@ -78,11 +84,17 @@ define i8* @call_memcpy(i8* %p, i8* nocapture readonly %q, i32 %n) {
@ud64 = internal global i64 undef
; CHECK: .type nil64,@object
; CHECK: .lcomm nil64,8,3{{$}}
; CHECK: .p2align 3{{$}}
; CHECK-NEXT: nil64:
; CHECK-NEXT: .int64 0{{$}}
; CHECK-NEXT: .size nil64, 8{{$}}
@nil64 = internal global i64 zeroinitializer
; CHECK: .type z64,@object
; CHECK: .lcomm z64,8,3{{$}}
; CHECK: .p2align 3{{$}}
; CHECK-NEXT: z64:
; CHECK-NEXT: .int64 0{{$}}
; CHECK-NEXT: .size z64, 8{{$}}
@z64 = internal global i64 0
; CHECK: .type twoP32,@object
@ -107,11 +119,17 @@ define i8* @call_memcpy(i8* %p, i8* nocapture readonly %q, i32 %n) {
@f32ud = internal global float undef
; CHECK: .type f32nil,@object
; CHECK: .lcomm f32nil,4,2{{$}}
; CHECK: .p2align 2{{$}}
; CHECK-NEXT: f32nil:
; CHECK-NEXT: .int32 0{{$}}
; CHECK-NEXT: .size f32nil, 4{{$}}
@f32nil = internal global float zeroinitializer
; CHECK: .type f32z,@object
; CHECK: .lcomm f32z,4,2{{$}}
; CHECK: .p2align 2{{$}}
; CHECK-NEXT: f32z:
; CHECK-NEXT: .int32 0{{$}}
; CHECK-NEXT: .size f32z, 4{{$}}
@f32z = internal global float 0.0
; CHECK: .type f32nz,@object
@ -136,11 +154,17 @@ define i8* @call_memcpy(i8* %p, i8* nocapture readonly %q, i32 %n) {
@f64ud = internal global double undef
; CHECK: .type f64nil,@object
; CHECK: .lcomm f64nil,8,3{{$}}
; CHECK: .p2align 3{{$}}
; CHECK-NEXT: f64nil:
; CHECK-NEXT: .int64 0{{$}}
; CHECK-NEXT: .size f64nil, 8{{$}}
@f64nil = internal global double zeroinitializer
; CHECK: .type f64z,@object
; CHECK: .lcomm f64z,8,3{{$}}
; CHECK: .p2align 3{{$}}
; CHECK-NEXT: f64z:
; CHECK-NEXT: .int64 0{{$}}
; CHECK-NEXT: .size f64z, 8{{$}}
@f64z = internal global double 0.0
; CHECK: .type f64nz,@object
@ -168,7 +192,7 @@ define i8* @call_memcpy(i8* %p, i8* nocapture readonly %q, i32 %n) {
; Constant global.
; CHECK: .type rom,@object{{$}}
; CHECK: .section .rodata,"a",@progbits{{$}}
; CHECK: .section .rodata.rom,
; CHECK: .globl rom{{$}}
; CHECK: .p2align 4{{$}}
; CHECK: rom:
@ -177,11 +201,11 @@ define i8* @call_memcpy(i8* %p, i8* nocapture readonly %q, i32 %n) {
@rom = constant [128 x i32] zeroinitializer, align 16
; CHECK: .type array,@object
; CHECK-NEXT: array:
; CHECK: array:
; CHECK-NEXT: .skip 8
; CHECK-NEXT: .size array, 8
; CHECK: .type pointer_to_array,@object
; CHECK-NEXT: .section .data.rel.ro,"aw",@progbits
; CHECK-NEXT: .section .data.rel.ro.pointer_to_array,
; CHECK-NEXT: .globl pointer_to_array
; CHECK-NEXT: .p2align 2
; CHECK-NEXT: pointer_to_array:

View File

@ -1,9 +1,9 @@
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
; Test loads and stores with custom alignment values.
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
target triple = "wasm32-unknown-unknown-wasm"
; CHECK-LABEL: ldi32_a1:
; CHECK-NEXT: .param i32{{$}}

View File

@ -1,9 +1,9 @@
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
; Test loads and stores with custom alignment values.
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
target triple = "wasm32-unknown-unknown-wasm"
; CHECK-LABEL: ldi64_a1:
; CHECK-NEXT: .param i32{{$}}

View File

@ -1,10 +1,10 @@
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -no-integrated-as | FileCheck %s
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -no-integrated-as | FileCheck %s
; Test basic inline assembly. Pass -no-integrated-as since these aren't
; actually valid assembly syntax.
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
target triple = "wasm32-unknown-unknown-wasm"
; CHECK-LABEL: foo:
; CHECK-NEXT: .param i32{{$}}
@ -33,7 +33,6 @@ entry:
; CHECK-LABEL: imm:
; CHECK-NEXT: .result i32{{$}}
; CHECK-NEXT: .local i32{{$}}
; CHECK-NEXT: #APP{{$}}
; CHECK-NEXT: # $0 = ccc(42){{$}}
; CHECK-NEXT: #NO_APP{{$}}

View File

@ -1,9 +1,9 @@
; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-block-placement | FileCheck %s
; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-block-placement -disable-wasm-explicit-locals | FileCheck %s
; Test irreducible CFG handling.
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
target triple = "wasm32-unknown-unknown-wasm"
; A simple loop with two entries.

View File

@ -1,9 +1,9 @@
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
; Test various types and operators that need to be legalized.
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
target triple = "wasm32-unknown-unknown-wasm"
; CHECK-LABEL: shl_i3:
; CHECK: i32.const $push0=, 7{{$}}

View File

@ -1,9 +1,9 @@
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
; Test that extending loads are assembled properly.
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
target triple = "wasm32-unknown-unknown-wasm"
; CHECK-LABEL: sext_i8_i32:
; CHECK: i32.load8_s $push0=, 0($0){{$}}

View File

@ -1,9 +1,9 @@
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
; Test that i1 extending loads and truncating stores are assembled properly.
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
target triple = "wasm32-unknown-unknown-wasm"
; CHECK-LABEL: load_u_i1_i32:
; CHECK: i32.load8_u $push[[NUM0:[0-9]+]]=, 0($0){{$}}

View File

@ -1,9 +1,9 @@
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -tail-dup-placement=0 | FileCheck %s
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -tail-dup-placement=0 | FileCheck %s
; Test memcpy, memmove, and memset intrinsics.
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
target triple = "wasm32-unknown-unknown-wasm"
declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture readonly, i32, i32, i1)
declare void @llvm.memmove.p0i8.p0i8.i32(i8* nocapture, i8* nocapture readonly, i32, i32, i1)

View File

@ -1,9 +1,9 @@
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
; Test that basic memory operations assemble as expected with 32-bit addresses.
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
target triple = "wasm32-unknown-unknown-wasm"
declare i32 @llvm.wasm.current.memory.i32() nounwind readonly
declare i32 @llvm.wasm.grow.memory.i32(i32) nounwind

View File

@ -1,9 +1,9 @@
; RUN: llc < %s -asm-verbose=false | FileCheck %s
; RUN: llc < %s -asm-verbose=false -disable-wasm-explicit-locals | FileCheck %s
; Test constant load and store address offsets.
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
target triple = "wasm32-unknown-unknown-wasm"
; With an nuw add, we can fold an offset.

View File

@ -1,9 +1,9 @@
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -verify-machineinstrs | FileCheck %s
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -verify-machineinstrs | FileCheck %s
; Test that phis are lowered.
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
target triple = "wasm32-unknown-unknown-wasm"
; Basic phi triangle.

View File

@ -1,9 +1,9 @@
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -verify-machineinstrs | FileCheck %s
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -verify-machineinstrs | FileCheck %s
; Test the register stackifier pass.
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
target triple = "wasm32-unknown-unknown-wasm"
; No because of pointer aliasing.
@ -126,7 +126,6 @@ false:
; CHECK-LABEL: multiple_uses:
; CHECK: .param i32, i32, i32{{$}}
; CHECK-NEXT: .local i32{{$}}
; CHECK-NEXT: block {{$}}
; CHECK-NEXT: i32.load $push[[NUM0:[0-9]+]]=, 0($2){{$}}
; CHECK-NEXT: tee_local $push[[NUM1:[0-9]+]]=, $3=, $pop[[NUM0]]{{$}}
@ -449,8 +448,7 @@ bb10: ; preds = %bb9, %bb
; CHECK-LABEL: stackpointer_dependency:
; CHECK: call {{.+}}, stackpointer_callee@FUNCTION,
; CHECK: i32.const $push[[L0:.+]]=, 0
; CHECK-NEXT: i32.store __stack_pointer($pop[[L0]]),
; CHECK-NEXT: set_global 0,
declare i32 @stackpointer_callee(i8* readnone, i8* readnone)
declare i8* @llvm.frameaddress(i32)
define i32 @stackpointer_dependency(i8* readnone) {

View File

@ -2,13 +2,13 @@
; RUN: llc < %s -asm-verbose=false -fast-isel -fast-isel-abort=1 | FileCheck %s
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
target triple = "wasm32-unknown-unknown-wasm"
; CHECK-LABEL: return_i32:
; CHECK-NEXT: .param i32{{$}}
; CHECK-NEXT: .result i32{{$}}
; CHECK-NEXT: copy_local $push0=, $0
; CHECK-NEXT: .endfunc{{$}}
; CHECK-NEXT: get_local $push0=, 0
; CHECK-NEXT: end_function{{$}}
define i32 @return_i32(i32 %p) {
ret i32 %p
}
@ -19,7 +19,7 @@ define i32 @return_i32(i32 %p) {
; CHECK-NEXT: return $pop[[L0]]{{$}}
; CHECK: store
; CHECK-NEXT: i32.const $push{{[^,]+}}=, 3{{$}}
; CHECK-NEXT: .endfunc{{$}}
; CHECK-NEXT: end_function{{$}}
define i32 @return_i32_twice(i32 %a) {
%b = icmp ne i32 %a, 0
br i1 %b, label %true, label %false

View File

@ -2,10 +2,10 @@
; RUN: llc < %s -asm-verbose=false -fast-isel -fast-isel-abort=1 | FileCheck %s
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
target triple = "wasm32-unknown-unknown-wasm"
; CHECK-LABEL: return_void:
; CHECK-NEXT: .endfunc{{$}}
; CHECK-NEXT: end_function{{$}}
define void @return_void() {
ret void
}
@ -14,7 +14,7 @@ define void @return_void() {
; CHECK: store
; CHECK-NEXT: return{{$}}
; CHECK: store
; CHECK-NEXT: .endfunc{{$}}
; CHECK-NEXT: end_function{{$}}
define void @return_void_twice(i32 %a) {
%b = icmp ne i32 %a, 0
br i1 %b, label %true, label %false

View File

@ -1,9 +1,9 @@
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
; Test that the "returned" attribute is optimized effectively.
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
target triple = "wasm32-unknown-unknown-wasm"
; CHECK-LABEL: _Z3foov:
; CHECK-NEXT: .result i32{{$}}

View File

@ -1,10 +1,10 @@
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -fast-isel -fast-isel-abort=1 | FileCheck %s
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -fast-isel -fast-isel-abort=1 | FileCheck %s
; Test that wasm select instruction is selected from LLVM select instruction.
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
target triple = "wasm32-unknown-unknown-wasm"
; CHECK-LABEL: select_i32_bool:
; CHECK-NEXT: .param i32, i32, i32{{$}}

View File

@ -1,9 +1,9 @@
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
; Test zeroext and signext ABI keywords
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
target triple = "wasm32-unknown-unknown-wasm"
; CHECK-LABEL: z2s_func:
; CHECK-NEXT: .param i32{{$}}

View File

@ -1,12 +1,12 @@
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -mattr=+simd128 | FileCheck %s --check-prefixes CHECK,SIMD128
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -mattr=+simd128 -fast-isel | FileCheck %s --check-prefixes CHECK,SIMD128
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -mattr=-simd128 | FileCheck %s --check-prefixes CHECK,NO-SIMD128
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -mattr=-simd128 -fast-isel | FileCheck %s --check-prefixes CHECK,NO-SIMD128
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -mattr=+simd128 | FileCheck %s --check-prefixes CHECK,SIMD128
; 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
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -mattr=-simd128 | FileCheck %s --check-prefixes CHECK,NO-SIMD128
; 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
; Test that basic SIMD128 arithmetic operations assemble as expected.
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
target triple = "wasm32-unknown-unknown-wasm"
declare i32 @llvm.ctlz.i32(i32, i1)
declare i32 @llvm.cttz.i32(i32, i1)

View File

@ -1,9 +1,9 @@
; RUN: llc < %s -asm-verbose=false | FileCheck %s
; RUN: llc < %s -asm-verbose=false -disable-wasm-explicit-locals | FileCheck %s
; Test that truncating stores are assembled properly.
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
target triple = "wasm32-unknown-unknown-wasm"
; CHECK-LABEL: trunc_i8_i32:
; CHECK: i32.store8 0($0), $1{{$}}

View File

@ -5,13 +5,14 @@
; conversions are implemented.
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
target triple = "wasm32-unknown-unknown-wasm"
; CHECK-LABEL: test:
; CHECK-NEXT: i32.const $push[[L0:[0-9]+]]=, 0{{$}}
; CHECK-NEXT: call has_i64_arg@FUNCTION, $pop[[L0]]{{$}}
; CHECK-NEXT: i32.call $drop=, has_i64_ret@FUNCTION{{$}}
; CHECK-NEXT: .endfunc
; CHECK-NEXT: i32.call $push{{[0-9]+}}=, has_i64_ret@FUNCTION{{$}}
; CHECK-NEXT: drop
; CHECK-NEXT: end_function
; CHECK-NOT: .Lbitcast

View File

@ -1,9 +1,9 @@
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
; Make sure that argument offsets are correct even if some arguments are unused.
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
target triple = "wasm32-unknown-unknown-wasm"
; CHECK-LABEL: unused_first:
; CHECK-NEXT: .param i32, i32{{$}}

View File

@ -1,7 +1,7 @@
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
target triple = "wasm32-unknown-unknown-wasm"
declare void @ext_func(i64* %ptr)
declare void @ext_func_i32(i32* %ptr)
@ -10,39 +10,38 @@ declare void @ext_func_i32(i32* %ptr)
; Check that there is an extra local for the stack pointer.
; CHECK: .local i32{{$}}
define void @alloca32() noredzone {
; CHECK: i32.const $push[[L4:.+]]=, 0{{$}}
; CHECK: i32.const $push[[L1:.+]]=, 0{{$}}
; CHECK-NEXT: i32.load $push[[L2:.+]]=, __stack_pointer($pop[[L1]])
; CHECK-NEXT: get_global $push[[L2:.+]]=, 0{{$}}
; CHECK-NEXT: i32.const $push[[L3:.+]]=, 16
; CHECK-NEXT: i32.sub $push[[L9:.+]]=, $pop[[L2]], $pop[[L3]]
; CHECK-NEXT: tee_local $push[[L8:.+]]=, $[[SP:.+]]=, $pop[[L9]]{{$}}
; CHECK-NEXT: i32.store __stack_pointer($pop[[L4]]), $pop[[L8]]{{$}}
; CHECK-NEXT: tee_local $push[[L8:.+]]=, [[SP:.+]], $pop[[L9]]{{$}}
; CHECK-NEXT: set_global 0, $pop[[L8]]{{$}}
%retval = alloca i32
; CHECK: get_local $push[[L4:.+]]=, [[SP]]{{$}}
; CHECK: i32.const $push[[L0:.+]]=, 0
; CHECK: i32.store 12($[[SP]]), $pop[[L0]]
; CHECK: i32.store 12($pop[[L4]]), $pop[[L0]]
store i32 0, i32* %retval
; CHECK: i32.const $push[[L6:.+]]=, 0
; CHECK: get_local $push[[L6:.+]]=, [[SP]]{{$}}
; CHECK-NEXT: i32.const $push[[L5:.+]]=, 16
; CHECK-NEXT: i32.add $push[[L7:.+]]=, $[[SP]], $pop[[L5]]
; CHECK-NEXT: i32.store __stack_pointer($pop[[L6]]), $pop[[L7]]
; CHECK-NEXT: i32.add $push[[L7:.+]]=, $pop[[L6]], $pop[[L5]]
; CHECK-NEXT: set_global 0, $pop[[L7]]
ret void
}
; CHECK-LABEL: alloca3264:
; CHECK: .local i32{{$}}
define void @alloca3264() {
; CHECK: i32.const $push[[L2:.+]]=, 0{{$}}
; CHECK-NEXT: i32.load $push[[L3:.+]]=, __stack_pointer($pop[[L2]])
; CHECK: get_global $push[[L3:.+]]=, 0{{$}}
; CHECK-NEXT: i32.const $push[[L4:.+]]=, 16
; CHECK-NEXT: i32.sub $push[[L6:.+]]=, $pop[[L3]], $pop[[L4]]
; CHECK-NEXT: tee_local $push[[L5:.+]]=, $[[SP:.+]]=, $pop[[L6]]
; CHECK-NEXT: tee_local $push[[L5:.+]]=, [[SP:.+]], $pop[[L6]]
%r1 = alloca i32
%r2 = alloca double
; CHECK-NEXT: i32.const $push[[L0:.+]]=, 0
; CHECK-NEXT: i32.store 12($pop[[L5]]), $pop[[L0]]
store i32 0, i32* %r1
; CHECK-NEXT: get_local $push[[L2:.+]]=, [[SP]]{{$}}
; CHECK-NEXT: i64.const $push[[L1:.+]]=, 0
; CHECK-NEXT: i64.store 0($[[SP]]), $pop[[L1]]
; CHECK-NEXT: i64.store 0($pop[[L2]]), $pop[[L1]]
store double 0.0, double* %r2
; CHECK-NEXT: return
ret void
@ -51,30 +50,29 @@ define void @alloca3264() {
; CHECK-LABEL: allocarray:
; CHECK: .local i32{{$}}
define void @allocarray() {
; CHECK: i32.const $push[[L6:.+]]=, 0{{$}}
; CHECK: i32.const $push[[L3:.+]]=, 0{{$}}
; CHECK-NEXT: i32.load $push[[L4:.+]]=, __stack_pointer($pop[[L3]])
; CHECK-NEXT: get_global $push[[L4:.+]]=, 0{{$}}
; CHECK-NEXT: i32.const $push[[L5:.+]]=, 144{{$}}
; CHECK-NEXT: i32.sub $push[[L12:.+]]=, $pop[[L4]], $pop[[L5]]
; CHECK-NEXT: tee_local $push[[L11:.+]]=, $0=, $pop[[L12]]
; CHECK-NEXT: i32.store __stack_pointer($pop[[L6]]), $pop[[L11]]
; CHECK-NEXT: tee_local $push[[L11:.+]]=, 0, $pop[[L12]]
; CHECK-NEXT: set_global 0, $pop[[L11]]
%r = alloca [33 x i32]
; CHECK: i32.const $push{{.+}}=, 24
; CHECK-NEXT: i32.add $push[[L3:.+]]=, $[[SP]], $pop{{.+}}
; CHECK-NEXT: i32.add $push[[L3:.+]]=, $pop{{.+}}, $pop{{.+}}
; CHECK-NEXT: i32.const $push[[L1:.+]]=, 1{{$}}
; CHECK-NEXT: i32.store 0($pop[[L3]]), $pop[[L1]]{{$}}
; CHECK-NEXT: get_local $push[[L4:.+]]=, 0{{$}}
; CHECK-NEXT: i32.const $push[[L10:.+]]=, 1{{$}}
; CHECK-NEXT: i32.store 12(${{.+}}), $pop[[L10]]{{$}}
; CHECK-NEXT: i32.store 12($pop[[L4]]), $pop[[L10]]{{$}}
%p = getelementptr [33 x i32], [33 x i32]* %r, i32 0, i32 0
store i32 1, i32* %p
%p2 = getelementptr [33 x i32], [33 x i32]* %r, i32 0, i32 3
store i32 1, i32* %p2
; CHECK: i32.const $push[[L9:.+]]=, 0{{$}}
; CHECK-NEXT: get_local $push[[L2:.+]]=, [[SP]]{{$}}
; CHECK-NEXT: i32.const $push[[L7:.+]]=, 144
; CHECK-NEXT: i32.add $push[[L8:.+]]=, $[[SP]], $pop[[L7]]
; CHECK-NEXT: i32.store __stack_pointer($pop[[L9]]), $pop[[L8]]
; CHECK-NEXT: i32.add $push[[L8:.+]]=, $pop[[L2]], $pop[[L7]]
; CHECK-NEXT: set_global 0, $pop[[L8]]
ret void
}
@ -82,24 +80,27 @@ define void @allocarray() {
define void @non_mem_use(i8** %addr) {
; CHECK: i32.const $push[[L2:.+]]=, 48
; CHECK-NEXT: i32.sub $push[[L12:.+]]=, {{.+}}, $pop[[L2]]
; CHECK-NEXT: tee_local $push[[L11:.+]]=, $[[SP:.+]]=, $pop[[L12]]
; CHECK-NEXT: i32.store {{.+}}, $pop[[L11]]
; CHECK-NEXT: tee_local $push[[L11:.+]]=, [[SP:.+]], $pop[[L12]]
; CHECK-NEXT: set_global 0, $pop[[L11]]
%buf = alloca [27 x i8], align 16
%r = alloca i64
%r2 = alloca i64
; %r is at SP+8
; CHECK: get_local $push[[L3:.+]]=, [[SP]]
; CHECK: i32.const $push[[OFF:.+]]=, 8
; CHECK-NEXT: i32.add $push[[ARG1:.+]]=, $[[SP]], $pop[[OFF]]
; CHECK-NEXT: i32.add $push[[ARG1:.+]]=, $pop[[L3]], $pop[[OFF]]
; CHECK-NEXT: call ext_func@FUNCTION, $pop[[ARG1]]
call void @ext_func(i64* %r)
; %r2 is at SP+0, no add needed
; CHECK-NEXT: call ext_func@FUNCTION, $[[SP]]
; CHECK: get_local $push[[L4:.+]]=, [[SP]]
; CHECK-NEXT: call ext_func@FUNCTION, $pop[[L4]]
call void @ext_func(i64* %r2)
; Use as a value, but in a store
; %buf is at SP+16
; CHECK: get_local $push[[L5:.+]]=, [[SP]]
; CHECK: i32.const $push[[OFF:.+]]=, 16
; CHECK-NEXT: i32.add $push[[VAL:.+]]=, $[[SP]], $pop[[OFF]]
; CHECK-NEXT: i32.store 0($0), $pop[[VAL]]
; CHECK-NEXT: i32.add $push[[VAL:.+]]=, $pop[[L5]], $pop[[OFF]]
; CHECK-NEXT: i32.store 0($pop{{.+}}), $pop[[VAL]]
%gep = getelementptr inbounds [27 x i8], [27 x i8]* %buf, i32 0, i32 0
store i8* %gep, i8** %addr
ret void
@ -108,13 +109,11 @@ define void @non_mem_use(i8** %addr) {
; CHECK-LABEL: allocarray_inbounds:
; CHECK: .local i32{{$}}
define void @allocarray_inbounds() {
; CHECK: i32.const $push[[L5:.+]]=, 0{{$}}
; CHECK: i32.const $push[[L2:.+]]=, 0{{$}}
; CHECK-NEXT: i32.load $push[[L3:.+]]=, __stack_pointer($pop[[L2]])
; CHECK: get_global $push[[L3:.+]]=, 0{{$}}
; CHECK-NEXT: i32.const $push[[L4:.+]]=, 32{{$}}
; CHECK-NEXT: i32.sub $push[[L11:.+]]=, $pop[[L3]], $pop[[L4]]
; CHECK-NEXT: tee_local $push[[L10:.+]]=, $[[SP:.+]]=, $pop[[L11]]
; CHECK-NEXT: i32.store __stack_pointer($pop[[L5]]), $pop[[L10]]{{$}}
; CHECK-NEXT: tee_local $push[[L10:.+]]=, [[SP:.+]], $pop[[L11]]
; CHECK-NEXT: set_global 0, $pop[[L10]]{{$}}
%r = alloca [5 x i32]
; CHECK: i32.const $push[[L3:.+]]=, 1
; CHECK-DAG: i32.store 24(${{.+}}), $pop[[L3]]
@ -126,45 +125,39 @@ define void @allocarray_inbounds() {
store i32 1, i32* %p2
call void @ext_func(i64* null);
; CHECK: call ext_func
; CHECK: i32.const $push[[L6:.+]]=, 0{{$}}
; CHECK-NEXT: i32.const $push[[L5:.+]]=, 32{{$}}
; CHECK: i32.const $push[[L5:.+]]=, 32{{$}}
; CHECK-NEXT: i32.add $push[[L7:.+]]=, ${{.+}}, $pop[[L5]]
; CHECK-NEXT: i32.store __stack_pointer($pop[[L6]]), $pop[[L7]]
; CHECK-NEXT: set_global 0, $pop[[L7]]
ret void
}
; CHECK-LABEL: dynamic_alloca:
define void @dynamic_alloca(i32 %alloc) {
; CHECK: i32.const $push[[L7:.+]]=, 0{{$}}
; CHECK: i32.const $push[[L1:.+]]=, 0{{$}}
; CHECK-NEXT: i32.load $push[[L13:.+]]=, __stack_pointer($pop[[L1]])
; CHECK: get_global $push[[L13:.+]]=, 0{{$}}
; CHECK-NEXT: tee_local $push[[L12:.+]]=, [[SP:.+]], $pop[[L13]]{{$}}
; Target independent codegen bumps the stack pointer.
; CHECK: i32.sub
; Check that SP is written back to memory after decrement
; CHECK: i32.store __stack_pointer($pop{{.+}}),
; CHECK: set_global 0,
%r = alloca i32, i32 %alloc
; Target-independent codegen also calculates the store addr
; CHECK: call ext_func_i32@FUNCTION
call void @ext_func_i32(i32* %r)
; CHECK: i32.const $push[[L3:.+]]=, 0{{$}}
; CHECK: i32.store __stack_pointer($pop[[L3]]), $pop{{.+}}
; CHECK: set_global 0, $pop{{.+}}
ret void
}
; CHECK-LABEL: dynamic_alloca_redzone:
define void @dynamic_alloca_redzone(i32 %alloc) {
; CHECK: i32.const $push[[L8:.+]]=, 0{{$}}
; CHECK-NEXT: i32.load $push[[L13:.+]]=, __stack_pointer($pop[[L1]])
; CHECK: get_global $push[[L13:.+]]=, 0{{$}}
; CHECK-NEXT: tee_local $push[[L12:.+]]=, [[SP:.+]], $pop[[L13]]{{$}}
; CHECK-NEXT: copy_local [[FP:.+]]=, $pop[[L12]]{{$}}
; Target independent codegen bumps the stack pointer
; CHECK: i32.sub
%r = alloca i32, i32 %alloc
; CHECK-NEXT: tee_local $push[[L8:.+]]=, $0=, $pop
; CHECK-NEXT: copy_local $drop=, $pop[[L8]]{{$}}
; CHECK-NEXT: tee_local $push[[L8:.+]]=, {{.+}}, $pop
; CHECK: get_local $push[[L7:.+]]=, 0{{$}}
; CHECK-NEXT: i32.const $push[[L6:.+]]=, 0{{$}}
; CHECK-NEXT: i32.store 0($0), $pop[[L6]]{{$}}
; CHECK-NEXT: i32.store 0($pop[[L7]]), $pop[[L6]]{{$}}
store i32 0, i32* %r
; CHECK-NEXT: return
ret void
@ -173,17 +166,15 @@ define void @dynamic_alloca_redzone(i32 %alloc) {
; CHECK-LABEL: dynamic_static_alloca:
define void @dynamic_static_alloca(i32 %alloc) noredzone {
; Decrement SP in the prolog by the static amount and writeback to memory.
; CHECK: i32.const $push[[L13:.+]]=, 0{{$}}
; CHECK: i32.const $push[[L10:.+]]=, 0{{$}}
; CHECK-NEXT: i32.load $push[[L11:.+]]=, __stack_pointer($pop[[L10]])
; CHECK: get_global $push[[L11:.+]]=, 0{{$}}
; CHECK-NEXT: i32.const $push[[L12:.+]]=, 16
; CHECK-NEXT: i32.sub $push[[L23:.+]]=, $pop[[L11]], $pop[[L12]]
; CHECK-NEXT: tee_local $push[[L22:.+]]=, $[[SP:.+]]=, $pop[[L23]]
; CHECK-NEXT: i32.store __stack_pointer($pop{{.+}}), $pop[[L22]]
; CHECK-NEXT: tee_local $push[[L22:.+]]=, [[SP:.+]], $pop[[L23]]
; CHECK-NEXT: set_global 0, $pop[[L22]]
; Alloc and write to a static alloca
; CHECK: copy_local $push[[L21:.+]]=, $[[SP]]
; CHECK-NEXT: tee_local $push[[pushedFP:.+]]=, $[[FP:.+]]=, $pop[[L21]]
; CHECK: get_local $push[[L21:.+]]=, [[SP:.+]]
; CHECK-NEXT: tee_local $push[[pushedFP:.+]]=, [[FP:.+]], $pop[[L21]]
; CHECK-NEXT: i32.const $push[[L0:.+]]=, 101
; CHECK-NEXT: i32.store [[static_offset:.+]]($pop[[pushedFP]]), $pop[[L0]]
%static = alloca i32
@ -191,44 +182,51 @@ define void @dynamic_static_alloca(i32 %alloc) noredzone {
; Decrement SP in the body by the dynamic amount.
; CHECK: i32.sub
; CHECK: tee_local $push{{.+}}=, $[[dynamic_local:.+]]=, $pop{{.+}}
; CHECK: i32.store __stack_pointer
; CHECK: tee_local $push[[L16:.+]]=, [[dynamic_local:.+]], $pop{{.+}}
; CHECK: tee_local $push[[L15:.+]]=, [[other:.+]], $pop[[L16]]{{$}}
; CHECK: set_global 0, $pop[[L15]]{{$}}
%dynamic = alloca i32, i32 %alloc
; Ensure we don't modify the frame pointer after assigning it.
; CHECK-NOT: $[[FP]]=
; Ensure the static address doesn't change after modifying the stack pointer.
; CHECK: get_local $push[[L17:.+]]=, [[FP]]
; CHECK: i32.const $push[[L7:.+]]=, 102
; CHECK-NEXT: i32.store [[static_offset]]($[[FP]]), $pop[[L7]]
; CHECK-NEXT: i32.store [[static_offset]]($pop[[L17]]), $pop[[L7]]
; CHECK-NEXT: get_local $push[[L9:.+]]=, [[dynamic_local]]{{$}}
; CHECK-NEXT: i32.const $push[[L8:.+]]=, 103
; CHECK-NEXT: i32.store 0($[[dynamic_local]]), $pop[[L8]]
; CHECK-NEXT: i32.store 0($pop[[L9]]), $pop[[L8]]
store volatile i32 102, i32* %static
store volatile i32 103, i32* %dynamic
; Decrement SP in the body by the dynamic amount.
; CHECK: i32.sub
; CHECK: tee_local $push{{.+}}=, $[[dynamic2_local:.+]]=, $pop{{.+}}
; CHECK: tee_local $push{{.+}}=, [[dynamic2_local:.+]], $pop{{.+}}
%dynamic.2 = alloca i32, i32 %alloc
; CHECK-NOT: $[[FP]]=
; Ensure neither the static nor dynamic address changes after the second
; modification of the stack pointer.
; CHECK: get_local $push[[L22:.+]]=, [[FP]]
; CHECK: i32.const $push[[L9:.+]]=, 104
; CHECK-NEXT: i32.store [[static_offset]]($[[FP]]), $pop[[L9]]
; CHECK-NEXT: i32.store [[static_offset]]($pop[[L22]]), $pop[[L9]]
; CHECK-NEXT: get_local $push[[L23:.+]]=, [[dynamic_local]]
; CHECK-NEXT: i32.const $push[[L10:.+]]=, 105
; CHECK-NEXT: i32.store 0($[[dynamic_local]]), $pop[[L10]]
; CHECK-NEXT: i32.store 0($pop[[L23]]), $pop[[L10]]
; CHECK-NEXT: get_local $push[[L23:.+]]=, [[dynamic2_local]]
; CHECK-NEXT: i32.const $push[[L11:.+]]=, 106
; CHECK-NEXT: i32.store 0($[[dynamic2_local]]), $pop[[L11]]
; CHECK-NEXT: i32.store 0($pop[[L23]]), $pop[[L11]]
store volatile i32 104, i32* %static
store volatile i32 105, i32* %dynamic
store volatile i32 106, i32* %dynamic.2
; Writeback to memory.
; CHECK: i32.const $push[[L17:.+]]=, 16
; CHECK-NEXT: i32.add $push[[L18:.+]]=, $[[FP]], $pop[[L17]]
; CHECK-NEXT: i32.store __stack_pointer($pop{{.+}}), $pop[[L18]]
; CHECK: get_local $push[[L24:.+]]=, [[FP]]{{$}}
; CHECK: i32.const $push[[L18:.+]]=, 16
; CHECK-NEXT: i32.add $push[[L19:.+]]=, $pop[[L24]], $pop[[L18]]
; CHECK-NEXT: set_global 0, $pop[[L19]]
ret void
}
@ -237,16 +235,17 @@ declare void @llvm.stackrestore(i8*)
; CHECK-LABEL: llvm_stack_builtins:
define void @llvm_stack_builtins(i32 %alloc) noredzone {
; CHECK: i32.load $push[[L11:.+]]=, __stack_pointer($pop{{.+}})
; CHECK-NEXT: tee_local $push[[L10:.+]]=, ${{.+}}=, $pop[[L11]]
; CHECK-NEXT: copy_local $[[STACK:.+]]=, $pop[[L10]]
; CHECK: get_global $push[[L11:.+]]=, 0{{$}}
; CHECK-NEXT: tee_local $push[[L10:.+]]=, {{.+}}, $pop[[L11]]
; CHECK-NEXT: set_local [[STACK:.+]], $pop[[L10]]
%stack = call i8* @llvm.stacksave()
; Ensure we don't reassign the stacksave local
; CHECK-NOT: $[[STACK]]=
; CHECK-NOT: set_local [[STACK]],
%dynamic = alloca i32, i32 %alloc
; CHECK: i32.store __stack_pointer($pop{{.+}}), $[[STACK]]
; CHECK: get_local $push[[L12:.+]]=, [[STACK]]
; CHECK-NEXT: set_global 0, $pop[[L12]]
call void @llvm.stackrestore(i8* %stack)
ret void
@ -257,14 +256,15 @@ define void @llvm_stack_builtins(i32 %alloc) noredzone {
; moved after the stack pointer was updated for the dynamic alloca.
; CHECK-LABEL: dynamic_alloca_nouse:
define void @dynamic_alloca_nouse(i32 %alloc) noredzone {
; CHECK: i32.load $push[[L11:.+]]=, __stack_pointer($pop{{.+}})
; CHECK-NEXT: tee_local $push[[L10:.+]]=, ${{.+}}=, $pop[[L11]]
; CHECK-NEXT: copy_local $[[FP:.+]]=, $pop[[L10]]
; CHECK: get_global $push[[L11:.+]]=, 0{{$}}
; CHECK-NEXT: tee_local $push[[L10:.+]]=, {{.+}}, $pop[[L11]]
; CHECK-NEXT: set_local [[FP:.+]], $pop[[L10]]
%dynamic = alloca i32, i32 %alloc
; CHECK-NOT: $[[FP]]=,
; CHECK-NOT: set_local [[FP]],
; CHECK: i32.store __stack_pointer($pop{{.+}}), $[[FP]]
; CHECK: get_local $push[[L12:.+]]=, [[FP]]
; CHECK-NEXT: set_global 0, $pop[[L12]]
ret void
}
@ -278,12 +278,13 @@ entry:
%addr = alloca i32
; CHECK: i32.const $push[[OFF:.+]]=, 12
; CHECK-NEXT: i32.add $push[[ADDR:.+]]=, $pop[[L3]], $pop[[OFF]]
; CHECK-NEXT: copy_local [[COPY:.+]]=, $pop[[ADDR]]
; CHECK-NEXT: set_local [[COPY:.+]], $pop[[ADDR]]
br label %body
body:
%a = phi i32* [%addr, %entry], [%b, %body]
store i32 1, i32* %a
; CHECK: i32.store 0([[COPY]]),
; CHECK: get_local $push[[L12:.+]]=, [[COPY]]
; CHECK: i32.store 0($pop[[L12]]),
br i1 %cond, label %body, label %exit
exit:
ret void
@ -294,13 +295,11 @@ declare i8* @llvm.frameaddress(i32)
; Test __builtin_frame_address(0).
; CHECK-LABEL: frameaddress_0:
; CHECK: i32.const $push[[L0:.+]]=, 0{{$}}
; CHECK-NEXT: i32.load $push[[L3:.+]]=, __stack_pointer($pop[[L0]])
; CHECK-NEXT: copy_local $push[[L4:.+]]=, $pop[[L3]]{{$}}
; CHECK-NEXT: tee_local $push[[L2:.+]]=, $[[FP:.+]]=, $pop[[L4]]{{$}}
; CHECK: get_global $push[[L3:.+]]=, 0{{$}}
; CHECK-NEXT: tee_local $push[[L2:.+]]=, [[FP:.+]], $pop[[L3]]{{$}}
; CHECK-NEXT: call use_i8_star@FUNCTION, $pop[[L2]]
; CHECK-NEXT: i32.const $push[[L1:.+]]=, 0{{$}}
; CHECK-NEXT: i32.store __stack_pointer($pop[[L1]]), $[[FP]]
; CHECK-NEXT: get_local $push[[L5:.+]]=, [[FP]]
; CHECK-NEXT: set_global 0, $pop[[L5]]
define void @frameaddress_0() {
%t = call i8* @llvm.frameaddress(i32 0)
call void @use_i8_star(i8* %t)
@ -321,7 +320,7 @@ define void @frameaddress_1() {
; Test a stack address passed to an inline asm.
; CHECK-LABEL: inline_asm:
; CHECK: __stack_pointer
; CHECK: get_global {{.+}}, 0{{$}}
; CHECK: #APP
; CHECK-NEXT: # %{{[0-9]+}}{{$}}
; CHECK-NEXT: #NO_APP

View File

@ -1,9 +1,9 @@
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -verify-machineinstrs | FileCheck %s
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -verify-machineinstrs | FileCheck %s
; Test varargs constructs.
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
target triple = "wasm32-unknown-unknown-wasm"
; Test va_start.
@ -52,7 +52,6 @@ entry:
; CHECK-LABEL: arg_i8:
; CHECK-NEXT: .param i32{{$}}
; CHECK-NEXT: .result i32{{$}}
; CHECK-NEXT: .local i32{{$}}
; CHECK-NEXT: i32.load $push[[NUM0:[0-9]+]]=, 0($0){{$}}
; CHECK-NEXT: tee_local $push[[NUM1:[0-9]+]]=, $1=, $pop[[NUM0]]{{$}}
; CHECK-NEXT: i32.const $push[[NUM2:[0-9]+]]=, 4{{$}}
@ -71,7 +70,6 @@ entry:
; CHECK-LABEL: arg_i32:
; CHECK-NEXT: .param i32{{$}}
; CHECK-NEXT: .result i32{{$}}
; CHECK-NEXT: .local i32{{$}}
; CHECK-NEXT: i32.load $push[[NUM0:[0-9]+]]=, 0($0){{$}}
; CHECK-NEXT: i32.const $push[[NUM1:[0-9]+]]=, 3{{$}}
; CHECK-NEXT: i32.add $push[[NUM2:[0-9]+]]=, $pop[[NUM0]], $pop[[NUM1]]{{$}}
@ -93,7 +91,6 @@ entry:
; CHECK-LABEL: arg_i128:
; CHECK-NEXT: .param i32, i32{{$}}
; CHECK-NEXT: .local
; CHECK: i32.and
; CHECK: i64.load
; CHECK: i64.load
@ -123,8 +120,8 @@ define void @caller_none() {
; disabling it.
; CHECK-LABEL: caller_some
; CHECK: i32.store
; CHECK: i64.store
; CHECK-DAG: i32.store
; CHECK-DAG: i64.store
define void @caller_some() {
call void (...) @callee(i32 0, double 2.0)
ret void

View File

@ -1,6 +1,6 @@
; RUN: llc < %s -asm-verbose=false | FileCheck %s --check-prefix=TYPEINFONAME
; RUN: llc < %s -asm-verbose=false | FileCheck %s --check-prefix=VTABLE
; RUN: llc < %s -asm-verbose=false | FileCheck %s --check-prefix=TYPEINFO
; RUN: llc < %s -asm-verbose=false -disable-wasm-explicit-locals | FileCheck %s --check-prefix=TYPEINFONAME
; RUN: llc < %s -asm-verbose=false -disable-wasm-explicit-locals | FileCheck %s --check-prefix=VTABLE
; RUN: llc < %s -asm-verbose=false -disable-wasm-explicit-locals | FileCheck %s --check-prefix=TYPEINFO
; Test that simple vtables assemble as expected.
;
@ -12,7 +12,7 @@
; Each with a virtual dtor and method foo.
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
target triple = "wasm32-unknown-unknown-wasm"
%struct.A = type { i32 (...)** }
%struct.B = type { %struct.A }
@ -36,7 +36,7 @@ target triple = "wasm32-unknown-unknown"
@_ZTS1D = constant [3 x i8] c"1D\00"
; VTABLE: .type _ZTV1A,@object
; VTABLE-NEXT: .section .data.rel.ro,"aw",@progbits
; VTABLE-NEXT: .section .data.rel.ro._ZTV1A,
; VTABLE-NEXT: .globl _ZTV1A
; VTABLE-LABEL: _ZTV1A:
; VTABLE-NEXT: .int32 0
@ -47,6 +47,7 @@ target triple = "wasm32-unknown-unknown"
; VTABLE-NEXT: .size _ZTV1A, 20
@_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
; VTABLE: .type _ZTV1B,@object
; VTABLE-NEXT: .section .data.rel.ro._ZTV1B,
; VTABLE-NEXT: .globl _ZTV1B
; VTABLE-LABEL: _ZTV1B:
; VTABLE-NEXT: .int32 0
@ -57,6 +58,7 @@ target triple = "wasm32-unknown-unknown"
; VTABLE-NEXT: .size _ZTV1B, 20
@_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
; VTABLE: .type _ZTV1C,@object
; VTABLE-NEXT: .section .data.rel.ro._ZTV1C,
; VTABLE-NEXT: .globl _ZTV1C
; VTABLE-LABEL: _ZTV1C:
; VTABLE-NEXT: .int32 0
@ -67,6 +69,7 @@ target triple = "wasm32-unknown-unknown"
; VTABLE-NEXT: .size _ZTV1C, 20
@_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
; VTABLE: .type _ZTV1D,@object
; VTABLE-NEXT: .section .data.rel.ro._ZTV1D,
; VTABLE-NEXT: .globl _ZTV1D
; VTABLE-LABEL: _ZTV1D:
; VTABLE-NEXT: .int32 0

View File

@ -1,5 +1,5 @@
; RUN: llc < %s -verify-machineinstrs -mtriple=wasm32-unknown-unknown | FileCheck %s
; RUN: llc < %s -verify-machineinstrs -mtriple=wasm32-unknown-unknown -fast-isel | FileCheck --check-prefix=CHECK-FAST %s
; RUN: llc < %s -verify-machineinstrs -mtriple=wasm32-unknown-unknown-wasm | FileCheck %s
; RUN: llc < %s -verify-machineinstrs -mtriple=wasm32-unknown-unknown-wasm -fast-isel | FileCheck --check-prefix=CHECK-FAST %s
; CHECK: #DEBUG_VALUE: decode:i <- [%vreg
; CHECK: #DEBUG_VALUE: decode:v <- [%vreg
; CHECK: DW_TAG_variable
@ -9,7 +9,7 @@
source_filename = "test/DebugInfo/WebAssembly/dbg-declare.ll"
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
target triple = "wasm32-unknown-unknown-wasm"
@key = external global [15 x i8], align 1