; RUN: opt < %s -passes=instcombine -S | FileCheck %s
@T1 = external constant i32
@T2 = external constant i32
@T3 = external constant i32
declare i32 @generic_personality(i32, i64, ptr, ptr)
declare i32 @__gxx_personality_v0(i32, i64, ptr, ptr)
declare i32 @__objc_personality_v0(i32, i64, ptr, ptr)
declare i32 @__C_specific_handler(...)
declare void @bar()
define void @foo_generic() personality ptr @generic_personality {
; CHECK-LABEL: @foo_generic(
invoke void @bar()
to label %cont.a unwind label %lpad.a
cont.a:
invoke void @bar()
to label %cont.b unwind label %lpad.b
cont.b:
invoke void @bar()
to label %cont.c unwind label %lpad.c
cont.c:
invoke void @bar()
to label %cont.d unwind label %lpad.d
cont.d:
invoke void @bar()
to label %cont.e unwind label %lpad.e
cont.e:
invoke void @bar()
to label %cont.f unwind label %lpad.f
cont.f:
invoke void @bar()
to label %cont.g unwind label %lpad.g
cont.g:
invoke void @bar()
to label %cont.h unwind label %lpad.h
cont.h:
invoke void @bar()
to label %cont.i unwind label %lpad.i
cont.i:
ret void
lpad.a:
%a = landingpad { ptr, i32 }
catch ptr @T1
catch ptr @T2
catch ptr @T1
catch ptr @T2
unreachable
; CHECK: %a = landingpad
; CHECK-NEXT: @T1
; CHECK-NEXT: @T2
; CHECK-NEXT: unreachable
lpad.b:
%b = landingpad { ptr, i32 }
filter [0 x ptr] zeroinitializer
catch ptr @T1
unreachable
; CHECK: %b = landingpad
; CHECK-NEXT: filter
; CHECK-NEXT: unreachable
lpad.c:
%c = landingpad { ptr, i32 }
catch ptr @T1
filter [1 x ptr] [ptr @T1]
catch ptr @T2
unreachable
; Caught types should not be removed from filters
; CHECK: %c = landingpad
; CHECK-NEXT: catch ptr @T1
; CHECK-NEXT: filter [1 x ptr] [ptr @T1]
; CHECK-NEXT: catch ptr @T2
; CHECK-NEXT: unreachable
lpad.d:
%d = landingpad { ptr, i32 }
filter [3 x ptr] zeroinitializer
unreachable
; CHECK: %d = landingpad
; CHECK-NEXT: filter [1 x ptr] zeroinitializer
; CHECK-NEXT: unreachable
lpad.e:
%e = landingpad { ptr, i32 }
catch ptr @T1
filter [3 x ptr] [ptr @T1, ptr @T2, ptr @T2]
unreachable
; Caught types should not be removed from filters
; CHECK: %e = landingpad
; CHECK-NEXT: catch ptr @T1
; CHECK-NEXT: filter [2 x ptr] [ptr @T1, ptr @T2]
; CHECK-NEXT: unreachable
lpad.f:
%f = landingpad { ptr, i32 }
filter [2 x ptr] [ptr @T2, ptr @T1]
filter [1 x ptr] [ptr @T1]
unreachable
; CHECK: %f = landingpad
; CHECK-NEXT: filter [1 x ptr] [ptr @T1]
; CHECK-NEXT: unreachable
lpad.g:
%g = landingpad { ptr, i32 }
filter [1 x ptr] [ptr @T1]
catch ptr @T3
filter [2 x ptr] [ptr @T2, ptr @T1]
unreachable
; CHECK: %g = landingpad
; CHECK-NEXT: filter [1 x ptr] [ptr @T1]
; CHECK-NEXT: catch ptr @T3
; CHECK-NEXT: unreachable
lpad.h:
%h = landingpad { ptr, i32 }
filter [2 x ptr] [ptr @T1, ptr null]
filter [1 x ptr] zeroinitializer
unreachable
; CHECK: %h = landingpad
; CHECK-NEXT: filter [1 x ptr] zeroinitializer
; CHECK-NEXT: unreachable
lpad.i:
%i = landingpad { ptr, i32 }
cleanup
filter [0 x ptr] zeroinitializer
unreachable
; CHECK: %i = landingpad
; CHECK-NEXT: filter
; CHECK-NEXT: unreachable
}
define void @foo_cxx() personality ptr @__gxx_personality_v0 {
; CHECK-LABEL: @foo_cxx(
invoke void @bar()
to label %cont.a unwind label %lpad.a
cont.a:
invoke void @bar()
to label %cont.b unwind label %lpad.b
cont.b:
invoke void @bar()
to label %cont.c unwind label %lpad.c
cont.c:
invoke void @bar()
to label %cont.d unwind label %lpad.d
cont.d:
ret void
lpad.a:
%a = landingpad { ptr, i32 }
catch ptr null
catch ptr @T1
unreachable
; CHECK: %a = landingpad
; CHECK-NEXT: null
; CHECK-NEXT: unreachable
lpad.b:
%b = landingpad { ptr, i32 }
filter [1 x ptr] zeroinitializer
unreachable
; CHECK: %b = landingpad
; CHECK-NEXT: cleanup
; CHECK-NEXT: unreachable
lpad.c:
%c = landingpad { ptr, i32 }
filter [2 x ptr] [ptr @T1, ptr null]
unreachable
; CHECK: %c = landingpad
; CHECK-NEXT: cleanup
; CHECK-NEXT: unreachable
lpad.d:
%d = landingpad { ptr, i32 }
cleanup
catch ptr null
unreachable
; CHECK: %d = landingpad
; CHECK-NEXT: null
; CHECK-NEXT: unreachable
}
define void @foo_objc() personality ptr @__objc_personality_v0 {
; CHECK-LABEL: @foo_objc(
invoke void @bar()
to label %cont.a unwind label %lpad.a
cont.a:
invoke void @bar()
to label %cont.b unwind label %lpad.b
cont.b:
invoke void @bar()
to label %cont.c unwind label %lpad.c
cont.c:
invoke void @bar()
to label %cont.d unwind label %lpad.d
cont.d:
ret void
lpad.a:
%a = landingpad { ptr, i32 }
catch ptr null
catch ptr @T1
unreachable
; CHECK: %a = landingpad
; CHECK-NEXT: null
; CHECK-NEXT: unreachable
lpad.b:
%b = landingpad { ptr, i32 }
filter [1 x ptr] zeroinitializer
unreachable
; CHECK: %b = landingpad
; CHECK-NEXT: cleanup
; CHECK-NEXT: unreachable
lpad.c:
%c = landingpad { ptr, i32 }
filter [2 x ptr] [ptr @T1, ptr null]
unreachable
; CHECK: %c = landingpad
; CHECK-NEXT: cleanup
; CHECK-NEXT: unreachable
lpad.d:
%d = landingpad { ptr, i32 }
cleanup
catch ptr null
unreachable
; CHECK: %d = landingpad
; CHECK-NEXT: null
; CHECK-NEXT: unreachable
}
define void @foo_seh() personality ptr @__C_specific_handler {
; CHECK-LABEL: @foo_seh(
invoke void @bar()
to label %cont.a unwind label %lpad.a
cont.a:
invoke void @bar()
to label %cont.b unwind label %lpad.b
cont.b:
invoke void @bar()
to label %cont.c unwind label %lpad.c
cont.c:
invoke void @bar()
to label %cont.d unwind label %lpad.d
cont.d:
ret void
lpad.a:
%a = landingpad { ptr, i32 }
catch ptr null
catch ptr @T1
unreachable
; CHECK: %a = landingpad
; CHECK-NEXT: null
; CHECK-NEXT: unreachable
lpad.b:
%b = landingpad { ptr, i32 }
filter [1 x ptr] zeroinitializer
unreachable
; CHECK: %b = landingpad
; CHECK-NEXT: cleanup
; CHECK-NEXT: unreachable
lpad.c:
%c = landingpad { ptr, i32 }
filter [2 x ptr] [ptr @T1, ptr null]
unreachable
; CHECK: %c = landingpad
; CHECK-NEXT: cleanup
; CHECK-NEXT: unreachable
lpad.d:
%d = landingpad { ptr, i32 }
cleanup
catch ptr null
unreachable
; CHECK: %d = landingpad
; CHECK-NEXT: null
; CHECK-NEXT: unreachable
}