1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-24 21:42:54 +02:00
llvm-mirror/test/Transforms/Inline/deoptimize-intrinsic.ll
Sanjoy Das ee178ad6c3 All llvm.deoptimize declarations must use the same calling convention
This new verifier rule lets us unambigously pick a calling convention
when creating a new declaration for
`@llvm.experimental.deoptimize.<ty>`.  It is also congruent with our
lowering strategy -- since all calls to `@llvm.experimental.deoptimize`
are lowered to calls to `__llvm_deoptimize`, it is reasonable to enforce
a unique calling convention.

Some of the tests that were breaking this verifier rule have had to be
split up into different .ll files.

The inliner was violating this rule as well, and has been fixed to avoid
producing invalid IR.

llvm-svn: 269261
2016-05-12 01:17:38 +00:00

124 lines
3.2 KiB
LLVM

; RUN: opt -S -always-inline < %s | FileCheck %s
declare i8 @llvm.experimental.deoptimize.i8(...)
declare i32 @llvm.experimental.deoptimize.i32(...)
define i8 @callee(i1* %c) alwaysinline {
%c0 = load volatile i1, i1* %c
br i1 %c0, label %left, label %right
left:
%c1 = load volatile i1, i1* %c
br i1 %c1, label %lleft, label %lright
lleft:
%v0 = call i8(...) @llvm.experimental.deoptimize.i8(i32 1) [ "deopt"(i32 1) ]
ret i8 %v0
lright:
ret i8 10
right:
%c2 = load volatile i1, i1* %c
br i1 %c2, label %rleft, label %rright
rleft:
%v1 = call i8(...) @llvm.experimental.deoptimize.i8(i32 1, i32 300, float 500.0, <2 x i32*> undef) [ "deopt"(i32 1) ]
ret i8 %v1
rright:
%v2 = call i8(...) @llvm.experimental.deoptimize.i8() [ "deopt"(i32 1) ]
ret i8 %v2
}
define void @caller_0(i1* %c, i8* %ptr) {
; CHECK-LABEL: @caller_0(
entry:
%v = call i8 @callee(i1* %c) [ "deopt"(i32 2) ]
store i8 %v, i8* %ptr
ret void
; CHECK: lleft.i:
; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid(i32 1) [ "deopt"(i32 2, i32 1) ]
; CHECK-NEXT: ret void
; CHECK: rleft.i:
; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid(i32 1, i32 300, float 5.000000e+02, <2 x i32*> undef) [ "deopt"(i32 2, i32 1) ]
; CHECK-NEXT: ret void
; CHECK: rright.i:
; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"(i32 2, i32 1) ]
; CHECK-NEXT: ret void
; CHECK: callee.exit:
; CHECK-NEXT: store i8 10, i8* %ptr
; CHECK-NEXT: ret void
}
define i32 @caller_1(i1* %c, i8* %ptr) personality i8 3 {
; CHECK-LABEL: @caller_1(
entry:
%v = invoke i8 @callee(i1* %c) [ "deopt"(i32 3) ] to label %normal
unwind label %unwind
; CHECK: lleft.i:
; CHECK-NEXT: %0 = call i32 (...) @llvm.experimental.deoptimize.i32(i32 1) [ "deopt"(i32 3, i32 1) ]
; CHECK-NEXT: ret i32 %0
; CHECK: rleft.i:
; CHECK-NEXT: %1 = call i32 (...) @llvm.experimental.deoptimize.i32(i32 1, i32 300, float 5.000000e+02, <2 x i32*> undef) [ "deopt"(i32 3, i32 1) ]
; CHECK-NEXT: ret i32 %1
; CHECK: rright.i:
; CHECK-NEXT: %2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 3, i32 1) ]
; CHECK-NEXT: ret i32 %2
; CHECK: callee.exit:
; CHECK-NEXT: br label %normal
; CHECK: normal:
; CHECK-NEXT: store i8 10, i8* %ptr
; CHECK-NEXT: ret i32 42
unwind:
%lp = landingpad i32 cleanup
ret i32 43
normal:
store i8 %v, i8* %ptr
ret i32 42
}
define i8 @callee_with_alloca() alwaysinline {
%t = alloca i8
%v0 = call i8(...) @llvm.experimental.deoptimize.i8(i32 1) [ "deopt"(i8* %t) ]
ret i8 %v0
}
define void @caller_with_lifetime() {
; CHECK-LABLE: @caller_with_lifetime(
; CHECK: call void (...) @llvm.experimental.deoptimize.isVoid(i32 1) [ "deopt"(i8* %t.i) ]
; CHECK-NEXT: ret void
entry:
call i8 @callee_with_alloca();
ret void
}
define i8 @callee_with_dynamic_alloca(i32 %n) alwaysinline {
%p = alloca i8, i32 %n
%v = call i8(...) @llvm.experimental.deoptimize.i8(i32 1) [ "deopt"(i8* %p) ]
ret i8 %v
}
define void @caller_with_stacksaverestore(i32 %n) {
; CHECK-LABEL: void @caller_with_stacksaverestore(
; CHECK: call void (...) @llvm.experimental.deoptimize.isVoid(i32 1) [ "deopt"(i8* %p.i) ]
; CHECK-NEXT: ret void
%p = alloca i32, i32 %n
call i8 @callee_with_dynamic_alloca(i32 %n)
ret void
}