1b9a539c0SWouter van Oortmerssen; RUN: llc < %s --mtriple=wasm32-unknown-unknown -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-keep-registers | FileCheck -DPTR=32 %s 2b9a539c0SWouter van Oortmerssen; RUN: llc < %s --mtriple=wasm64-unknown-unknown -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-keep-registers | FileCheck -DPTR=64 %s 39769debfSDerek Schuff 44b3bb213SDerek Schuffdeclare void @ext_func(i64* %ptr) 54b3bb213SDerek Schuffdeclare void @ext_func_i32(i32* %ptr) 64b3bb213SDerek Schuff 7*9647a6f7SWouter van Oortmerssen; CHECK: .globaltype __stack_pointer, i[[PTR]]{{$}} 8*9647a6f7SWouter van Oortmerssen 99769debfSDerek Schuff; CHECK-LABEL: alloca32: 1045cd5a79SDerek Schuff; Check that there is an extra local for the stack pointer. 11b9a539c0SWouter van Oortmerssen; CHECK: .local i[[PTR]]{{$}} 124b3bb213SDerek Schuffdefine void @alloca32() noredzone { 13275d15ecSSam Clegg ; CHECK-NEXT: global.get $push[[L2:.+]]=, __stack_pointer{{$}} 14b9a539c0SWouter van Oortmerssen ; CHECK-NEXT: i[[PTR]].const $push[[L3:.+]]=, 16 15b9a539c0SWouter van Oortmerssen ; CHECK-NEXT: i[[PTR]].sub $push[[L9:.+]]=, $pop[[L2]], $pop[[L3]] 166a87ddacSThomas Lively ; CHECK-NEXT: local.tee $push[[L8:.+]]=, [[SP:.+]], $pop[[L9]]{{$}} 17275d15ecSSam Clegg ; CHECK-NEXT: global.set __stack_pointer, $pop[[L8]]{{$}} 189769debfSDerek Schuff %retval = alloca i32 196a87ddacSThomas Lively ; CHECK: local.get $push[[L4:.+]]=, [[SP]]{{$}} 20dc5f6aa4SDerek Schuff ; CHECK: i32.const $push[[L0:.+]]=, 0 217d7409e5SDan Gohman ; CHECK: i32.store 12($pop[[L4]]), $pop[[L0]] 229769debfSDerek Schuff store i32 0, i32* %retval 236a87ddacSThomas Lively ; CHECK: local.get $push[[L6:.+]]=, [[SP]]{{$}} 24b9a539c0SWouter van Oortmerssen ; CHECK-NEXT: i[[PTR]].const $push[[L5:.+]]=, 16 25b9a539c0SWouter van Oortmerssen ; CHECK-NEXT: i[[PTR]].add $push[[L7:.+]]=, $pop[[L6]], $pop[[L5]] 26275d15ecSSam Clegg ; CHECK-NEXT: global.set __stack_pointer, $pop[[L7]] 279769debfSDerek Schuff ret void 289769debfSDerek Schuff} 299769debfSDerek Schuff 309769debfSDerek Schuff; CHECK-LABEL: alloca3264: 31b9a539c0SWouter van Oortmerssen; CHECK: .local i[[PTR]]{{$}} 329769debfSDerek Schuffdefine void @alloca3264() { 33275d15ecSSam Clegg ; CHECK: global.get $push[[L3:.+]]=, __stack_pointer{{$}} 34b9a539c0SWouter van Oortmerssen ; CHECK-NEXT: i[[PTR]].const $push[[L4:.+]]=, 16 35b9a539c0SWouter van Oortmerssen ; CHECK-NEXT: i[[PTR]].sub $push[[L6:.+]]=, $pop[[L3]], $pop[[L4]] 366a87ddacSThomas Lively ; CHECK-NEXT: local.tee $push[[L5:.+]]=, [[SP:.+]], $pop[[L6]] 379769debfSDerek Schuff %r1 = alloca i32 389769debfSDerek Schuff %r2 = alloca double 393a996818SChandler Carruth store i32 0, i32* %r1 403a996818SChandler Carruth store double 0.0, double* %r2 41bb83558fSChandler Carruth ; CHECK-NEXT: i64.const $push[[L1:.+]]=, 0 42bb83558fSChandler Carruth ; CHECK-NEXT: i64.store 0($pop[[L5]]), $pop[[L1]] 436a87ddacSThomas Lively ; CHECK-NEXT: local.get $push[[L2:.+]]=, [[SP]]{{$}} 44bb83558fSChandler Carruth ; CHECK-NEXT: i32.const $push[[L0:.+]]=, 0 45bb83558fSChandler Carruth ; CHECK-NEXT: i32.store 12($pop[[L2]]), $pop[[L0]] 464b3bb213SDerek Schuff ; CHECK-NEXT: return 479769debfSDerek Schuff ret void 489769debfSDerek Schuff} 499769debfSDerek Schuff 5045cd5a79SDerek Schuff; CHECK-LABEL: allocarray: 51b9a539c0SWouter van Oortmerssen; CHECK: .local i[[PTR]]{{$}} 529769debfSDerek Schuffdefine void @allocarray() { 53275d15ecSSam Clegg ; CHECK-NEXT: global.get $push[[L4:.+]]=, __stack_pointer{{$}} 54b9a539c0SWouter van Oortmerssen ; CHECK-NEXT: i[[PTR]].const $push[[L5:.+]]=, 144{{$}} 55b9a539c0SWouter van Oortmerssen ; CHECK-NEXT: i[[PTR]].sub $push[[L12:.+]]=, $pop[[L4]], $pop[[L5]] 566a87ddacSThomas Lively ; CHECK-NEXT: local.tee $push[[L11:.+]]=, 0, $pop[[L12]] 57275d15ecSSam Clegg ; CHECK-NEXT: global.set __stack_pointer, $pop[[L11]] 584b3bb213SDerek Schuff %r = alloca [33 x i32] 597e64917fSDan Gohman 60b9a539c0SWouter van Oortmerssen ; CHECK: i[[PTR]].const $push{{.+}}=, 24 61b9a539c0SWouter van Oortmerssen ; CHECK-NEXT: i[[PTR]].add $push[[L3:.+]]=, $pop{{.+}}, $pop{{.+}} 620cfb5f85SDan Gohman ; CHECK-NEXT: i32.const $push[[L1:.+]]=, 1{{$}} 637f1bdb2eSDan Gohman ; CHECK-NEXT: i32.store 0($pop[[L3]]), $pop[[L1]]{{$}} 646a87ddacSThomas Lively ; CHECK-NEXT: local.get $push[[L4:.+]]=, 0{{$}} 65c9623db8SDan Gohman ; CHECK-NEXT: i32.const $push[[L10:.+]]=, 1{{$}} 667d7409e5SDan Gohman ; CHECK-NEXT: i32.store 12($pop[[L4]]), $pop[[L10]]{{$}} 674b3bb213SDerek Schuff %p = getelementptr [33 x i32], [33 x i32]* %r, i32 0, i32 0 689769debfSDerek Schuff store i32 1, i32* %p 694b3bb213SDerek Schuff %p2 = getelementptr [33 x i32], [33 x i32]* %r, i32 0, i32 3 709769debfSDerek Schuff store i32 1, i32* %p2 717e64917fSDan Gohman 726a87ddacSThomas Lively ; CHECK-NEXT: local.get $push[[L2:.+]]=, [[SP]]{{$}} 73b9a539c0SWouter van Oortmerssen ; CHECK-NEXT: i[[PTR]].const $push[[L7:.+]]=, 144 74b9a539c0SWouter van Oortmerssen ; CHECK-NEXT: i[[PTR]].add $push[[L8:.+]]=, $pop[[L2]], $pop[[L7]] 75275d15ecSSam Clegg ; CHECK-NEXT: global.set __stack_pointer, $pop[[L8]] 769769debfSDerek Schuff ret void 779769debfSDerek Schuff} 789769debfSDerek Schuff 7990d9e8d3SDerek Schuff; CHECK-LABEL: non_mem_use 80c97ba939SDerek Schuffdefine void @non_mem_use(i8** %addr) { 81b9a539c0SWouter van Oortmerssen ; CHECK: i[[PTR]].const $push[[L2:.+]]=, 48 82b9a539c0SWouter van Oortmerssen ; CHECK-NEXT: i[[PTR]].sub $push[[L12:.+]]=, {{.+}}, $pop[[L2]] 836a87ddacSThomas Lively ; CHECK-NEXT: local.tee $push[[L11:.+]]=, [[SP:.+]], $pop[[L12]] 84275d15ecSSam Clegg ; CHECK-NEXT: global.set __stack_pointer, $pop[[L11]] 85c97ba939SDerek Schuff %buf = alloca [27 x i8], align 16 8690d9e8d3SDerek Schuff %r = alloca i64 8790d9e8d3SDerek Schuff %r2 = alloca i64 8890d9e8d3SDerek Schuff ; %r is at SP+8 896a87ddacSThomas Lively ; CHECK: local.get $push[[L3:.+]]=, [[SP]] 90b9a539c0SWouter van Oortmerssen ; CHECK: i[[PTR]].const $push[[OFF:.+]]=, 8 91b9a539c0SWouter van Oortmerssen ; CHECK-NEXT: i[[PTR]].add $push[[ARG1:.+]]=, $pop[[L3]], $pop[[OFF]] 92275d15ecSSam Clegg ; CHECK-NEXT: call ext_func, $pop[[ARG1]] 9390d9e8d3SDerek Schuff call void @ext_func(i64* %r) 9490d9e8d3SDerek Schuff ; %r2 is at SP+0, no add needed 956a87ddacSThomas Lively ; CHECK: local.get $push[[L4:.+]]=, [[SP]] 96275d15ecSSam Clegg ; CHECK-NEXT: call ext_func, $pop[[L4]] 9790d9e8d3SDerek Schuff call void @ext_func(i64* %r2) 98c97ba939SDerek Schuff ; Use as a value, but in a store 99c97ba939SDerek Schuff ; %buf is at SP+16 1006a87ddacSThomas Lively ; CHECK: local.get $push[[L5:.+]]=, [[SP]] 101b9a539c0SWouter van Oortmerssen ; CHECK: i[[PTR]].const $push[[OFF:.+]]=, 16 102b9a539c0SWouter van Oortmerssen ; CHECK-NEXT: i[[PTR]].add $push[[VAL:.+]]=, $pop[[L5]], $pop[[OFF]] 103b9a539c0SWouter van Oortmerssen ; CHECK-NEXT: i[[PTR]].store 0($pop{{.+}}), $pop[[VAL]] 104c97ba939SDerek Schuff %gep = getelementptr inbounds [27 x i8], [27 x i8]* %buf, i32 0, i32 0 105c97ba939SDerek Schuff store i8* %gep, i8** %addr 10690d9e8d3SDerek Schuff ret void 10790d9e8d3SDerek Schuff} 10890d9e8d3SDerek Schuff 1097e64917fSDan Gohman; CHECK-LABEL: allocarray_inbounds: 110b9a539c0SWouter van Oortmerssen; CHECK: .local i[[PTR]]{{$}} 1119bfea27cSDerek Schuffdefine void @allocarray_inbounds() { 112275d15ecSSam Clegg ; CHECK: global.get $push[[L3:.+]]=, __stack_pointer{{$}} 113b9a539c0SWouter van Oortmerssen ; CHECK-NEXT: i[[PTR]].const $push[[L4:.+]]=, 32{{$}} 114b9a539c0SWouter van Oortmerssen ; CHECK-NEXT: i[[PTR]].sub $push[[L11:.+]]=, $pop[[L3]], $pop[[L4]] 1156a87ddacSThomas Lively ; CHECK-NEXT: local.tee $push[[L10:.+]]=, [[SP:.+]], $pop[[L11]] 116275d15ecSSam Clegg ; CHECK-NEXT: global.set __stack_pointer, $pop[[L10]]{{$}} 1179bfea27cSDerek Schuff %r = alloca [5 x i32] 1189bfea27cSDerek Schuff ; CHECK: i32.const $push[[L3:.+]]=, 1 1197f1bdb2eSDan Gohman ; CHECK-DAG: i32.store 24(${{.+}}), $pop[[L3]] 1209bfea27cSDerek Schuff %p = getelementptr inbounds [5 x i32], [5 x i32]* %r, i32 0, i32 0 1219bfea27cSDerek Schuff store i32 1, i32* %p 1229bfea27cSDerek Schuff ; This store should have both the GEP and the FI folded into it. 1237f1bdb2eSDan Gohman ; CHECK-DAG: i32.store 12(${{.+}}), $pop 124bb372243SDan Gohman %p2 = getelementptr inbounds [5 x i32], [5 x i32]* %r, i32 0, i32 3 1259bfea27cSDerek Schuff store i32 1, i32* %p2 1264b3bb213SDerek Schuff call void @ext_func(i64* null); 127d530f68dSDan Gohman ; CHECK: call ext_func 128b9a539c0SWouter van Oortmerssen ; CHECK: i[[PTR]].const $push[[L5:.+]]=, 32{{$}} 129b9a539c0SWouter van Oortmerssen ; CHECK-NEXT: i[[PTR]].add $push[[L7:.+]]=, ${{.+}}, $pop[[L5]] 130275d15ecSSam Clegg ; CHECK-NEXT: global.set __stack_pointer, $pop[[L7]] 1319bfea27cSDerek Schuff ret void 1329bfea27cSDerek Schuff} 1339bfea27cSDerek Schuff 1347e64917fSDan Gohman; CHECK-LABEL: dynamic_alloca: 1358bb5f292SDerek Schuffdefine void @dynamic_alloca(i32 %alloc) { 136275d15ecSSam Clegg ; CHECK: global.get $push[[L13:.+]]=, __stack_pointer{{$}} 1376a87ddacSThomas Lively ; CHECK-NEXT: local.tee $push[[L12:.+]]=, [[SP:.+]], $pop[[L13]]{{$}} 13827e3b8a6SDerek Schuff ; Target independent codegen bumps the stack pointer. 139b9a539c0SWouter van Oortmerssen ; CHECK: i[[PTR]].sub 14027e3b8a6SDerek Schuff ; Check that SP is written back to memory after decrement 141275d15ecSSam Clegg ; CHECK: global.set __stack_pointer, 1426ea637afSDerek Schuff %r = alloca i32, i32 %alloc 1436ea637afSDerek Schuff ; Target-independent codegen also calculates the store addr 144275d15ecSSam Clegg ; CHECK: call ext_func_i32 1454b3bb213SDerek Schuff call void @ext_func_i32(i32* %r) 146275d15ecSSam Clegg ; CHECK: global.set __stack_pointer, $pop{{.+}} 1476ea637afSDerek Schuff ret void 1486ea637afSDerek Schuff} 1496ea637afSDerek Schuff 1504b3bb213SDerek Schuff; CHECK-LABEL: dynamic_alloca_redzone: 1514b3bb213SDerek Schuffdefine void @dynamic_alloca_redzone(i32 %alloc) { 152275d15ecSSam Clegg ; CHECK: global.get $push[[L13:.+]]=, __stack_pointer{{$}} 1536a87ddacSThomas Lively ; CHECK-NEXT: local.tee $push[[L12:.+]]=, [[SP:.+]], $pop[[L13]]{{$}} 1544b3bb213SDerek Schuff ; Target independent codegen bumps the stack pointer 155b9a539c0SWouter van Oortmerssen ; CHECK: i[[PTR]].sub 1564b3bb213SDerek Schuff %r = alloca i32, i32 %alloc 157b9a539c0SWouter van Oortmerssen ; CHECK-NEXT: local.tee $push[[L8:.+]]=, [[SP2:.+]], $pop 158b9a539c0SWouter van Oortmerssen ; CHECK: local.get $push[[L7:.+]]=, [[SP2]]{{$}} 1590cfb5f85SDan Gohman ; CHECK-NEXT: i32.const $push[[L6:.+]]=, 0{{$}} 1607d7409e5SDan Gohman ; CHECK-NEXT: i32.store 0($pop[[L7]]), $pop[[L6]]{{$}} 1614b3bb213SDerek Schuff store i32 0, i32* %r 1624b3bb213SDerek Schuff ; CHECK-NEXT: return 1634b3bb213SDerek Schuff ret void 1644b3bb213SDerek Schuff} 1654b3bb213SDerek Schuff 1666ea637afSDerek Schuff; CHECK-LABEL: dynamic_static_alloca: 1674b3bb213SDerek Schuffdefine void @dynamic_static_alloca(i32 %alloc) noredzone { 16827e3b8a6SDerek Schuff ; Decrement SP in the prolog by the static amount and writeback to memory. 169275d15ecSSam Clegg ; CHECK: global.get $push[[L11:.+]]=, __stack_pointer{{$}} 170b9a539c0SWouter van Oortmerssen ; CHECK-NEXT: i[[PTR]].const $push[[L12:.+]]=, 16 171b9a539c0SWouter van Oortmerssen ; CHECK-NEXT: i[[PTR]].sub $push[[L23:.+]]=, $pop[[L11]], $pop[[L12]] 1726a87ddacSThomas Lively ; CHECK-NEXT: local.tee $push[[L22:.+]]=, [[SP:.+]], $pop[[L23]] 173275d15ecSSam Clegg ; CHECK-NEXT: global.set __stack_pointer, $pop[[L22]] 17492d300ebSDerek Schuff 17592d300ebSDerek Schuff ; Alloc and write to a static alloca 1766a87ddacSThomas Lively ; CHECK: local.get $push[[L21:.+]]=, [[SP:.+]] 1776a87ddacSThomas Lively ; CHECK-NEXT: local.tee $push[[pushedFP:.+]]=, [[FP:.+]], $pop[[L21]] 17892d300ebSDerek Schuff ; CHECK-NEXT: i32.const $push[[L0:.+]]=, 101 1797f1bdb2eSDan Gohman ; CHECK-NEXT: i32.store [[static_offset:.+]]($pop[[pushedFP]]), $pop[[L0]] 18092d300ebSDerek Schuff %static = alloca i32 18192d300ebSDerek Schuff store volatile i32 101, i32* %static 18292d300ebSDerek Schuff 18327e3b8a6SDerek Schuff ; Decrement SP in the body by the dynamic amount. 184b9a539c0SWouter van Oortmerssen ; CHECK: i[[PTR]].sub 1856a87ddacSThomas Lively ; CHECK: local.tee $push[[L16:.+]]=, [[dynamic_local:.+]], $pop{{.+}} 1866a87ddacSThomas Lively ; CHECK: local.tee $push[[L15:.+]]=, [[other:.+]], $pop[[L16]]{{$}} 187275d15ecSSam Clegg ; CHECK: global.set __stack_pointer, $pop[[L15]]{{$}} 18892d300ebSDerek Schuff %dynamic = alloca i32, i32 %alloc 18992d300ebSDerek Schuff 19092d300ebSDerek Schuff ; Ensure we don't modify the frame pointer after assigning it. 19192d300ebSDerek Schuff ; CHECK-NOT: $[[FP]]= 19292d300ebSDerek Schuff 19392d300ebSDerek Schuff ; Ensure the static address doesn't change after modifying the stack pointer. 1946a87ddacSThomas Lively ; CHECK: local.get $push[[L17:.+]]=, [[FP]] 19592d300ebSDerek Schuff ; CHECK: i32.const $push[[L7:.+]]=, 102 1967d7409e5SDan Gohman ; CHECK-NEXT: i32.store [[static_offset]]($pop[[L17]]), $pop[[L7]] 1976a87ddacSThomas Lively ; CHECK-NEXT: local.get $push[[L9:.+]]=, [[dynamic_local]]{{$}} 19892d300ebSDerek Schuff ; CHECK-NEXT: i32.const $push[[L8:.+]]=, 103 1997d7409e5SDan Gohman ; CHECK-NEXT: i32.store 0($pop[[L9]]), $pop[[L8]] 20092d300ebSDerek Schuff store volatile i32 102, i32* %static 20192d300ebSDerek Schuff store volatile i32 103, i32* %dynamic 20292d300ebSDerek Schuff 20392d300ebSDerek Schuff ; Decrement SP in the body by the dynamic amount. 204b9a539c0SWouter van Oortmerssen ; CHECK: i[[PTR]].sub 2056a87ddacSThomas Lively ; CHECK: local.tee $push{{.+}}=, [[dynamic2_local:.+]], $pop{{.+}} 20692d300ebSDerek Schuff %dynamic.2 = alloca i32, i32 %alloc 20792d300ebSDerek Schuff 20892d300ebSDerek Schuff ; CHECK-NOT: $[[FP]]= 20992d300ebSDerek Schuff 21092d300ebSDerek Schuff ; Ensure neither the static nor dynamic address changes after the second 21192d300ebSDerek Schuff ; modification of the stack pointer. 2126a87ddacSThomas Lively ; CHECK: local.get $push[[L22:.+]]=, [[FP]] 21392d300ebSDerek Schuff ; CHECK: i32.const $push[[L9:.+]]=, 104 2147d7409e5SDan Gohman ; CHECK-NEXT: i32.store [[static_offset]]($pop[[L22]]), $pop[[L9]] 2156a87ddacSThomas Lively ; CHECK-NEXT: local.get $push[[L23:.+]]=, [[dynamic_local]] 21692d300ebSDerek Schuff ; CHECK-NEXT: i32.const $push[[L10:.+]]=, 105 2177d7409e5SDan Gohman ; CHECK-NEXT: i32.store 0($pop[[L23]]), $pop[[L10]] 2186a87ddacSThomas Lively ; CHECK-NEXT: local.get $push[[L23:.+]]=, [[dynamic2_local]] 21992d300ebSDerek Schuff ; CHECK-NEXT: i32.const $push[[L11:.+]]=, 106 2207d7409e5SDan Gohman ; CHECK-NEXT: i32.store 0($pop[[L23]]), $pop[[L11]] 22192d300ebSDerek Schuff store volatile i32 104, i32* %static 22292d300ebSDerek Schuff store volatile i32 105, i32* %dynamic 22392d300ebSDerek Schuff store volatile i32 106, i32* %dynamic.2 22492d300ebSDerek Schuff 22527e3b8a6SDerek Schuff ; Writeback to memory. 2266a87ddacSThomas Lively ; CHECK: local.get $push[[L24:.+]]=, [[FP]]{{$}} 227b9a539c0SWouter van Oortmerssen ; CHECK: i[[PTR]].const $push[[L18:.+]]=, 16 228b9a539c0SWouter van Oortmerssen ; CHECK-NEXT: i[[PTR]].add $push[[L19:.+]]=, $pop[[L24]], $pop[[L18]] 229275d15ecSSam Clegg ; CHECK-NEXT: global.set __stack_pointer, $pop[[L19]] 2308bb5f292SDerek Schuff ret void 2318bb5f292SDerek Schuff} 232c97ba939SDerek Schuff 233e9e6891bSDerek Schuffdeclare i8* @llvm.stacksave() 234e9e6891bSDerek Schuffdeclare void @llvm.stackrestore(i8*) 235e9e6891bSDerek Schuff 236e9e6891bSDerek Schuff; CHECK-LABEL: llvm_stack_builtins: 237e9e6891bSDerek Schuffdefine void @llvm_stack_builtins(i32 %alloc) noredzone { 238275d15ecSSam Clegg ; CHECK: global.get $push[[L11:.+]]=, __stack_pointer{{$}} 2396a87ddacSThomas Lively ; CHECK-NEXT: local.tee $push[[L10:.+]]=, {{.+}}, $pop[[L11]] 2406a87ddacSThomas Lively ; CHECK-NEXT: local.set [[STACK:.+]], $pop[[L10]] 241e9e6891bSDerek Schuff %stack = call i8* @llvm.stacksave() 242e9e6891bSDerek Schuff 243e9e6891bSDerek Schuff ; Ensure we don't reassign the stacksave local 2446a87ddacSThomas Lively ; CHECK-NOT: local.set [[STACK]], 245e9e6891bSDerek Schuff %dynamic = alloca i32, i32 %alloc 246e9e6891bSDerek Schuff 2476a87ddacSThomas Lively ; CHECK: local.get $push[[L12:.+]]=, [[STACK]] 248275d15ecSSam Clegg ; CHECK-NEXT: global.set __stack_pointer, $pop[[L12]] 249e9e6891bSDerek Schuff call void @llvm.stackrestore(i8* %stack) 250e9e6891bSDerek Schuff 251e9e6891bSDerek Schuff ret void 252e9e6891bSDerek Schuff} 253e9e6891bSDerek Schuff 254e9e6891bSDerek Schuff; Not actually using the alloca'd variables exposed an issue with register 255e9e6891bSDerek Schuff; stackification, where copying the stack pointer into the frame pointer was 256e9e6891bSDerek Schuff; moved after the stack pointer was updated for the dynamic alloca. 257e9e6891bSDerek Schuff; CHECK-LABEL: dynamic_alloca_nouse: 258e9e6891bSDerek Schuffdefine void @dynamic_alloca_nouse(i32 %alloc) noredzone { 259275d15ecSSam Clegg ; CHECK: global.get $push[[L11:.+]]=, __stack_pointer{{$}} 2606a87ddacSThomas Lively ; CHECK-NEXT: local.tee $push[[L10:.+]]=, {{.+}}, $pop[[L11]] 2616a87ddacSThomas Lively ; CHECK-NEXT: local.set [[FP:.+]], $pop[[L10]] 262e9e6891bSDerek Schuff %dynamic = alloca i32, i32 %alloc 263e9e6891bSDerek Schuff 2646a87ddacSThomas Lively ; CHECK-NOT: local.set [[FP]], 265e9e6891bSDerek Schuff 2666a87ddacSThomas Lively ; CHECK: local.get $push[[L12:.+]]=, [[FP]] 267275d15ecSSam Clegg ; CHECK-NEXT: global.set __stack_pointer, $pop[[L12]] 268e9e6891bSDerek Schuff ret void 269e9e6891bSDerek Schuff} 270e9e6891bSDerek Schuff 271aadc89c2SDerek Schuff; The use of the alloca in a phi causes a CopyToReg DAG node to be generated, 272aadc89c2SDerek Schuff; which has to have special handling because CopyToReg can't have a FI operand 273aadc89c2SDerek Schuff; CHECK-LABEL: copytoreg_fi: 274aadc89c2SDerek Schuffdefine void @copytoreg_fi(i1 %cond, i32* %b) { 275aadc89c2SDerek Schuffentry: 276b9a539c0SWouter van Oortmerssen ; CHECK: i[[PTR]].const $push[[L1:.+]]=, 16 277b9a539c0SWouter van Oortmerssen ; CHECK-NEXT: i[[PTR]].sub $push[[L3:.+]]=, {{.+}}, $pop[[L1]] 278aadc89c2SDerek Schuff %addr = alloca i32 279b9a539c0SWouter van Oortmerssen ; CHECK: i[[PTR]].const $push[[OFF:.+]]=, 12 280b9a539c0SWouter van Oortmerssen ; CHECK-NEXT: i[[PTR]].add $push[[ADDR:.+]]=, $pop[[L3]], $pop[[OFF]] 2816a87ddacSThomas Lively ; CHECK-NEXT: local.set [[COPY:.+]], $pop[[ADDR]] 282aadc89c2SDerek Schuff br label %body 283aadc89c2SDerek Schuffbody: 284aadc89c2SDerek Schuff %a = phi i32* [%addr, %entry], [%b, %body] 285aadc89c2SDerek Schuff store i32 1, i32* %a 2866a87ddacSThomas Lively ; CHECK: local.get $push[[L12:.+]]=, [[COPY]] 2877d7409e5SDan Gohman ; CHECK: i32.store 0($pop[[L12]]), 288aadc89c2SDerek Schuff br i1 %cond, label %body, label %exit 289aadc89c2SDerek Schuffexit: 290aadc89c2SDerek Schuff ret void 291aadc89c2SDerek Schuff} 292aadc89c2SDerek Schuff 29394c65660SDan Gohmandeclare void @use_i8_star(i8*) 29494c65660SDan Gohmandeclare i8* @llvm.frameaddress(i32) 29594c65660SDan Gohman 29694c65660SDan Gohman; Test __builtin_frame_address(0). 29794c65660SDan Gohman; CHECK-LABEL: frameaddress_0: 298275d15ecSSam Clegg; CHECK: global.get $push[[L3:.+]]=, __stack_pointer{{$}} 2996a87ddacSThomas Lively; CHECK-NEXT: local.tee $push[[L2:.+]]=, [[FP:.+]], $pop[[L3]]{{$}} 300275d15ecSSam Clegg; CHECK-NEXT: call use_i8_star, $pop[[L2]] 3016a87ddacSThomas Lively; CHECK-NEXT: local.get $push[[L5:.+]]=, [[FP]] 302275d15ecSSam Clegg; CHECK-NEXT: global.set __stack_pointer, $pop[[L5]] 30394c65660SDan Gohmandefine void @frameaddress_0() { 30494c65660SDan Gohman %t = call i8* @llvm.frameaddress(i32 0) 30594c65660SDan Gohman call void @use_i8_star(i8* %t) 30694c65660SDan Gohman ret void 30794c65660SDan Gohman} 30894c65660SDan Gohman 30994c65660SDan Gohman; Test __builtin_frame_address(1). 31094c65660SDan Gohman 31194c65660SDan Gohman; CHECK-LABEL: frameaddress_1: 312b9a539c0SWouter van Oortmerssen; CHECK: i[[PTR]].const $push0=, 0{{$}} 313275d15ecSSam Clegg; CHECK-NEXT: call use_i8_star, $pop0{{$}} 31494c65660SDan Gohman; CHECK-NEXT: return{{$}} 31594c65660SDan Gohmandefine void @frameaddress_1() { 31694c65660SDan Gohman %t = call i8* @llvm.frameaddress(i32 1) 31794c65660SDan Gohman call void @use_i8_star(i8* %t) 31894c65660SDan Gohman ret void 31994c65660SDan Gohman} 32094c65660SDan Gohman 32102c0871aSDan Gohman; Test a stack address passed to an inline asm. 32202c0871aSDan Gohman; CHECK-LABEL: inline_asm: 323275d15ecSSam Clegg; CHECK: global.get {{.+}}, __stack_pointer{{$}} 32402c0871aSDan Gohman; CHECK: #APP 32502c0871aSDan Gohman; CHECK-NEXT: # %{{[0-9]+}}{{$}} 32602c0871aSDan Gohman; CHECK-NEXT: #NO_APP 32702c0871aSDan Gohmandefine void @inline_asm() { 32802c0871aSDan Gohman %tmp = alloca i8 32902c0871aSDan Gohman call void asm sideeffect "# %0", "r"(i8* %tmp) 33002c0871aSDan Gohman ret void 33102c0871aSDan Gohman} 33202c0871aSDan Gohman 3330fca6517SJulien Jorge; We optimize the format of "frame offset + operand" by folding it, but this is 3340fca6517SJulien Jorge; only possible when that operand is an immediate. In this example it is a 3350fca6517SJulien Jorge; global address, so we should not fold it. 3360fca6517SJulien Jorge; CHECK-LABEL: frame_offset_with_global_address 3370fca6517SJulien Jorge; CHECK: i[[PTR]].const ${{.*}}=, str 3380fca6517SJulien Jorge@str = local_unnamed_addr global [3 x i8] c"abc", align 16 3390fca6517SJulien Jorgedefine i8 @frame_offset_with_global_address() { 3400fca6517SJulien Jorge %1 = alloca i8, align 4 3410fca6517SJulien Jorge %2 = ptrtoint i8* %1 to i32 3420fca6517SJulien Jorge ;; Here @str is a global address and not an immediate, so cannot be folded 3430fca6517SJulien Jorge %3 = getelementptr [3 x i8], [3 x i8]* @str, i32 0, i32 %2 3440fca6517SJulien Jorge %4 = load i8, i8* %3, align 8 3450fca6517SJulien Jorge %5 = and i8 %4, 67 3460fca6517SJulien Jorge ret i8 %5 3470fca6517SJulien Jorge} 3480fca6517SJulien Jorge 349c97ba939SDerek Schuff; TODO: test over-aligned alloca 350