llvm/llvm/test/CodeGen/X86/stack-coloring-wineh.ll

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3
; RUN: llc -mtriple=i686-windows-msvc < %s | FileCheck %s --check-prefix=I686
; RUN: llc -mtriple=x86_64-windows-msvc < %s | FileCheck %s --check-prefix=X86_64

@type_info = external global ptr

; Make sure %a1 and %a2 don't share the same stack offset.
define void @pr66984(ptr %arg) personality ptr @__CxxFrameHandler3 {
; I686-LABEL: pr66984:
; I686:       # %bb.0: # %bb
; I686-NEXT:    pushl %ebp
; I686-NEXT:    movl %esp, %ebp
; I686-NEXT:    pushl %ebx
; I686-NEXT:    pushl %edi
; I686-NEXT:    pushl %esi
; I686-NEXT:    subl $24, %esp
; I686-NEXT:    movl %esp, -28(%ebp)
; I686-NEXT:    movl $-1, -16(%ebp)
; I686-NEXT:    leal -24(%ebp), %eax
; I686-NEXT:    movl $___ehhandler$pr66984, -20(%ebp)
; I686-NEXT:    movl %fs:0, %ecx
; I686-NEXT:    movl %ecx, -24(%ebp)
; I686-NEXT:    movl %eax, %fs:0
; I686-NEXT:    movl $1, -16(%ebp)
; I686-NEXT:    calll _throw
; I686-NEXT:  # %bb.1: # %bb14
; I686-NEXT:  LBB0_3: # Block address taken
; I686-NEXT:    # %bb17
; I686-NEXT:    addl $12, %ebp
; I686-NEXT:    jmp LBB0_4
; I686-NEXT:  LBB0_4: # %exit
; I686-NEXT:  $ehgcr_0_4:
; I686-NEXT:    movl -24(%ebp), %eax
; I686-NEXT:    movl %eax, %fs:0
; I686-NEXT:    addl $24, %esp
; I686-NEXT:    popl %esi
; I686-NEXT:    popl %edi
; I686-NEXT:    popl %ebx
; I686-NEXT:    popl %ebp
; I686-NEXT:    retl
; I686-NEXT:    .def "?catch$2@?0?pr66984@4HA";
; I686-NEXT:    .scl 3;
; I686-NEXT:    .type 32;
; I686-NEXT:    .endef
; I686-NEXT:    .p2align 4
; I686-NEXT:  "?catch$2@?0?pr66984@4HA":
; I686-NEXT:  LBB0_2: # %bb17
; I686-NEXT:    pushl %ebp
; I686-NEXT:    addl $12, %ebp
; I686-NEXT:    movl %esp, -28(%ebp)
; I686-NEXT:    movl -36(%ebp), %ecx
; I686-NEXT:    movl $2, -16(%ebp)
; I686-NEXT:    calll _cleanup
; I686-NEXT:    movl $LBB0_3, %eax
; I686-NEXT:    popl %ebp
; I686-NEXT:    retl # CATCHRET
; I686-NEXT:    .def "?dtor$5@?0?pr66984@4HA";
; I686-NEXT:    .scl 3;
; I686-NEXT:    .type 32;
; I686-NEXT:    .endef
; I686-NEXT:    .p2align 4
; I686-NEXT:  "?dtor$5@?0?pr66984@4HA":
; I686-NEXT:  LBB0_5: # %bb8
; I686-NEXT:    pushl %ebp
; I686-NEXT:    addl $12, %ebp
; I686-NEXT:    movl 8(%ebp), %eax
; I686-NEXT:    movl %eax, -32(%ebp)
; I686-NEXT:    leal -32(%ebp), %ecx
; I686-NEXT:    calll _foo
; I686-NEXT:    popl %ebp
; I686-NEXT:    retl # CLEANUPRET
; I686-NEXT:  Lfunc_end0:
;
; X86_64-LABEL: pr66984:
; X86_64:       # %bb.0: # %bb
; X86_64-NEXT:    pushq %rbp
; X86_64-NEXT:    .seh_pushreg %rbp
; X86_64-NEXT:    subq $64, %rsp
; X86_64-NEXT:    .seh_stackalloc 64
; X86_64-NEXT:    leaq {{[0-9]+}}(%rsp), %rbp
; X86_64-NEXT:    .seh_setframe %rbp, 64
; X86_64-NEXT:    .seh_endprologue
; X86_64-NEXT:    movq $-2, -16(%rbp)
; X86_64-NEXT:    movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
; X86_64-NEXT:  .Ltmp0:
; X86_64-NEXT:    callq throw
; X86_64-NEXT:  .Ltmp1:
; X86_64-NEXT:  # %bb.1: # %bb14
; X86_64-NEXT:  .LBB0_3: # Block address taken
; X86_64-NEXT:    # %exit
; X86_64-NEXT:  $ehgcr_0_3:
; X86_64-NEXT:    nop
; X86_64-NEXT:    addq $64, %rsp
; X86_64-NEXT:    popq %rbp
; X86_64-NEXT:    retq
; X86_64-NEXT:    .seh_handlerdata
; X86_64-NEXT:    .long ($cppxdata$pr66984)@IMGREL
; X86_64-NEXT:    .text
; X86_64-NEXT:    .seh_endproc
; X86_64-NEXT:    .def "?catch$2@?0?pr66984@4HA";
; X86_64-NEXT:    .scl 3;
; X86_64-NEXT:    .type 32;
; X86_64-NEXT:    .endef
; X86_64-NEXT:    .p2align 4
; X86_64-NEXT:  "?catch$2@?0?pr66984@4HA":
; X86_64-NEXT:  .seh_proc "?catch$2@?0?pr66984@4HA"
; X86_64-NEXT:    .seh_handler __CxxFrameHandler3, @unwind, @except
; X86_64-NEXT:  .LBB0_2: # %bb17
; X86_64-NEXT:    movq %rdx, {{[0-9]+}}(%rsp)
; X86_64-NEXT:    pushq %rbp
; X86_64-NEXT:    .seh_pushreg %rbp
; X86_64-NEXT:    subq $32, %rsp
; X86_64-NEXT:    .seh_stackalloc 32
; X86_64-NEXT:    leaq 64(%rdx), %rbp
; X86_64-NEXT:    .seh_endprologue
; X86_64-NEXT:    movq -8(%rbp), %rcx
; X86_64-NEXT:    callq cleanup
; X86_64-NEXT:    leaq .LBB0_3(%rip), %rax
; X86_64-NEXT:    addq $32, %rsp
; X86_64-NEXT:    popq %rbp
; X86_64-NEXT:    retq # CATCHRET
; X86_64-NEXT:    .seh_handlerdata
; X86_64-NEXT:    .long ($cppxdata$pr66984)@IMGREL
; X86_64-NEXT:    .text
; X86_64-NEXT:    .seh_endproc
; X86_64-NEXT:    .def "?dtor$4@?0?pr66984@4HA";
; X86_64-NEXT:    .scl 3;
; X86_64-NEXT:    .type 32;
; X86_64-NEXT:    .endef
; X86_64-NEXT:    .p2align 4
; X86_64-NEXT:  "?dtor$4@?0?pr66984@4HA":
; X86_64-NEXT:  .seh_proc "?dtor$4@?0?pr66984@4HA"
; X86_64-NEXT:  .LBB0_4: # %bb8
; X86_64-NEXT:    movq %rdx, {{[0-9]+}}(%rsp)
; X86_64-NEXT:    pushq %rbp
; X86_64-NEXT:    .seh_pushreg %rbp
; X86_64-NEXT:    subq $32, %rsp
; X86_64-NEXT:    .seh_stackalloc 32
; X86_64-NEXT:    leaq 64(%rdx), %rbp
; X86_64-NEXT:    .seh_endprologue
; X86_64-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Reload
; X86_64-NEXT:    movq %rax, -32(%rbp)
; X86_64-NEXT:    leaq -32(%rbp), %rcx
; X86_64-NEXT:    callq foo
; X86_64-NEXT:    nop
; X86_64-NEXT:    addq $32, %rsp
; X86_64-NEXT:    popq %rbp
; X86_64-NEXT:    retq # CLEANUPRET
; X86_64-NEXT:  .Lfunc_end0:
; X86_64-NEXT:    .seh_handlerdata
; X86_64-NEXT:    .text
; X86_64-NEXT:    .seh_endproc
bb:
  %a1 = alloca ptr, align 4
  %a2 = alloca ptr, align 4
  call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %a2)
  invoke void @throw()
          to label %bb14 unwind label %bb8

bb8:                                              ; preds = %bb7
  %i9 = cleanuppad within none []
  call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %a1)
  store ptr %arg, ptr %a1, align 4
  call fastcc void @foo(ptr %a1) [ "funclet"(token %i9) ]
  call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %a1)
  cleanupret from %i9 unwind label %bb15

bb14:                                             ; preds = %bb7
  unreachable

bb15:                                             ; preds = %bb13, %bb5
  %cs = catchswitch within none [label %bb17] unwind to caller

bb17:                                             ; preds = %bb15
  %cp = catchpad within %cs [ptr @type_info, i32 8, ptr %a2]
  %p = load ptr, ptr %a2, align 4
  call fastcc void @cleanup(ptr %p) [ "funclet"(token %cp) ]
  catchret from %cp to label %exit

exit:
  call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %a2)
  ret void
}

declare i32 @__CxxFrameHandler3(...)
declare void @throw()
declare void @cleanup(ptr)
declare void @foo(ptr)
declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture)
declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture)