| ; 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 |
| } |