1 ; RUN: opt -S -winehprepare -sehprepare -mtriple=x86_64-windows-msvc < %s | FileCheck %s 2 3 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 4 target triple = "x86_64-pc-windows-msvc" 5 6 declare void @cleanup() 7 declare i32 @filt() 8 declare void @might_crash() 9 declare i32 @__C_specific_handler(...) 10 declare i32 @llvm.eh.typeid.for(i8*) 11 12 define i32 @simple_except_store() { 13 entry: 14 %retval = alloca i32 15 store i32 0, i32* %retval 16 invoke void @might_crash() 17 to label %return unwind label %lpad 18 19 lpad: 20 %ehvals = landingpad { i8*, i32 } personality i32 (...)* @__C_specific_handler 21 catch i32 ()* @filt 22 %sel = extractvalue { i8*, i32 } %ehvals, 1 23 %filt_sel = tail call i32 @llvm.eh.typeid.for(i8* bitcast (i32 ()* @filt to i8*)) 24 %matches = icmp eq i32 %sel, %filt_sel 25 br i1 %matches, label %__except, label %eh.resume 26 27 __except: 28 store i32 1, i32* %retval 29 br label %return 30 31 return: 32 %r = load i32, i32* %retval 33 ret i32 %r 34 35 eh.resume: 36 resume { i8*, i32 } %ehvals 37 } 38 39 ; CHECK-LABEL: define i32 @simple_except_store() 40 ; CHECK: landingpad { i8*, i32 } 41 ; CHECK-NEXT: catch i32 ()* @filt 42 ; CHECK-NEXT: call i8* (...) @llvm.eh.actions(i32 1, i8* bitcast (i32 ()* @filt to i8*), i32 -1, i8* blockaddress(@simple_except_store, %__except)) 43 ; CHECK-NEXT: indirectbr {{.*}} [label %__except] 44 45 define i32 @catch_all() { 46 entry: 47 %retval = alloca i32 48 store i32 0, i32* %retval 49 invoke void @might_crash() 50 to label %return unwind label %lpad 51 52 lpad: 53 %ehvals = landingpad { i8*, i32 } personality i32 (...)* @__C_specific_handler 54 catch i8* null 55 store i32 1, i32* %retval 56 br label %return 57 58 return: 59 %r = load i32, i32* %retval 60 ret i32 %r 61 } 62 63 ; CHECK-LABEL: define i32 @catch_all() 64 ; CHECK: landingpad { i8*, i32 } 65 ; CHECK-NEXT: catch i8* null 66 ; CHECK-NEXT: call i8* (...) @llvm.eh.actions(i32 1, i8* null, i32 -1, i8* blockaddress(@catch_all, %catch.all)) 67 ; CHECK-NEXT: indirectbr {{.*}} [label %catch.all] 68 ; 69 ; CHECK: catch.all: 70 ; CHECK: store i32 1, i32* %retval 71 72 73 define i32 @except_phi() { 74 entry: 75 invoke void @might_crash() 76 to label %return unwind label %lpad 77 78 lpad: 79 %ehvals = landingpad { i8*, i32 } personality i32 (...)* @__C_specific_handler 80 catch i32 ()* @filt 81 %sel = extractvalue { i8*, i32 } %ehvals, 1 82 %filt_sel = tail call i32 @llvm.eh.typeid.for(i8* bitcast (i32 ()* @filt to i8*)) 83 %matches = icmp eq i32 %sel, %filt_sel 84 br i1 %matches, label %return, label %eh.resume 85 86 return: 87 %r = phi i32 [0, %entry], [1, %lpad] 88 ret i32 %r 89 90 eh.resume: 91 resume { i8*, i32 } %ehvals 92 } 93 94 ; CHECK-LABEL: define i32 @except_phi() 95 ; CHECK: landingpad { i8*, i32 } 96 ; CHECK-NEXT: catch i32 ()* @filt 97 ; CHECK-NEXT: call i8* (...) @llvm.eh.actions(i32 1, i8* bitcast (i32 ()* @filt to i8*), i32 -1, i8* blockaddress(@except_phi, %return)) 98 ; CHECK-NEXT: indirectbr {{.*}} [label %return] 99 ; 100 ; CHECK: return: 101 ; CHECK-NEXT: %r = phi i32 [ 0, %entry ], [ 1, %lpad1 ] 102 ; CHECK-NEXT: ret i32 %r 103 104 define i32 @cleanup_and_except() { 105 entry: 106 invoke void @might_crash() 107 to label %return unwind label %lpad 108 109 lpad: 110 %ehvals = landingpad { i8*, i32 } personality i32 (...)* @__C_specific_handler 111 cleanup 112 catch i32 ()* @filt 113 call void @cleanup() 114 %sel = extractvalue { i8*, i32 } %ehvals, 1 115 %filt_sel = tail call i32 @llvm.eh.typeid.for(i8* bitcast (i32 ()* @filt to i8*)) 116 %matches = icmp eq i32 %sel, %filt_sel 117 br i1 %matches, label %return, label %eh.resume 118 119 return: 120 %r = phi i32 [0, %entry], [1, %lpad] 121 ret i32 %r 122 123 eh.resume: 124 resume { i8*, i32 } %ehvals 125 } 126 127 ; CHECK-LABEL: define i32 @cleanup_and_except() 128 ; CHECK: landingpad { i8*, i32 } 129 ; CHECK-NEXT: cleanup 130 ; CHECK-NEXT: catch i32 ()* @filt 131 ; CHECK-NEXT: call i8* (...) @llvm.eh.actions( 132 ; CHECK: i32 0, void (i8*, i8*)* @cleanup_and_except.cleanup, 133 ; CHECK: i32 1, i8* bitcast (i32 ()* @filt to i8*), i32 -1, i8* blockaddress(@cleanup_and_except, %return)) 134 ; CHECK-NEXT: indirectbr {{.*}} [label %return] 135 ; 136 ; CHECK: return: 137 ; CHECK-NEXT: %r = phi i32 [ 0, %entry ], [ 1, %lpad1 ] 138 ; CHECK-NEXT: ret i32 %r 139