forked from OSchip/llvm-project
[SimplifyCFG] Teach removeUndefIntroducingPredecessor to preserve DomTree
This commit is contained in:
parent
2461cdb417
commit
b4429f3cdd
|
@ -6563,14 +6563,16 @@ static bool passingValueIsAlwaysUndefined(Value *V, Instruction *I) {
|
|||
|
||||
/// If BB has an incoming value that will always trigger undefined behavior
|
||||
/// (eg. null pointer dereference), remove the branch leading here.
|
||||
static bool removeUndefIntroducingPredecessor(BasicBlock *BB) {
|
||||
static bool removeUndefIntroducingPredecessor(BasicBlock *BB,
|
||||
DomTreeUpdater *DTU) {
|
||||
for (PHINode &PHI : BB->phis())
|
||||
for (unsigned i = 0, e = PHI.getNumIncomingValues(); i != e; ++i)
|
||||
if (passingValueIsAlwaysUndefined(PHI.getIncomingValue(i), &PHI)) {
|
||||
Instruction *T = PHI.getIncomingBlock(i)->getTerminator();
|
||||
BasicBlock *Predecessor = PHI.getIncomingBlock(i);
|
||||
Instruction *T = Predecessor->getTerminator();
|
||||
IRBuilder<> Builder(T);
|
||||
if (BranchInst *BI = dyn_cast<BranchInst>(T)) {
|
||||
BB->removePredecessor(PHI.getIncomingBlock(i));
|
||||
BB->removePredecessor(Predecessor);
|
||||
// Turn uncoditional branches into unreachables and remove the dead
|
||||
// destination from conditional branches.
|
||||
if (BI->isUnconditional())
|
||||
|
@ -6579,6 +6581,9 @@ static bool removeUndefIntroducingPredecessor(BasicBlock *BB) {
|
|||
Builder.CreateBr(BI->getSuccessor(0) == BB ? BI->getSuccessor(1)
|
||||
: BI->getSuccessor(0));
|
||||
BI->eraseFromParent();
|
||||
if (DTU)
|
||||
DTU->applyUpdatesPermissive(
|
||||
{{DominatorTree::Delete, Predecessor, BB}});
|
||||
return true;
|
||||
}
|
||||
// TODO: SwitchInst.
|
||||
|
@ -6611,7 +6616,7 @@ bool SimplifyCFGOpt::simplifyOnceImpl(BasicBlock *BB) {
|
|||
Changed |= EliminateDuplicatePHINodes(BB);
|
||||
|
||||
// Check for and remove branches that will always cause undefined behavior.
|
||||
Changed |= removeUndefIntroducingPredecessor(BB);
|
||||
Changed |= removeUndefIntroducingPredecessor(BB, DTU);
|
||||
|
||||
// Merge basic blocks into their predecessor if there is only one distinct
|
||||
// pred, and if there is only one distinct successor of the predecessor, and
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
; RUN: llc -march=hexagon -O3 -debug-only=isel 2>&1 -simplifycfg-require-and-preserve-domtree=0 < %s | FileCheck %s
|
||||
; RUN: llc -march=hexagon -O3 -debug-only=isel 2>&1 -simplifycfg-require-and-preserve-domtree=1 < %s | FileCheck %s
|
||||
; REQUIRES: asserts
|
||||
|
||||
; DAGCombiner converts the two vector stores to a double vector store,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
; RUN: llc -march=hexagon -mcpu=hexagonv5 -simplifycfg-require-and-preserve-domtree=0 < %s
|
||||
; RUN: llc -march=hexagon -mcpu=hexagonv5 -simplifycfg-require-and-preserve-domtree=1 < %s
|
||||
; REQUIRES: asserts
|
||||
|
||||
define void @test(i8* noalias nocapture readonly %src, i32 %srcStride) local_unnamed_addr #0 {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
; RUN: llc -march=hexagon -O2 -simplifycfg-require-and-preserve-domtree=0 < %s
|
||||
; RUN: llc -march=hexagon -O2 -simplifycfg-require-and-preserve-domtree=1 < %s
|
||||
; REQUIRES: asserts
|
||||
|
||||
; Function Attrs: noinline nounwind ssp
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
; RUN: llc -march=hexagon -O2 -simplifycfg-require-and-preserve-domtree=0 < %s
|
||||
; RUN: llc -march=hexagon -O2 -simplifycfg-require-and-preserve-domtree=1 < %s
|
||||
; REQUIRES: asserts
|
||||
|
||||
; Test that we generate the correct Phi names in the epilog when we need
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
; RUN: llc -simplifycfg-require-and-preserve-domtree=0 < %s -mtriple=thumbv7-apple-darwin -mcpu=cortex-a8 -relocation-model=pic -frame-pointer=all
|
||||
; RUN: llc -simplifycfg-require-and-preserve-domtree=1 < %s -mtriple=thumbv7-apple-darwin -mcpu=cortex-a8 -relocation-model=pic -frame-pointer=all
|
||||
|
||||
%0 = type { %struct.GAP } ; type %0
|
||||
%1 = type { i16, i8, i8 } ; type %1
|
||||
|
|
Loading…
Reference in New Issue