mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-19 02:52:53 +02:00
[Inliner] Modernize all of the inliner tests that were using grep.
This mostly involved converting from grep to FileCheck and tidying up the IR used. In one case (invoke_test-3.ll) the test had become completely pointless as we use 'resume' rather than 'unwind' now, and even then it did not occur at the end of the line. llvm-svn: 290570
This commit is contained in:
parent
9b6bc7d9d3
commit
a375a1b982
@ -1,53 +1,68 @@
|
||||
; RUN: opt < %s -inline -S | not grep "invoke void asm"
|
||||
; RUN: opt < %s -inline -S | FileCheck %s
|
||||
; PR1335
|
||||
|
||||
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64"
|
||||
target triple = "i686-pc-linux-gnu"
|
||||
%struct.gnat__strings__string_access = type { i8*, %struct.string___XUB* }
|
||||
%struct.string___XUB = type { i32, i32 }
|
||||
|
||||
define void @bc__support__high_resolution_time__clock() {
|
||||
entry:
|
||||
call void asm "rdtsc\0A\09movl %eax, $0\0A\09movl %edx, $1", "=*imr,=*imr,~{dirflag},~{fpsr},~{flags},~{dx},~{ax}"( i32* null, i32* null ) nounwind
|
||||
unreachable
|
||||
}
|
||||
|
||||
define fastcc void @bc__support__high_resolution_time__initialize_clock_rate() personality i32 (...)* @__gxx_personality_v0 {
|
||||
entry:
|
||||
invoke void @gnat__os_lib__getenv( %struct.gnat__strings__string_access* null )
|
||||
to label %invcont unwind label %cleanup144
|
||||
|
||||
invcont: ; preds = %entry
|
||||
invoke void @ada__calendar__delays__delay_for( )
|
||||
to label %invcont64 unwind label %cleanup144
|
||||
|
||||
invcont64: ; preds = %invcont
|
||||
invoke void @ada__calendar__clock( )
|
||||
to label %invcont65 unwind label %cleanup144
|
||||
|
||||
invcont65: ; preds = %invcont64
|
||||
invoke void @bc__support__high_resolution_time__clock( )
|
||||
to label %invcont67 unwind label %cleanup144
|
||||
|
||||
invcont67: ; preds = %invcont65
|
||||
ret void
|
||||
|
||||
cleanup144: ; preds = %invcont65, %invcont64, %invcont, %entry
|
||||
%exn = landingpad {i8*, i32}
|
||||
cleanup
|
||||
resume { i8*, i32 } %exn
|
||||
}
|
||||
|
||||
declare i32 @__gxx_personality_v0(...)
|
||||
|
||||
declare void @gnat__os_lib__getenv(%struct.gnat__strings__string_access*)
|
||||
declare void @a()
|
||||
|
||||
declare void @ada__calendar__delays__delay_for()
|
||||
declare void @b()
|
||||
|
||||
declare void @ada__calendar__clock()
|
||||
declare void @c()
|
||||
|
||||
define void @bc__support__high_resolution_time___elabb() {
|
||||
define void @f() {
|
||||
; CHECK-LABEL: define void @f()
|
||||
entry:
|
||||
call fastcc void @bc__support__high_resolution_time__initialize_clock_rate( )
|
||||
call void asm "rdtsc\0A\09movl %eax, $0\0A\09movl %edx, $1", "=*imr,=*imr,~{dirflag},~{fpsr},~{flags},~{dx},~{ax}"( i32* null, i32* null ) nounwind
|
||||
; CHECK: call void asm
|
||||
unreachable
|
||||
}
|
||||
|
||||
define void @g() personality i32 (...)* @__gxx_personality_v0 {
|
||||
; CHECK-LABEL: define void @g() personality i32 (...)* @__gxx_personality_v0
|
||||
entry:
|
||||
invoke void @a() to label %invcont1 unwind label %cleanup
|
||||
; CHECK-NOT: {{call|invoke}}
|
||||
; CHECK: invoke void @a()
|
||||
|
||||
invcont1:
|
||||
invoke void @b() to label %invcont2 unwind label %cleanup
|
||||
; CHECK-NOT: {{call|invoke}}
|
||||
; CHECK: invoke void @b()
|
||||
|
||||
invcont2:
|
||||
invoke void @c() to label %invcont3 unwind label %cleanup
|
||||
; CHECK-NOT: {{call|invoke}}
|
||||
; CHECK: invoke void @c()
|
||||
|
||||
invcont3:
|
||||
invoke void @f() to label %invcont4 unwind label %cleanup
|
||||
; CHECK-NOT: {{call|invoke}}
|
||||
; CHECK: call void asm
|
||||
; CHECK-NOT: {{call|invoke}}
|
||||
|
||||
invcont4:
|
||||
ret void
|
||||
|
||||
cleanup:
|
||||
%ex = landingpad {i8*, i32} cleanup
|
||||
resume { i8*, i32 } %ex
|
||||
}
|
||||
|
||||
define void @h() {
|
||||
; CHECK-LABEL: define void @h() personality i32 (...)* @__gxx_personality_v0
|
||||
entry:
|
||||
call void @g()
|
||||
; CHECK-NOT: {{call|invoke}}
|
||||
; CHECK: invoke void @a()
|
||||
; CHECK-NOT: {{call|invoke}}
|
||||
; CHECK: invoke void @b()
|
||||
; CHECK-NOT: {{call|invoke}}
|
||||
; CHECK: invoke void @c()
|
||||
; CHECK-NOT: {{call|invoke}}
|
||||
; CHECK: call void asm
|
||||
; CHECK-NOT: {{call|invoke}}
|
||||
|
||||
ret void
|
||||
}
|
||||
|
@ -1,14 +1,17 @@
|
||||
; RUN: opt < %s -inline -S | grep call
|
||||
; RUN: opt < %s -inline -S | FileCheck %s
|
||||
|
||||
; 'bar' can be overridden at link-time, don't inline it.
|
||||
define weak void @bar() {
|
||||
; CHECK-LABEL: define weak void @bar()
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo() {
|
||||
; CHECK-LABEL: define void @foo()
|
||||
entry:
|
||||
tail call void @bar( ) ; <i32> [#uses=0]
|
||||
ret void
|
||||
}
|
||||
|
||||
define weak void @bar() {
|
||||
tail call void @bar()
|
||||
; CHECK: tail call void @bar()
|
||||
ret void
|
||||
}
|
||||
|
||||
|
@ -1,19 +1,34 @@
|
||||
; RUN: opt < %s -inline -S | grep nounwind
|
||||
; RUN: opt < %s -inline -S | grep unreachable
|
||||
; RUN: opt < %s -inline -S | FileCheck %s
|
||||
|
||||
declare i1 @extern()
|
||||
|
||||
define internal i32 @test() {
|
||||
; CHECK-NOT: define .* @test()
|
||||
entry:
|
||||
%n = call i1 @extern()
|
||||
br i1 %n, label %r, label %u
|
||||
|
||||
r:
|
||||
ret i32 0
|
||||
|
||||
u:
|
||||
unreachable
|
||||
}
|
||||
|
||||
define i32 @caller() {
|
||||
; CHECK-LABEL: define i32 @caller()
|
||||
entry:
|
||||
%X = call i32 @test() nounwind
|
||||
; CHECK-NOT: call i32 @test()
|
||||
; CHECK: call i1 @extern() #0
|
||||
; CHECK: br i1 %{{.*}}, label %[[R:.*]], label %[[U:.*]]
|
||||
|
||||
; CHECK: [[U]]:
|
||||
; CHECK: unreachable
|
||||
|
||||
; CHECK: [[R]]:
|
||||
ret i32 %X
|
||||
; CHECK: ret i32 0
|
||||
}
|
||||
|
||||
; CHECK: attributes #0 = { nounwind }
|
||||
|
@ -1,10 +1,16 @@
|
||||
; RUN: opt < %s -inline -S | grep call | count 1
|
||||
; RUN: opt < %s -inline -S | FileCheck %s
|
||||
|
||||
define i32 @fn2() noinline {
|
||||
; CHECK-LABEL: define i32 @fn2()
|
||||
entry:
|
||||
ret i32 1
|
||||
}
|
||||
|
||||
define i32 @fn3() {
|
||||
; CHECK-LABEL: define i32 @fn3()
|
||||
entry:
|
||||
%r = call i32 @fn2()
|
||||
; CHECK: call i32 @fn2()
|
||||
|
||||
ret i32 %r
|
||||
}
|
||||
|
@ -1,36 +1,39 @@
|
||||
; RUN: opt < %s -inline -S | grep call
|
||||
; Do not inline calls to variable-sized alloca.
|
||||
; RUN: opt < %s -inline -S | FileCheck %s
|
||||
; Do not inline calls with variable-sized alloca.
|
||||
|
||||
@q = common global i8* null ; <i8**> [#uses=1]
|
||||
@q = common global i8* null
|
||||
|
||||
define i8* @a(i32 %i) nounwind {
|
||||
; CHECK-LABEL: define i8* @a
|
||||
entry:
|
||||
%i_addr = alloca i32 ; <i32*> [#uses=2]
|
||||
%retval = alloca i8* ; <i8**> [#uses=1]
|
||||
%p = alloca i8* ; <i8**> [#uses=2]
|
||||
%"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
|
||||
%i_addr = alloca i32
|
||||
%retval = alloca i8*
|
||||
%p = alloca i8*
|
||||
%"alloca point" = bitcast i32 0 to i32
|
||||
store i32 %i, i32* %i_addr
|
||||
%0 = load i32, i32* %i_addr, align 4 ; <i32> [#uses=1]
|
||||
%1 = alloca i8, i32 %0 ; <i8*> [#uses=1]
|
||||
%0 = load i32, i32* %i_addr, align 4
|
||||
%1 = alloca i8, i32 %0
|
||||
store i8* %1, i8** %p, align 4
|
||||
%2 = load i8*, i8** %p, align 4 ; <i8*> [#uses=1]
|
||||
%2 = load i8*, i8** %p, align 4
|
||||
store i8* %2, i8** @q, align 4
|
||||
br label %return
|
||||
|
||||
return: ; preds = %entry
|
||||
%retval1 = load i8*, i8** %retval ; <i8*> [#uses=1]
|
||||
return:
|
||||
%retval1 = load i8*, i8** %retval
|
||||
ret i8* %retval1
|
||||
}
|
||||
|
||||
define void @b(i32 %i) nounwind {
|
||||
; CHECK-LABEL: define void @b
|
||||
entry:
|
||||
%i_addr = alloca i32 ; <i32*> [#uses=2]
|
||||
%"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
|
||||
%i_addr = alloca i32
|
||||
%"alloca point" = bitcast i32 0 to i32
|
||||
store i32 %i, i32* %i_addr
|
||||
%0 = load i32, i32* %i_addr, align 4 ; <i32> [#uses=1]
|
||||
%1 = call i8* @a(i32 %0) nounwind ; <i8*> [#uses=0]
|
||||
%0 = load i32, i32* %i_addr, align 4
|
||||
%1 = call i8* @a(i32 %0) nounwind
|
||||
; CHECK: call i8* @a
|
||||
br label %return
|
||||
|
||||
return: ; preds = %entry
|
||||
return:
|
||||
ret void
|
||||
}
|
||||
|
@ -1,19 +1,17 @@
|
||||
; RUN: opt < %s -inline -S | grep "ret i32 1"
|
||||
; ModuleID = 'short.opt.bc'
|
||||
|
||||
define i32 @testBool(i1 %X) {
|
||||
%tmp = zext i1 %X to i32 ; <i32> [#uses=1]
|
||||
ret i32 %tmp
|
||||
}
|
||||
; RUN: opt < %s -inline -S | FileCheck %s
|
||||
|
||||
define i32 @testByte(i8 %X) {
|
||||
%tmp = icmp ne i8 %X, 0 ; <i1> [#uses=1]
|
||||
%tmp.i = zext i1 %tmp to i32 ; <i32> [#uses=1]
|
||||
entry:
|
||||
%tmp = icmp ne i8 %X, 0
|
||||
%tmp.i = zext i1 %tmp to i32
|
||||
ret i32 %tmp.i
|
||||
}
|
||||
|
||||
define i32 @main() {
|
||||
%rslt = call i32 @testByte( i8 123 ) ; <i32> [#uses=1]
|
||||
; CHECK-LABEL: define i32 @main()
|
||||
entry:
|
||||
%rslt = call i32 @testByte(i8 123)
|
||||
; CHECK-NOT: call
|
||||
ret i32 %rslt
|
||||
; CHECK: ret i32 1
|
||||
}
|
||||
|
||||
|
@ -1,16 +1,20 @@
|
||||
; This test ensures that inlining an "empty" function does not destroy the CFG
|
||||
;
|
||||
; RUN: opt < %s -inline -S | not grep br
|
||||
; RUN: opt < %s -inline -S | FileCheck %s
|
||||
|
||||
define i32 @func(i32 %i) {
|
||||
ret i32 %i
|
||||
}
|
||||
|
||||
declare void @bar()
|
||||
|
||||
define i32 @main(i32 %argc) {
|
||||
Entry:
|
||||
%X = call i32 @func( i32 7 ) ; <i32> [#uses=1]
|
||||
define i32 @main() {
|
||||
; CHECK-LABEL: define i32 @main()
|
||||
entry:
|
||||
%X = call i32 @func(i32 7)
|
||||
; CHECK-NOT: call
|
||||
; CHECK-NOT: br
|
||||
|
||||
ret i32 %X
|
||||
; CHECK: ret i32 7
|
||||
}
|
||||
|
||||
|
@ -1,16 +1,22 @@
|
||||
; RUN: opt < %s -inline -constprop -S > %t
|
||||
; RUN: not grep test_function %t
|
||||
; RUN: grep "ret i32 5" %t
|
||||
; RUN: opt < %s -inline -constprop -S | FileCheck %s
|
||||
|
||||
|
||||
; test_function should not be emitted to the .s file.
|
||||
define available_externally i32 @test_function() {
|
||||
; CHECK-NOT: @test_function
|
||||
entry:
|
||||
ret i32 4
|
||||
}
|
||||
|
||||
|
||||
define i32 @result() {
|
||||
; CHECK-LABEL: define i32 @result()
|
||||
entry:
|
||||
%A = call i32 @test_function()
|
||||
; CHECK-NOT: call
|
||||
; CHECK-NOT: @test_function
|
||||
|
||||
%B = add i32 %A, 1
|
||||
ret i32 %B
|
||||
; CHECK: ret i32 5
|
||||
}
|
||||
|
||||
; CHECK-NOT: @test_function
|
||||
|
@ -2,6 +2,8 @@
|
||||
; PR3550
|
||||
|
||||
define internal void @foo(i32* %p, i32* %q) {
|
||||
; CHECK-NOT: @foo
|
||||
entry:
|
||||
%pp = bitcast i32* %p to i8*
|
||||
%qq = bitcast i32* %q to i8*
|
||||
tail call void @llvm.memcpy.p0i8.p0i8.i32(i8* %pp, i8* %qq, i32 4, i32 1, i1 false)
|
||||
@ -9,12 +11,19 @@ define internal void @foo(i32* %p, i32* %q) {
|
||||
}
|
||||
|
||||
define i32 @main() personality i32 (...)* @__gxx_personality_v0 {
|
||||
%a = alloca i32 ; <i32*> [#uses=3]
|
||||
%b = alloca i32 ; <i32*> [#uses=2]
|
||||
; CHECK-LABEL: define i32 @main() personality i32 (...)* @__gxx_personality_v0
|
||||
entry:
|
||||
%a = alloca i32
|
||||
%b = alloca i32
|
||||
store i32 1, i32* %a, align 4
|
||||
store i32 0, i32* %b, align 4
|
||||
invoke void @foo(i32* %a, i32* %b)
|
||||
to label %invcont unwind label %lpad
|
||||
; CHECK-NOT: invoke
|
||||
; CHECK-NOT: @foo
|
||||
; CHECK-NOT: tail
|
||||
; CHCEK: call void @llvm.memcpy.p0i8.p0i8.i32
|
||||
; CHECK: br
|
||||
|
||||
invcont:
|
||||
%retval = load i32, i32* %a, align 4
|
||||
|
@ -5,21 +5,32 @@
|
||||
; RUN: not grep @reallysmall
|
||||
|
||||
define internal i32 @reallysmall(i32 %A) {
|
||||
; CHECK-NOT: @reallysmall
|
||||
entry:
|
||||
ret i32 %A
|
||||
}
|
||||
|
||||
define void @caller1() {
|
||||
call i32 @reallysmall( i32 5 ) ; <i32>:1 [#uses=0]
|
||||
; CHECK-LABEL: define void @caller1()
|
||||
entry:
|
||||
call i32 @reallysmall(i32 5)
|
||||
; CHECK-NOT: call
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @caller2(i32 %A) {
|
||||
call i32 @reallysmall( i32 %A ) ; <i32>:1 [#uses=0]
|
||||
; CHECK-LABEL: define void @caller2(i32 %A)
|
||||
entry:
|
||||
call i32 @reallysmall(i32 %A)
|
||||
; CHECK-NOT: call
|
||||
ret void
|
||||
}
|
||||
|
||||
define i32 @caller3(i32 %A) {
|
||||
%B = call i32 @reallysmall( i32 %A ) ; <i32> [#uses=1]
|
||||
; CHECK-LABEL: define void @caller3(i32 %A)
|
||||
entry:
|
||||
%B = call i32 @reallysmall(i32 %A)
|
||||
; CHECK-NOT: call
|
||||
ret i32 %B
|
||||
}
|
||||
|
||||
|
@ -1,45 +1,53 @@
|
||||
; RUN: opt < %s -inline -S | \
|
||||
; RUN: not grep "callee[12]("
|
||||
; RUN: opt < %s -inline -S | not grep mul
|
||||
; RUN: opt < %s -inline -S | FileCheck %s
|
||||
|
||||
define internal i32 @callee1(i32 %A, i32 %B) {
|
||||
%cond = icmp eq i32 %A, 123 ; <i1> [#uses=1]
|
||||
; CHECK-NOT: @callee1
|
||||
entry:
|
||||
%cond = icmp eq i32 %A, 123
|
||||
br i1 %cond, label %T, label %F
|
||||
|
||||
T: ; preds = %0
|
||||
%C = mul i32 %B, %B ; <i32> [#uses=1]
|
||||
T:
|
||||
%C = mul i32 %B, %B
|
||||
ret i32 %C
|
||||
|
||||
F: ; preds = %0
|
||||
F:
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
define internal i32 @callee2(i32 %A, i32 %B) {
|
||||
; CHECK-NOT: @callee2
|
||||
entry:
|
||||
switch i32 %A, label %T [
|
||||
i32 10, label %F
|
||||
i32 1234, label %G
|
||||
]
|
||||
; No predecessors!
|
||||
%cond = icmp eq i32 %A, 123 ; <i1> [#uses=1]
|
||||
|
||||
dead:
|
||||
%cond = icmp eq i32 %A, 123
|
||||
br i1 %cond, label %T, label %F
|
||||
|
||||
T: ; preds = %1, %0
|
||||
%C = mul i32 %B, %B ; <i32> [#uses=1]
|
||||
T:
|
||||
%C = mul i32 %B, %B
|
||||
ret i32 %C
|
||||
|
||||
F: ; preds = %1, %0
|
||||
F:
|
||||
ret i32 0
|
||||
|
||||
G: ; preds = %0
|
||||
%D = mul i32 %B, %B ; <i32> [#uses=1]
|
||||
%E = mul i32 %D, %B ; <i32> [#uses=1]
|
||||
G:
|
||||
%D = mul i32 %B, %B
|
||||
%E = mul i32 %D, %B
|
||||
ret i32 %E
|
||||
}
|
||||
|
||||
define i32 @test(i32 %A) {
|
||||
%X = call i32 @callee1( i32 10, i32 %A ) ; <i32> [#uses=1]
|
||||
%Y = call i32 @callee2( i32 10, i32 %A ) ; <i32> [#uses=1]
|
||||
%Z = add i32 %X, %Y ; <i32> [#uses=1]
|
||||
; CHECK-LABEL: define i32 @test(i32 %A)
|
||||
entry:
|
||||
%X = call i32 @callee1( i32 10, i32 %A )
|
||||
%Y = call i32 @callee2( i32 10, i32 %A )
|
||||
; CHECK-NOT: call
|
||||
; CHECK-NOT: mul
|
||||
|
||||
%Z = add i32 %X, %Y
|
||||
ret i32 %Z
|
||||
}
|
||||
|
||||
|
@ -1,25 +1,29 @@
|
||||
; Test that we can inline a simple function, turning the calls in it into invoke
|
||||
; instructions
|
||||
|
||||
; RUN: opt < %s -inline -S | \
|
||||
; RUN: not grep "call[^e]"
|
||||
; RUN: opt < %s -inline -S | FileCheck %s
|
||||
|
||||
declare void @might_throw()
|
||||
|
||||
define internal void @callee() {
|
||||
entry:
|
||||
call void @might_throw()
|
||||
ret void
|
||||
}
|
||||
|
||||
; caller returns true if might_throw throws an exception...
|
||||
define i32 @caller() personality i32 (...)* @__gxx_personality_v0 {
|
||||
; CHECK-LABEL: define i32 @caller() personality i32 (...)* @__gxx_personality_v0
|
||||
entry:
|
||||
invoke void @callee()
|
||||
to label %cont unwind label %exc
|
||||
; CHECK-NOT: @callee
|
||||
; CHECK: invoke void @might_throw()
|
||||
|
||||
cont: ; preds = %0
|
||||
cont:
|
||||
ret i32 0
|
||||
|
||||
exc: ; preds = %0
|
||||
exc:
|
||||
%exn = landingpad {i8*, i32}
|
||||
cleanup
|
||||
ret i32 1
|
||||
|
@ -1,19 +1,19 @@
|
||||
; Test that if an invoked function is inlined, and if that function cannot
|
||||
; throw, that the dead handler is now unreachable.
|
||||
|
||||
; RUN: opt < %s -inline -simplifycfg -S | \
|
||||
; RUN: not grep UnreachableExceptionHandler
|
||||
; RUN: opt < %s -inline -simplifycfg -S | FileCheck %s
|
||||
|
||||
declare void @might_throw()
|
||||
|
||||
define internal i32 @callee() personality i32 (...)* @__gxx_personality_v0 {
|
||||
enrty:
|
||||
invoke void @might_throw()
|
||||
to label %cont unwind label %exc
|
||||
|
||||
cont: ; preds = %0
|
||||
cont:
|
||||
ret i32 0
|
||||
|
||||
exc: ; preds = %0
|
||||
exc:
|
||||
%exn = landingpad {i8*, i32}
|
||||
cleanup
|
||||
ret i32 1
|
||||
@ -21,16 +21,32 @@ exc: ; preds = %0
|
||||
|
||||
; caller returns true if might_throw throws an exception... callee cannot throw.
|
||||
define i32 @caller() personality i32 (...)* @__gxx_personality_v0 {
|
||||
; CHECK-LABEL: define i32 @caller() personality i32 (...)* @__gxx_personality_v0
|
||||
enrty:
|
||||
%X = invoke i32 @callee()
|
||||
to label %cont unwind label %UnreachableExceptionHandler ; <i32> [#uses=1]
|
||||
to label %cont unwind label %UnreachableExceptionHandler
|
||||
; CHECK-NOT: @callee
|
||||
; CHECK: invoke void @might_throw()
|
||||
; CHECK: to label %[[C:.*]] unwind label %[[E:.*]]
|
||||
|
||||
cont: ; preds = %0
|
||||
; CHECK: [[E]]:
|
||||
; CHECK: landingpad
|
||||
; CHECK: cleanup
|
||||
; CHECK: br label %[[C]]
|
||||
|
||||
cont:
|
||||
; CHECK: [[C]]:
|
||||
ret i32 %X
|
||||
; CHECK: %[[PHI:.*]] = phi i32
|
||||
; CHECK: ret i32 %[[PHI]]
|
||||
|
||||
UnreachableExceptionHandler: ; preds = %0
|
||||
UnreachableExceptionHandler:
|
||||
; CHECK-NOT: UnreachableExceptionHandler:
|
||||
%exn = landingpad {i8*, i32}
|
||||
cleanup
|
||||
ret i32 -1
|
||||
; CHECK-NOT: ret i32 -1
|
||||
}
|
||||
; CHECK: }
|
||||
|
||||
declare i32 @__gxx_personality_v0(...)
|
||||
|
@ -1,18 +1,19 @@
|
||||
; Test that any rethrown exceptions in an inlined function are automatically
|
||||
; turned into branches to the invoke destination.
|
||||
|
||||
; RUN: opt < %s -inline -S | not grep unwind$
|
||||
; RUN: opt < %s -inline -S | FileCheck %s
|
||||
|
||||
declare void @might_throw()
|
||||
|
||||
define internal i32 @callee() personality i32 (...)* @__gxx_personality_v0 {
|
||||
entry:
|
||||
invoke void @might_throw()
|
||||
to label %cont unwind label %exc
|
||||
|
||||
cont: ; preds = %0
|
||||
cont:
|
||||
ret i32 0
|
||||
|
||||
exc: ; preds = %0a
|
||||
exc:
|
||||
; This just rethrows the exception!
|
||||
%exn = landingpad {i8*, i32}
|
||||
cleanup
|
||||
@ -22,13 +23,21 @@ exc: ; preds = %0a
|
||||
; caller returns true if might_throw throws an exception... which gets
|
||||
; propagated by callee.
|
||||
define i32 @caller() personality i32 (...)* @__gxx_personality_v0 {
|
||||
; CHECK-LABEL: define i32 @caller()
|
||||
entry:
|
||||
%X = invoke i32 @callee()
|
||||
to label %cont unwind label %Handler ; <i32> [#uses=1]
|
||||
to label %cont unwind label %Handler
|
||||
; CHECK-NOT: @callee
|
||||
; CHECK: invoke void @might_throw()
|
||||
; At this point we just check that the rest of the function does not 'resume'
|
||||
; at any point and instead the inlined resume is threaded into normal control
|
||||
; flow.
|
||||
; CHECK-NOT: resume
|
||||
|
||||
cont: ; preds = %0
|
||||
cont:
|
||||
ret i32 %X
|
||||
|
||||
Handler: ; preds = %0
|
||||
Handler:
|
||||
; This consumes an exception thrown by might_throw
|
||||
%exn = landingpad {i8*, i32}
|
||||
cleanup
|
||||
|
Loading…
Reference in New Issue
Block a user