llvm-project/llvm/test/CodeGen/WinEH/wineh-inlined-inalloca.ll
Mirko 926a71f0c9
[CodeGen][WinEH] Update saved esp for inlined inallocas (#116585)
This fixes issue #116583

When inalloca calls are inlined the static stack pointer saving prolog
of X86WinEHState breaks due to dynamic allocas.
In this case we need to update the saved esp for every inalloca and for
every stackrestore also related to inalloca.
2024-11-21 13:58:43 -08:00

91 lines
3.2 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc < %s | FileCheck %s
target datalayout = "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32-a:0:32-S32"
target triple = "i386-pc-windows-msvc"
%struct.Foo = type { i32, i32 }
define dso_local noundef i32 @foo() local_unnamed_addr #0 personality ptr @__CxxFrameHandler3 {
; CHECK-LABEL: foo:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: pushl %ebp
; CHECK-NEXT: movl %esp, %ebp
; CHECK-NEXT: pushl %ebx
; CHECK-NEXT: pushl %edi
; CHECK-NEXT: pushl %esi
; CHECK-NEXT: subl $16, %esp
; CHECK-NEXT: movl %esp, -28(%ebp)
; CHECK-NEXT: movl $-1, -16(%ebp)
; CHECK-NEXT: leal -24(%ebp), %eax
; CHECK-NEXT: movl $___ehhandler$foo, -20(%ebp)
; CHECK-NEXT: movl %fs:0, %ecx
; CHECK-NEXT: movl %ecx, -24(%ebp)
; CHECK-NEXT: movl %eax, %fs:0
; CHECK-NEXT: pushl %eax
; CHECK-NEXT: pushl %eax
; CHECK-NEXT: movl %esp, %ecx
; CHECK-NEXT: movl %esp, -28(%ebp)
; CHECK-NEXT: movl $123, (%ecx)
; CHECK-NEXT: calll _bar
; CHECK-NEXT: movl $0, -16(%ebp)
; CHECK-NEXT: calll _alwaysthrows
; CHECK-NEXT: # %bb.3: # %unreachable.i
; CHECK-NEXT: LBB0_2: # Block address taken
; CHECK-NEXT: # %catch.i
; CHECK-NEXT: addl $12, %ebp
; CHECK-NEXT: jmp LBB0_4
; CHECK-NEXT: LBB0_4: # %exit
; CHECK-NEXT: $ehgcr_0_4:
; CHECK-NEXT: movl -24(%ebp), %eax
; CHECK-NEXT: movl %eax, %fs:0
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: leal -12(%ebp), %esp
; CHECK-NEXT: popl %esi
; CHECK-NEXT: popl %edi
; CHECK-NEXT: popl %ebx
; CHECK-NEXT: popl %ebp
; CHECK-NEXT: retl
; CHECK-NEXT: .def "?catch$1@?0?foo@4HA";
; CHECK-NEXT: .scl 3;
; CHECK-NEXT: .type 32;
; CHECK-NEXT: .endef
; CHECK-NEXT: .p2align 4
; CHECK-NEXT: "?catch$1@?0?foo@4HA":
; CHECK-NEXT: LBB0_1: # %catch.i
; CHECK-NEXT: pushl %ebp
; CHECK-NEXT: addl $12, %ebp
; CHECK-NEXT: movl %esp, -28(%ebp)
; CHECK-NEXT: movl $LBB0_2, %eax
; CHECK-NEXT: popl %ebp
; CHECK-NEXT: retl # CATCHRET
; CHECK-NEXT: Lfunc_end0:
entry:
%argmem = alloca inalloca <{ %struct.Foo }>, align 4
store i32 123, ptr %argmem, align 4
call x86_thiscallcc void @bar(ptr noundef nonnull align 4 dereferenceable(8) %argmem)
invoke void @alwaysthrows() #1
to label %unreachable.i unwind label %catch.dispatch.i
catch.dispatch.i: ; preds = %entry
%3 = catchswitch within none [label %catch.i] unwind to caller
catch.i: ; preds = %catch.dispatch.i
%4 = catchpad within %3 [ptr null, i32 64, ptr null]
catchret from %4 to label %exit
unreachable.i: ; preds = %entry
unreachable
exit: ; preds = %catch.i
ret i32 0
}
declare dso_local x86_thiscallcc void @bar(ptr noundef nonnull align 4 dereferenceable(8) %this) local_unnamed_addr
declare dso_local i32 @__CxxFrameHandler3(...)
declare dso_local void @alwaysthrows() local_unnamed_addr
attributes #0 = { norecurse "min-legal-vector-width"="0" "target-cpu"="pentium4" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
attributes #1 = { noreturn }