Skip to content

Commit

Permalink
[WebAssembly] Convert the remaining unit tests to the new wasm-object…
Browse files Browse the repository at this point in the history
…-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
  • Loading branch information
Dan Gohman committed Feb 28, 2017
1 parent 06f92e6 commit 7d7409e
Show file tree
Hide file tree
Showing 38 changed files with 261 additions and 221 deletions.
16 changes: 16 additions & 0 deletions llvm/lib/Target/WebAssembly/README.txt
Expand Up @@ -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.

//===---------------------------------------------------------------------===//
12 changes: 12 additions & 0 deletions llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp
Expand Up @@ -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 {
Expand Down Expand Up @@ -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())
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/CodeGen/WebAssembly/address-offsets.ll
@@ -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

Expand Down
25 changes: 10 additions & 15 deletions llvm/test/CodeGen/WebAssembly/byval.ll
@@ -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 }
Expand All @@ -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]]
Expand All @@ -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
}
Expand All @@ -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]]{{$}}
Expand All @@ -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)
Expand Down Expand Up @@ -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]]{{$}}
Expand Down
8 changes: 3 additions & 5 deletions llvm/test/CodeGen/WebAssembly/cfg-stackify.ll
@@ -1,13 +1,13 @@
; 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.

; Explicitly disable fast-isel, since it gets implicitly enabled in the
; 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()

Expand Down Expand Up @@ -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{{$}}
Expand All @@ -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{{$}}
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/CodeGen/WebAssembly/conv.ll
@@ -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{{$}}
Expand Down
16 changes: 8 additions & 8 deletions llvm/test/CodeGen/WebAssembly/cpus.ll
@@ -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
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/CodeGen/WebAssembly/dbgvalue.ll
@@ -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
Expand Down
3 changes: 2 additions & 1 deletion llvm/test/CodeGen/WebAssembly/fast-isel.ll
@@ -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.

Expand Down
4 changes: 2 additions & 2 deletions llvm/test/CodeGen/WebAssembly/frem.ll
@@ -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{{$}}
Expand Down
6 changes: 3 additions & 3 deletions llvm/test/CodeGen/WebAssembly/func.ll
@@ -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
Expand Down
19 changes: 8 additions & 11 deletions llvm/test/CodeGen/WebAssembly/function-bitcasts.ll
@@ -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{{$}}
Expand All @@ -20,37 +20,34 @@ 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{{$}}
; CHECK-NEXT: i32.store 0($[[L5:[0-9]+]]), $pop[[L4]]{{$}}
; 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()
Expand Down

0 comments on commit 7d7409e

Please sign in to comment.