Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions llvm/lib/Transforms/Utils/SimplifyCFG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7474,9 +7474,6 @@ static bool simplifySwitchOfCmpIntrinsic(SwitchInst *SI, IRBuilderBase &Builder,
/// IncomingValue and add it in the Wrapper so isEqual can do O(1) checking
/// of the incoming values.
struct SwitchSuccWrapper {
// Keep so we can use SwitchInst::setSuccessor to do the replacement. It won't
// be important to equality though.
unsigned SuccNum;
BasicBlock *Dest;
DenseMap<PHINode *, SmallDenseMap<BasicBlock *, Value *, 8>> *PhiPredIVs;
};
Expand Down Expand Up @@ -7563,6 +7560,7 @@ bool SimplifyCFGOpt::simplifyDuplicateSwitchArms(SwitchInst *SI,
SmallPtrSet<PHINode *, 8> Phis;
SmallPtrSet<BasicBlock *, 8> Seen;
DenseMap<PHINode *, SmallDenseMap<BasicBlock *, Value *, 8>> PhiPredIVs;
DenseMap<BasicBlock *, SmallVector<unsigned, 4>> BBToSuccessorIndexes;
SmallVector<SwitchSuccWrapper> Cases;
Cases.reserve(SI->getNumSuccessors());

Expand All @@ -7575,8 +7573,9 @@ bool SimplifyCFGOpt::simplifyDuplicateSwitchArms(SwitchInst *SI,
continue;

// FIXME: This case needs some extra care because the terminators other than
// SI need to be updated.
if (BB->hasNPredecessorsOrMore(2))
// SI need to be updated. For now, consider only backedges to the SI.
if (BB->hasNPredecessorsOrMore(4) ||
BB->getUniquePredecessor() != SI->getParent())
continue;

// FIXME: Relax that the terminator is a BranchInst by checking for equality
Expand All @@ -7591,8 +7590,11 @@ bool SimplifyCFGOpt::simplifyDuplicateSwitchArms(SwitchInst *SI,
for (BasicBlock *Succ : BI->successors())
for (PHINode &Phi : Succ->phis())
Phis.insert(&Phi);
// Add the successor only if not previously visited.
Cases.emplace_back(SwitchSuccWrapper{BB, &PhiPredIVs});
}
Cases.emplace_back(SwitchSuccWrapper{I, BB, &PhiPredIVs});

BBToSuccessorIndexes[BB].emplace_back(I);
}

// Precompute a data structure to improve performance of isEqual for
Expand Down Expand Up @@ -7627,7 +7629,9 @@ bool SimplifyCFGOpt::simplifyDuplicateSwitchArms(SwitchInst *SI,
// We know that SI's parent BB no longer dominates the old case successor
// since we are making it dead.
Updates.push_back({DominatorTree::Delete, SI->getParent(), SSW.Dest});
SI->setSuccessor(SSW.SuccNum, (*It)->Dest);
const auto &Successors = BBToSuccessorIndexes.at(SSW.Dest);
for (unsigned Idx : Successors)
SI->setSuccessor(Idx, (*It)->Dest);
MadeChange = true;
}
}
Expand Down
34 changes: 21 additions & 13 deletions llvm/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll
Original file line number Diff line number Diff line change
Expand Up @@ -314,20 +314,20 @@ lor.end:
define i32 @overflow(i32 %type) {
; CHECK-LABEL: @overflow(
; CHECK-NEXT: entry:
; CHECK-NEXT: switch i32 [[TYPE:%.*]], label [[IF_END:%.*]] [
; CHECK-NEXT: switch i32 [[TYPE:%.*]], label [[SW_DEFAULT:%.*]] [
; CHECK-NEXT: i32 3, label [[SW_BB3:%.*]]
; CHECK-NEXT: i32 -2147483645, label [[SW_BB3]]
; CHECK-NEXT: i32 1, label [[SW_BB1:%.*]]
; CHECK-NEXT: i32 1, label [[IF_END:%.*]]
; CHECK-NEXT: i32 2, label [[SW_BB2:%.*]]
; CHECK-NEXT: ]
; CHECK: sw.bb1:
; CHECK-NEXT: br label [[IF_END]]
; CHECK: sw.bb2:
; CHECK-NEXT: br label [[IF_END]]
; CHECK: sw.bb3:
; CHECK-NEXT: br label [[IF_END]]
; CHECK: sw.default:
; CHECK-NEXT: br label [[IF_END]]
; CHECK: if.end:
; CHECK-NEXT: [[DIRENT_TYPE_0:%.*]] = phi i32 [ 6, [[SW_BB3]] ], [ 5, [[SW_BB2]] ], [ 0, [[SW_BB1]] ], [ 3, [[ENTRY:%.*]] ]
; CHECK-NEXT: [[DIRENT_TYPE_0:%.*]] = phi i32 [ 3, [[SW_DEFAULT]] ], [ 6, [[SW_BB3]] ], [ 5, [[SW_BB2]] ], [ 0, [[ENTRY:%.*]] ]
; CHECK-NEXT: ret i32 [[DIRENT_TYPE_0]]
;
entry:
Expand All @@ -340,15 +340,23 @@ entry:
i32 3, label %sw.bb3
]

sw.bb: br label %if.end
sw.bb1: br label %if.end
sw.bb2: br label %if.end
sw.bb3: br label %if.end
sw.default: br label %if.end
if.else: br label %if.end
sw.bb: ; preds = %entry, %entry
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you mean to change these lines?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took the chance to regenerate the test too, as the if.else branch was dead.

br label %if.end

if.end:
%dirent_type.0 = phi i32 [ 3, %sw.default ], [ 6, %sw.bb3 ], [ 5, %sw.bb2 ], [ 0, %sw.bb1 ], [ 3, %sw.bb ], [ 0, %if.else ]
sw.bb1: ; preds = %entry
br label %if.end

sw.bb2: ; preds = %entry
br label %if.end

sw.bb3: ; preds = %entry, %entry
br label %if.end

sw.default: ; preds = %entry
br label %if.end

if.end: ; preds = %sw.default, %sw.bb3, %sw.bb2, %sw.bb1, %sw.bb
%dirent_type.0 = phi i32 [ 3, %sw.default ], [ 6, %sw.bb3 ], [ 5, %sw.bb2 ], [ 0, %sw.bb1 ], [ 3, %sw.bb ]
ret i32 %dirent_type.0
}

Expand Down
72 changes: 72 additions & 0 deletions llvm/test/Transforms/SimplifyCFG/switch-dup-bbs.ll
Original file line number Diff line number Diff line change
Expand Up @@ -127,3 +127,75 @@ define i32 @switch_dup_default(i32 %0, i32 %1, i32 %2, i32 %3) {
%9 = phi i32 [ %3, %5 ], [ %2, %6 ], [ %2, %7 ]
ret i32 %9
}

define i32 @switch_dup_exit(i32 %val) {
; SIMPLIFY-CFG-LABEL: define i32 @switch_dup_exit(
; SIMPLIFY-CFG-SAME: i32 [[VAL:%.*]]) {
; SIMPLIFY-CFG-NEXT: [[ENTRY:.*]]:
; SIMPLIFY-CFG-NEXT: switch i32 [[VAL]], label %[[DEFAULT:.*]] [
; SIMPLIFY-CFG-NEXT: i32 1, label %[[EXIT:.*]]
; SIMPLIFY-CFG-NEXT: i32 11, label %[[EXIT]]
; SIMPLIFY-CFG-NEXT: i32 22, label %[[BB1:.*]]
; SIMPLIFY-CFG-NEXT: ]
; SIMPLIFY-CFG: [[BB1]]:
; SIMPLIFY-CFG-NEXT: br label %[[EXIT]]
; SIMPLIFY-CFG: [[DEFAULT]]:
; SIMPLIFY-CFG-NEXT: br label %[[EXIT]]
; SIMPLIFY-CFG: [[EXIT]]:
; SIMPLIFY-CFG-NEXT: [[RET:%.*]] = phi i32 [ 0, %[[DEFAULT]] ], [ 3, %[[BB1]] ], [ 1, %[[ENTRY]] ], [ 1, %[[ENTRY]] ]
; SIMPLIFY-CFG-NEXT: ret i32 [[RET]]
;
entry:
switch i32 %val, label %default [
i32 1, label %exit
i32 11, label %exit
i32 22, label %bb1
i32 15, label %bb2
i32 0, label %bb2
]

bb1:
br label %exit

bb2:
br label %exit

default:
br label %exit

exit:
%ret = phi i32 [ 0, %default ], [ 0, %bb2 ], [ 3, %bb1 ], [ 1, %entry ], [ 1, %entry ]
ret i32 %ret
}

define i64 @switch_dup_exit_2(i32 %val) {
; SIMPLIFY-CFG-LABEL: define i64 @switch_dup_exit_2(
; SIMPLIFY-CFG-SAME: i32 [[VAL:%.*]]) {
; SIMPLIFY-CFG-NEXT: [[ENTRY:.*:]]
; SIMPLIFY-CFG-NEXT: [[SWITCH_SELECTCMP_CASE1:%.*]] = icmp eq i32 [[VAL]], 1
; SIMPLIFY-CFG-NEXT: [[SWITCH_SELECTCMP_CASE2:%.*]] = icmp eq i32 [[VAL]], 11
; SIMPLIFY-CFG-NEXT: [[SWITCH_SELECTCMP:%.*]] = or i1 [[SWITCH_SELECTCMP_CASE1]], [[SWITCH_SELECTCMP_CASE2]]
; SIMPLIFY-CFG-NEXT: [[RET:%.*]] = select i1 [[SWITCH_SELECTCMP]], i64 1, i64 0
; SIMPLIFY-CFG-NEXT: ret i64 [[RET]]
;
entry:
switch i32 %val, label %default [
i32 1, label %bb2
i32 11, label %exit
i32 13, label %bb1
i32 0, label %bb1
]

bb1:
br label %exit

bb2:
br label %exit

default:
br label %exit

exit:
%ret = phi i64 [ 0, %default ], [ 0, %bb1 ], [ 1, %entry ], [ 1, %bb2 ]
ret i64 %ret
}
Loading