| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature |
| ; RUN: opt -passes=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: define {{[^@]+}}@caller() { |
| ; CHECK-NEXT: Top: |
| ; CHECK-NEXT: callbr void asm sideeffect "", "!i,~{dirflag},~{fpsr},~{flags}"() |
| ; CHECK-NEXT: to label [[NEXTCOND:%.*]] [label %Top.split] |
| ; CHECK: Top.split: |
| ; CHECK-NEXT: call void @callee(i1 false) |
| ; CHECK-NEXT: br label [[CALLSITEBB:%.*]] |
| ; CHECK: NextCond: |
| ; CHECK-NEXT: br label [[NEXTCOND_SPLIT:%.*]] |
| ; CHECK: NextCond.split: |
| ; CHECK-NEXT: call void @callee(i1 true) |
| ; CHECK-NEXT: br label [[CALLSITEBB]] |
| ; CHECK: CallSiteBB: |
| ; CHECK-NEXT: [[PHI:%.*]] = phi i1 [ false, [[TOP_SPLIT:%.*]] ], [ true, [[NEXTCOND_SPLIT]] ] |
| ; CHECK-NEXT: callbr void asm sideeffect "", "r,!i,~{dirflag},~{fpsr},~{flags}"(i1 [[PHI]]) |
| ; CHECK-NEXT: to label [[END:%.*]] [label %End2] |
| ; CHECK: End: |
| ; CHECK-NEXT: ret void |
| ; CHECK: End2: |
| ; CHECK-NEXT: ret void |
| ; |
| Top: |
| callbr void asm sideeffect "", "!i,~{dirflag},~{fpsr},~{flags}"() |
| 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,!i,~{dirflag},~{fpsr},~{flags}"(i1 %phi) |
| to label %End [label %End2] |
| |
| End: |
| ret void |
| End2: |
| ret void |
| } |
| |
| define void @callee(i1 %b) { |
| ; CHECK-LABEL: define {{[^@]+}}@callee |
| ; CHECK-SAME: (i1 [[B:%.*]]) { |
| ; CHECK-NEXT: ret void |
| ; |
| ret void |
| } |