diff options
author | Reid Kleckner <reid@kleckner.net> | 2015-07-07 00:36:30 +0000 |
---|---|---|
committer | Reid Kleckner <reid@kleckner.net> | 2015-07-07 00:36:30 +0000 |
commit | 9fe7f2396b5f1960fd3554f0d6c550c17b94b135 (patch) | |
tree | 96ca1c89652a8185b20a326ad963fa1550a594da /clang/test | |
parent | 1faf289e27bcb54e54b2e3e0f492d6f54d59cd9e (diff) | |
download | bcm5719-llvm-9fe7f2396b5f1960fd3554f0d6c550c17b94b135.tar.gz bcm5719-llvm-9fe7f2396b5f1960fd3554f0d6c550c17b94b135.zip |
Revert "Revert 241171, 241187, 241199 (32-bit SEH)."
This reverts commit r241244, but restricts SEH support to Win64.
This way, Chromium builds will still fall back on TUs with SEH, and
Clang developers can work on this incrementally upstream while patching
this small predicate locally. It'll also make it easier to review small
fixes.
llvm-svn: 241533
Diffstat (limited to 'clang/test')
-rw-r--r-- | clang/test/CodeGen/exceptions-seh-finally.c | 67 | ||||
-rw-r--r-- | clang/test/CodeGen/exceptions-seh-leave.c | 8 | ||||
-rw-r--r-- | clang/test/CodeGen/exceptions-seh.c | 136 |
3 files changed, 129 insertions, 82 deletions
diff --git a/clang/test/CodeGen/exceptions-seh-finally.c b/clang/test/CodeGen/exceptions-seh-finally.c index 345d514611e..de602fac416 100644 --- a/clang/test/CodeGen/exceptions-seh-finally.c +++ b/clang/test/CodeGen/exceptions-seh-finally.c @@ -1,4 +1,6 @@ // RUN: %clang_cc1 %s -triple x86_64-pc-win32 -fms-extensions -emit-llvm -o - | FileCheck %s +// FIXME: Re-enable 32-bit SEH. +// RUNX: %clang_cc1 %s -triple i686-pc-win32 -fms-extensions -emit-llvm -o - | FileCheck %s void abort(void) __attribute__((noreturn)); void might_crash(void); @@ -18,17 +20,17 @@ void basic_finally(void) { // // CHECK: [[invoke_cont]] // CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) -// CHECK: call void @"\01?fin$0@0@basic_finally@@"(i8 0, i8* %[[fp]]) +// CHECK: call void @"\01?fin$0@0@basic_finally@@"({{i8( zeroext)?}} 0, i8* %[[fp]]) // 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]]) +// CHECK: call void @"\01?fin$0@0@basic_finally@@"({{i8( zeroext)?}} 1, i8* %[[fp]]) // 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. @@ -58,10 +60,10 @@ l: // // 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]]) +// CHECK: call void @"\01?fin$0@0@label_in_finally@@"({{i8( zeroext)?}} 0, i8* %[[fp]]) // 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]] @@ -85,18 +87,18 @@ void use_abnormal_termination(void) { // // 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]]) +// CHECK: call void @"\01?fin$0@0@use_abnormal_termination@@"({{i8( zeroext)?}} 0, i8* %[[fp]]) // 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]]) +// CHECK: call void @"\01?fin$0@0@use_abnormal_termination@@"({{i8( zeroext)?}} 1, i8* %[[fp]]) // 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 +// CHECK: define internal void @"\01?fin$0@0@use_abnormal_termination@@"({{i8( zeroext)?}} %[[abnormal:abnormal_termination]], i8* %frame_pointer) +// CHECK: %[[abnormal_zext:[^ ]*]] = zext i8 %[[abnormal]] to i32 // CHECK: store i32 %[[abnormal_zext]], i32* @crashed // CHECK-NEXT: ret void @@ -109,11 +111,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 +131,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 +151,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 +172,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 +207,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..158adc0011b 100644 --- a/clang/test/CodeGen/exceptions-seh.c +++ b/clang/test/CodeGen/exceptions-seh.c @@ -1,4 +1,8 @@ -// 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 +// FIXME: Re-enable 32-bit SEH. +// RUNX: %clang_cc1 %s -triple i686-pc-win32 -fms-extensions -emit-llvm -o - \ +// RUNX: | FileCheck %s --check-prefix=CHECK --check-prefix=X86 void try_body(int numerator, int denominator, int *myres) { *myres = numerator / denominator; @@ -19,20 +23,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 +76,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 +116,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 +129,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,40 +156,55 @@ 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) { - ++g; +int basic_finally(int g) { __try { j(); } __finally { - --g; + ++g; } + return g; } -// CHECK-LABEL: define void @basic_finally() {{.*}} personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) -// CHECK: load i32, i32* @g -// CHECK: add i32 %{{.*}}, 1 -// CHECK: store i32 %{{.*}}, i32* @g +// CHECK-LABEL: define i32 @basic_finally(i32 %g) +// X64-SAME: personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) +// X86-SAME: personality i8* bitcast (i32 (...)* @_except_handler3 to i8*) +// CHECK: %[[g_addr:[^ ]*]] = alloca i32, align 4 +// CHECK: call void (...) @llvm.frameescape(i32* %[[g_addr]]) +// CHECK: store i32 %g, i32* %[[g_addr]] // // CHECK: invoke void @j() // 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]]) -// CHECK: ret void +// CHECK: call void @"\01?fin$0@0@basic_finally@@"({{i8( zeroext)?}} 0, i8* %[[fp]]) +// CHECK: load i32, i32* %[[g_addr]], align 4 +// CHECK: ret i32 // // 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]]) +// CHECK: call void @"\01?fin$0@0@basic_finally@@"({{i8( zeroext)?}} 1, i8* %[[fp]]) // CHECK: resume -// CHECK: define internal void @"\01?fin$0@0@basic_finally@@"(i8 %abnormal_termination, i8* %frame_pointer) -// CHECK: load i32, i32* @g, align 4 -// CHECK: add i32 %{{.*}}, -1 -// CHECK: store i32 %{{.*}}, i32* @g, align 4 +// CHECK: define internal void @"\01?fin$0@0@basic_finally@@"({{i8( zeroext)?}} %abnormal_termination, i8* %frame_pointer) +// CHECK: call i8* @llvm.framerecover(i8* bitcast (i32 (i32)* @basic_finally to i8*), i8* %frame_pointer, i32 0) +// CHECK: load i32, i32* %{{.*}}, align 4 +// CHECK: add nsw i32 %{{.*}}, 1 +// CHECK: store i32 %{{.*}}, i32* %{{.*}}, align 4 // CHECK: ret void int returns_int(void); |