summaryrefslogtreecommitdiffstats
path: root/clang/test/CodeGen
diff options
context:
space:
mode:
authorReid Kleckner <reid@kleckner.net>2015-07-01 17:10:10 +0000
committerReid Kleckner <reid@kleckner.net>2015-07-01 17:10:10 +0000
commitd0d9a1f63f1770458df9efd811fa4455a6aeacae (patch)
treed936c40a36f1b8c0dea7624ef1a8a4473b0a5706 /clang/test/CodeGen
parentf80636682ce2b1588ba3e04fa4ebfd00adac969a (diff)
downloadbcm5719-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.c94
-rw-r--r--clang/test/CodeGen/exceptions-seh-leave.c8
-rw-r--r--clang/test/CodeGen/exceptions-seh.c118
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
OpenPOWER on IntegriCloud