1; RUN: llc -mtriple=x86_64-windows-gnu %s -o - | FileCheck %s 2 3; Based on this C++ code: 4; struct as { 5; as() { at = static_cast<int *>(operator new(sizeof(int))); } 6; ~as() { operator delete(at); } 7; int *at; 8; }; 9; void am(int) { 10; static as au; 11; as av; 12; throw 0; 13; } 14 15; optnone was added to ensure that branch folding and block layout are not 16; disturbed. The key thing about this test is that it ends in an empty 17; unreachable block, which forces us to scan back across blocks. 18 19; CHECK: _Z2ami: 20; CHECK: callq __cxa_throw 21; CHECK: # %eh.resume 22; CHECK: callq _Unwind_Resume 23; CHECK-NEXT: # %unreachable 24; CHECK-NEXT: int3 25; CHECK-NEXT: .Lfunc_end0: 26 27%struct.as = type { ptr } 28 29@_ZZ2amiE2au = internal unnamed_addr global %struct.as zeroinitializer, align 8 30@_ZGVZ2amiE2au = internal global i64 0, align 8 31@_ZTIi = external constant ptr 32 33define dso_local void @_Z2ami(i32 %0) noinline optnone personality ptr @__gxx_personality_seh0 { 34entry: 35 %1 = load atomic i8, ptr @_ZGVZ2amiE2au acquire, align 8 36 %guard.uninitialized = icmp eq i8 %1, 0 37 br i1 %guard.uninitialized, label %init.check, label %init.end 38 39init.check: ; preds = %entry 40 %2 = tail call i32 @__cxa_guard_acquire(ptr nonnull @_ZGVZ2amiE2au) 41 %tobool = icmp eq i32 %2, 0 42 br i1 %tobool, label %init.end, label %init 43 44init: ; preds = %init.check 45 %call.i3 = invoke ptr @_Znwy(i64 4) 46 to label %invoke.cont unwind label %lpad 47 48invoke.cont: ; preds = %init 49 store ptr %call.i3, ptr @_ZZ2amiE2au, align 8 50 %3 = tail call i32 @atexit(ptr nonnull @__dtor__ZZ2amiE2au) 51 tail call void @__cxa_guard_release(ptr nonnull @_ZGVZ2amiE2au) 52 br label %init.end 53 54init.end: ; preds = %init.check, %invoke.cont, %entry 55 %call.i = tail call ptr @_Znwy(i64 4) 56 %exception = tail call ptr @__cxa_allocate_exception(i64 4) 57 store i32 0, ptr %exception, align 16 58 invoke void @__cxa_throw(ptr %exception, ptr @_ZTIi, ptr null) 59 to label %unreachable unwind label %lpad1 60 61lpad: ; preds = %init 62 %4 = landingpad { ptr, i32 } 63 cleanup 64 %5 = extractvalue { ptr, i32 } %4, 0 65 %6 = extractvalue { ptr, i32 } %4, 1 66 tail call void @__cxa_guard_abort(ptr nonnull @_ZGVZ2amiE2au) 67 br label %eh.resume 68 69lpad1: ; preds = %init.end 70 %7 = landingpad { ptr, i32 } 71 cleanup 72 %8 = extractvalue { ptr, i32 } %7, 0 73 %9 = extractvalue { ptr, i32 } %7, 1 74 tail call void @_ZdlPv(ptr %call.i) 75 br label %eh.resume 76 77eh.resume: ; preds = %lpad1, %lpad 78 %exn.slot.0 = phi ptr [ %8, %lpad1 ], [ %5, %lpad ] 79 %ehselector.slot.0 = phi i32 [ %9, %lpad1 ], [ %6, %lpad ] 80 %lpad.val = insertvalue { ptr, i32 } undef, ptr %exn.slot.0, 0 81 %lpad.val2 = insertvalue { ptr, i32 } %lpad.val, i32 %ehselector.slot.0, 1 82 resume { ptr, i32 } %lpad.val2 83 84unreachable: ; preds = %init.end 85 unreachable 86} 87 88declare dso_local i32 @__cxa_guard_acquire(ptr) 89 90declare dso_local i32 @__gxx_personality_seh0(...) 91 92declare dso_local void @__dtor__ZZ2amiE2au() 93 94declare dso_local i32 @atexit(ptr) 95 96declare dso_local void @__cxa_guard_abort(ptr) 97 98declare dso_local void @__cxa_guard_release(ptr) 99 100declare dso_local ptr @__cxa_allocate_exception(i64) 101 102declare dso_local void @__cxa_throw(ptr, ptr, ptr) 103 104declare dso_local noalias ptr @_Znwy(i64) 105 106declare dso_local void @_ZdlPv(ptr) 107