mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-15 20:29:48 +00:00
39789f81ab
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
67 lines
2.2 KiB
LLVM
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()
|