| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py |
| ; RUN: opt -callsite-splitting -S -o - < %s | FileCheck %s |
| |
| ; Check that we can split the critical edge between Top and CallSiteBB, and |
| ; rewrite the first callbr's indirect destination correctly. |
| |
| define void @caller() { |
| ; CHECK-LABEL: @caller( |
| ; CHECK-NEXT: Top: |
| ; CHECK-NEXT: callbr void asm sideeffect "", "X,~{dirflag},~{fpsr},~{flags}"(i8* blockaddress(@caller, [[TOP_SPLIT:%.*]])) |
| ; CHECK-NEXT: to label [[NEXTCOND:%.*]] [label %Top.split] |
| ; CHECK-LABEL: Top.split: |
| ; CHECK-NEXT: call void @callee(i1 false) |
| ; CHECK-NEXT: br label [[CALLSITEBB:%.*]] |
| ; CHECK-LABEL: NextCond: |
| ; CHECK-NEXT: br label [[NEXTCOND_SPLIT:%.*]] |
| ; CHECK-LABEL: NextCond.split: |
| ; CHECK-NEXT: call void @callee(i1 true) |
| ; CHECK-NEXT: br label [[CALLSITEBB]] |
| ; CHECK-LABEL: CallSiteBB: |
| ; CHECK-NEXT: [[PHI:%.*]] = phi i1 [ false, [[TOP_SPLIT]] ], [ true, [[NEXTCOND_SPLIT]] ] |
| ; CHECK-NEXT: callbr void asm sideeffect "", "r,X,~{dirflag},~{fpsr},~{flags}"(i1 [[PHI]], i8* blockaddress(@caller, [[END2:%.*]])) |
| ; CHECK-NEXT: to label [[END:%.*]] [label %End2] |
| ; CHECK-LABEL: End: |
| ; CHECK-NEXT: ret void |
| ; CHECK-LABEL: End2: |
| ; CHECK-NEXT: ret void |
| ; |
| Top: |
| callbr void asm sideeffect "", "X,~{dirflag},~{fpsr},~{flags}"(i8* blockaddress(@caller, %CallSiteBB)) |
| to label %NextCond [label %CallSiteBB] |
| |
| NextCond: |
| br label %CallSiteBB |
| |
| CallSiteBB: |
| %phi = phi i1 [0, %Top],[1, %NextCond] |
| call void @callee(i1 %phi) |
| callbr void asm sideeffect "", "r,X,~{dirflag},~{fpsr},~{flags}"(i1 %phi, i8* blockaddress(@caller, %End2)) |
| to label %End [label %End2] |
| |
| End: |
| ret void |
| End2: |
| ret void |
| } |
| |
| define void @callee(i1 %b) { |
| ; CHECK-LABEL: @callee( |
| ; CHECK-NEXT: ret void |
| ; |
| ret void |
| } |