diff options
Diffstat (limited to 'test/Transforms/Inline/deopt-bundles.ll')
-rw-r--r-- | test/Transforms/Inline/deopt-bundles.ll | 203 |
1 files changed, 203 insertions, 0 deletions
diff --git a/test/Transforms/Inline/deopt-bundles.ll b/test/Transforms/Inline/deopt-bundles.ll new file mode 100644 index 000000000000..3e3c52f7d2d5 --- /dev/null +++ b/test/Transforms/Inline/deopt-bundles.ll @@ -0,0 +1,203 @@ +; RUN: opt -S -always-inline < %s | FileCheck %s + +declare void @f() +declare i32 @g() +declare fastcc i32 @g.fastcc() + +define i32 @callee_0() alwaysinline { + entry: + call void @f() + ret i32 2 +} + +define i32 @caller_0() { +; CHECK-LABEL: @caller_0( + entry: +; CHECK: entry: +; CHECK-NEXT: call void @f() +; CHECK-NEXT: ret i32 2 + %x = call i32 @callee_0() [ "deopt"(i32 5) ] + ret i32 %x +} + +define i32 @callee_1() alwaysinline { + entry: + call void @f() [ "deopt"() ] + call void @f() [ "deopt"(i32 0, i32 1) ] + call void @f() [ "deopt"(i32 0, i32 1), "foo"(double 0.0) ] + ret i32 2 +} + +define i32 @caller_1() { +; CHECK-LABEL: @caller_1( + entry: +; CHECK: entry: +; CHECK-NEXT: call void @f() [ "deopt"(i32 5) ] +; CHECK-NEXT: call void @f() [ "deopt"(i32 5, i32 0, i32 1) ] +; CHECK-NEXT: call void @f() [ "deopt"(i32 5, i32 0, i32 1), "foo"(double 0.000000e+00) ] +; CHECK-NEXT: ret i32 2 + + %x = call i32 @callee_1() [ "deopt"(i32 5) ] + ret i32 %x +} + +define i32 @callee_2() alwaysinline { + entry: + %v = call i32 @g() [ "deopt"(i32 0, i32 1), "foo"(double 0.0) ] + ret i32 %v +} + +define i32 @caller_2(i32 %val) { +; CHECK-LABEL: @caller_2( + entry: +; CHECK: entry: +; CHECK-NEXT: [[RVAL:%[^ ]+]] = call i32 @g() [ "deopt"(i32 %val, i32 0, i32 1), "foo"(double 0.000000e+00) ] +; CHECK-NEXT: ret i32 [[RVAL]] + %x = call i32 @callee_2() [ "deopt"(i32 %val) ] + ret i32 %x +} + +define i32 @callee_3() alwaysinline { + entry: + %v = call i32 @g() [ "deopt"(i32 0, i32 1), "foo"(double 0.0) ] + ret i32 %v +} + +define i32 @caller_3() personality i8 3 { +; CHECK-LABEL: @caller_3( + entry: + %x = invoke i32 @callee_3() [ "deopt"(i32 7) ] to label %normal unwind label %unwind +; CHECK: invoke i32 @g() [ "deopt"(i32 7, i32 0, i32 1), "foo"(double 0.000000e+00) ] + + normal: + ret i32 %x + + unwind: + %cleanup = landingpad i8 cleanup + ret i32 101 +} + +define i32 @callee_4() alwaysinline personality i8 3 { + entry: + %v = invoke i32 @g() [ "deopt"(i32 0, i32 1), "foo"(double 0.0) ] to label %normal unwind label %unwind + + normal: + ret i32 %v + + unwind: + %cleanup = landingpad i8 cleanup + ret i32 100 +} + +define i32 @caller_4() { +; CHECK-LABEL: @caller_4( + entry: +; CHECK: invoke i32 @g() [ "deopt"(i32 7, i32 0, i32 1), "foo"(double 0.000000e+00) ] + %x = call i32 @callee_4() [ "deopt"(i32 7) ] + ret i32 %x +} + +define i32 @callee_5() alwaysinline personality i8 3 { + entry: + %v = invoke fastcc i32 @g.fastcc() #0 [ "deopt"(i32 0, i32 1), "foo"(double 0.0) ] to label %normal unwind label %unwind + + normal: + ret i32 %v + + unwind: + %cleanup = landingpad i8 cleanup + ret i32 100 +} + +define i32 @caller_5() { +; CHECK-LABEL: @caller_5( + entry: +; CHECK: invoke fastcc i32 @g.fastcc() #[[FOO_BAR_ATTR_IDX:[0-9]+]] [ "deopt"(i32 7, i32 0, i32 1), "foo"(double 0.000000e+00) ] + %x = call i32 @callee_5() [ "deopt"(i32 7) ] + ret i32 %x +} + +define i32 @callee_6() alwaysinline personality i8 3 { + entry: + %v = call fastcc i32 @g.fastcc() #0 [ "deopt"(i32 0, i32 1), "foo"(double 0.0) ] + ret i32 %v +} + +define i32 @caller_6() { +; CHECK-LABEL: @caller_6( + entry: +; CHECK: call fastcc i32 @g.fastcc() #[[FOO_BAR_ATTR_IDX]] [ "deopt"(i32 7, i32 0, i32 1), "foo"(double 0.000000e+00) ] + %x = call i32 @callee_6() [ "deopt"(i32 7) ] + ret i32 %x +} + +define i32 @callee_7(i1 %val) alwaysinline personality i8 3 { +; We want something that PruningFunctionCloner is not smart enough to +; recognize, but can be recognized by recursivelySimplifyInstruction. + + entry: + br i1 %val, label %check, label %precheck + + precheck: + br label %check + + check: + %p = phi i1 [ %val, %entry ], [ true, %precheck ] + br i1 %p, label %do.not, label %do + + do.not: + ret i32 0 + + do: + %v = call fastcc i32 @g.fastcc() [ "deopt"(i32 0, i32 1), "foo"(double 0.0) ] + ret i32 %v +} + +define i32 @caller_7() { +; CHECK-LABEL: @caller_7( + entry: +; CHECK-NOT: call fastcc i32 @g.fastcc() +; CHECK: ret i32 0 + %x = call i32 @callee_7(i1 true) [ "deopt"(i32 7) ] + ret i32 %x +} + +define i32 @callee_8(i1 %val) alwaysinline personality i8 3 { +; We want something that PruningFunctionCloner is not smart enough to +; recognize, but can be recognized by recursivelySimplifyInstruction. + + entry: + br i1 %val, label %check, label %precheck + + precheck: + br label %check + + check: + %p = phi i1 [ %val, %entry ], [ true, %precheck ] + br i1 %p, label %do.not, label %do + + do.not: + ret i32 0 + + do: + %phi = phi i32 [ 0, %check ], [ %v, %do ] + %v = call fastcc i32 @g.fastcc() [ "deopt"(i32 0, i32 1), "foo"(double 0.0) ] + %ic = icmp eq i32 %v, 42 + br i1 %ic, label %do, label %done + + done: + ret i32 %phi +} + +define i32 @caller_8() { +; CHECK-LABEL: @caller_8( + entry: +; CHECK-NOT: call fastcc i32 @g.fastcc() +; CHECK: ret i32 0 + %x = call i32 @callee_8(i1 true) [ "deopt"(i32 7) ] + ret i32 %x +} + +attributes #0 = { "foo"="bar" } + +; CHECK: attributes #[[FOO_BAR_ATTR_IDX]] = { "foo"="bar" } |