diff options
-rw-r--r-- | llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td | 2 | ||||
-rw-r--r-- | llvm/test/CodeGen/WebAssembly/userstack.ll | 8 |
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. |