1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 02:52:53 +02:00

[CallSiteSplitting] Do not crash when BB's terminator changes.

Change doCallSiteSplitting to iterate until we reach the terminator instruction.
tryToSplitCallSite can replace BB's terminator in case BB is a successor of
itself. Then IE will be invalidated and we also have to check the current
terminator.

Reviewers: junbuml, davidxl, davide, fhahn

Reviewed By: fhahn, junbuml

Differential Revision: https://reviews.llvm.org/D43824

llvm-svn: 326793
This commit is contained in:
Florian Hahn 2018-03-06 14:00:58 +00:00
parent 89d4955b62
commit 100aba8783
2 changed files with 97 additions and 1 deletions

View File

@ -469,7 +469,13 @@ static bool doCallSiteSplitting(Function &F, TargetLibraryInfo &TLI,
bool Changed = false;
for (Function::iterator BI = F.begin(), BE = F.end(); BI != BE;) {
BasicBlock &BB = *BI++;
for (BasicBlock::iterator II = BB.begin(), IE = BB.end(); II != IE;) {
auto II = BB.getFirstNonPHIOrDbg()->getIterator();
auto IE = BB.getTerminator()->getIterator();
// Iterate until we reach the terminator instruction. tryToSplitCallSite
// can replace BB's terminator in case BB is a successor of itself. In that
// case, IE will be invalidated and we also have to check the current
// terminator.
while (II != IE && &*II != BB.getTerminator()) {
Instruction *I = &*II++;
CallSite CS(cast<Value>(I));
if (!CS || isa<IntrinsicInst>(I) || isInstructionTriviallyDead(I, &TLI))

View File

@ -0,0 +1,90 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -S -callsite-splitting -simplifycfg < %s | FileCheck %s
define i16 @test1() {
; CHECK-LABEL: @test1(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 undef, i16 1, i16 0
; CHECK-NEXT: call void @callee(i16 0)
; CHECK-NEXT: br label [[FOR_COND12:%.*]]
; CHECK: for.cond12:
; CHECK-NEXT: call void @callee(i16 [[SPEC_SELECT]])
; CHECK-NEXT: br label [[FOR_COND12]]
;
entry:
%spec.select = select i1 undef, i16 1, i16 0
%tobool18 = icmp ne i16 %spec.select, 0
br i1 %tobool18, label %for.cond12.us, label %for.cond12
for.cond12.us:
unreachable
for.cond12:
call void @callee(i16 %spec.select)
br label %for.cond12
}
define i16 @test2() {
; CHECK-LABEL: @test2(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[S:%.*]] = select i1 undef, i16 1, i16 0
; CHECK-NEXT: call void @callee(i16 0)
; CHECK-NEXT: br label [[FOR_COND12:%.*]]
; CHECK: for.cond12:
; CHECK-NEXT: [[ADD:%.*]] = add i16 [[S]], 10
; CHECK-NEXT: [[ADD2:%.*]] = add i16 [[S]], 10
; CHECK-NEXT: call void @callee(i16 [[S]])
; CHECK-NEXT: br label [[FOR_COND12]]
;
entry:
%s= select i1 undef, i16 1, i16 0
%tobool18 = icmp ne i16 %s, 0
br i1 %tobool18, label %for.cond12.us, label %for.cond12
for.cond12.us:
unreachable
for.cond12:
call void @callee(i16 %s)
%add = add i16 %s, 10
%add2 = add i16 %s, 10
br label %for.cond12
}
define i16 @test3() {
; CHECK-LABEL: @test3(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[S:%.*]] = select i1 undef, i16 1, i16 0
; CHECK-NEXT: call void @callee(i16 0)
; CHECK-NEXT: br label [[FOR_COND12:%.*]]
; CHECK: for.cond12:
; CHECK-NEXT: [[ADD:%.*]] = add i16 [[S]], 10
; CHECK-NEXT: [[ADD2:%.*]] = add i16 [[ADD]], 10
; CHECK-NEXT: br i1 undef, label [[FOR_COND12_SPLIT:%.*]], label [[EXIT:%.*]]
; CHECK: for.cond12.split:
; CHECK-NEXT: call void @callee(i16 [[S]])
; CHECK-NEXT: br label [[FOR_COND12]]
; CHECK: exit:
; CHECK-NEXT: ret i16 [[ADD2]]
;
entry:
%s= select i1 undef, i16 1, i16 0
%tobool18 = icmp ne i16 %s, 0
br i1 %tobool18, label %for.cond12.us, label %for.cond12
for.cond12.us:
unreachable
for.cond12:
call void @callee(i16 %s)
%add = add i16 %s, 10
%add2 = add i16 %add, 10
br i1 undef, label %for.cond12, label %exit
exit:
ret i16 %add2
}
define internal void @callee(i16 %flag) {
ret void
}