
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.
91 lines
3.2 KiB
LLVM
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 }
|