1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 18:54:02 +01:00
llvm-mirror/test/Transforms/CallSiteSplitting/callsite-split-callbr.ll
Nick Desaulniers 60914a2419 BreakCriticalEdges for callbr indirect dests
Summary:
llvm::SplitEdge was failing an assertion that the BasicBlock only had
one successor (for BasicBlocks terminated by CallBrInst, we typically
have multiple successors).  It was surprising that the earlier call to
SplitCriticalEdge did not handle the critical edge (there was an early
return).  Removing that triggered another assertion relating to creating
a BlockAddress for a BasicBlock that did not (yet) have a parent, which
is a simple order of operations issue in llvm::SplitCriticalEdge (a
freshly constructed BasicBlock must be inserted into a Function's basic
block list to have a parent).

Thanks to @nathanchance for the report.
Fixes: https://github.com/ClangBuiltLinux/linux/issues/1018

Reviewers: craig.topper, jyknight, void, fhahn, efriedma

Reviewed By: efriedma

Subscribers: eli.friedman, rnk, efriedma, fhahn, hiraditya, llvm-commits, nathanchance, srhines

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D81607
2020-06-17 11:45:06 -07:00

54 lines
1.7 KiB
LLVM

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