summaryrefslogtreecommitdiffstats
path: root/llvm/test/CodeGen/WebAssembly
diff options
context:
space:
mode:
authorDerek Schuff <dschuff@google.com>2016-02-22 21:57:17 +0000
committerDerek Schuff <dschuff@google.com>2016-02-22 21:57:17 +0000
commit27e3b8a6e3a5c75a0e23d18a7bb3f32bce851db8 (patch)
tree7c1d816cf9179850ab0f110b01df51867c61b57e /llvm/test/CodeGen/WebAssembly
parentfb31d580ea5e887159a1bc684a357a7b2e27e123 (diff)
downloadbcm5719-llvm-27e3b8a6e3a5c75a0e23d18a7bb3f32bce851db8.tar.gz
bcm5719-llvm-27e3b8a6e3a5c75a0e23d18a7bb3f32bce851db8.zip
[WebAssembly] Fix writeback of stack pointer with dynamic alloca
Previously the stack pointer was only written back to memory in the prolog. But this is wrong for dynamic allocas, for which target-independent codegen handles SP updates after the prolog (and possibly even in another BB). Instead update the SP global in ADJCALLSTACKDOWN which is generated after the SP update sequence. This will have further refinements when we add red zone support. llvm-svn: 261579
Diffstat (limited to 'llvm/test/CodeGen/WebAssembly')
-rw-r--r--llvm/test/CodeGen/WebAssembly/userstack.ll17
1 files changed, 12 insertions, 5 deletions
diff --git a/llvm/test/CodeGen/WebAssembly/userstack.ll b/llvm/test/CodeGen/WebAssembly/userstack.ll
index 1b9807399a8..74edd89323a 100644
--- a/llvm/test/CodeGen/WebAssembly/userstack.ll
+++ b/llvm/test/CodeGen/WebAssembly/userstack.ll
@@ -134,8 +134,11 @@ define void @dynamic_alloca(i32 %alloc) {
; CHECK: i32.const $push[[L1:.+]]=, __stack_pointer
; CHECK-NEXT: i32.load [[SP:.+]]=, 0($pop[[L1]])
; CHECK-NEXT: copy_local [[FP:.+]]=, [[SP]]
- ; Target independent codegen bumps the stack pointer
- ; CHECK: i32.const $push[[L4:.+]]=, __stack_pointer{{$}}
+ ; Target independent codegen bumps the stack pointer.
+ ; CHECK: i32.sub
+ ; CHECK-NEXT: copy_local [[SP]]=,
+ ; Check that SP is written back to memory after decrement
+ ; CHECK-NEXT: i32.const $push[[L4:.+]]=, __stack_pointer{{$}}
; CHECK-NEXT: i32.store $discard=, 0($pop[[L4]]), [[SP]]
%r = alloca i32, i32 %alloc
; Target-independent codegen also calculates the store addr
@@ -145,9 +148,9 @@ define void @dynamic_alloca(i32 %alloc) {
ret void
}
-
; CHECK-LABEL: dynamic_static_alloca:
define void @dynamic_static_alloca(i32 %alloc) {
+ ; Decrement SP in the prolog by the static amount and writeback to memory.
; CHECK: i32.const $push[[L1:.+]]=, __stack_pointer
; CHECK-NEXT: i32.load $push[[L2:.+]]=, 0($pop[[L1]])
; CHECK-NEXT: i32.const $push[[L3:.+]]=, 16
@@ -155,6 +158,12 @@ define void @dynamic_static_alloca(i32 %alloc) {
; CHECK-NEXT: copy_local [[FP:.+]]=, [[SP]]
; CHECK-NEXT: i32.const $push[[L4:.+]]=, __stack_pointer
; CHECK-NEXT: i32.store {{.*}}=, 0($pop[[L4]]), [[SP]]
+ ; Decrement SP in the body by the dynamic amount.
+ ; CHECK: i32.sub
+ ; CHECK: copy_local [[SP]]=,
+ ; Writeback to memory.
+ ; CHECK-NEXT: i32.const $push[[L4:.+]]=, __stack_pointer
+ ; CHECK-NEXT: i32.store {{.*}}=, 0($pop[[L4]]), [[SP]]
%r1 = alloca i32
%r = alloca i32, i32 %alloc
store i32 0, i32* %r
@@ -194,8 +203,6 @@ declare i8* @llvm.frameaddress(i32)
; CHECK: i32.const $push[[L1:.+]]=, __stack_pointer
; CHECK-NEXT: i32.load [[SP:.+]]=, 0($pop[[L1]])
; CHECK-NEXT: copy_local [[FP:.+]]=, [[SP]]
-; CHECK-NEXT: i32.const $push[[L2:.+]]=, __stack_pointer{{$}}
-; CHECK-NEXT: i32.store $discard=, 0($pop[[L2]]), [[SP]]
; CHECK-NEXT: call use_i8_star@FUNCTION, [[FP]]
; CHECK-NEXT: i32.const $push[[L6:.+]]=, __stack_pointer
; CHECK-NEXT: i32.store [[SP]]=, 0($pop[[L6]]), [[FP]]
OpenPOWER on IntegriCloud