summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td2
-rw-r--r--llvm/test/CodeGen/WebAssembly/userstack.ll8
2 files changed, 7 insertions, 3 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td
index a0ec3698aa5..4b319871cf1 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td
@@ -110,6 +110,7 @@ let Defs = [ARGUMENTS] in {
// get_local and set_local are not generated by instruction selection; they
// are implied by virtual register uses and defs.
multiclass LOCAL<WebAssemblyRegClass vt> {
+let hasSideEffects = 0 in {
// COPY_LOCAL is not an actual instruction in wasm, but since we allow
// get_local and set_local to be implicit, we can have a COPY_LOCAL which
// is actually a no-op because all the work is done in the implied
@@ -124,6 +125,7 @@ multiclass LOCAL<WebAssemblyRegClass vt> {
let isAsCheapAsAMove = 1 in
def TEE_LOCAL_#vt : I<(outs vt:$res, vt:$also), (ins vt:$src), [],
"tee_local\t$res, $also, $src">;
+} // hasSideEffects = 0
}
defm : LOCAL<I32>;
defm : LOCAL<I64>;
diff --git a/llvm/test/CodeGen/WebAssembly/userstack.ll b/llvm/test/CodeGen/WebAssembly/userstack.ll
index a83ce531546..15dea2b9633 100644
--- a/llvm/test/CodeGen/WebAssembly/userstack.ll
+++ b/llvm/test/CodeGen/WebAssembly/userstack.ll
@@ -131,10 +131,10 @@ define void @allocarray_inbounds() {
; CHECK-LABEL: dynamic_alloca:
define void @dynamic_alloca(i32 %alloc) {
+ ; CHECK: i32.const $push[[L7:.+]]=, __stack_pointer
; CHECK: i32.const $push[[L1:.+]]=, __stack_pointer
; CHECK-NEXT: i32.load $push[[L13:.+]]=, 0($pop[[L1]])
; 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
; Check that SP is written back to memory after decrement
@@ -144,7 +144,7 @@ define void @dynamic_alloca(i32 %alloc) {
; CHECK: call ext_func_i32@FUNCTION
call void @ext_func_i32(i32* %r)
; CHECK: i32.const $push[[L3:.+]]=, __stack_pointer
- ; CHECK-NEXT: i32.store $discard=, 0($pop[[L3]]), [[FP]]
+ ; CHECK: i32.store $discard=, 0($pop[[L3]]), $pop{{.+}}
ret void
}
@@ -169,12 +169,14 @@ 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[[L7:.+]]=, __stack_pointer
+ ; CHECK: i32.const $push[[L8:.+]]=, __stack_pointer
; CHECK: i32.const $push[[L9:.+]]=, __stack_pointer
; CHECK-NEXT: i32.load $push[[L10:.+]]=, 0($pop[[L9]])
; CHECK-NEXT: i32.const $push[[L11:.+]]=, 16
; CHECK-NEXT: i32.sub $push[[L20:.+]]=, $pop[[L10]], $pop[[L11]]
; CHECK-NEXT: tee_local $push[[L19:.+]]=, $[[FP:.+]]=, $pop[[L20]]
- ; CHECK: i32.store $push[[L0:.+]]=, 0($pop{{.+}}), $[[FP]]
+ ; CHECK: i32.store $push[[L0:.+]]=, 0($pop{{.+}}), $pop{{.+}}
; Decrement SP in the body by the dynamic amount.
; CHECK: i32.sub
; Writeback to memory.
OpenPOWER on IntegriCloud