diff options
Diffstat (limited to 'test/CodeGen/WinEH/seh-simple.ll')
-rw-r--r-- | test/CodeGen/WinEH/seh-simple.ll | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/test/CodeGen/WinEH/seh-simple.ll b/test/CodeGen/WinEH/seh-simple.ll new file mode 100644 index 0000000..26b3f83 --- /dev/null +++ b/test/CodeGen/WinEH/seh-simple.ll @@ -0,0 +1,138 @@ +; RUN: opt -S -winehprepare -sehprepare -mtriple=x86_64-windows-msvc < %s | FileCheck %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-windows-msvc" + +declare void @cleanup() +declare i32 @filt() +declare void @might_crash() +declare i32 @__C_specific_handler(...) +declare i32 @llvm.eh.typeid.for(i8*) + +define i32 @simple_except_store() { +entry: + %retval = alloca i32 + store i32 0, i32* %retval + invoke void @might_crash() + to label %return unwind label %lpad + +lpad: + %ehvals = landingpad { i8*, i32 } personality i32 (...)* @__C_specific_handler + catch i32 ()* @filt + %sel = extractvalue { i8*, i32 } %ehvals, 1 + %filt_sel = tail call i32 @llvm.eh.typeid.for(i8* bitcast (i32 ()* @filt to i8*)) + %matches = icmp eq i32 %sel, %filt_sel + br i1 %matches, label %__except, label %eh.resume + +__except: + store i32 1, i32* %retval + br label %return + +return: + %r = load i32, i32* %retval + ret i32 %r + +eh.resume: + resume { i8*, i32 } %ehvals +} + +; CHECK-LABEL: define i32 @simple_except_store() +; CHECK: landingpad { i8*, i32 } +; CHECK-NEXT: catch i32 ()* @filt +; CHECK-NEXT: call i8* (...)* @llvm.eh.actions(i32 1, i8* bitcast (i32 ()* @filt to i8*), i8* null, i8* blockaddress(@simple_except_store, %__except)) +; CHECK-NEXT: indirectbr {{.*}} [label %__except] + +define i32 @catch_all() { +entry: + %retval = alloca i32 + store i32 0, i32* %retval + invoke void @might_crash() + to label %return unwind label %lpad + +lpad: + %ehvals = landingpad { i8*, i32 } personality i32 (...)* @__C_specific_handler + catch i8* null + store i32 1, i32* %retval + br label %return + +return: + %r = load i32, i32* %retval + ret i32 %r +} + +; CHECK-LABEL: define i32 @catch_all() +; CHECK: landingpad { i8*, i32 } +; CHECK-NEXT: catch i8* null +; CHECK-NEXT: call i8* (...)* @llvm.eh.actions(i32 1, i8* null, i8* null, i8* blockaddress(@catch_all, %catch.all)) +; CHECK-NEXT: indirectbr {{.*}} [label %catch.all] +; +; CHECK: catch.all: +; CHECK: store i32 1, i32* %retval + + +define i32 @except_phi() { +entry: + invoke void @might_crash() + to label %return unwind label %lpad + +lpad: + %ehvals = landingpad { i8*, i32 } personality i32 (...)* @__C_specific_handler + catch i32 ()* @filt + %sel = extractvalue { i8*, i32 } %ehvals, 1 + %filt_sel = tail call i32 @llvm.eh.typeid.for(i8* bitcast (i32 ()* @filt to i8*)) + %matches = icmp eq i32 %sel, %filt_sel + br i1 %matches, label %return, label %eh.resume + +return: + %r = phi i32 [0, %entry], [1, %lpad] + ret i32 %r + +eh.resume: + resume { i8*, i32 } %ehvals +} + +; CHECK-LABEL: define i32 @except_phi() +; CHECK: landingpad { i8*, i32 } +; CHECK-NEXT: catch i32 ()* @filt +; CHECK-NEXT: call i8* (...)* @llvm.eh.actions(i32 1, i8* bitcast (i32 ()* @filt to i8*), i8* null, i8* blockaddress(@except_phi, %return)) +; CHECK-NEXT: indirectbr {{.*}} [label %return] +; +; CHECK: return: +; CHECK-NEXT: %r = phi i32 [ 0, %entry ], [ 1, %lpad1 ] +; CHECK-NEXT: ret i32 %r + +define i32 @cleanup_and_except() { +entry: + invoke void @might_crash() + to label %return unwind label %lpad + +lpad: + %ehvals = landingpad { i8*, i32 } personality i32 (...)* @__C_specific_handler + cleanup + catch i32 ()* @filt + call void @cleanup() + %sel = extractvalue { i8*, i32 } %ehvals, 1 + %filt_sel = tail call i32 @llvm.eh.typeid.for(i8* bitcast (i32 ()* @filt to i8*)) + %matches = icmp eq i32 %sel, %filt_sel + br i1 %matches, label %return, label %eh.resume + +return: + %r = phi i32 [0, %entry], [1, %lpad] + ret i32 %r + +eh.resume: + resume { i8*, i32 } %ehvals +} + +; CHECK-LABEL: define i32 @cleanup_and_except() +; CHECK: landingpad { i8*, i32 } +; CHECK-NEXT: cleanup +; CHECK-NEXT: catch i32 ()* @filt +; CHECK-NEXT: call i8* (...)* @llvm.eh.actions( +; CHECK: i32 0, void (i8*, i8*)* @cleanup_and_except.cleanup, +; CHECK: i32 1, i8* bitcast (i32 ()* @filt to i8*), i8* null, i8* blockaddress(@cleanup_and_except, %return)) +; CHECK-NEXT: indirectbr {{.*}} [label %return] +; +; CHECK: return: +; CHECK-NEXT: %r = phi i32 [ 0, %entry ], [ 1, %lpad1 ] +; CHECK-NEXT: ret i32 %r |