1; RUN: llc < %s -mtriple=x86_64-windows-msvc | FileCheck %s 2 3%struct.MakeCleanup = type { i8 } 4%eh.ThrowInfo = type { i32, i32, i32, i32 } 5 6; Function Attrs: noinline nounwind optnone uwtable 7define dso_local i32 @foo() { 8entry: 9 %call = call i32 @cond() 10 %tobool = icmp ne i32 %call, 0 11 br i1 %tobool, label %if.then, label %if.end 12 13if.then: ; preds = %entry 14 call void @abort1() 15 unreachable 16 17if.end: ; preds = %entry 18 %call1 = call i32 @cond() 19 %tobool2 = icmp ne i32 %call1, 0 20 br i1 %tobool2, label %if.then3, label %if.end4 21 22if.then3: ; preds = %if.end 23 call void @abort2() 24 unreachable 25 26if.end4: ; preds = %if.end 27 %call5 = call i32 @cond() 28 %tobool6 = icmp ne i32 %call5, 0 29 br i1 %tobool6, label %if.then7, label %if.end8 30 31if.then7: ; preds = %if.end4 32 call void @abort3() 33 unreachable 34 35if.end8: ; preds = %if.end4 36 ret i32 0 37} 38 39; CHECK-LABEL: foo: 40; CHECK: callq cond 41; CHECK: callq cond 42; CHECK: callq cond 43; We don't need int3's between these calls to abort, since they won't confuse 44; the unwinder. 45; CHECK: callq abort1 46; CHECK-NEXT: # %if.then3 47; CHECK: callq abort2 48; CHECK-NEXT: # %if.then7 49; CHECK: callq abort3 50; CHECK-NEXT: int3 51 52declare dso_local i32 @cond() 53 54declare dso_local void @abort1() noreturn 55declare dso_local void @abort2() noreturn 56declare dso_local void @abort3() noreturn 57 58define dso_local void @throw_exception() uwtable personality ptr @__CxxFrameHandler3 { 59entry: 60 %o = alloca %struct.MakeCleanup, align 1 61 %call = invoke i32 @cond() 62 to label %invoke.cont unwind label %ehcleanup 63 64invoke.cont: ; preds = %entry 65 %cmp1 = icmp eq i32 0, %call 66 br i1 %cmp1, label %if.then, label %if.end 67 68if.then: ; preds = %invoke.cont 69 invoke void @_CxxThrowException(ptr null, ptr null) 70 to label %unreachable unwind label %ehcleanup 71 72if.end: ; preds = %invoke.cont 73 %call2 = invoke i32 @cond() 74 to label %invoke.cont1 unwind label %ehcleanup 75 76invoke.cont1: ; preds = %if.end 77 %cmp2 = icmp eq i32 0, %call2 78 br i1 %cmp2, label %if.then3, label %if.end4 79 80if.then3: ; preds = %invoke.cont1 81 invoke void @_CxxThrowException(ptr null, ptr null) 82 to label %unreachable unwind label %ehcleanup 83 84if.end4: ; preds = %invoke.cont1 85 call void @"??1MakeCleanup@@QEAA@XZ"(ptr nonnull %o) 86 ret void 87 88ehcleanup: ; preds = %if.then3, %if.end, %if.then, %entry 89 %cp = cleanuppad within none [] 90 call void @"??1MakeCleanup@@QEAA@XZ"(ptr nonnull %o) [ "funclet"(token %cp) ] 91 cleanupret from %cp unwind to caller 92 93unreachable: ; preds = %if.then3, %if.then 94 unreachable 95} 96 97declare dso_local i32 @__CxxFrameHandler3(...) 98declare dso_local void @_CxxThrowException(ptr, ptr) 99declare dso_local void @"??1MakeCleanup@@QEAA@XZ"(ptr) 100 101; CHECK-LABEL: throw_exception: 102; CHECK: callq cond 103; CHECK: je 104; CHECK: callq cond 105; CHECK: je 106; CHECK: retq 107; CHECK: callq _CxxThrowException 108; CHECK-NOT: {{(addq|subq) .*, %rsp}} 109; CHECK: callq _CxxThrowException 110; CHECK-NOT: {{(addq|subq) .*, %rsp}} 111; CHECK: # %unreachable 112; CHECK: int3 113; CHECK: .seh_handlerdata 114