; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --no_x86_scrub_sp
; RUN: llc < %s | FileCheck %s

target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

; | case1 | alloca + align < probe_size
define i32 @foo1(i64 %i) local_unnamed_addr #0 {
; CHECK-LABEL: foo1:
; CHECK:       # %bb.0:
; CHECK-NEXT:    pushq %rbp
; CHECK-NEXT:    .cfi_def_cfa_offset 16
; CHECK-NEXT:    .cfi_offset %rbp, -16
; CHECK-NEXT:    movq %rsp, %rbp
; CHECK-NEXT:    .cfi_def_cfa_register %rbp
; CHECK-NEXT:    andq $-64, %rsp
; CHECK-NEXT:    subq $832, %rsp # imm = 0x340
; CHECK-NEXT:    movl $1, (%rsp,%rdi,4)
; CHECK-NEXT:    movl (%rsp), %eax
; CHECK-NEXT:    movq %rbp, %rsp
; CHECK-NEXT:    popq %rbp
; CHECK-NEXT:    .cfi_def_cfa %rsp, 8
; CHECK-NEXT:    retq
  %a = alloca i32, i32 200, align 64
  %b = getelementptr inbounds i32, i32* %a, i64 %i
  store volatile i32 1, i32* %b
  %c = load volatile i32, i32* %a
  ret i32 %c
}

; | case2 | alloca > probe_size, align > probe_size
define i32 @foo2(i64 %i) local_unnamed_addr #0 {
; CHECK-LABEL: foo2:
; CHECK:       # %bb.0:
; CHECK-NEXT:    pushq %rbp
; CHECK-NEXT:    .cfi_def_cfa_offset 16
; CHECK-NEXT:    .cfi_offset %rbp, -16
; CHECK-NEXT:    movq %rsp, %rbp
; CHECK-NEXT:    .cfi_def_cfa_register %rbp
; CHECK-NEXT:    andq $-2048, %rsp # imm = 0xF800
; CHECK-NEXT:    subq $2048, %rsp # imm = 0x800
; CHECK-NEXT:    movq $0, (%rsp)
; CHECK-NEXT:    subq $4096, %rsp # imm = 0x1000
; CHECK-NEXT:    movq $0, (%rsp)
; CHECK-NEXT:    subq $2048, %rsp # imm = 0x800
; CHECK-NEXT:    movl $1, (%rsp,%rdi,4)
; CHECK-NEXT:    movl (%rsp), %eax
; CHECK-NEXT:    movq %rbp, %rsp
; CHECK-NEXT:    popq %rbp
; CHECK-NEXT:    .cfi_def_cfa %rsp, 8
; CHECK-NEXT:    retq
  %a = alloca i32, i32 2000, align 2048
  %b = getelementptr inbounds i32, i32* %a, i64 %i
  store volatile i32 1, i32* %b
  %c = load volatile i32, i32* %a
  ret i32 %c
}

; | case3 | alloca < probe_size, align < probe_size, alloca + align > probe_size
define i32 @foo3(i64 %i) local_unnamed_addr #0 {
; CHECK-LABEL: foo3:
; CHECK:       # %bb.0:
; CHECK-NEXT:    pushq %rbp
; CHECK-NEXT:    .cfi_def_cfa_offset 16
; CHECK-NEXT:    .cfi_offset %rbp, -16
; CHECK-NEXT:    movq %rsp, %rbp
; CHECK-NEXT:    .cfi_def_cfa_register %rbp
; CHECK-NEXT:    andq $-1024, %rsp # imm = 0xFC00
; CHECK-NEXT:    subq $3072, %rsp # imm = 0xC00
; CHECK-NEXT:    movq $0, (%rsp)
; CHECK-NEXT:    subq $1024, %rsp # imm = 0x400
; CHECK-NEXT:    movl $1, (%rsp,%rdi,4)
; CHECK-NEXT:    movl (%rsp), %eax
; CHECK-NEXT:    movq %rbp, %rsp
; CHECK-NEXT:    popq %rbp
; CHECK-NEXT:    .cfi_def_cfa %rsp, 8
; CHECK-NEXT:    retq
  %a = alloca i32, i32 1000, align 1024
  %b = getelementptr inbounds i32, i32* %a, i64 %i
  store volatile i32 1, i32* %b
  %c = load volatile i32, i32* %a
  ret i32 %c
}

; | case4 | alloca + probe_size < probe_size, followed by dynamic alloca
define i32 @foo4(i64 %i) local_unnamed_addr #0 {
; CHECK-LABEL: foo4:
; CHECK:       # %bb.0:
; CHECK-NEXT:    pushq %rbp
; CHECK-NEXT:    .cfi_def_cfa_offset 16
; CHECK-NEXT:    .cfi_offset %rbp, -16
; CHECK-NEXT:    movq %rsp, %rbp
; CHECK-NEXT:    .cfi_def_cfa_register %rbp
; CHECK-NEXT:    pushq %rbx
; CHECK-NEXT:    andq $-64, %rsp
; CHECK-NEXT:    subq $896, %rsp # imm = 0x380
; CHECK-NEXT:    movq %rsp, %rbx
; CHECK-NEXT:    .cfi_offset %rbx, -24
; CHECK-NEXT:    movl $1, (%rbx,%rdi,4)
; CHECK-NEXT:    movl (%rbx), %ecx
; CHECK-NEXT:    movq %rsp, %rax
; CHECK-NEXT:    leaq 15(,%rcx,4), %rcx
; CHECK-NEXT:    andq $-16, %rcx
; CHECK-NEXT:    subq %rcx, %rax
; CHECK-NEXT:    cmpq %rsp, %rax
; CHECK-NEXT:    jge .LBB3_3
; CHECK-NEXT:  .LBB3_2: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT:    xorq $0, (%rsp)
; CHECK-NEXT:    subq $4096, %rsp # imm = 0x1000
; CHECK-NEXT:    cmpq %rsp, %rax
; CHECK-NEXT:    jl .LBB3_2
; CHECK-NEXT:  .LBB3_3:
; CHECK-NEXT:    andq $-64, %rax
; CHECK-NEXT:    movq %rax, %rsp
; CHECK-NEXT:    movl (%rax), %eax
; CHECK-NEXT:    leaq -8(%rbp), %rsp
; CHECK-NEXT:    popq %rbx
; CHECK-NEXT:    popq %rbp
; CHECK-NEXT:    .cfi_def_cfa %rsp, 8
; CHECK-NEXT:    retq
  %a = alloca i32, i32 200, align 64
  %b = getelementptr inbounds i32, i32* %a, i64 %i
  store volatile i32 1, i32* %b
  %c = load volatile i32, i32* %a
  %d = alloca i32, i32 %c, align 64
  %e = load volatile i32, i32* %d
  ret i32 %e
}

attributes #0 =  {"probe-stack"="inline-asm"}
