summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/Transforms/CallSiteSplitting/musttail.ll109
1 files changed, 109 insertions, 0 deletions
diff --git a/test/Transforms/CallSiteSplitting/musttail.ll b/test/Transforms/CallSiteSplitting/musttail.ll
new file mode 100644
index 00000000000..97548501cd5
--- /dev/null
+++ b/test/Transforms/CallSiteSplitting/musttail.ll
@@ -0,0 +1,109 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -callsite-splitting -S | FileCheck %s
+
+define i8* @caller(i8* %a, i8* %b) {
+; CHECK-LABEL: @caller(
+; CHECK-NEXT: Top:
+; CHECK-NEXT: [[C:%.*]] = icmp eq i8* [[A:%.*]], null
+; CHECK-NEXT: br i1 [[C]], label [[TAIL_PREDBB1_SPLIT:%.*]], label [[TBB:%.*]]
+; CHECK: TBB:
+; CHECK-NEXT: [[C2:%.*]] = icmp eq i8* [[B:%.*]], null
+; CHECK-NEXT: br i1 [[C2]], label [[TAIL_PREDBB2_SPLIT:%.*]], label [[END:%.*]]
+; CHECK: Tail.predBB1.split:
+; CHECK-NEXT: [[TMP0:%.*]] = musttail call i8* @callee(i8* null, i8* [[B]])
+; CHECK-NEXT: [[CB1:%.*]] = bitcast i8* [[TMP0]] to i8*
+; CHECK-NEXT: ret i8* [[CB1]]
+; CHECK: Tail.predBB2.split:
+; CHECK-NEXT: [[TMP1:%.*]] = musttail call i8* @callee(i8* nonnull [[A]], i8* null)
+; CHECK-NEXT: [[CB2:%.*]] = bitcast i8* [[TMP1]] to i8*
+; CHECK-NEXT: ret i8* [[CB2]]
+; CHECK: End:
+; CHECK-NEXT: ret i8* null
+;
+Top:
+ %c = icmp eq i8* %a, null
+ br i1 %c, label %Tail, label %TBB
+TBB:
+ %c2 = icmp eq i8* %b, null
+ br i1 %c2, label %Tail, label %End
+Tail:
+ %ca = musttail call i8* @callee(i8* %a, i8* %b)
+ %cb = bitcast i8* %ca to i8*
+ ret i8* %cb
+End:
+ ret i8* null
+}
+
+define i8* @callee(i8* %a, i8* %b) noinline {
+; CHECK-LABEL: define i8* @callee(
+; CHECK-NEXT: ret i8* [[A:%.*]]
+;
+ ret i8* %a
+}
+
+define i8* @no_cast_caller(i8* %a, i8* %b) {
+; CHECK-LABEL: @no_cast_caller(
+; CHECK-NEXT: Top:
+; CHECK-NEXT: [[C:%.*]] = icmp eq i8* [[A:%.*]], null
+; CHECK-NEXT: br i1 [[C]], label [[TAIL_PREDBB1_SPLIT:%.*]], label [[TBB:%.*]]
+; CHECK: TBB:
+; CHECK-NEXT: [[C2:%.*]] = icmp eq i8* [[B:%.*]], null
+; CHECK-NEXT: br i1 [[C2]], label [[TAIL_PREDBB2_SPLIT:%.*]], label [[END:%.*]]
+; CHECK: Tail.predBB1.split:
+; CHECK-NEXT: [[TMP0:%.*]] = musttail call i8* @callee(i8* null, i8* [[B]])
+; CHECK-NEXT: ret i8* [[TMP0]]
+; CHECK: Tail.predBB2.split:
+; CHECK-NEXT: [[TMP1:%.*]] = musttail call i8* @callee(i8* nonnull [[A]], i8* null)
+; CHECK-NEXT: ret i8* [[TMP1]]
+; CHECK: End:
+; CHECK-NEXT: ret i8* null
+;
+Top:
+ %c = icmp eq i8* %a, null
+ br i1 %c, label %Tail, label %TBB
+TBB:
+ %c2 = icmp eq i8* %b, null
+ br i1 %c2, label %Tail, label %End
+Tail:
+ %ca = musttail call i8* @callee(i8* %a, i8* %b)
+ ret i8* %ca
+End:
+ ret i8* null
+}
+
+define void @void_caller(i8* %a, i8* %b) {
+; CHECK-LABEL: @void_caller(
+; CHECK-NEXT: Top:
+; CHECK-NEXT: [[C:%.*]] = icmp eq i8* [[A:%.*]], null
+; CHECK-NEXT: br i1 [[C]], label [[TAIL_PREDBB1_SPLIT:%.*]], label [[TBB:%.*]]
+; CHECK: TBB:
+; CHECK-NEXT: [[C2:%.*]] = icmp eq i8* [[B:%.*]], null
+; CHECK-NEXT: br i1 [[C2]], label [[TAIL_PREDBB2_SPLIT:%.*]], label [[END:%.*]]
+; CHECK: Tail.predBB1.split:
+; CHECK-NEXT: musttail call void @void_callee(i8* null, i8* [[B]])
+; CHECK-NEXT: ret void
+; CHECK: Tail.predBB2.split:
+; CHECK-NEXT: musttail call void @void_callee(i8* nonnull [[A]], i8* null)
+; CHECK-NEXT: ret void
+; CHECK: End:
+; CHECK-NEXT: ret void
+;
+Top:
+ %c = icmp eq i8* %a, null
+ br i1 %c, label %Tail, label %TBB
+TBB:
+ %c2 = icmp eq i8* %b, null
+ br i1 %c2, label %Tail, label %End
+Tail:
+ musttail call void @void_callee(i8* %a, i8* %b)
+ ret void
+End:
+ ret void
+}
+
+define void @void_callee(i8* %a, i8* %b) noinline {
+; CHECK-LABEL: define void @void_callee(
+; CHECK-NEXT: ret void
+;
+ ret void
+}