1*9880d681SAndroid Build Coastguard Worker; RUN: llc -mtriple i686-pc-windows-msvc < %s | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker 3*9880d681SAndroid Build Coastguard Worker; This test case is also intended to be run manually as a complete functional 4*9880d681SAndroid Build Coastguard Worker; test. It should link, print something, and exit zero rather than crashing. 5*9880d681SAndroid Build Coastguard Worker; It is the hypothetical lowering of a C source program that looks like: 6*9880d681SAndroid Build Coastguard Worker; 7*9880d681SAndroid Build Coastguard Worker; int safe_div(int *n, int *d) { 8*9880d681SAndroid Build Coastguard Worker; int r; 9*9880d681SAndroid Build Coastguard Worker; __try { 10*9880d681SAndroid Build Coastguard Worker; __try { 11*9880d681SAndroid Build Coastguard Worker; r = *n / *d; 12*9880d681SAndroid Build Coastguard Worker; } __except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION) { 13*9880d681SAndroid Build Coastguard Worker; puts("EXCEPTION_ACCESS_VIOLATION"); 14*9880d681SAndroid Build Coastguard Worker; r = -1; 15*9880d681SAndroid Build Coastguard Worker; } 16*9880d681SAndroid Build Coastguard Worker; } __except(GetExceptionCode() == EXCEPTION_INT_DIVIDE_BY_ZERO) { 17*9880d681SAndroid Build Coastguard Worker; puts("EXCEPTION_INT_DIVIDE_BY_ZERO"); 18*9880d681SAndroid Build Coastguard Worker; r = -2; 19*9880d681SAndroid Build Coastguard Worker; } 20*9880d681SAndroid Build Coastguard Worker; return r; 21*9880d681SAndroid Build Coastguard Worker; } 22*9880d681SAndroid Build Coastguard Worker 23*9880d681SAndroid Build Coastguard Worker@str1 = internal constant [27 x i8] c"EXCEPTION_ACCESS_VIOLATION\00" 24*9880d681SAndroid Build Coastguard Worker@str2 = internal constant [29 x i8] c"EXCEPTION_INT_DIVIDE_BY_ZERO\00" 25*9880d681SAndroid Build Coastguard Worker 26*9880d681SAndroid Build Coastguard Workerdefine i32 @safe_div(i32* %n, i32* %d) personality i8* bitcast (i32 (...)* @_except_handler3 to i8*) { 27*9880d681SAndroid Build Coastguard Workerentry: 28*9880d681SAndroid Build Coastguard Worker %r = alloca i32, align 4 29*9880d681SAndroid Build Coastguard Worker store i32 42, i32* %r 30*9880d681SAndroid Build Coastguard Worker invoke void @try_body(i32* %r, i32* %n, i32* %d) 31*9880d681SAndroid Build Coastguard Worker to label %__try.cont unwind label %lpad0 32*9880d681SAndroid Build Coastguard Worker 33*9880d681SAndroid Build Coastguard Workerlpad0: 34*9880d681SAndroid Build Coastguard Worker %cs0 = catchswitch within none [label %handler0] unwind label %lpad1 35*9880d681SAndroid Build Coastguard Worker 36*9880d681SAndroid Build Coastguard Workerhandler0: 37*9880d681SAndroid Build Coastguard Worker %p0 = catchpad within %cs0 [i8* bitcast (i32 ()* @safe_div_filt0 to i8*)] 38*9880d681SAndroid Build Coastguard Worker call void @puts(i8* getelementptr ([27 x i8], [27 x i8]* @str1, i32 0, i32 0)) [ "funclet"(token %p0) ] 39*9880d681SAndroid Build Coastguard Worker store i32 -1, i32* %r, align 4 40*9880d681SAndroid Build Coastguard Worker catchret from %p0 to label %__try.cont 41*9880d681SAndroid Build Coastguard Worker 42*9880d681SAndroid Build Coastguard Workerlpad1: 43*9880d681SAndroid Build Coastguard Worker %cs1 = catchswitch within none [label %handler1] unwind to caller 44*9880d681SAndroid Build Coastguard Worker 45*9880d681SAndroid Build Coastguard Workerhandler1: 46*9880d681SAndroid Build Coastguard Worker %p1 = catchpad within %cs1 [i8* bitcast (i32 ()* @safe_div_filt1 to i8*)] 47*9880d681SAndroid Build Coastguard Worker call void @puts(i8* getelementptr ([29 x i8], [29 x i8]* @str2, i32 0, i32 0)) [ "funclet"(token %p1) ] 48*9880d681SAndroid Build Coastguard Worker store i32 -2, i32* %r, align 4 49*9880d681SAndroid Build Coastguard Worker catchret from %p1 to label %__try.cont 50*9880d681SAndroid Build Coastguard Worker 51*9880d681SAndroid Build Coastguard Worker__try.cont: 52*9880d681SAndroid Build Coastguard Worker %safe_ret = load i32, i32* %r, align 4 53*9880d681SAndroid Build Coastguard Worker ret i32 %safe_ret 54*9880d681SAndroid Build Coastguard Worker} 55*9880d681SAndroid Build Coastguard Worker 56*9880d681SAndroid Build Coastguard Worker; Normal path code 57*9880d681SAndroid Build Coastguard Worker 58*9880d681SAndroid Build Coastguard Worker; CHECK: {{^}}_safe_div: 59*9880d681SAndroid Build Coastguard Worker; CHECK: movl $42, [[rloc:.*\(%ebp\)]] 60*9880d681SAndroid Build Coastguard Worker; CHECK: leal [[rloc]], 61*9880d681SAndroid Build Coastguard Worker; CHECK: calll _try_body 62*9880d681SAndroid Build Coastguard Worker; CHECK: [[cont_bb:LBB0_[0-9]+]]: 63*9880d681SAndroid Build Coastguard Worker; CHECK: movl [[rloc]], %eax 64*9880d681SAndroid Build Coastguard Worker; CHECK: retl 65*9880d681SAndroid Build Coastguard Worker 66*9880d681SAndroid Build Coastguard Worker; Landing pad code 67*9880d681SAndroid Build Coastguard Worker 68*9880d681SAndroid Build Coastguard Worker; CHECK: [[handler1:LBB0_[0-9]+]]: # %handler1 69*9880d681SAndroid Build Coastguard Worker; Restore SP 70*9880d681SAndroid Build Coastguard Worker; CHECK: movl {{.*}}(%ebp), %esp 71*9880d681SAndroid Build Coastguard Worker; CHECK: calll _puts 72*9880d681SAndroid Build Coastguard Worker; CHECK: jmp [[cont_bb]] 73*9880d681SAndroid Build Coastguard Worker 74*9880d681SAndroid Build Coastguard Worker; CHECK: [[handler0:LBB0_[0-9]+]]: # %handler0 75*9880d681SAndroid Build Coastguard Worker; Restore SP 76*9880d681SAndroid Build Coastguard Worker; CHECK: movl {{.*}}(%ebp), %esp 77*9880d681SAndroid Build Coastguard Worker; CHECK: calll _puts 78*9880d681SAndroid Build Coastguard Worker; CHECK: jmp [[cont_bb]] 79*9880d681SAndroid Build Coastguard Worker 80*9880d681SAndroid Build Coastguard Worker; CHECK: .section .xdata,"dr" 81*9880d681SAndroid Build Coastguard Worker; CHECK: L__ehtable$safe_div: 82*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .long -1 83*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .long _safe_div_filt1 84*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .long [[handler1]] 85*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .long 0 86*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .long _safe_div_filt0 87*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .long [[handler0]] 88*9880d681SAndroid Build Coastguard Worker 89*9880d681SAndroid Build Coastguard Workerdefine void @try_body(i32* %r, i32* %n, i32* %d) { 90*9880d681SAndroid Build Coastguard Workerentry: 91*9880d681SAndroid Build Coastguard Worker %0 = load i32, i32* %n, align 4 92*9880d681SAndroid Build Coastguard Worker %1 = load i32, i32* %d, align 4 93*9880d681SAndroid Build Coastguard Worker %div = sdiv i32 %0, %1 94*9880d681SAndroid Build Coastguard Worker store i32 %div, i32* %r, align 4 95*9880d681SAndroid Build Coastguard Worker ret void 96*9880d681SAndroid Build Coastguard Worker} 97*9880d681SAndroid Build Coastguard Worker 98*9880d681SAndroid Build Coastguard Worker; The prototype of these filter functions is: 99*9880d681SAndroid Build Coastguard Worker; int filter(EXCEPTION_POINTERS *eh_ptrs, void *rbp); 100*9880d681SAndroid Build Coastguard Worker 101*9880d681SAndroid Build Coastguard Worker; The definition of EXCEPTION_POINTERS is: 102*9880d681SAndroid Build Coastguard Worker; typedef struct _EXCEPTION_POINTERS { 103*9880d681SAndroid Build Coastguard Worker; EXCEPTION_RECORD *ExceptionRecord; 104*9880d681SAndroid Build Coastguard Worker; CONTEXT *ContextRecord; 105*9880d681SAndroid Build Coastguard Worker; } EXCEPTION_POINTERS; 106*9880d681SAndroid Build Coastguard Worker 107*9880d681SAndroid Build Coastguard Worker; The definition of EXCEPTION_RECORD is: 108*9880d681SAndroid Build Coastguard Worker; typedef struct _EXCEPTION_RECORD { 109*9880d681SAndroid Build Coastguard Worker; DWORD ExceptionCode; 110*9880d681SAndroid Build Coastguard Worker; ... 111*9880d681SAndroid Build Coastguard Worker; } EXCEPTION_RECORD; 112*9880d681SAndroid Build Coastguard Worker 113*9880d681SAndroid Build Coastguard Workerdefine i32 @safe_div_filt0() { 114*9880d681SAndroid Build Coastguard Worker %ebp = call i8* @llvm.frameaddress(i32 1) 115*9880d681SAndroid Build Coastguard Worker %eh_ptrs.addr.i8 = getelementptr inbounds i8, i8* %ebp, i32 -20 116*9880d681SAndroid Build Coastguard Worker %eh_ptrs.addr = bitcast i8* %eh_ptrs.addr.i8 to i32*** 117*9880d681SAndroid Build Coastguard Worker %eh_ptrs = load i32**, i32*** %eh_ptrs.addr 118*9880d681SAndroid Build Coastguard Worker %eh_rec = load i32*, i32** %eh_ptrs 119*9880d681SAndroid Build Coastguard Worker %eh_code = load i32, i32* %eh_rec 120*9880d681SAndroid Build Coastguard Worker ; EXCEPTION_ACCESS_VIOLATION = 0xC0000005 121*9880d681SAndroid Build Coastguard Worker %cmp = icmp eq i32 %eh_code, 3221225477 122*9880d681SAndroid Build Coastguard Worker %filt.res = zext i1 %cmp to i32 123*9880d681SAndroid Build Coastguard Worker ret i32 %filt.res 124*9880d681SAndroid Build Coastguard Worker} 125*9880d681SAndroid Build Coastguard Workerdefine i32 @safe_div_filt1() { 126*9880d681SAndroid Build Coastguard Worker %ebp = call i8* @llvm.frameaddress(i32 1) 127*9880d681SAndroid Build Coastguard Worker %eh_ptrs.addr.i8 = getelementptr inbounds i8, i8* %ebp, i32 -20 128*9880d681SAndroid Build Coastguard Worker %eh_ptrs.addr = bitcast i8* %eh_ptrs.addr.i8 to i32*** 129*9880d681SAndroid Build Coastguard Worker %eh_ptrs = load i32**, i32*** %eh_ptrs.addr 130*9880d681SAndroid Build Coastguard Worker %eh_rec = load i32*, i32** %eh_ptrs 131*9880d681SAndroid Build Coastguard Worker %eh_code = load i32, i32* %eh_rec 132*9880d681SAndroid Build Coastguard Worker ; EXCEPTION_INT_DIVIDE_BY_ZERO = 0xC0000094 133*9880d681SAndroid Build Coastguard Worker %cmp = icmp eq i32 %eh_code, 3221225620 134*9880d681SAndroid Build Coastguard Worker %filt.res = zext i1 %cmp to i32 135*9880d681SAndroid Build Coastguard Worker ret i32 %filt.res 136*9880d681SAndroid Build Coastguard Worker} 137*9880d681SAndroid Build Coastguard Worker 138*9880d681SAndroid Build Coastguard Worker@str_result = internal constant [21 x i8] c"safe_div result: %d\0A\00" 139*9880d681SAndroid Build Coastguard Worker 140*9880d681SAndroid Build Coastguard Workerdefine i32 @main() { 141*9880d681SAndroid Build Coastguard Worker %d.addr = alloca i32, align 4 142*9880d681SAndroid Build Coastguard Worker %n.addr = alloca i32, align 4 143*9880d681SAndroid Build Coastguard Worker 144*9880d681SAndroid Build Coastguard Worker store i32 10, i32* %n.addr, align 4 145*9880d681SAndroid Build Coastguard Worker store i32 2, i32* %d.addr, align 4 146*9880d681SAndroid Build Coastguard Worker %r1 = call i32 @safe_div(i32* %n.addr, i32* %d.addr) 147*9880d681SAndroid Build Coastguard Worker call void (i8*, ...) @printf(i8* getelementptr ([21 x i8], [21 x i8]* @str_result, i32 0, i32 0), i32 %r1) 148*9880d681SAndroid Build Coastguard Worker 149*9880d681SAndroid Build Coastguard Worker store i32 10, i32* %n.addr, align 4 150*9880d681SAndroid Build Coastguard Worker store i32 0, i32* %d.addr, align 4 151*9880d681SAndroid Build Coastguard Worker %r2 = call i32 @safe_div(i32* %n.addr, i32* %d.addr) 152*9880d681SAndroid Build Coastguard Worker call void (i8*, ...) @printf(i8* getelementptr ([21 x i8], [21 x i8]* @str_result, i32 0, i32 0), i32 %r2) 153*9880d681SAndroid Build Coastguard Worker 154*9880d681SAndroid Build Coastguard Worker %r3 = call i32 @safe_div(i32* %n.addr, i32* null) 155*9880d681SAndroid Build Coastguard Worker call void (i8*, ...) @printf(i8* getelementptr ([21 x i8], [21 x i8]* @str_result, i32 0, i32 0), i32 %r3) 156*9880d681SAndroid Build Coastguard Worker ret i32 0 157*9880d681SAndroid Build Coastguard Worker} 158*9880d681SAndroid Build Coastguard Worker 159*9880d681SAndroid Build Coastguard Workerdeclare i32 @_except_handler3(...) 160*9880d681SAndroid Build Coastguard Workerdeclare i32 @llvm.eh.typeid.for(i8*) readnone nounwind 161*9880d681SAndroid Build Coastguard Workerdeclare void @puts(i8*) 162*9880d681SAndroid Build Coastguard Workerdeclare void @printf(i8*, ...) 163*9880d681SAndroid Build Coastguard Workerdeclare void @abort() 164*9880d681SAndroid Build Coastguard Workerdeclare i8* @llvm.frameaddress(i32) 165