blob: eba56c9630adbbab2425a8b8f646399ce14036f0 [file] [log] [blame]
; RUN: opt < %s -passes='function-attrs' -S | FileCheck %s
declare i32 @f()
; CHECK: Function Attrs: noreturn
; CHECK-NEXT: @noreturn()
declare i32 @noreturn() noreturn
; CHECK: Function Attrs: noreturn
; CHECK-NEXT: @caller()
define i32 @caller() {
%c = call i32 @noreturn()
ret i32 %c
}
; CHECK: Function Attrs: noreturn
; CHECK-NEXT: @caller2()
define i32 @caller2() {
%c = call i32 @caller()
ret i32 %c
}
; CHECK: Function Attrs: noreturn
; CHECK-NEXT: @caller3()
define i32 @caller3() {
entry:
br label %end
end:
%c = call i32 @noreturn()
ret i32 %c
}
; CHECK-NOT: Function Attrs: {{.*}}noreturn
; CHECK: define i32 @caller4()
define i32 @caller4() {
entry:
br label %end
end:
%c = call i32 @f()
ret i32 %c
}
; CHECK-NOT: Function Attrs: {{.*}}noreturn
; CHECK: @caller5()
; We currently don't handle unreachable blocks.
define i32 @caller5() {
entry:
%c = call i32 @noreturn()
ret i32 %c
unreach:
%d = call i32 @f()
ret i32 %d
}
; CHECK-NOT: Function Attrs: {{.*}}noreturn
; CHECK: @caller6()
define i32 @caller6() naked {
%c = call i32 @noreturn()
ret i32 %c
}
; CHECK: Function Attrs: {{.*}}noreturn
; CHECK-NEXT: @alreadynoreturn()
define i32 @alreadynoreturn() noreturn {
unreachable
}
; CHECK: Function Attrs: {{.*}}noreturn
; CHECK-NEXT: @callsite_noreturn()
define void @callsite_noreturn() {
call i32 @f() noreturn
ret void
}
; CHECK: Function Attrs: {{.*}}noreturn
; CHECK-NEXT: @unreachable
define void @unreachable() {
unreachable
}
; CHECK-NOT: Function Attrs: {{.*}}noreturn
; CHECK: @coro
define void @coro() "coroutine.presplit"="1" {
call token @llvm.coro.id.retcon.once(i32 0, i32 0, i8* null, i8* bitcast(void() *@coro to i8*), i8* null, i8* null)
call i1 @llvm.coro.end(i8* null, i1 false)
unreachable
}
declare token @llvm.coro.id.retcon.once(i32 %size, i32 %align, i8* %buffer, i8* %prototype, i8* %alloc, i8* %free)
declare i1 @llvm.coro.end(i8*, i1)