llvm-6502/test/CodeGen/WinEH/seh-resume-phi.ll
Reid Kleckner 39789f81ab [SEH] Implement GetExceptionCode in __except blocks
This introduces an intrinsic called llvm.eh.exceptioncode. It is lowered
by copying the EAX value live into whatever basic block it is called
from. Obviously, this only works if you insert it late during codegen,
because otherwise mid-level passes might reschedule it.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@235768 91177308-0d34-0410-b5e6-96231b3b80d8
2015-04-24 20:25:05 +00:00

67 lines
2.2 KiB
LLVM

; RUN: opt -S -winehprepare < %s | FileCheck %s
target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-windows-msvc"
declare void @might_crash(i8* %ehptr)
declare i32 @filt()
declare void @cleanup()
declare i32 @__C_specific_handler(...)
declare i32 @llvm.eh.typeid.for(i8*)
define void @resume_phi() {
entry:
invoke void @might_crash(i8* null)
to label %return unwind label %lpad1
lpad1:
%ehvals1 = landingpad { i8*, i32 } personality i32 (...)* @__C_specific_handler
catch i32 ()* @filt
%ehptr1 = extractvalue { i8*, i32 } %ehvals1, 0
%ehsel1 = extractvalue { i8*, i32 } %ehvals1, 1
%filt_sel = tail call i32 @llvm.eh.typeid.for(i8* bitcast (i32 ()* @filt to i8*))
%matches = icmp eq i32 %ehsel1, %filt_sel
br i1 %matches, label %__except, label %eh.resume
__except:
invoke void @might_crash(i8* %ehptr1)
to label %return unwind label %lpad2
lpad2:
%ehvals2 = landingpad { i8*, i32 } personality i32 (...)* @__C_specific_handler
cleanup
%ehptr2 = extractvalue { i8*, i32 } %ehvals2, 0
%ehsel2 = extractvalue { i8*, i32 } %ehvals2, 1
call void @cleanup()
br label %eh.resume
return:
ret void
eh.resume:
%ehptr.phi = phi i8* [ %ehptr1, %lpad1 ], [ %ehptr2, %lpad2 ]
%ehsel.phi = phi i32 [ %ehsel1, %lpad1 ], [ %ehsel2, %lpad2 ]
%ehval.phi1 = insertvalue { i8*, i32 } undef, i8* %ehptr.phi, 0
%ehval.phi2 = insertvalue { i8*, i32 } %ehval.phi1, i32 %ehsel.phi, 1
resume { i8*, i32 } %ehval.phi2
}
; CHECK-LABEL: define void @resume_phi()
; CHECK: invoke void @might_crash(i8* null)
; CHECK: landingpad { i8*, i32 }
; CHECK-NEXT: catch i32 ()* @filt
; CHECK-NEXT: call i8* (...) @llvm.eh.actions(
; CHECK-SAME: i32 1, i8* bitcast (i32 ()* @filt to i8*), i32 -1, i8* blockaddress(@resume_phi, %__except))
; CHECK-NEXT: indirectbr {{.*}} [label %__except]
;
; CHECK: __except:
; CHECK: call i32 @llvm.eh.exceptioncode()
; CHECK: invoke void @might_crash(i8* %{{.*}})
; CHECK: landingpad { i8*, i32 }
; CHECK-NEXT: cleanup
; CHECK-NEXT: call i8* (...) @llvm.eh.actions(i32 0, void (i8*, i8*)* @resume_phi.cleanup)
; CHECK-NEXT: indirectbr {{.*}} []
; CHECK-LABEL: define internal void @resume_phi.cleanup(i8*, i8*)
; CHECK: call void @cleanup()