From 8271be9a1da41ac9221fc13831a9166ddf53a002 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Wed, 12 Oct 2016 19:50:57 +0000 Subject: [PATCH] Do not remove implicit defs in BranchFolder Branch folder removes implicit defs if they are the only non-branching instructions in a block, and the branches do not use the defined registers. The problem is that in some cases these implicit defs are required for the liveness information to be correct. Differential Revision: https://reviews.llvm.org/D25478 llvm-svn: 284036 --- llvm/lib/CodeGen/BranchFolding.cpp | 54 ------------------- llvm/lib/CodeGen/BranchFolding.h | 1 - .../Hexagon/branchfolder-keep-impdef.ll | 29 ++++++++++ .../X86/2012-01-13-phielim.ll | 1 + 4 files changed, 30 insertions(+), 55 deletions(-) create mode 100644 llvm/test/CodeGen/Hexagon/branchfolder-keep-impdef.ll diff --git a/llvm/lib/CodeGen/BranchFolding.cpp b/llvm/lib/CodeGen/BranchFolding.cpp index ec736a04bbd36..71074513c89ea 100644 --- a/llvm/lib/CodeGen/BranchFolding.cpp +++ b/llvm/lib/CodeGen/BranchFolding.cpp @@ -145,59 +145,6 @@ void BranchFolder::RemoveDeadBlock(MachineBasicBlock *MBB) { MLI->removeBlock(MBB); } -/// OptimizeImpDefsBlock - If a basic block is just a bunch of implicit_def -/// followed by terminators, and if the implicitly defined registers are not -/// used by the terminators, remove those implicit_def's. e.g. -/// BB1: -/// r0 = implicit_def -/// r1 = implicit_def -/// br -/// This block can be optimized away later if the implicit instructions are -/// removed. -bool BranchFolder::OptimizeImpDefsBlock(MachineBasicBlock *MBB) { - SmallSet ImpDefRegs; - MachineBasicBlock::iterator I = MBB->begin(); - while (I != MBB->end()) { - if (!I->isImplicitDef()) - break; - unsigned Reg = I->getOperand(0).getReg(); - if (TargetRegisterInfo::isPhysicalRegister(Reg)) { - for (MCSubRegIterator SubRegs(Reg, TRI, /*IncludeSelf=*/true); - SubRegs.isValid(); ++SubRegs) - ImpDefRegs.insert(*SubRegs); - } else { - ImpDefRegs.insert(Reg); - } - ++I; - } - if (ImpDefRegs.empty()) - return false; - - MachineBasicBlock::iterator FirstTerm = I; - while (I != MBB->end()) { - if (!TII->isUnpredicatedTerminator(*I)) - return false; - // See if it uses any of the implicitly defined registers. - for (const MachineOperand &MO : I->operands()) { - if (!MO.isReg() || !MO.isUse()) - continue; - unsigned Reg = MO.getReg(); - if (ImpDefRegs.count(Reg)) - return false; - } - ++I; - } - - I = MBB->begin(); - while (I != FirstTerm) { - MachineInstr *ImpDefMI = &*I; - ++I; - MBB->erase(ImpDefMI); - } - - return true; -} - /// OptimizeFunction - Perhaps branch folding, tail merging and other /// CFG optimizations on the given function. Block placement changes the layout /// and may create new tail merging opportunities. @@ -228,7 +175,6 @@ bool BranchFolder::OptimizeFunction(MachineFunction &MF, SmallVector Cond; if (!TII->analyzeBranch(MBB, TBB, FBB, Cond, true)) MadeChange |= MBB.CorrectExtraCFGEdges(TBB, FBB, !Cond.empty()); - MadeChange |= OptimizeImpDefsBlock(&MBB); } // Recalculate funclet membership. diff --git a/llvm/lib/CodeGen/BranchFolding.h b/llvm/lib/CodeGen/BranchFolding.h index bce8d62b14c41..096b44a043a7e 100644 --- a/llvm/lib/CodeGen/BranchFolding.h +++ b/llvm/lib/CodeGen/BranchFolding.h @@ -156,7 +156,6 @@ namespace llvm { bool OptimizeBranches(MachineFunction &MF); bool OptimizeBlock(MachineBasicBlock *MBB); void RemoveDeadBlock(MachineBasicBlock *MBB); - bool OptimizeImpDefsBlock(MachineBasicBlock *MBB); bool HoistCommonCode(MachineFunction &MF); bool HoistCommonCodeInSuccs(MachineBasicBlock *MBB); diff --git a/llvm/test/CodeGen/Hexagon/branchfolder-keep-impdef.ll b/llvm/test/CodeGen/Hexagon/branchfolder-keep-impdef.ll new file mode 100644 index 0000000000000..a56680bd43999 --- /dev/null +++ b/llvm/test/CodeGen/Hexagon/branchfolder-keep-impdef.ll @@ -0,0 +1,29 @@ +; RUN: llc -march=hexagon -verify-machineinstrs < %s | FileCheck %s +; +; Check that the testcase compiles successfully. Expect that if-conversion +; took place. +; CHECK-LABEL: fred: +; CHECK: if (!p0) r1 = memw(r0 + #0) + +target triple = "hexagon" + +define void @fred(i32 %p0) local_unnamed_addr align 2 { +b0: + br i1 undef, label %b1, label %b2 + +b1: ; preds = %b0 + %t0 = load i8*, i8** undef, align 4 + br label %b2 + +b2: ; preds = %b1, %b0 + %t1 = phi i8* [ %t0, %b1 ], [ undef, %b0 ] + %t2 = getelementptr inbounds i8, i8* %t1, i32 %p0 + tail call void @llvm.memmove.p0i8.p0i8.i32(i8* undef, i8* %t2, i32 undef, i32 1, i1 false) #1 + unreachable +} + +declare void @llvm.memmove.p0i8.p0i8.i32(i8* nocapture, i8* nocapture readonly, i32, i32, i1) #0 + +attributes #0 = { argmemonly nounwind } +attributes #1 = { nounwind } + diff --git a/llvm/test/Transforms/LoopStrengthReduce/X86/2012-01-13-phielim.ll b/llvm/test/Transforms/LoopStrengthReduce/X86/2012-01-13-phielim.ll index bdc36bdaf2e80..096d89779da34 100644 --- a/llvm/test/Transforms/LoopStrengthReduce/X86/2012-01-13-phielim.ll +++ b/llvm/test/Transforms/LoopStrengthReduce/X86/2012-01-13-phielim.ll @@ -100,6 +100,7 @@ while.end: ; preds = %entry ; CHECK-NEXT: in Loop: Header ; CHECK-NEXT: incq ; CHECK-NEXT: %for.body3.us.i +; CHECK-NEXT: Parent Loop ; CHECK-NEXT: Inner Loop ; CHECK: testb ; CHECK: je