1 ; RUN: llc -mtriple=x86_64-pc-windows-msvc < %s | FileCheck %s
3 ; C++ EH rethrows are interesting, because they are calls to noreturn
4 ; functions. There *must* be some code after the call instruction that doesn't
5 ; look like an epilogue. We use int3 to be consistent with MSVC.
7 ; Based on this C++ source:
21 target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
22 target triple = "x86_64-pc-windows-msvc"
24 %rtti.TypeDescriptor2 = type { i8**, i8*, [3 x i8] }
25 %eh.CatchableType = type { i32, i32, i32, i32, i32, i32, i32 }
26 %eh.CatchableTypeArray.1 = type { i32, [1 x i32] }
27 %eh.ThrowInfo = type { i32, i32, i32, i32 }
29 $"\01??_R0H@8" = comdat any
31 $"_CT??_R0H@84" = comdat any
37 @"\01??_7type_info@@6B@" = external constant i8*
38 @"\01??_R0H@8" = linkonce_odr global %rtti.TypeDescriptor2 { i8** @"\01??_7type_info@@6B@", i8* null, [3 x i8] c".H\00" }, comdat
39 @__ImageBase = external constant i8
40 @"_CT??_R0H@84" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor2* @"\01??_R0H@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 -1, i32 0, i32 4, i32 0 }, section ".xdata", comdat
41 @_CTA1H = linkonce_odr unnamed_addr constant %eh.CatchableTypeArray.1 { i32 1, [1 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%eh.CatchableType* @"_CT??_R0H@84" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32)] }, section ".xdata", comdat
42 @_TI1H = linkonce_odr unnamed_addr constant %eh.ThrowInfo { i32 0, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%eh.CatchableTypeArray.1* @_CTA1H to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, section ".xdata", comdat
44 define i32 @main() #0 personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
46 %tmp = alloca i32, align 4
47 store i32 42, i32* %tmp, align 4
48 %0 = bitcast i32* %tmp to i8*
49 invoke void @_CxxThrowException(i8* %0, %eh.ThrowInfo* nonnull @_TI1H) #1
50 to label %unreachable unwind label %catch.dispatch
52 catch.dispatch: ; preds = %entry
53 %1 = catchpad [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null]
54 to label %catch unwind label %catchendblock
56 catch: ; preds = %catch.dispatch
57 invoke void @_CxxThrowException(i8* null, %eh.ThrowInfo* null) #1
58 to label %unreachable unwind label %catch.dispatch.1
60 catch.dispatch.1: ; preds = %catch
61 %2 = catchpad [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null]
62 to label %catch.3 unwind label %catchendblock.2
64 catch.3: ; preds = %catch.dispatch.1
65 catchret %2 to label %try.cont
67 try.cont: ; preds = %catch.3
68 catchret %1 to label %try.cont.5
70 try.cont.5: ; preds = %try.cont
73 catchendblock.2: ; preds = %catch.dispatch.1
74 catchendpad unwind label %catchendblock
76 catchendblock: ; preds = %catchendblock.2, %catch.dispatch
77 catchendpad unwind to caller
79 unreachable: ; preds = %catch, %entry
83 declare void @_CxxThrowException(i8*, %eh.ThrowInfo*)
85 declare i32 @__CxxFrameHandler3(...)
87 attributes #0 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-features"="+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" }
88 attributes #1 = { noreturn }
91 ; CHECK: .seh_proc main
93 ; CHECK-DAG: leaq {{.*}}, %rcx
94 ; CHECK-DAG: leaq _TI1H(%rip), %rdx
95 ; CHECK: callq _CxxThrowException
98 ; CHECK: "?catch$1@?0?main@4HA":
99 ; CHECK: .seh_proc "?catch$1@?0?main@4HA"
100 ; CHECK-DAG: xorl %ecx, %ecx
101 ; CHECK-DAG: xorl %edx, %edx
102 ; CHECK: callq _CxxThrowException