diff options
| author | Reid Kleckner <reid@kleckner.net> | 2015-07-01 17:10:10 +0000 |
|---|---|---|
| committer | Reid Kleckner <reid@kleckner.net> | 2015-07-01 17:10:10 +0000 |
| commit | d0d9a1f63f1770458df9efd811fa4455a6aeacae (patch) | |
| tree | d936c40a36f1b8c0dea7624ef1a8a4473b0a5706 /clang/test/CodeGen | |
| parent | f80636682ce2b1588ba3e04fa4ebfd00adac969a (diff) | |
| download | bcm5719-llvm-d0d9a1f63f1770458df9efd811fa4455a6aeacae.tar.gz bcm5719-llvm-d0d9a1f63f1770458df9efd811fa4455a6aeacae.zip | |
[SEH] Add 32-bit lowering for SEH __try
This re-lands r236052 and adds support for __exception_code().
In 32-bit SEH, the exception code is not available in eax. It is only
available in the filter function, and now we arrange to load it and
store it into an escaped variable in the parent frame.
As a consequence, we have to disable the "catch i8* null" optimization
on 32-bit and always generate a filter function. We can re-enable the
optimization if we detect an __except block that doesn't use the
exception code, but this probably isn't worth optimizing.
Reviewers: majnemer
Differential Revision: http://reviews.llvm.org/D10852
llvm-svn: 241171
Diffstat (limited to 'clang/test/CodeGen')
| -rw-r--r-- | clang/test/CodeGen/exceptions-seh-finally.c | 94 | ||||
| -rw-r--r-- | clang/test/CodeGen/exceptions-seh-leave.c | 8 | ||||
| -rw-r--r-- | clang/test/CodeGen/exceptions-seh.c | 118 |
3 files changed, 141 insertions, 79 deletions
diff --git a/clang/test/CodeGen/exceptions-seh-finally.c b/clang/test/CodeGen/exceptions-seh-finally.c index 345d514611e..ad90e4d2b4a 100644 --- a/clang/test/CodeGen/exceptions-seh-finally.c +++ b/clang/test/CodeGen/exceptions-seh-finally.c @@ -1,4 +1,7 @@ -// RUN: %clang_cc1 %s -triple x86_64-pc-win32 -fms-extensions -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -triple x86_64-pc-win32 -fms-extensions -emit-llvm -o - \ +// RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=X64 +// RUN: %clang_cc1 %s -triple i686-pc-win32 -fms-extensions -emit-llvm -o - \ +// RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=X86 void abort(void) __attribute__((noreturn)); void might_crash(void); @@ -17,18 +20,20 @@ void basic_finally(void) { // CHECK: to label %[[invoke_cont:[^ ]*]] unwind label %[[lpad:[^ ]*]] // // CHECK: [[invoke_cont]] -// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) -// CHECK: call void @"\01?fin$0@0@basic_finally@@"(i8 0, i8* %[[fp]]) +// X64: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// X64: call void @"\01?fin$0@0@basic_finally@@"(i8 0, i8* %[[fp]]) +// X86: call void @"\01?fin$0@0@basic_finally@@"() // CHECK-NEXT: ret void // // CHECK: [[lpad]] // CHECK-NEXT: landingpad // CHECK-NEXT: cleanup -// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) -// CHECK: call void @"\01?fin$0@0@basic_finally@@"(i8 1, i8* %[[fp]]) +// X64: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// X64: call void @"\01?fin$0@0@basic_finally@@"(i8 1, i8* %[[fp]]) +// X86: call void @"\01?fin$0@0@basic_finally@@"() // CHECK: resume { i8*, i32 } -// CHECK: define internal void @"\01?fin$0@0@basic_finally@@"(i8 %abnormal_termination, i8* %frame_pointer) +// CHECK: define internal void @"\01?fin$0@0@basic_finally@@"({{.*}}) // CHECK: call void @cleanup() // Mostly check that we don't double emit 'r' which would crash. @@ -57,11 +62,12 @@ l: // CHECK: to label %[[invoke_cont:[^ ]*]] unwind label %[[lpad:[^ ]*]] // // CHECK: [[invoke_cont]] -// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) -// CHECK: call void @"\01?fin$0@0@label_in_finally@@"(i8 0, i8* %[[fp]]) +// X64: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// X64: call void @"\01?fin$0@0@label_in_finally@@"(i8 0, i8* %[[fp]]) +// X86: call void @"\01?fin$0@0@label_in_finally@@"() // CHECK: ret void -// CHECK: define internal void @"\01?fin$0@0@label_in_finally@@"(i8 %abnormal_termination, i8* %frame_pointer) +// CHECK: define internal void @"\01?fin$0@0@label_in_finally@@"({{.*}}) // CHECK: br label %[[l:[^ ]*]] // // CHECK: [[l]] @@ -80,23 +86,34 @@ void use_abnormal_termination(void) { } // CHECK-LABEL: define void @use_abnormal_termination() +// X86: call void (...) @llvm.frameescape(i32* %[[abnormal_termination:[^ ),]*]]) +// X86: store i32 1, i32* %[[abnormal_termination]] // CHECK: invoke void @might_crash() // CHECK: to label %[[invoke_cont:[^ ]*]] unwind label %[[lpad:[^ ]*]] // // CHECK: [[invoke_cont]] -// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) -// CHECK: call void @"\01?fin$0@0@use_abnormal_termination@@"(i8 0, i8* %[[fp]]) +// X64: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// X64: call void @"\01?fin$0@0@use_abnormal_termination@@"(i8 0, i8* %[[fp]]) +// X86: store i32 0, i32* %[[abnormal_termination]] +// X86: call void @"\01?fin$0@0@use_abnormal_termination@@"() // CHECK: ret void // // CHECK: [[lpad]] // CHECK-NEXT: landingpad // CHECK-NEXT: cleanup -// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) -// CHECK: call void @"\01?fin$0@0@use_abnormal_termination@@"(i8 1, i8* %[[fp]]) +// X64: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// X64: call void @"\01?fin$0@0@use_abnormal_termination@@"(i8 1, i8* %[[fp]]) +// X86: call void @"\01?fin$0@0@use_abnormal_termination@@"() // CHECK: resume { i8*, i32 } -// CHECK: define internal void @"\01?fin$0@0@use_abnormal_termination@@"(i8 %abnormal_termination, i8* %frame_pointer) -// CHECK: %[[abnormal_zext:[^ ]*]] = zext i8 %abnormal_termination to i32 +// X64: define internal void @"\01?fin$0@0@use_abnormal_termination@@"(i8 %[[abnormal:abnormal_termination]], i8* %frame_pointer) +// X64: %[[abnormal_zext:[^ ]*]] = zext i8 %[[abnormal]] to i32 +// X86: define internal void @"\01?fin$0@0@use_abnormal_termination@@"() +// X86: %[[ebp:[^ ]*]] = call i8* @llvm.frameaddress(i32 1) +// X86: %[[fp:[^ ]*]] = call i8* @llvm.x86.seh.recoverfp(i8* bitcast (void ()* @use_abnormal_termination to i8*), i8* %[[ebp]]) +// X86: %[[abnormal_i8:[^ ]*]] = call i8* @llvm.framerecover(i8* bitcast (void ()* @use_abnormal_termination to i8*), i8* %[[fp]], i32 0) +// X86: %[[abnormal:[^ ]*]] = bitcast i8* %[[abnormal_i8]] to i32* +// X86: %[[abnormal_zext:[^ ]*]] = load i32, i32* %[[abnormal]] // CHECK: store i32 %[[abnormal_zext]], i32* @crashed // CHECK-NEXT: ret void @@ -109,11 +126,10 @@ void noreturn_noop_finally() { } // CHECK-LABEL: define void @noreturn_noop_finally() -// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) -// CHECK: call void @"\01?fin$0@0@noreturn_noop_finally@@"(i8 0, i8* %[[fp]]) +// CHECK: call void @"\01?fin$0@0@noreturn_noop_finally@@"({{.*}}) // CHECK: ret void -// CHECK: define internal void @"\01?fin$0@0@noreturn_noop_finally@@"(i8 %abnormal_termination, i8* %frame_pointer) +// CHECK: define internal void @"\01?fin$0@0@noreturn_noop_finally@@"({{.*}}) // CHECK: call void @abort() // CHECK: unreachable @@ -130,18 +146,16 @@ void noreturn_finally() { // CHECK: to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]] // // CHECK: [[cont]] -// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) -// CHECK: call void @"\01?fin$0@0@noreturn_finally@@"(i8 0, i8* %[[fp]]) +// CHECK: call void @"\01?fin$0@0@noreturn_finally@@"({{.*}}) // CHECK: ret void // // CHECK: [[lpad]] // CHECK: landingpad // CHECK-NEXT: cleanup -// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) -// CHECK: call void @"\01?fin$0@0@noreturn_finally@@"(i8 1, i8* %[[fp]]) +// CHECK: call void @"\01?fin$0@0@noreturn_finally@@"({{.*}}) // CHECK: resume { i8*, i32 } -// CHECK: define internal void @"\01?fin$0@0@noreturn_finally@@"(i8 %abnormal_termination, i8* %frame_pointer) +// CHECK: define internal void @"\01?fin$0@0@noreturn_finally@@"({{.*}}) // CHECK: call void @abort() // CHECK: unreachable @@ -152,11 +166,10 @@ int finally_with_return() { } } // CHECK-LABEL: define i32 @finally_with_return() -// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) -// CHECK-NEXT: call void @"\01?fin$0@0@finally_with_return@@"(i8 0, i8* %[[fp]]) +// CHECK: call void @"\01?fin$0@0@finally_with_return@@"({{.*}}) // CHECK-NEXT: ret i32 42 -// CHECK: define internal void @"\01?fin$0@0@finally_with_return@@"(i8 %abnormal_termination, i8* %frame_pointer) +// CHECK: define internal void @"\01?fin$0@0@finally_with_return@@"({{.*}}) // CHECK-NOT: br i1 // CHECK-NOT: br label // CHECK: ret void @@ -174,25 +187,22 @@ int nested___finally___finally() { } // CHECK-LABEL: define i32 @nested___finally___finally -// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) -// CHECK: invoke void @"\01?fin$1@0@nested___finally___finally@@"(i8 0, i8* %[[fp]]) +// CHECK: invoke void @"\01?fin$1@0@nested___finally___finally@@"({{.*}}) // CHECK: to label %[[outercont:[^ ]*]] unwind label %[[lpad:[^ ]*]] // // CHECK: [[outercont]] -// CHECK-NEXT: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) -// CHECK-NEXT: call void @"\01?fin$0@0@nested___finally___finally@@"(i8 0, i8* %[[fp]]) +// CHECK: call void @"\01?fin$0@0@nested___finally___finally@@"({{.*}}) // CHECK-NEXT: ret i32 0 // // CHECK: [[lpad]] // CHECK-NEXT: landingpad // CHECK-NEXT: cleanup -// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) -// CHECK-NEXT: call void @"\01?fin$0@0@nested___finally___finally@@"(i8 1, i8* %[[fp]]) +// CHECK: call void @"\01?fin$0@0@nested___finally___finally@@"({{.*}}) -// CHECK-LABEL: define internal void @"\01?fin$0@0@nested___finally___finally@@"(i8 %abnormal_termination, i8* %frame_pointer) +// CHECK-LABEL: define internal void @"\01?fin$0@0@nested___finally___finally@@"({{.*}}) // CHECK: ret void -// CHECK-LABEL: define internal void @"\01?fin$1@0@nested___finally___finally@@"(i8 %abnormal_termination, i8* %frame_pointer) +// CHECK-LABEL: define internal void @"\01?fin$1@0@nested___finally___finally@@"({{.*}}) // CHECK: unreachable int nested___finally___finally_with_eh_edge() { @@ -212,31 +222,27 @@ int nested___finally___finally_with_eh_edge() { // CHECK-NEXT: to label %[[invokecont:[^ ]*]] unwind label %[[lpad1:[^ ]*]] // // [[invokecont]] -// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) -// CHECK: invoke void @"\01?fin$1@0@nested___finally___finally_with_eh_edge@@"(i8 0, i8* %[[fp]]) +// CHECK: invoke void @"\01?fin$1@0@nested___finally___finally_with_eh_edge@@"({{.*}}) // CHECK: to label %[[outercont:[^ ]*]] unwind label %[[lpad2:[^ ]*]] // // CHECK: [[outercont]] -// CHECK-NEXT: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) -// CHECK-NEXT: call void @"\01?fin$0@0@nested___finally___finally_with_eh_edge@@"(i8 0, i8* %[[fp]]) +// CHECK: call void @"\01?fin$0@0@nested___finally___finally_with_eh_edge@@"({{.*}}) // CHECK-NEXT: ret i32 912 // // CHECK: [[lpad1]] // CHECK-NEXT: landingpad // CHECK-NEXT: cleanup -// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) -// CHECK: invoke void @"\01?fin$1@0@nested___finally___finally_with_eh_edge@@"(i8 1, i8* %[[fp]]) +// CHECK: invoke void @"\01?fin$1@0@nested___finally___finally_with_eh_edge@@"({{.*}}) // CHECK: to label %[[outercont:[^ ]*]] unwind label %[[lpad2]] // // CHECK: [[lpad2]] // CHECK-NEXT: landingpad // CHECK-NEXT: cleanup -// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) -// CHECK: call void @"\01?fin$0@0@nested___finally___finally_with_eh_edge@@"(i8 1, i8* %[[fp]]) +// CHECK: call void @"\01?fin$0@0@nested___finally___finally_with_eh_edge@@"({{.*}}) // CHECK: resume -// CHECK-LABEL: define internal void @"\01?fin$0@0@nested___finally___finally_with_eh_edge@@"(i8 %abnormal_termination, i8* %frame_pointer) +// CHECK-LABEL: define internal void @"\01?fin$0@0@nested___finally___finally_with_eh_edge@@"({{.*}}) // CHECK: ret void -// CHECK-LABEL: define internal void @"\01?fin$1@0@nested___finally___finally_with_eh_edge@@"(i8 %abnormal_termination, i8* %frame_pointer) +// CHECK-LABEL: define internal void @"\01?fin$1@0@nested___finally___finally_with_eh_edge@@"({{.*}}) // CHECK: unreachable diff --git a/clang/test/CodeGen/exceptions-seh-leave.c b/clang/test/CodeGen/exceptions-seh-leave.c index 36b896d0624..ca585d4b069 100644 --- a/clang/test/CodeGen/exceptions-seh-leave.c +++ b/clang/test/CodeGen/exceptions-seh-leave.c @@ -205,7 +205,7 @@ int nested___except___except() { // CHECK: br label %[[except:[^ ]*]] // CHECK: [[except]] -// CHECK-NEXT: invoke void @g() +// CHECK: invoke void @g() // CHECK-NEXT: to label %[[g2_cont:.*]] unwind label %[[g2_lpad:.*]] // CHECK: [[g2_cont]] @@ -216,7 +216,7 @@ int nested___except___except() { // CHECK: br label %[[outerexcept:[^ ]*]] // CHECK: [[outerexcept]] -// CHECK-NEXT: br label %[[trycont4:[^ ]*]] +// CHECK: br label %[[trycont4:[^ ]*]] // CHECK: [[trycont4]] // CHECK-NEXT: ret i32 1 @@ -258,11 +258,11 @@ int nested___finally___except() { // CHECK: br label %[[except:[^ ]*]] // CHECK: [[except]] -// CHECK-NEXT: invoke void @g() +// CHECK: invoke void @g() // CHECK-NEXT: to label %[[g2_cont:.*]] unwind label %[[g2_lpad:.*]] // CHECK: [[g2_cont]] -// CHECK-NEXT: br label %[[tryleave:[^ ]*]] +// CHECK: br label %[[tryleave:[^ ]*]] // CHECK-NOT: 23 // CHECK: [[g2_lpad]] diff --git a/clang/test/CodeGen/exceptions-seh.c b/clang/test/CodeGen/exceptions-seh.c index 1b77ad61627..ab6fad6f3ef 100644 --- a/clang/test/CodeGen/exceptions-seh.c +++ b/clang/test/CodeGen/exceptions-seh.c @@ -1,4 +1,7 @@ -// RUN: %clang_cc1 %s -triple x86_64-pc-win32 -fms-extensions -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -triple x86_64-pc-win32 -fms-extensions -emit-llvm -o - \ +// RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=X64 +// RUN: %clang_cc1 %s -triple i686-pc-win32 -fms-extensions -emit-llvm -o - \ +// RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=X86 void try_body(int numerator, int denominator, int *myres) { *myres = numerator / denominator; @@ -19,20 +22,46 @@ int safe_div(int numerator, int denominator, int *res) { *res = myres; return success; } -// CHECK-LABEL: define i32 @safe_div(i32 %numerator, i32 %denominator, i32* %res) {{.*}} personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) -// CHECK: invoke void @try_body(i32 %{{.*}}, i32 %{{.*}}, i32* %{{.*}}) #[[NOINLINE:[0-9]+]] -// CHECK: to label %{{.*}} unwind label %[[lpad:[^ ]*]] -// -// CHECK: [[lpad]] -// CHECK: landingpad { i8*, i32 } -// CHECK-NEXT: catch i8* null -// CHECK-NOT: br i1 -// CHECK: br label %[[except:[^ ]*]] -// CHECK: [[except]] -// CHECK-NEXT: store i32 -42, i32* %[[success:[^ ]*]] -// -// CHECK: %[[res:[^ ]*]] = load i32, i32* %[[success]] -// CHECK: ret i32 %[[res]] + +// X64-LABEL: define i32 @safe_div(i32 %numerator, i32 %denominator, i32* %res) {{.*}} personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) +// X64: invoke void @try_body(i32 %{{.*}}, i32 %{{.*}}, i32* %{{.*}}) #[[NOINLINE:[0-9]+]] +// X64: to label %{{.*}} unwind label %[[lpad:[^ ]*]] +// +// X64: [[lpad]] +// X64: landingpad { i8*, i32 } +// X64-NEXT: catch i8* null +// X64-NOT: br i1 +// X64: br label %[[except:[^ ]*]] +// X64: [[except]] +// X64: store i32 -42, i32* %[[success:[^ ]*]] +// +// X64: %[[res:[^ ]*]] = load i32, i32* %[[success]] +// X64: ret i32 %[[res]] + +// X86-LABEL: define i32 @safe_div(i32 %numerator, i32 %denominator, i32* %res) {{.*}} personality i8* bitcast (i32 (...)* @_except_handler3 to i8*) +// X86: invoke void @try_body(i32 %{{.*}}, i32 %{{.*}}, i32* %{{.*}}) #[[NOINLINE:[0-9]+]] +// X86: to label %{{.*}} unwind label %[[lpad:[^ ]*]] +// +// X86: [[lpad]] +// X86: landingpad { i8*, i32 } +// X86-NEXT: catch i8* bitcast (i32 ()* @"\01?filt$0@0@safe_div@@" to i8*) +// X86-NOT: br i1 +// X86: br label %[[except:[^ ]*]] +// X86: [[except]] +// X86: store i32 -42, i32* %[[success:[^ ]*]] +// +// X86: %[[res:[^ ]*]] = load i32, i32* %[[success]] +// X86: ret i32 %[[res]] + +// X86-LABEL: define internal i32 @"\01?filt$0@0@safe_div@@"() +// X86: %[[ebp:[^ ]*]] = call i8* @llvm.frameaddress(i32 1) +// X86: %[[fp:[^ ]*]] = call i8* @llvm.x86.seh.recoverfp(i8* bitcast (i32 (i32, i32, i32*)* @safe_div to i8*), i8* %[[ebp]]) +// X86: call i8* @llvm.framerecover(i8* bitcast (i32 (i32, i32, i32*)* @safe_div to i8*), i8* %[[fp]], i32 0) +// X86: load i8*, i8** +// X86: load i32*, i32** +// X86: load i32, i32* +// X86: store i32 %{{.*}}, i32* +// X86: ret i32 1 void j(void); @@ -46,20 +75,29 @@ int filter_expr_capture(void) { return r; } -// CHECK-LABEL: define i32 @filter_expr_capture() {{.*}} personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) -// CHECK: call void (...) @llvm.frameescape(i32* %[[r:[^ ,]*]]) +// CHECK-LABEL: define i32 @filter_expr_capture() +// X64-SAME: personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) +// X86-SAME: personality i8* bitcast (i32 (...)* @_except_handler3 to i8*) +// X64: call void (...) @llvm.frameescape(i32* %[[r:[^ ,]*]]) +// X86: call void (...) @llvm.frameescape(i32* %[[r:[^ ,]*]], i32* %[[code:[^ ,]*]]) // CHECK: store i32 42, i32* %[[r]] // CHECK: invoke void @j() #[[NOINLINE]] // // CHECK: landingpad -// CHECK-NEXT: catch i8* bitcast (i32 (i8*, i8*)* @"\01?filt$0@0@filter_expr_capture@@" to i8*) +// CHECK-NEXT: catch i8* bitcast (i32 ({{.*}})* @"\01?filt$0@0@filter_expr_capture@@" to i8*) // CHECK: store i32 13, i32* %[[r]] // // CHECK: %[[rv:[^ ]*]] = load i32, i32* %[[r]] // CHECK: ret i32 %[[rv]] -// CHECK-LABEL: define internal i32 @"\01?filt$0@0@filter_expr_capture@@"(i8* %exception_pointers, i8* %frame_pointer) -// CHECK: call i8* @llvm.framerecover(i8* bitcast (i32 ()* @filter_expr_capture to i8*), i8* %frame_pointer, i32 0) +// X64-LABEL: define internal i32 @"\01?filt$0@0@filter_expr_capture@@"(i8* %exception_pointers, i8* %frame_pointer) +// X64: call i8* @llvm.framerecover(i8* bitcast (i32 ()* @filter_expr_capture to i8*), i8* %frame_pointer, i32 0) +// +// X86-LABEL: define internal i32 @"\01?filt$0@0@filter_expr_capture@@"() +// X86: %[[ebp:[^ ]*]] = call i8* @llvm.frameaddress(i32 1) +// X86: %[[fp:[^ ]*]] = call i8* @llvm.x86.seh.recoverfp(i8* bitcast (i32 ()* @filter_expr_capture to i8*), i8* %[[ebp]]) +// X86: call i8* @llvm.framerecover(i8* bitcast (i32 ()* @filter_expr_capture to i8*), i8* %[[fp]], i32 0) +// // CHECK: store i32 -1, i32* %{{.*}} // CHECK: ret i32 -1 @@ -77,7 +115,9 @@ int nested_try(void) { } return r; } -// CHECK-LABEL: define i32 @nested_try() {{.*}} personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) +// CHECK-LABEL: define i32 @nested_try() +// X64-SAME: personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) +// X86-SAME: personality i8* bitcast (i32 (...)* @_except_handler3 to i8*) // CHECK: store i32 42, i32* %[[r:[^ ,]*]] // CHECK: invoke void @j() #[[NOINLINE]] // CHECK: to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]] @@ -88,18 +128,18 @@ int nested_try(void) { // // CHECK: [[lpad]] // CHECK: landingpad { i8*, i32 } -// CHECK: catch i8* bitcast (i32 (i8*, i8*)* @"\01?filt$1@0@nested_try@@" to i8*) -// CHECK: catch i8* bitcast (i32 (i8*, i8*)* @"\01?filt$0@0@nested_try@@" to i8*) +// CHECK: catch i8* bitcast (i32 ({{.*}})* @"\01?filt$1@0@nested_try@@" to i8*) +// CHECK: catch i8* bitcast (i32 ({{.*}})* @"\01?filt$0@0@nested_try@@" to i8*) // CHECK: store i8* %{{.*}}, i8** %[[ehptr_slot:[^ ]*]] // CHECK: store i32 %{{.*}}, i32* %[[sel_slot:[^ ]*]] // // CHECK: load i32, i32* %[[sel_slot]] -// CHECK: call i32 @llvm.eh.typeid.for(i8* bitcast (i32 (i8*, i8*)* @"\01?filt$1@0@nested_try@@" to i8*)) +// CHECK: call i32 @llvm.eh.typeid.for(i8* bitcast (i32 ({{.*}})* @"\01?filt$1@0@nested_try@@" to i8*)) // CHECK: icmp eq i32 // CHECK: br i1 // // CHECK: load i32, i32* %[[sel_slot]] -// CHECK: call i32 @llvm.eh.typeid.for(i8* bitcast (i32 (i8*, i8*)* @"\01?filt$0@0@nested_try@@" to i8*)) +// CHECK: call i32 @llvm.eh.typeid.for(i8* bitcast (i32 ({{.*}})* @"\01?filt$0@0@nested_try@@" to i8*)) // CHECK: icmp eq i32 // CHECK: br i1 // @@ -115,6 +155,18 @@ int nested_try(void) { // // CHECK: [[inner_try_cont]] // CHECK: br label %[[outer_try_cont]] +// +// CHECK-LABEL: define internal i32 @"\01?filt$0@0@nested_try@@"({{.*}}) +// X86: call i8* @llvm.x86.seh.recoverfp({{.*}}) +// CHECK: load i32*, i32** +// CHECK: load i32, i32* +// CHECK: icmp eq i32 %{{.*}}, 456 +// +// CHECK-LABEL: define internal i32 @"\01?filt$1@0@nested_try@@"({{.*}}) +// X86: call i8* @llvm.x86.seh.recoverfp({{.*}}) +// CHECK: load i32*, i32** +// CHECK: load i32, i32* +// CHECK: icmp eq i32 %{{.*}}, 123 static unsigned g = 0; void basic_finally(void) { @@ -125,7 +177,9 @@ void basic_finally(void) { --g; } } -// CHECK-LABEL: define void @basic_finally() {{.*}} personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) +// CHECK-LABEL: define void @basic_finally() +// X64-SAME: personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) +// X86-SAME: personality i8* bitcast (i32 (...)* @_except_handler3 to i8*) // CHECK: load i32, i32* @g // CHECK: add i32 %{{.*}}, 1 // CHECK: store i32 %{{.*}}, i32* @g @@ -134,18 +188,20 @@ void basic_finally(void) { // CHECK: to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]] // // CHECK: [[cont]] -// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) -// CHECK: call void @"\01?fin$0@0@basic_finally@@"(i8 0, i8* %[[fp]]) +// X64: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// X64: call void @"\01?fin$0@0@basic_finally@@"(i8 0, i8* %[[fp]]) +// X86: call void @"\01?fin$0@0@basic_finally@@"() // CHECK: ret void // // CHECK: [[lpad]] // CHECK: landingpad { i8*, i32 } // CHECK-NEXT: cleanup -// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) -// CHECK: call void @"\01?fin$0@0@basic_finally@@"(i8 1, i8* %[[fp]]) +// X64: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// X64: call void @"\01?fin$0@0@basic_finally@@"(i8 1, i8* %[[fp]]) +// X86: call void @"\01?fin$0@0@basic_finally@@"() // CHECK: resume -// CHECK: define internal void @"\01?fin$0@0@basic_finally@@"(i8 %abnormal_termination, i8* %frame_pointer) +// CHECK: define internal void @"\01?fin$0@0@basic_finally@@"({{.*}}) // CHECK: load i32, i32* @g, align 4 // CHECK: add i32 %{{.*}}, -1 // CHECK: store i32 %{{.*}}, i32* @g, align 4 |

